写程序,做产品,过日子

成功其实很简单,就是强迫自己坚持下去

BlogJava 首页 新随笔 联系 聚合 管理
  69 Posts :: 1 Stories :: 92 Comments :: 0 Trackbacks

2006年12月5日 #

Zoundry是最老牌的离线博客客户端。现在的正式名字叫Raven Zoundry,网址是http://www.zoundryraven.com/。它的最大特点是:

  • 可下载和阅读所有已发布的博客文章。
  • 可同时发布到多个博客。
  • 支持多种图片上传方式,如直接上传,FTP上传,ImageShack/Pisca等开放API的相册上传。

在Zoundry中配置博客账户的一般步骤是:

  1. 打开新的博客站点向导窗口,输入博客网址。
     image
  2. Zoundry会自动检测BSP的类型和API,但大多数情况下,需要人工输入。
    image
    这一步是关键,不同的BSP有不同的设置,详情请见后表。
  3. 确认博客名称和媒体库。
     image
    • 如果同一账号下有多个博客,需要在这里选择和第一步中输入的网址想对应的博客。
    • 如果发布博客的API支持上传图片,文件上传方式默认设为“Blog Fileupload”。
    • 如果不能直接使用上传图片,Zoundry会自动创建一个ImageShack的图片库。
    • 也可以不用ImageShack,通过“创建新的媒体库”。

    Note: 不管是使用ImageShack,还是别的 什么相册网张作为图片库。图片都会被上传到指定的相册网站。在你的博客文章中,只是一个指向这个网站的图片连接。

完成配置,Zoundry会自动下载所有已发布的博客文章。

目前,国内门户网站提供的博客服务,大部分根本不支持离线客户端,如新浪,搜狐等。另外一些专业的BSP,或IT领域的一些BSP,也只针对Windows Live Writer提供支持。真正良好支持Zoundry的没几家。具体情况请参见下表。

BSP

API类型

API链接

图片上传

备注

博客园

Customer MetaWeb

http://yourname.blogjava.net/services/metaweblog.aspx

API直接上传

笔者是博客园BlogJava子站的API链接,其他子站类似和

Windows Live Spaces

Windows Live Spaces

http://storage.msn.com/storageservice/MetaWeblog.rpc

需要第三方媒体库,如ImageShack

不要用Windows Live账号的用户名和密码。用户名是WLS空间上的个人域名;密码是机密字

Blogger

Blogger

http://www.blogger.com/feeds/default/blogs

需要第三方媒体库,建议使用Picasa,都是Google一家的嘛。

国内上传API似乎被封了,需要使用国外代理。

使用Gmail用户名,但不要带上gmail.com的后缀。

CSDN博客

Customer MetaWeb

http://blog.csdn.net/yourname/services/metablogapi.aspx

需要第三方媒体库,如ImageShack

没有开放下载博客文章功能。

 

 

 

 

 

Table 1. 国内BSP支持Zoundry的情况

 

Note: Zoundry支持通过代理连接Internet,但在笔者需要用户名和密码验证的代理环境下,所有的BSP都不能接收Zoundry的发布。

Technorati 标签: ,
posted @ 2008-12-16 15:47 Welkin Hu 阅读(1203) | 评论 (4)编辑 收藏


微软实在是太有钱了,一个在线存储就能搞出三套产品,让我等百姓都挑花了眼。到底哪一个才合用呢?存储的容量和速度已经有很多人谈到了。我这里就功能上说一说。

SkyDrive : skydrive.live.com

SkyDrive就是网络磁盘服务,在SkyDrive服务器上为每个用户提供据说是5G的免费空间,用于存储和共享各种文件。用户通过WEB页面进行上传和下载。
SkyDrive是纯Web服务,没有客户端程序,不提供文件夹同步等功能。
SkyDrive面临的竞争对手很多,如Box.net, RayFile, 纳米盘等。

Folder Share : www.foldershare.com

FolderShare不是网络磁盘,而是文件同步工具。他采用P2P技术,为多台机器之间提供文件同步服务。参与同步的机器都必须安装Folder Share 客户端。FolderShare服务器上紧保存同步信息:有哪些文件夹需要同步,在哪几台机器上同步等。但不在服务器上保存需要同步的文件。只有联入互联网的机器才能参与同步。
FolderShare恰如其名,也可以提供文件分享服务。前提是存有源文件的机器要联入互联网。FoldeShare甚至还提供远程桌面服务。
   在Microsoft Office 2007中,还有一个和Folder Share 相似的东东,叫Groove,据说出了P2P同步外,还能P2S同步到服务器。但我没试出来。
 

Mesh www.mesh.com

Live Mesh估计才是微软云存储战略的重点。它兼有Folder ShareSkyDrive的功能。
首先,它通过客户端,提供文件同步功能。本地电脑之间同步时,据说也是采取的P2P技术。
其次,它自带Live Desktop, 为用户提供了据说是2G的网络空间。用户可以在自己的电脑和Live Desktop之间进行文件同步。这样,就不要求用户自己参与同步的电脑都必须同时在线。
最后,它也提供文件共享功能和远程桌面服务。可以和MSN上的朋友共享文件。
由于Mesh的服务器在国外,所以网速比较慢一些。昨晚在ADSL联入下实测上传12M文件到Live Desktop, 时间从22:51 22.57,共6分钟。下载则4分钟不到。
 
 

综述

显然Live Mesh才代表未来。不过目前仍处在beta版,易用性比较差。也不支持需要用户名和密码的代理访问互联网。
FolderShare倒是提供了独立的代理设置,可我怎么试都连不上。
Live Mesh的论坛中列出了十多条重要的功能建议,其中有两条很值得注意:
一是支持授权代理,有了这个我才能用它。
    二是与Folder Share, SkyDrive集成。

, , ,

posted @ 2008-12-08 11:51 Welkin Hu 阅读(863) | 评论 (0)编辑 收藏

加密代理ScribeFire测试

posted @ 2008-12-08 11:50 Welkin Hu 阅读(294) | 评论 (1)编辑 收藏

Google的个性化主页iGoogle是一个非常了不起的服务。我一直都用它作为我的浏览器主页,浏览博客和电子邮件全从这里进入。Google ReaderGmail, Yahoo邮箱,甚至还有我自制的带农历日历,它们全在一个页面,一目了然,方便之至。
进来发现iGoogle的访问有些慢,特别是订阅的博客,都超过3分钟才能出来。再加上不想让Google一家独大,就想试试别家的服务。网上一搜,初选了两家和iGoogle比较:国内的中搜IG([url]http://www.zhongsou.com[/url])和国外的Netvibes([url]www.netvibes.com[/url])
所谓个性化主页,有的叫个人门户,就是把页面分成很多的小区块,这些区块,iGoogleGadget, 中搜IG叫微件,NetvibesContentWidget, 还有的角porlet. 其中WidgetPorlet的叫法比较通用,这里就统一称为widget。普通用户,可以自由的在个性化主页上添加,甚至设计widget。典型的个性化主页布局分为三栏,放置6个左右的widget
本想详细比较的,结果只博客订阅这一项,后两家就被排除了,还是iGoogle好。
iGoogle不但有订阅单个博客的Widget,还有一个Google Reader Widget,可以列出Google Reader中所有订阅的博客和文章。
Netvibes则只有订阅单个博客的Widget,订阅了几个博客,就的放置几个widget。它提供了导入OPML的功能,可以一次性的导入Google Reader的订阅。
中搜IG也只有订阅单个博客的Widget,而且不能导入OPML。中搜IG将博客和RSS分成两个类别。在添加博客时,只能搜索到一些名人博客,我订阅的博客,一个都不能搜索到。PS:它列出来的名人博客,我基本上都没有访问过。我只能在RSS订阅中,一个一个的输入我订阅的博客Feed
个性化主页的重点是集成,通过开放的Web API集成来自不同网站的内容。博客订阅的功能自然比不上专业的服务商,比如Google Reader, 抓虾和Bloglines。提供适用于这些博客订阅服务的Widget才是王道。
posted @ 2008-12-08 11:12 Welkin Hu 阅读(190) | 评论 (0)编辑 收藏

     摘要: 从两三个人的小项目,到几百人的大工程,都需要一套项目管理工具来支撑,用于管理任务,进度,人员,资源和成果等。对于IT项目来说,也是一样。     简单的纸面计划方式显然不能满足时代的需求了。而主流的Microsoft Project系列产品,做计划确实很好很强大。但协同和跟踪功能实在太差劲,文档管理和议题管理更是别完全界定在范围之外。其昂贵的价格更是让人退避三舍。...  阅读全文
posted @ 2008-12-05 20:37 Welkin Hu 阅读(664) | 评论 (2)编辑 收藏

     摘要: 1.      产品简介 网址:http://www.liquidplanner.com 官方博客:http://www.liquidplanner.com/blog/ 公司简介:LiquidPlanner公司,2006年成立,总部位于美国华盛顿州的Bellevue。 官方产品介绍关键词: l  LiquidPlanner是一款All-i...  阅读全文
posted @ 2008-12-05 20:31 Welkin Hu 阅读(1925) | 评论 (1)编辑 收藏

Technorati 标签:

宝贝儿子四岁了,在看他一岁前的录像。

爸爸问:“是录像里面的宝宝可爱呢,还是你可爱?”

宝宝:“还是录像里面的宝宝可爱。”

爸爸:“为什么呢?”

宝宝:“因为他像我呀!”

posted @ 2008-12-04 22:42 Welkin Hu 阅读(179) | 评论 (0)编辑 收藏

     “成功其实很简单,就是强迫自己继续练下去。有的时候很累,很累,但是再辛苦也要坚持,因为梦还在远方!”

       这句话语自今年2月3日,在济南冬训的中国跳水队的一场主题为“我的追求”的演讲比赛,演讲者是郭晶晶。 我是从新华网上找到这则消息的:http://news.xinhuanet.com/sports/2008-02/03/content_7561711.htm

        前天晚上,郭晶晶毫无悬念的以415.35的历史最高分,卫冕北京奥运会女子3米跳板跳水桂冠,并且以4金2银的奥运会成绩成为女子跳水第一人! 这番话也随之脍炙人口。可能有媒体觉得这番话不够精炼,就加工成“成功其实很简单,就是强迫自己坚持下去!”

       我也是在她卫冕之后,才看到这番话的。在看到一刹那,我就被感染了。朴实而深刻。成功,既不困难,也不复杂。它很简单。但是它需要我们坚持,很多时候还的强迫自己坚持下去。

       我决定将这句话作为我新的座佑铭。我要在IT这个领域一直坚持下去,开创自己的事业。

      我的学生时代曾有一个座佑铭,是但丁的名句:“做自己的路,让别人说去吧。”
      那时我是个特立独行的学生,上课极少听讲,作业也不认真。绝大部分课程是靠自学的。在那个师资力量乏弱的环境里,很多老师的信条是“上课不听讲,怎么学的好!”我被视为异类,甚至被老师戏称为鬼才。

      高中文理分科时,我放弃了有较大优势的文科,只是因为不愿再试卷上填满恶心的官话和假话,不愿意将来从事一个以官话和假话为主要生存武器的职业。
      到了填报志愿时,为了我的航天梦想,我没有选择近在咫尺的武大和华工,而是去了冷门的西北工业大学。让我的老师着实失望了一把。
      可是过了大学四年,我发现航天系统很难容下人我这个特立独行的家伙。而且我的兴趣也迁移到计算机上。干脆改换行头,脱机入电,干起了软件开发。
      工作后,渐渐发现自己并不是很特立独行了,做的事情都是别人曾经做过事情,研究的东西也都是别人搞出来的东西。于是慢慢的不提“走自己的路,让别人去说吧。”,慢慢的也就变得浑浑噩噩了。
       如今已是三十而立,上有老,下有小,再不能一事无成了。我要以这句话自勉,闯出自己的一片天地!
posted @ 2008-08-19 14:17 Welkin Hu 阅读(476) | 评论 (3)编辑 收藏

Maven 2的安装和使用虽然不是一点即用,但也不是很复杂。然而,这两天我新装Maven,刚刚过了mvn -version,尝试create maven project就出问题了。问题详情如下。

D:\mavenSample>mvn archetype:create -DgroupId=com.mycompany.app -DartifactId=my-app
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'archetype'.
[INFO] org.apache.maven.plugins: checking for updates from central
[INFO] org.codehaus.mojo: checking for updates from central
[INFO] artifact org.apache.maven.plugins:maven-archetype-plugin: checking for updates from central
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] The plugin 'org.apache.maven.plugins:maven-archetype-plugin' does not exist or no valid version could be found
[INFO] ------------------------------------------------------------------------
[INFO] For more information, run Maven with the -e switch
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3 seconds
[INFO] Finished at: Wed Mar 19 14:26:49 CST 2008
[INFO] Final Memory: 1M/2M
[INFO] ------------------------------------------------------------------------

开始以为是internet 代理设置有问题。网上也有帖子这么说。可是换到ADSL后,不用代理了,问题仍然存在。

几经周折后发现,原因在于我画蛇添足多加了几个镜像,其中有的镜像没有同步更新maven库。经过测试,如下maven 镜像工作正常:

<mirror>
<id>ibiblio.org</id>
<name>ibiblio Mirror of http://repo1.maven.org/maven2/</name>
<url>http://mirrors.ibiblio.org/pub/mirrors/maven2</url>
<mirrorOf>central</mirrorOf>
<!-- United States, North Carolina -->
</mirror>
<mirror>
<id>redv.com</id>
<url>http://mirrors.redv.com/maven2</url>
<mirrorOf>central</mirrorOf>
<!-- Shanghai, China , Very fast-->
</mirror>
<mirror>
<id>dotsrc.org</id>
<url>http://mirrors.dotsrc.org/maven2</url>
<mirrorOf>central</mirrorOf>
<!-- Denmark -->
</mirror>
<mirror>
<id>sunsite.dk</id>
<url>http://mirrors.sunsite.dk/maven2</url>
<mirrorOf>central</mirrorOf>
<!-- Denmark -->
</mirror>
<mirror>
<id>skynet.be</id>
<url>http://maven2.mirrors.skynet.be/pub/maven2</url>
<mirrorOf>central</mirrorOf>
<!-- Belgium -->
</mirror>
<mirror>
<id>cica.es</id>
<url>http://ftp.cica.es/mirrors/maven2</url>
<mirrorOf>central</mirrorOf>
<!-- Spain, Sevilla -->
</mirror>
<!-- these just point to ibiblio.org -->
<mirror>
<id>ibiblio.net</id>
<name>ibiblio.net Mirror of http://repo1.maven.org/maven2/</name>
<url>http://www.ibiblio.net/pub/packages/maven2</url>
<mirrorOf>central</mirrorOf>
<!-- United States, North Carolina Fast-->
</mirror>

而下面的Maven镜像都有问题。

<mirror>
<id>planetmirror</id>
<name>Australian Mirror of http://repo1.maven.org/maven2/</name>
<url>http://public.planetmirror.com/maven2/</url>
<mirrorOf>central</mirrorOf>
</mirror>
<mirror>
<id>lsu.edu</id>
<url>http://ibiblio.lsu.edu/main/pub/packages/maven2</url>
<mirrorOf>central</mirrorOf>
<!-- United States, Louisiana -->
</mirror>
<mirror>
<id>sateh.com</id>
<url>http://maven.sateh.com/repository</url>
<mirrorOf>central</mirrorOf>
<!-- The Netherlands, Amsterdam -->
</mirror>
<mirror>
<id>ggi-project.org</id>
<url>http://ftp.ggi-project.org/pub/packages/maven2</url>
<mirrorOf>central</mirrorOf>
<!-- The Netherlands, Amsterdam -->
</mirror>

posted @ 2008-08-13 12:40 Welkin Hu 阅读(1987) | 评论 (0)编辑 收藏

博客搜索已经出来个年头了,我一直都没用过。博客和普通的网页并没什么大的区别。只要能搜出想要的东西,我并不介意结果是在博客,论坛或其他的什么网页上。

所以我一直不明白为什么要把博客搜索和普通网页搜索分离。今天看了一下有关的资料。原来博客搜索强调的是时效性——你刚写好博客,就能被人从搜索服务中搜到!据说搜索引擎更新普通网页的频率长达一周左右。

仔细想想还真是这个理,从Google、百度等搜到的东西,真的有很多是陈年古董。而搜索新闻时十有八九不如意。

除了时效性外,让博客文章有机会在海量的搜索结果中浮出水面也是一大原因。也许是搜索竞价排名惹得祸,通过普通搜索得到的结果,博客文章往往被淹没了。

以此类推,除了博客外,论坛,新闻等都需要单独的搜索服务。

posted @ 2008-08-13 12:36 Welkin Hu 阅读(195) | 评论 (0)编辑 收藏

一直想找一个理想的网页书签收藏工具,可是始终未能如愿。我对理想的书签收藏的要求是:

  1. 有在线服务,不会因为换了电脑就找不到书签了。
  2. 不用打开在线书签的网页,就可以在IE和Firefox中找到,服务器与本机自动同步。
  3. 同时适用于IE和Firefox。
  4. 最好能集成到IE/Firefox自带的书签/收藏夹中去。

目前业界提供在线书签服务的其实很多,但没有一个能完全达到这些要求。

IE专用插件:IE Pro

http://www.ie7pro.com/

特点
  • 提供在线收藏服务。
  • 与IE收藏夹完全集成。每次关闭IE时同步收藏夹。
  • 提供多种实用服务。
  • 仅在工具栏中占一个图标位置。
缺点
  • IE7专用,不适用于FireFox。
  • 在线收藏的服务器可能在美国,网速较慢。

Firefox专用插件: Foxmarks Bookmark Synchronizer

https://addons.mozilla.org/zh-CN/firefox/addon/2410

特点
  • 与IE Pro 类似的书签插件,提供在线收藏服务。
  • 与Firefox书签菜单完全集成。
  • 没有额外菜单和工具图标
缺点
  • Firefox专用,不适用于IE。
  • 在线收藏的服务器可能在美国,网速较慢。

FireFox中使用IE搜藏夹插件: PlainOldFavorites

https://addons.mozilla.org/zh-CN/firefox/addon/668

特点
  • 在Firefox上额外添加一个"收藏"菜单,列出本机IE收藏夹的内容。
  • Firefox原有的书签功能不受影响。
缺点
  • 没有在线服务,仅适用于一台电脑上的IE和Firefox
  • 可通过"收藏"菜单添加当前页到收藏夹,但不能通过右键添加。
  • "收藏"与"书签"两个菜单并存,本应加到"收藏"中的书签经常被加到"书签"中。
  • 不能应用于"书签工具栏"上的书签项,而这些书签项通常是最常用的。

在线书签 Delicious

http://delicious.com 据说是现在最好的在线书签服务商。目前已被雅虎收购并升级为Delicious 2.0. 原来的怪异网址del.icio.us也不再主推了。

特点
  • 良好的在线书签服务功能。
  • 标签化书签管理,书签搜索功能。特别适用于大量的书签管理。
  • 同时为IE和Firefox提供了插件。
  • IE/Firefox插件仅占用两三个工具图标位,不用单独占用一行。
缺点
  • 浏览器插件并没有浏览器自带的"收藏/书签"功能集成。不能相互同步。
  • 似乎不能通过右键添加书签。
  • 在线收藏的服务器可能在美国,网速较慢。
  • 不能批量删除书签。
  • 不支持树形目录。
  • 排序功能很差。
  • 不能应用于"书签工具栏"上的书签项,而这些书签项通常是最常用的。

在线书签 Google bookmarks

http://www.google.com/bookmarks/,提供与Delicious相似的在线书签服务。据说市场份额早已超过Delicious.

特点
  • 良好的在线书签服务功能。
  • 标签化书签管理,书签搜索功能。特别适用于大量的书签管理。
  • 与google笔记功能集成,这是一绝啊!
  • 在IE和Firefox的google工具栏提供了书签菜单
  • Firefox下还有第三方开发的Gmark插件,能以树型方式展现书签。
  • Google服务器,数度快,稳定。
缺点
  • 无论在IE中,还是在FireFox中,google工具栏都要独占一行。而且搜索框十分多余!
  • 浏览器插件并没有浏览器自带的"收藏/书签"功能集成。不能相互同步。
  • 似乎不能通过右键添加书签。
  • 界面太简单,不支持树形目录。
  • 不能应用于"书签工具栏"上的书签项,而这些书签项通常是最常用的。

image

其他在线书签服务

Windows Live Favorites :
  • 与IE收藏夹完全集成。但不适用Firefox。
  • 服务器超级慢。
Baidu搜藏
  • 与Google bookmarks类似。
  • 需要通过baidu工具栏与浏览器集成,与google工具栏存在一样的问题。
  • 同过添加注册表项,可在IE中支持右键添加。
  • 特色功能,如果书签指向的网址失效,可显示相应的百度快照
QQ书签
  • 与Google bookmarks类似。
  • 与QQ集成
Furl.net
  • 与Delicious类似。
  • 无IE插件或工具栏集成。
  • Firefox中有插件集成。
  • 特色功能:为所有书签指向的网页保存了备份,以防失效。
  • 服务器超级慢。

组合服务,覆盖在线书签,IE和firefox.

方案一 IE Pro + PlainOldFavorites
  1. 使用IE Pro 插件,在IE中获得在线服务。
  2. Firefox中同过PlainOldFavorites插件,直接使用IE收藏夹。
  3. Firefox自带的书签功能基本不用。
方案二 Google bookmarks.
  1. 使用Google bookmarks在线服务。
  2. IE中安装 Google 工具栏,忍受一下它的独占一行。
  3. Firefox中安装Gmark插件
  4. Firefox自带的书签功能基本不用。
posted @ 2008-08-13 12:28 Welkin Hu 阅读(2679) | 评论 (1)编辑 收藏

今天顺手是了一下Google Sites.

写了一个含iFrame的html页面放上去,居然不让过。报错如下:

HTML content will be modified

Your HTML either contains unsafe tags (iframe, embed, styles, script) or extra attributes. They will be removed when the page is viewed.

但是 google 自己的 Calendar, Docs, Video, 甚至乱七八糟的 gadget 都可以加进去。

51.la 专业、免费、强健的访问统计

posted @ 2008-08-09 17:27 Welkin Hu 阅读(325) | 评论 (0)编辑 收藏

Blog要在群里活的才滋润。从上半年开始,我的主要工作就不是Java了,这个BlogJava的站变得越来越不适合我。很多东西我只能选择发到"非技术区"。

posted @ 2008-08-09 15:21 Welkin Hu 阅读(227) | 评论 (0)编辑 收藏

目前免费的带语法高亮的文本编辑器,最优秀的莫过于PSPad和Notepad++。就个人使用感受,Notepad++更胜一筹,除了列编辑模式欠缺,和UltraEdit、EditPlus有一拼。用了好几个月,但实在受不了Notepad++主页上的“抵制北京奥运会”,最终决定弃用它。
本人忙于供房养家,对北京奥运会并不感冒。但对这种以技术外衣,宣扬反华的行为却是无法容忍。

posted @ 2008-06-03 17:34 Welkin Hu 阅读(2671) | 评论 (10)编辑 收藏

近来根据公司要求,学习Microsoft.Net。于是仿照EyeLoveU,写了一个C#的小程序。现在比较稳定了,就想放到在SoruceForge这样的网站上去秀一秀。

最开始考虑的自然是SourceForge。但在公司需要通过Proxy访问sourceforge.net时,速度奇慢。

第二个考虑的是Google Code。无论在家通过ADSL访问,还是在公司通过Proxy访问,速度都可以接受。最好用的是支持对Issue, Discussion, Document等自定义属性标签,如priority, type, milestone等。

无论是SourceForge,还是Google Code,与subversion和eclipse的集成都非常好。可是我用的是Microsoft Visual Studio 2008和C#,与这两个东家都不合拍:

  •  Subversion 与VS2008的集成需要购买Visual SVN
  • VS2008不能发布下载包到SourceForge和Google Code上。

最后我发现CodePlex这个网站,居然提供Visual Studio Team Fundation Server的服务。与我用的VS2008完全是一家!可惜的是它的网速非常不稳定,很难访问。估计服务器只在美国。最要命的是,在公司的Proxy环境下,我可以从IE访问CodePlex的VSTS服务器,但VS2008的Team Explorer怎么也访问不了。

posted @ 2008-02-27 10:20 Welkin Hu 阅读(1197) | 评论 (0)编辑 收藏

Collection mapping table

HBM Element Java Interface Java Implementation
<set> Set HashSet
<set> with order SortedSet TreeSet
<list> List ArrayList
<bag>, <idbag> Collection ArrayList
<map> Map HashMap
<map> with order SortedMap TreeMap
<array>, <primitive-array> N/A array

 

Sample Tables

CREATE TABLE `core_sample_company` (
  `companyId` decimal(18,0) NOT NULL,
  `companyName` varchar(128) NOT NULL,
  `description` varchar(1024) default NULL,
  PRIMARY KEY  (`companyId`)
);

CREATE TABLE `core_sample_role` (
  `roleId` decimal(18,0) NOT NULL,
  `roleName` varchar(128) NOT NULL,
  `companyId` decimal(18,0) NOT NULL,
  `description` varchar(1024) default NULL,
  PRIMARY KEY  (`roleId`)
);

CREATE TABLE `core_sample_user` (
  `userId` decimal(18,0) NOT NULL,
  `userName` varchar(128) NOT NULL,
  `companyId` decimal(18,0) NOT NULL,
  `defaultRoleId` decimal(18,0) default NULL,
  `description` varchar(1024) default NULL,
  PRIMARY KEY  (`userId`)
);

CREATE TABLE `core_sample_user_role` (
  `userId` decimal(18,0) NOT NULL,
  `roleId` decimal(18,0) NOT NULL,
  `pripority` int(11) NOT NULL,
  PRIMARY KEY  (`userId`,`roleId`)
);

HBM defintion

The definiton of <set>, <bag>, <list> is similar.

Defines a collection whose element type is simple data type.

<class name="SampleCompany" table="core_sample_company">

        <bag name="roleNames" table="core_sample_role" lazy="false" >
            <key column="companyId"/>
            <element column="roleName" type="string"/>
        </bag>

</class>

Query HQL: select c.id, c.name, r from SampleCompany c left join c.roleNames r

Defines a collection whose element type is another mapped java class

<class name="SampleCompany" table="core_sample_company">   

   <bag name="roles" cascade="none">
            <key column="companyId"/>
            <one-to-many class="SampleRole" not-found="ignore"/>
        </bag>

</class>

Query HQL: select c.id, c.name, r.name from SampleCompany c left join c.role r

Pay attention that key column is a foreign column of SampleRole table.

Defines a list with list-index

<list> is not a popular element. It request a index column in table. The index column is the index of java List, it has to be a sequence starts from 0.

<class name="SampleUser" table="core_sample_user">

     <list name="roles" table="core_sample_user_role" cascade="all" lazy="false" >
            <key><column name="userId" sql-type="integer"/></key>
            <index column="priority"></index>
            <many-to-many class="SampleRole">
                <column name="roleId"></column>
            </many-to-many>
        </list>

</class>

The benifit of <list> is it alwasy sorts list by index column. However, It is hard to resort the list. I tried remove a role from role list and add it to another poisition. When save the role list, an exception throwed:

java.sql.BatchUpdateException: Duplicate entry 'user001-role003 for key 1

This should be a hibernate bug.

Defines a bag with relationship table

<class name="SampleRole" table="core_sample_role">

      <bag name="users" table="core_sample_user_role" cascade="none" lazy="false">
            <key><column name="roleId" sql-type="integer"/></key>
            <many-to-many class="SampleUser">
                <column name="userId"></column>
            </many-to-many>
        </bag>

</class>

  • Key column is foreign column from relationship table to current table(SampleRole>
  • many-to-many sub column is foreign column from relationship table to target table (SampleUser)
posted @ 2007-10-24 11:09 Welkin Hu 阅读(692) | 评论 (0)编辑 收藏

转贴自:http://news.newhua.com/Html/System_win/2004-9/8/16...

 

安装Windows XP时,如果设置了一个管理员账户,那么系统内置没有密码保护的Administrator管理员账户是不会出现在用户登录列表中的。虽然它身在幕后,可却拥有系统最高权限,为了方便操作及保证系统安全,可以先给它设置密码,然后再把它请到台前来。以下便介绍具体方法。

1.使用“传统登录提示”登录

  启动系统到欢迎屏幕时,按两次“Ctrl+Alt+Delete”组合键,在出现的登录框中输入Administrator账户的用户名和密码即可。也可以单击“开始→控制面板”,双击“用户账号”图标,在弹出的“用户账号”窗口中,单击“更改用户登录或注销的方式”,去掉“使用欢迎屏幕”前的复选框,单击“应用选项”即可在启动时直接输入Administrator账户名及密码登录。

2.在登录的欢迎屏幕显示Administrator账户

  单击“开始→运行”,输入regedit后回车,打开注册表编辑器,依次展开“HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\SpecialAccounts\UserList”分支,将右边的Administrator的值改为1,即可让Administrator账户出现在登录的欢迎屏幕上。

3.自动登录到Administrator账户

  单击“开始→运行”,输入control userpasswords2后回车,在打开的“用户账户”窗口去掉“要使用本机,用户必须输入密码”前的复选框,按“应用”后,在弹出的“自动登录”窗口中输入Administrator账户密码(如图1),按两次“确定”即可。注意:如果原来就设置了其它账户自动登录,应该先选中“要使用本机,用户必须输入密码”前的复选框,按“应用”后再去掉选中的复选框。也可以修改注册表实现自动登录,不过没有以上方法方便。

  图1

  当然,如果不需要Administrator账户,可以依次打开“开始→控制面板→管理工具→计算机管理”,在“计算机管理”窗口,展开“系统工具→本地用户和组→用户”,在“用户”右边窗口双击Administrator账户,在弹出的“属性”窗口中选中“账号已停用”前的复选框(如图2),按“确定”即可停用Administrator账户。

  图2

 

补充材料:修改注册表来实现XP的自动登录

 

在进入Windows XP桌面之前,每次都会出现一个用脑登录界面,要求我们输入用户名与密码,可以加大了系统的安全性,也为多人共用一台电脑提供了方便,但如果是家用电脑,只有你一个人使用,这样每次密码,的确不有点不大方便。我们可以通过修改注册表来实现XP的自动登录。

  第1步:运行注册表编辑器,依次展开[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon ]分支,然后在右侧窗口双击“DefaultUserName”,接着输入你的登录用户名。如果没有预设的用户名称,可以在注册表编辑器的菜单栏点选“编辑→新建→字符串值(s)→DefaultUserName”来添加这个项目,注意要区分大小写字母。  

  第2步:同样在该分支下,在注册表编辑器的右侧窗口中双击“DefaultPassword”,然后在空白栏内输入你的密码。假如未发现“DefaultPassword”一项,可按上面的步骤来新建该字符串值。  

  第3步:接下来在右侧窗口中双击“AutoAdminLogon”,将数值设置为“1”。假如未发现“AutoAdminLogon”,可按上面的步骤来新建。  

  现在关闭注册表编辑器并重新启动电脑,以后你会发现那个令人讨厌的登录对话框不见了。

posted @ 2007-08-31 14:07 Welkin Hu 阅读(1295) | 评论 (1)编辑 收藏

Office 2007使用Ribbon代替了主菜单和工具栏。而Ribbon中没有选项设置这一栏。经过查找,发现它被挤一个很不起眼的地方。

 

在Office 2007(Word等)的左上角,有一个Office图标按钮。点击它就会弹出一个菜单窗口,里面包含着Ribbon上没有的菜单项。其中在菜单窗口的右下方,有一个"Word Options"的按钮,这个就是选项设置的菜单了。

Outlook写邮件时,用的编辑器也是Word,但它的设置与Word的设置是独立的。必须在Outlook中打开编辑器,与Word一样设置编辑器选项。

 

这里列举几个比较重要的设置例子。

一、消除换行符。

Word 2007中默认会显示一直回车换行符。通过点击Ribbon上Paragraph栏中的"Show/Hide Edit Marks"图标并不能消除它。打开"Word Options"窗口,选择"Display"栏,勾掉一直显示符号中的"Paragrahp Marks"项,就可以不显示回车换行符了。

 

二、不让输入法随Office启动。

如果安装了中文输入法(当然,其它语言的输入法也一样),这个输入法有可能总跟着Word/Outlook一起启动。非常烦人。要去掉这个特性,只需勾掉“Edit Options"中的最后一项“IME Control Active”。如下图所示。

同时,还建议大家在控制面板中,把高级语言服务关掉。实际上大家常用的中文输入法只有一种,直接使用Ctrl+Space的方法最方便。根本不需要鼠标切换。

 

0001

posted @ 2007-08-20 09:45 Welkin Hu 阅读(3061) | 评论 (1)编辑 收藏

Sysdeo是知名的Tomcat插件。今天在构建eclipse 3.3 + sysdeo3.2.1 + tomcat 6.0.13时,发现如下几个注意点。

  1. Sysdeo主配置项中Tomcat Home是配置Tomcat目录的,注意最后不要加“\”。比如F:\java\tomcat-6.0.13是对了,F:\java\tomcat-6.0.13\就不对了。
  2. Sysdeo advance配置中的Tomcat Base指的是配置Tomcat运行时的基准目录。实际上这个配置项是多余的,可以不配,也不应当配。它必须和Sysdeo主配置项中Tomcat Home一致,否则会有一些Tomcat系统文件找不到。
  3. 如果不通过eclipse和Sysdeo,直接运行Tomcat的startup.bat,基准目录是%TOMCAT_HOME%/webapps。而sysdeo设定的基准目录是%TOMCAT_HOME%。这个会导致一些冲突。比如放在%TOMCAT_HOME%/logs/中的log文件的位置,直接运行要写成“../logs/app.log”,运行sysdeo时要写成“logs/app.log”
posted @ 2007-07-03 18:06 Welkin Hu 阅读(1219) | 评论 (1)编辑 收藏

1、不得在超类中使用通配符,例如

public class PojoModelTree extends IdentifiableTree<? extends PojoModel>

错误信息如下:

The type PojoModelTree cannot extend or implement IdentifiableTree<? extends PojoModel>. A
supertype may not specify any wildcard

2、只有<? super Type>,没有<E super Type>

正确用法:TreeNode<? super Node> getTree()

错误用法 <E super Node> E getParent();

3、函数返回值类型不应使用通配符:

错误用法:TreeNode<? extends T> getChildNode(String pKey)

这种用法本身无错,但在赋返回值给其它变量时会报类型不匹配。

正确用法:<N extends T> TreeNode<N> getChildNode(String pKey)

4、带通配符的泛型集合不能使用add方法。不带通配符的泛型集合也可接收子类元素。

错误用法:

List<? extends Number> list1 = new ArrayList<Number>();
list1.add(new Integer(11)); // 类型不匹配。

第二行报错为:

The method add(capture#1-of ? extends Number) in the type List<capture#1-of ? extends
Number> is not applicable for the arguments (Integer)

正确用法:

List<Number> list1 = new ArrayList<Number>();
list1.add(new Integer(11));

显然,在泛型的检查之下,仍可向集合中添加指定泛型的子类元素。以下代码也是合法的:

List<Number> list1 = new ArrayList<Number>();
list1.add(new Integer(11));
List<Integer> list2 = new ArrayList<Integer>();
list2.add(33);
list2.add(44);
list1.addAll(list2);

但是,如果写list1=list2就不合法了。

Technorati : ,

posted @ 2007-06-20 09:37 Welkin Hu 阅读(2491) | 评论 (0)编辑 收藏

Spring对Hibernate Session Factory提供了高度封装。如下例所示。

<bean id="mySessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource"/>
<property name="mappingResources">
<list>
<value>product.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.HSQLDialect
</value>
</property>
</bean>

然而,在我的案例中,因为业务需要,我们必须在运行时加入新的HBM。在单独使用Hibernate的时,只要取到Hiberante Configuration对象,修改一下配置,然后rebuild session factory就可以了。

可是经Spring这一封装,我只能取到一个只读的SessionFactory对象,无法进行重置。

这里有两种可能方法,但我都不知道如何做。

1,取到LocalSessionFactoryBean对象进行重置。

2,取到Hibernate Configuration对象进行重置。

Technorati : , ,

posted @ 2007-06-11 17:46 Welkin Hu 阅读(4477) | 评论 (5)编辑 收藏

Spring 2.0无缝集成了Hibernate.提供了很多功能。但在我看来,除了整合事务管理外,很多功能都 是可有可无的。

最典型的就是HibernateTemplate,这个类其实就是代理了Hibernate Session的所有功能。把我看得一愣一愣的。半天没明白这个类有什么奇妙用处。我用Hiberante API已经轻车熟路,自然不愿再学习新的API。

它引入这个HibernateTemplate有什么作用呢?其API也不比Hibernate的API简单啊。

后来的测试表明Spring对Hibernate原生的API在事务支持上存在一些问题,而用HibernateTemplate,事务就运行得很好。

Technorati : , ,

posted @ 2007-06-11 13:53 Welkin Hu 阅读(5861) | 评论 (8)编辑 收藏

1. 在Eclipse中运行DOS

这种方法的好处是连DOS执行窗口也集成在Eclipse Console中。

在上面的设置是,Working Directory的设置非常重要。${container_loc}表示以当前选中文件的上级目录为工作目录。如果你选中的是某个目录,比如说某个包,那么很不幸,它会指向这个目录的上级目录。所以,${container_loc}只适合选中一个文件的情况。

另一个变量${resource_loc}则相反,它总是以选中的文件或目录为工作目录。就是说它适合选中一个目录的情况。如果选中一个文件,运行DOS就会出错,因为文件不能作为DOS的工作目录。

两个变量各有优缺点。由于Java编程中,大部分DOS命令是在工程目录下执行的,所以${resource_loc}会好一些。使用${container_loc}很难定位到工程目录。

2. Mylar导致Content Assist中出现重复的方法提示。

最近发现我的Eclipse 3.3M7中出了个不大不小的问题,就是Java编辑窗口中的代码提示工具把每一个方法都重复的列了两次。如下图所示。

这个问题让我百思不得其解,最后打开java -> Editor ->Content Assist的设置,才发现是新装了Mylar的原因。如下图所示,Mylar为content assist增加了几个同名的Proposal,将这些同名的Porposals任意勾掉一个就解决问题了。

Technorati :

posted @ 2007-05-22 09:48 Welkin Hu 阅读(373) | 评论 (1)编辑 收藏

Spring和AOP像一个强力的粘合剂,将完全独立开发的组件(或说是模块,下同)粘合成一个有机的,完整的,可扩展的系统。正是有了这个粘合剂的帮助,才实现了比较彻底的独立组件开发。

说它是“比较彻底”,是因为它极大的减少了组件之间的依赖。在你开发一个组件时,基本上不会因为其它组件没有开发完成,或出现Bug而影响到你的进度。

但是,它并没有完全消除开发时组件之间的依赖,你仍然得依赖于其它组件提供的API接口。为此,我们不得不把一个组件拆成两个jar包:一个component-api.jar,一个component-impl.jar。由于api包内全是公用接口和Value Object,所以它相对稳定,可以早早的提供出来。这样,一个组件如果要使用另一个组件的服务,在开发阶段,只须依赖于api包即可。运行时,Spring再根据服务提供组件的配置信息找到正确的实现类。

 

昨天,我们在一个讨论会上发现了一个有趣的问题:

组件UIA是一个UI组件,它要求提供一些数据,于时它把自己的要求写时接口ProviderA中。组件C1和C2是两个不同的业务组件,它们的UI中都有使用UIA这个组件,而它们都提供了自己的数据接口ServiceC1和ServiceC2。

ProviderA所要求的方法,在ServiceC1和ServiceC2中都有提供。这个时候怎么做才能使各个组件完独立呢。

一、让ServiceC1和ServiceC2继承于ProviderA。但是这样将导致业务组件依赖于UI组件。有谁知道一共有多少个UI组件需要依赖啊?而且UI组件是最易变的。

二、把ProviderA从uia.jar抽出来,放到单独的uia-api.jar中。这个就未免小题大做了。一个系统少说也有几十个UI组件,难道要生成上百个jar包不成?

三、把所有的UI的要求的API都抽出来,放到一个ui-api.jar中。这样jar包是少了,可是单个的UI组件就失去独立性了。

上面三个方案,不管怎么管理UI组件的接口,都没有解决业务组件依赖于不定数目的UI组件这个问题。

 

最后,我们采用的方法是:把UI组件视为某个业务组件的子组件,UI组件自己不定义接口。所有对外的接口和对UI的接口,都放在业务组件的api包中。

这样做,业务组件和UI组件都依赖于api包,互相之间没有依赖。当然,这样做,UI组件就不能游离于大的业务组件之外。而我们采用这个方案的原因也在于,我们认定为多个组件提供服务的UI组件是很少的。

 

显然我们采用的方法只是就事论事的一个折衷方案。并没有解决服务提供者和消费者之间的交叉依赖。

要解决这种交叉依赖,我的思路是再提供一个接口之间的粘合机制。消费者定义自己要求的服务接口,提供者定义自己提供的服务接口。最后用一个配置文件,将二者粘合起来。

目前,Spring还没有提供这种功能。

posted @ 2007-05-11 10:00 Welkin Hu 阅读(1186) | 评论 (9)编辑 收藏

Windows网上邻居互访的基本条件

1) 双方计算机打开,且设置了网络共享资源;
2) 双方的计算机添加了 "Microsoft 网络文件和打印共享" 服务;
3) 双方都正确设置了网内IP地址,且必须在一个网段中;

4) 双方的计算机中都关闭了防火墙,或者防火墙策略中没有阻止网上邻居访问的策略。



Windows 98/2000/XP/2003访问XP的用户验证问题



首先关于启用Guest为什么不能访问的问题:



1、默认情况下,XP 禁用Guest帐户



2、默认情况下,XP的本地安全策略禁止Guest用户从网络访问



3、默认情况下,XP的 本地安全策略 -> 安全选项 里,"账户:使用空密码用户只能进行控制台登录"是启用的,也就是说,空密码的任何账户都不能从网络访问只能本地登录,Guest默认空密码......



所以,如果需要使用Guest用户访问XP的话,要进行上面的三个设置:启用Guest、修改安全策略允许Guest从网络访问、禁用3里面的安全策略或者给Guest加个密码。



有时还会遇到另外一种情况:访问XP的时候,登录对话框中的用户名是灰的,始终是Guest用户,不能输入别的用户帐号。



原因是这个安全策略在作怪(管理工具 -> 本地安全策略 -> 安全选项 -> "网络访问:本地帐户的共享和安全模式")。默认情况下,XP的访问方式是"仅来宾"的方式,那么你访问它,当然就固定为Guest不能输入其他用户帐号了。



所以,访问XP最简单的方法就是:不用启用Guest,仅修改上面的安全策略为"经典"就行了。别的系统访问XP就可以自己输入帐户信息。



至于访问2003,默认情况下2003禁用Guest,但是没有 XP 那个讨厌的默认自相矛盾的来宾方式共享,所以可以直接输入用户名密码访问。



一个小型办公局域网,都是winxp系统,都能上外网,也能看到对方计算机,却不能看到对方共享的计算机提示网络路径不正确,或你没有权限使用网络大概就是这个意思 我记的不太清楚!!来宾帐户我也启用了!winxp的防火墙也是关闭的,ip地址也没什么问题!!



原因:Win2000/XP中存在安全策略限制。



有时,Win2000/XP"聪明"过了头,虽然我们已经启用了Guest账户,从Win98中却仍然无法访问Win2000/XP,比如使用了类似瑞星等的防火墙漏洞修补,它会修改"拒绝从网络访问这台计算机"的策略,按下面的方法修改回来:



开始 -> 运行 -> gpedit.msc -> 计算机配置 -> windows设置 -> 本地策略 -> 用户权利分配 -> 删除"拒绝从网络访问这台计算机"中的guest用户。



Win2000/XP与Win98互访



如果两台电脑都使用Win2000/XP操作系统,那么组建局域网是一件非常简单轻松的事情,当硬件连接完成后,正常情况下立即可以在"网上邻居"中看到对方。但如果局域网中有一台电脑使用Win98,那情况可就不一定了,我们经常会发觉虽然Ping命令可以通过,但仍然无法在"网上邻居"中实现互访,这时该怎么办呢?




对策一:在Win2000/XP中启用Guest用户。在Win2000/XP系统安装之后会缺省建立两个用户账户,即Administrator(系统管理员)和Guest(来宾账户),所有在本地计算机没有被分配到账户的用户都将默认使用Guest账户,该账户是没有密码的。不过,在缺省设置下,这个Guest账户并未被启用,我们可以从"控制面板|管理工具|计算机管理|本地用户和组|用户"中找到 "Guest"账户,并用鼠标右击打开"Guest属性"对话框,去除这里的"账户已停用"复选框上的对钩标记,这样退出后就可以从Win98中访问到 Win2000/XP了。



其实,启用了Guest账户后,最大的好处是从Win98访问Win2000/XP时就不需要输入用户名和密码了,这种方法比较适合于用户不确定、访问量较大的局域网,但对家庭用户来说并不适用。



对策二:检查Win2000/XP中是否存在安全策略限制。有时,Win2000/XP"聪明"过了头,虽然我们已经启用了Guest账户,从 Win98中却仍然无法访问Win2000/XP,这时就要从"控制面板|管理工具|本地安全策略|本地策略|用户权利指派"中找到"从网络访问此计算机 "或者"拒绝从网络访问这台计算机",然后检查一下其中是否出现了Guest账户或者其他对应的账户,然后根据不同情况进行添加或者删除即可。



对策三:停用本地连接上的防火墙。防火墙是充当网络与外部世界之间的保卫边界的安全系统,微软在WinXP中为用户提供了一个内置的Internet连接防火墙(ICF),启用后可以限制某些不安全信息从外部进入内部网络。不过,如果您是在本地连接上启用了这个防火墙,那么就会造成工作组之间无法互访,出现"XXX无法访问"、"您可能没有权限使用网络资源"、"请与这台服务器的管理员联系以查明您是否有访问权限"、"找不到网络路径"等类似的提示,此时请停用本地连接的防火墙屏蔽。



对策四:为WinXP添加NetBEUI协议。其实,直接添加NetBEUI协议对于解决不能互访的问题有时反而更为简单一些,而且它可以解决上面提到的启用防火墙的问题。Win98安装时会自动安装NetBEUI协议,但由于WinXP已经不再提供对NetBEUI协议的技术支持,因此只能手工添加了。



找出WinXP安装光盘,进入"valueadd\Msft\Net\ Netbeui"文件夹下,这里有Nbf.sys、Netbeui.txt、Netnbf.inf共3个文件,先将Nbf.sys文件复制到本机的 "Windows\System32\Drivers"文件夹下(这里的本机指安装了WinXP的那台电脑),再将Netnbf.inf文件复制到本机的 "Windows\INF"文件夹下,Netbeui.txt文件可有可无。不过, INF文件夹具有隐藏属性,用户需要先在WinXP下的"工具|属性"窗口中选择显示文件才可以看到该目录。



对策五:启用 Win98中的"文件及打印机共享"。这是一个很简单但却经常被人忽略的问题,就是装有Win2000/XP的机器虽然可以从"网上邻居"中发现装有 Win98的机器,但却无法访问,这是因为Win98未启用"允许其他用户访问我的文件"而造成的,启用该选项就可以解决这个问题。



当然,除了上面提到的各种原因外,还有两台电脑不处于同一工作组中,或者是两台电脑的内部IP地址发生了冲突,甚至包括Hub故障、线路故障等。

posted @ 2007-05-10 21:48 Welkin Hu 阅读(553) | 评论 (0)编辑 收藏

     摘要: Powerdesigner是我最喜欢的建模软件,其功能最全,易用性最好,使用感受最舒服。可扩展性也非常好。
Powerdesigner对MDA的支持很灵活。其实,MDA工具所要做的事情,就是UML模型与代码间的双向转换,这里面有两个关键点:
1、模型生成的代码不能是垃圾代码,要正确,还要符合我们所指定的编码规范——尤其是注释。
2、从代码到模型再到代码时,原始代码中的所有内容应当充分保留。不应发生注释或方法体丢失。
我根据特定的编码规范,通过二次定制powerdeisgner的java 5语言成功实现了上述MDA特性。  阅读全文
posted @ 2007-05-04 15:57 Welkin Hu 阅读(1316) | 评论 (1)编辑 收藏

AOP的概念已经热了很久了,我一直不太关注,也不太理解这个面向方面编程中的方面是什么意思。由于AOP和OOP仅一字之差,所以在网上看到大量的文章来拿这两个作对比,看完后还是稀里糊涂的。

 

这段时间开始拿Spring做新产品,于是开始仔细研究AOP。这才发现AOP和OOP讲的根本不是同一类的东西。 

AOP中的方面是指问题的一个方面,相对于问题的全部来说的。AOP就是针对问题的一个方面编程。它把一个问题(或者说是需求)从程序级别上拆分成几个方面,让程序员在编程时只关注自己应当关注的方面,而完全忽略其它的方面。最后由AOP框架来组合不同程序员(或者说是不同模块)的程序。

 

从这点上来说,AOP的确对模块化开发有很大的裨益。



AOP的好处,主要有两点。
一、完全消除了编码时模块之间的依赖,解决了团队开发中一龙拦住千江水的瓶颈问题。当然,做到这一点除了AOP外,还必须做到面向接口编程。
二、可以在任意阶段,向已有功能模块中填加新功能,且不侵入原有功能。
posted @ 2007-04-24 12:07 Welkin Hu 阅读(3946) | 评论 (2)编辑 收藏

Myeclipse无疑是最优秀的Java开发平台之一。它以年费方式销售,标准版31.75美元,专业版52.95美元。对老美来说实在是太便宜了。但换成人民币可就不菲。

这里列几个Myelipse做得好与不好的地方,供大家参考。以下为个人体验,不代表官方意见:)

用Myeclipse的理由:

  1. 可视化的HTML/JSP/JSF编辑器。
  2. JSP, Javascripte调试功能
  3. 良好的XML编辑器。
  4. 良好的Hibernate集成。

在以上几个方面,Bea workshop都有相关功能,而且界面做得非常好。可惜一来价钱太贵,二来在我的机子上出现茂名其妙的bug,所以就放弃了。

Myeclipse使用Hibernate Tools集成了很多功能,除了HQL编辑器的集成我不满意外,其它的都不错。

XML编辑器,个人一直很纳闷为什么eclipse本身不提供一个这样的插件,居然缺省用普通文本编辑器编辑XML。其它开源的XML插件都差强人意,收费倒是有一些。但仅为XML买一个插件,有点冤。Myeclipse的刚刚够用,好!

开源的插件中,没有可视化的HTML/JSP/JSF编辑器。想要这个功能,只能选Myeclipse或Bea workshop了。

再说说Myelipse做得不好的地方。

  1. UML功能,可用性很不好,没有MDA,一些开源软件都做得比它好。
  2. 项目粒度过细,做一个ear,至少要做三个项目:ear, war,ejb。
  3. 图片编辑,这是个鸡肋功能。
  4. 对eclipse, hibernate, spring等开源软件的新版本支持不及时。

UML和图片编辑是Myelipse专业本才有的功能。如此看来,用标准版就足够满足我的需要。但是标准版中没有Java script 调试功能,这个确实不爽。

最后说说Netbeans. Netbeans 6中提供了UML功能,虽然易用性上不及Rose和Powerdesigner,但是比一般的开源UML工具好用。如果它再提供可视化的HTML/JSP开发,我就转向Netbeans了。说来也奇怪,Netbeans支持可视化的JSF开发,却不支持可视化的HTML/JSP开发。



2007-4-27: 这两天受到UML功能的吸引,再次试了一下Netbeans5.5和6.0M8。6.0M8还很不稳定,经常有些错误框跳出来。两个版本都通过mavenide2这个插件支持maven。但是支持的很不好。所有的maven项目都不能单独debug一个java class,全部要求在Junit下运行。看来还不是用netbeans的时候。

posted @ 2007-04-18 10:05 Welkin Hu 阅读(3195) | 评论 (5)编辑 收藏

     摘要: Insert title here 为了验证 Hibernate 批量数据插入的性能,选择合适的 batchsize ,我做了一个 benchmark 的测试。可是测试的结果非常奇怪。 Jdbc.batch_size 的设置对性能基本没有影响。 ...  阅读全文
posted @ 2007-03-27 10:43 Welkin Hu 阅读(4265) | 评论 (5)编辑 收藏

 

ejb-jar.xml in ejb/META-INF

 

<session >
... ...

<resource-ref>
<res-ref-name>XPCDataSource</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Application</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>

</session>

 

jboss.xml in ejb/META-INF

 

<?xml version="1.0"?>
<!DOCTYPE jboss PUBLIC
"-//JBoss//DTD JBOSS 3.0//EN"
"http://www.jboss.org/j2ee/dtd/jboss_3_0.dtd">

<jboss>
<enterprise-beans>
<session>
<ejb-name>CacheDemo1</ejb-name>
<jndi-name>ejb/CacheDemo1</jndi-name>
<local-jndi-name>ejb/CacheDemo1Local</local-jndi-name>
<resource-ref>
<res-ref-name>XPCDataSource</res-ref-name>
<jndi-name>java:/XPCDataSource</jndi-name>
</resource-ref>
</session>
</enterprise-beans>
</jboss>

 

web.xml  in web/WEB-INF

<resource-ref>
<res-ref-name>XPCDataSource</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Application</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>

 

jboss-web.xml in web/WEB-INF

<resource-ref>
<res-ref-name>XPCDataSource</res-ref-name>
<jndi-name>java:/XPCDataSource</jndi-name>
</resource-ref>

 

创建Data Source

Context c = new InitialContext();
Object obj = c.lookup("java:comp/env/XPCDataSource");
DataSource ds = (DataSource)narrow(obj, DataSource.class);
connection = ds.getConnection();

 

取得Transaction

//context is javax.ejb.SessionContext

//Transaction should be getten from EJB

UserTransaction tx = context.getUserTransaction();

 

Webspere deployer will change ejb-jar.xml. Never put struts to Webspere/lib/ext

posted @ 2007-03-07 09:51 Welkin Hu 阅读(499) | 评论 (0)编辑 收藏

这两天因为想测试一下群集Cache,用Myeclipse 建了一个测试程序,快把我折腾死了。

在Myeclipse的设计中,Project的粒度很细。EAR Project, WAR Project, 和EJB Project是三个不同的Project。它不支持EAR Project包打天下不太一样。

我按照这个要求,创建了四个项目:EAR, WAR, EJB和一个公用的Pojo Project。

公司刚刚换用了SubVersion首先涮了我一把。Subeclipse 1.0.1只认一个项目一个项目的check out。一下子把我的四个项目合并成一个什么都不是的大项目。 我只好把这个大项目关掉,再一个一个的导入进来。

可是碰在新建Subversion库的当口上,项目的服务器路径变动了好几次。每次都要我这么弄几下。迫不得已,装上TortoiseSVN-1.4.3。这东西爽!可以一下子把四个项目全取下来,而且不破坏eclipse项目结构。

然而,当我打开eclipse,又碰到一个经典问题: subeclipse 1.0.1和TortoiseSVN-1.4.3不兼容,报告说我的subversion客户端太老(其实是它自己老了),直接罢工了。

左找右找,终于发现有人说subeclipse 1.1.6搞定了这个问题。于是升级,搞定了这个问题。

 

要说Myeclipse对于EJB和JSP的支持确实漂亮,轻轻松松的就开发完成了。部署并初步运行也是成功的。

只有一个美中不足:它生成的war包和jar包不能指定名字。在EAR的.mymetadata中,有这么一段配置:

< project-modules >
< project-module
type ="WEB"
name
="Cache Web"
id
="myeclipse.1171417787608"
context-root
="/cache"
j2ee-spec
="1.4"
archive
="Cache Web.war" >
< attributes >
< attribute  name ="webrootdir"  value ="/root"   />
</ attributes >
</ project-module >
< project-module
type ="EJB"
name
="Cache Ejb"
id
="myeclipse.1171417692847"
j2ee-spec
="1.4"
archive
="Cache Ejb.jar"   />
</ project-modules >

 

包名中带空格可不是我的风格。我尝试修改上面的archive属性。但是最后生成的EAR中,包名还是照旧。很有可能archive属性根本就没有作用。Myeclipse简单的拿工程名做包名。

 

没办法,将就过吧。继续测试。Pojo是个单独的Hibernate Pojo项目。EJB和JSP都有引用到。

在EJB中,调用Pojo得到一个List,里面的元素是Order对象。在EJB中从Object转成Order成功。但在JSP中转型时,碰到一个极为古怪的问题:ClassCastException。

调用EJB得到List都成功了,可怎么从中转出Order对象会出问题呢?打开Debug看看,List中的确是Order对象啊!太古怪了!

没救了,死马当活马医吧。把远程EJB调用改成本地EJB调用——问题照旧!检查所有配置文件,都简单得不可能出问题啊!

……神啊,救救我吧。

最后,在检查部署后的文件时发现了问题。WAR包和EJB包各自把Pojo项目中的所有classs合并了进来。这样在一个EAR中,每个pojo的class都有两份。JSP和EJB各引用各的,从而导致了类型不匹配。

问题的原因在于Myeclipse中指定的部署方法不对。为了省事,我在WAR和EJB的部署配置中,都选择了“Merge dependent Java Project Delopyment"。如下图所示。

将部署配置改为Ignore之后,然后手工将pojo包放到jboss server的lib中,问题终于解决了。

可是这样一来,每次我都得手工的部署pojo包。在EAR的配置中有一个"Jar dependent Java projects"。选中它,并且在引用项目中选中Pojo项目。Myeclipse就会自动将Pojo包部署到EAR中。

然而,它部署是部署了,没把人家放到classpath中去,一运行就报错:ClassNotFound。这个问题好解决,在EJB和WAR的MANIFEST.MF中加入classpath就可以了。

一开始我用的是pojo.jar这个名字,放到classpath中后运行成功。

可是Myeclipse在每次自动生成pojo包时,给的是工程名"cache pojo.jar",里面有个空格。classpath死活不认识它,用引号引起来也不行。

问题到了最后,还是没有圆满解决——早知今日,我还不如直接用个ant building呢!

posted @ 2007-02-16 16:15 Welkin Hu 阅读(2840) | 评论 (3)编辑 收藏

登录及任意操作,70%出现无效用户请求

每次点“信用卡”,有90%概率出现下面的问题。

 

银行软件,安全固然重要。可是这样的可用性,拿出来不嫌丢人吗?

 

我的浏览器这么大,可它出来的“疑难解答”只用了那么一点点,还搞了个滚动条。真是笨得可以啊。

posted @ 2007-02-08 16:52 Welkin Hu 阅读(872) | 评论 (0)编辑 收藏

 

http://www.wujianrong.com/archives/2006/11/jdbc.ht...

posted @ 2007-02-08 10:38 Welkin Hu 阅读(294) | 评论 (0)编辑 收藏

Right-click contex menu doesn't work
http://www.myeclipseide.com/index.php?name=PNphpBB2&file=viewtopic&t=15728

http://www.eclipseworld.org/bbs/read.php?tid=9920

This is a known problem when installing the 5.1 release of MYEclipse into an install of Eclipse that has the JST and WST plugins already installed (it supreceedes our versions of the plugin that need to get loaded).

The workaround is to load the manage configuration dialog from Help > Software Updates > Mangae Configuration. Then find the JST and WST plugins from your Eclipse install (probably under WTP) and disable them, then restart.

posted @ 2007-02-01 09:15 Welkin Hu 阅读(625) | 评论 (0)编辑 收藏

目前Java IDE的主流自然是eclipse系列,我一直用的也是这个。在Sun积极宣传Netbeans5.5的时候,我也试用了一下,并没有找到从eclipse转移过去的理由。我对它的不满意主要有两点:
1、没有所见即所得的JSP/HTML编辑器。
2、没有为Hibernate提供开发支持。
Netbeans5.5在java 6下的桌面开发能力很强,不过短期内我还用不上。

下面重点说说Eclipse平台下的一些开发工具。

1、JSP/HTML编辑工具
Lomboz是开源的JSP编辑器,不过它不支持所见即所得的可视化编辑。虽然我并不喜欢在可视化设计界面中通过拖拉来调整页面。但是它对代码的快速定位是我所需要的。
Bea Workshop for JSP的确精彩,不过它要求把所有的JSP一个WEB-INF的目录。我的项目很大,每个模块都有独立的JSP目录,这个要求很烦的。好像这个目录可以配置(但是必须有),不过由于其它原因,我已经放弃了。
我现在选的是MyEclipse,它的JSP编辑器做得不如Bea Workshop精细和强大,但是自由,够用。另外,MyEclipse比Bea Workshop便宜得多,有可能说服老板买单。不过,MyEclipse集成的Hibernate功能着实让我光火了很长的时间。

2. Hibernate集成工具
在Eclipse中集成Hibernate开发的有三种:Hibernate官方出的Hibernate Tools, Myeclipse和Bea Workshop。Jbuilder 2007也部分支持Hibernate。Hibernate Tools是开源的,其它的工具都是在它的基础上进行增强而来的。

如果使用Ant命令来操作Hibernate Tools,你会发现它非常强大,可以灵活的在表,HBM和pojo间互相转换。可是它的Eclipse集成太狠了点,只要求一个逆向工程的配置文件,就可以根据数据库表生成所有的HBM和pojo。这个功能貌似一步到位,其实很不灵活。
(1)如何写好HBM是很有学问的,我经常需要细心的调理好HBM再生成pojo。
(2)每次生成时都一刀切的做法对于增量开发来说是个灾难。好不容易调理好的HBM和Pojo,一下子全被冲掉了。
(3)它的数据库连接也有个问题,不会过滤Schema,每次都把所有的数据库列出来。我们的开发数据库服务器上安装有三四十个数据库,想想多么恐怖啊。
Hibernate Tools最强的功能,当数HQL编辑器。可以查错,可以检查最终生成的SQL,可以得到运行结果,可以添加参数。这些功能实在是太有用了。

Myeclipse对Hibernate Tools进行了改进。所以它和原生的Hibernate Tools共存时会发生一些奇怪的问题。Myeclipse中有两个改进非常棒:指定数据库Schema(再也不用在三四个数据库中找我的那份试验田了),根据选中的HBM生成Pojo(放心大胆的用吧,已经做好的HBM和Pojo不会再被冲掉了)。
不过,Myeclipse对HQL编辑器的改进就有点让人光火了。首先是连接问题,横竖就是连不上数据库,左找右找找不到原因,最后把Eclipse workspace重建,把相同的配置连接,一下子又可以了。
其次,Myeclipse没有提供新建HQL编辑器的菜单,而是在我手工建立一个hql的文件后,在打开它时调用HQL编辑器!打开的过程可能涉及到数据库连接,非常慢。如果你在退出eclipse中没有关掉HQL文件,那么再次进入eclipse的时候,您先去喝杯茶,慢慢等吧。

Bea Workshop各方面做得都非常精致,Hiberenate集成也不例外,各类编辑器的功能布局明了易用。但是我在试用时碰到一个难以置信的致命的bug:所有Bea Workshop编辑器和对话框中的文本输入框基本不接收光标!
这是什么概念?就是说你没法点进文本框,没法输入任何东西。我唯一成功的一次是在没有光标的情况下,乱打了几个字母再回车。对话框没有显示任何东西直接关闭,但在主编辑器中我打的字母显示了出来。不过除了文本框外,其它的如下拉框,选择框都正常。
哪个开发人员会出这么离谱的Bug啊!我试过两台机,问题一模一样。难道是因为我的JDK是1.5的缘故?!
不管什么原因,我是没办法再试下去了,只好将其请出了我的电脑。在请出之前,通过菜单检查,没有发现指定HBM生成Pojo的功能。这两大原因,足够我放弃它了。

Jbuilder 2007做得太强了。我用它明显感觉小脚穿大鞋。人家根本不希罕Hibernate。仅仅把Hiberenate作为EJB 3.0和JPA的一种实现方式。所以根据没有HBM这一说。而且是彻头彻尾的可视化MDA开发。真的需要一个明星团队,在严格的流程支持下,才能玩转Jbuilder 2007。我两个条件都不符合,最重要的是老板嫌它太贵,只能放弃。

Technorati : , , , ,

posted @ 2007-01-28 17:27 Welkin Hu 阅读(1003) | 评论 (3)编辑 收藏

最近正在做JDO 2.0与Hibernate的方案选择。JDO实现选的是Jpox,个别问题也参看了Bea Kodo 4.1。但是今天发现JDO2.0在一项关键功能上无法满足要求,有可能被直接叫停。

这个功能就是动态O/R Mapping。就是说,在系统运行时,动态生成一份新的O/R Mapping,或者往原来的O/R Mapping中添加字段。并且这些改动,应当无须重启Application Server就能生效。

Hibernate虽然也没有很好的支持这一点,但是提供了可实现的渠道。

1. 重建SessionFactory时可以添加新的Mapping文件。

2. Dynamic Component可以在pojo中将动态字段表达为Map,这样只用修改Mapping文件,不用修改java类。

3. Hibernate 3.2.1还提供不用java类的Mapping方式。在Mapping文件中,只指定entity-name,不指定class,Hiberante就会使用Map来表达它。

Jpox没有提供上面三种渠道中的任何一种。我已经在Jpox forum上发贴问了,不知道什么时候能有答复。

Kodo的文档中也没有直接提到,本想去bea发贴的,但是网速太慢。

posted @ 2007-01-24 10:50 Welkin Hu 阅读(663) | 评论 (0)编辑 收藏

一直以为,在Hiberenate中用多对一关系表达外键,并设置为延迟加载时,Hibernate不会在查主表时去查引用表。今天的测试却发现不是这么回事。

我定义了一个Topic类,其中有一个外键引用Company类:

 

< many-to-one  name ="company"  class ="Company"  lazy ="no-proxy" >
< column  name ="COMPANY"  length ="32"   />
</ many-to-one >

 

测试HQL如下:select id, company from Topic

而我期望的SQL应当是这样:select boid, company from DT_TOPIC.

结果Hiberate Tools 生成的SQL是这样:

 

select
topic0_.BOID 
as  col_0_0_,
topic0_.COMPANY 
as  col_1_0_,
company1_.COMPID 
as  COMPID409_,
company1_.COMPNAME 
as  COMPNAME409_,
company1_.DESCRIPTION 
as  DESCRIPT3_409_,
company1_.STATUS 
as  STATUS409_ 
from
DT_TOPIC topic0_ 
inner   join
XPC_COMPANY company1_ 
on  topic0_.COMPANY = company1_.COMPID

 

Hibernate生成的SQL多做了两件影响性能的事情:

1, 与XPC_COMPANY进行inner join。

2,把XPC_COMPANY中的所有字段全取出来了。

这样还叫什么延迟加载啊?

 

哪位高手能告诉我这是为什么?

posted @ 2007-01-17 21:54 Welkin Hu 阅读(3008) | 评论 (4)编辑 收藏

Java 5.0发布了,许多人都将开始使用这个JDK版本的一些新增特性。从增强的for循环到诸如泛型(generic)之类更复杂的特性,都将很快出现在您所编写的代码中。我们刚刚完成了一个基于Java 5.0的大型任务,而本文就是要介绍我们使用这些新特性的体验。本文不是一篇入门性的文章,而是对这些特性以及它们所产生的影响的深入介绍,同时还给出了一些在项目中更有效地使用这些特性的技巧。

简介
  在JDK 1.5的beta阶段,我们为BEA的Java IDE开发了一个Java 5编译器。因为我们实现了许多新特性,所以人们开始以新的方式利用它们;有些用法很聪明,而有些用法明显应该被列入禁用清单。编译器本身使用了新的语言特性,所以我们也获得了使用这些特性维护代码的直接体验。本文将介绍其中的许多特性和使用它们的体验。
  我们假定您已经熟悉了这些新特性,所以不再全面介绍每个特性,而是谈论一些有趣的、但很可能不太明显的内容和用法。这些技巧出自我们的实际体验,并大致按照语言特性进行了分类。
  我们将从最简单的特性开始,逐步过渡到高级特性。泛型所包含的内容特别丰富,因此占了本文一半的篇幅。

增强的for循环
  为了迭代集合和数组,增强的for循环提供了一个简单、兼容的语法。有两点值得一提:

Init表达式
  在循环中,初始化表达式只计算一次。这意味着您通常可以移除一个变量声明。在这个例子中,我们必须创建一个整型数组来保存computeNumbers()的结果,以防止每一次循环都重新计算该方法。您可以看到,下面的代码要比上面的代码整洁一些,并且没有泄露变量numbers:
未增强的For:



int sum = 0;
Integer[] numbers 
= computeNumbers();
for (int i=0; i < numbers.length ; i++)
    sum 
+= numbers[i];
增强后的For:
int sum = 0;

for ( int number: computeNumbers() )
    sum 
+= number;


局限性

有时需要在迭代期间访问迭代器或下标,看起来增强的for循环应该允许该操作,但事实上不是这样,请看下面的例子:

for (int i=0; i < numbers.length ; i++{
    
if (i != 0) System.out.print(",");
    System.out.print(numbers[i]);
}

  我们希望将数组中的值打印为一个用逗号分隔的清单。我们需要知道目前是否是第一项,以便确定是否应该打印逗号。使用增强的for循环是无法获知这种信息的。我们需要自己保留一个下标或一个布尔值来指示是否经过了第一项。   这是另一个例子:

for (Iterator<integer> it = n.iterator() ; it.hasNext() ; )
    
if (it.next() < 0)
        it.remove();

  在此例中,我们想从整数集合中删除负数项。为此,需要对迭代器调用一个方法,但是当使用增强的for 循环时,迭代器对我们来说是看不到的。因此,我们只能使用Java 5之前版本的迭代方法。   顺便说一下,这里需要注意的是,由于Iterator是泛型,所以其声明是Iterator<Integer>。许多人都忘记了这一点而使用了Iterator的原始格式。

注释
  注释处理是一个很大的话题。因为本文只关注核心的语言特性,所以我们不打算涵盖它所有的可能形式和陷阱。  我们将讨论内置的注释(SuppressWarnings,Deprecated和Override)以及一般注释处理的局限性。

Suppress Warnings
  该注释关闭了类或方法级别的编译器警告。有时候您比编译器更清楚地知道,代码必须使用一个被否决的方法或执行一些无法静态确定是否类型安全的动作,而使用:

@SuppressWarnings("deprecation")
public static void selfDestruct() {
    Thread.currentThread().stop();
}

  这可能是内置注释最有用的地方。遗憾的是,1.5.0_04的javac不支持它。但是1.6支持它,并且Sun正在努力将其向后移植到1.5中。
Eclipse 3.1中支持该注释,其他IDE也可能支持它。这允许您把代码彻底地从警告中解脱出来。如果在编译时出现警告,可以确定是您刚刚把它添加进来——以帮助查看那些可能不安全的代码。随着泛型的添加,它使用起来将更趁手。

Deprecated
  遗憾的是,Deprecated没那么有用。它本来旨在替换@deprecated javadoc标签,但是由于它不包含任何字段,所以也就没有方法来建议deprecated类或方法的用户应该使用什么做为替代品。大多数用法都同时需要javadoc标签和这个注释。

Override
  Override表示,它所注释的方法应该重写超类中具有相同签名的方法:

@Override
public int hashCode() {
    
}

  看上面的例子,如果没有在hashCode中将“C”大写,在编译时不会出现错误,但是在运行时将无法像期望的那样调用该方法。通过添加Override标签,编译器会提示它是否真正地执行了重写。
  在超类发生改变的情况中,这也很有帮助。如果向该方法中添加一个新参数,而且方法本身也被重命名了,那么子类将突然不能编译,因为它不再重写超类的任何东西。

其它注释
  注释在其他场景中非常有用。当不是直接修改行为而是增强行为时,特别是在添加样板代码的情况下,注释在诸如EJB和Web services这样的框架中运行得非常好。
注释不能用做预处理器。Sun的设计特别预防了完全因为注释而修改类的字节码。这样可以正确地理解该语言的成果,而且IDE之类的工具也可以执行深入的代码分析和重构之类的功能。
注释不是银弹。第一次遇到的时候,人们试图尝试各种技巧。请看下面这个从别人那里获得的建议:

public class Foo {
 
    @Property
    
private int bar;
 
}

  其思想是为私有字段bar自动创建getter和setter方法。遗憾的是,这个想法有两个失败之处:1)它不能运行,2)它使代码难以阅读和处理。   它是无法实现的,因为前面已经提到了,Sun特别阻止了对出现注释的类进行修改。
  即使是可能的,它也不是一个好主意,因为它使代码可读性差。第一次看到这段代码的人会不知道该注释创建了方法。此外,如果将来您需要在这些方法内部执行一些操作,注释也是没用的。   总之,不要试图用注释去做那些常规代码可以完成的事情。

枚举
  enum非常像public static final int声明,后者作为枚举值已经使用了很多年。对int所做的最大也是最明显的改进是类型安全——您不能错误地用枚举的一种类型代替另一种类型,这一点和int不同,所有的int对编译器来说都是一样的。除去极少数例外的情况,通常都应该用enum实例替换全部的枚举风格的int结构。
  枚举提供了一些附加的特性。EnumMap和EnumSet这两个实用类是专门为枚举优化的标准集合实现。如果知道集合只包含枚举类型,那么应该使用这些专门的集合来代替HashMap或HashSet。
  大部分情况下,可以使用enum对代码中的所有public static final int做插入替换。它们是可比的,并且可以静态导入,所以对它们的引用看起来是等同的,即使是对于内部类(或内部枚举类型)。注意,比较枚举类型的时候,声明它们的指令表明了它们的顺序值。

“隐藏的”静态方法
  两个静态方法出现在所有枚举类型声明中。因为它们是枚举子类上的静态方法,而不是Enum本身的方法,所以它们在java.lang.Enum的javadoc中没有出现。
  第一个是values(),返回一个枚举类型所有可能值的数组。
  第二个是valueOf(),为提供的字符串返回一个枚举类型,该枚举类型必须精确地匹配源代码声明。
方法
  关于枚举类型,我们最喜欢的一个方面是它可以有方法。过去您可能需要编写一些代码,对public static final int进行转换,把它从数据库类型转换为JDBC URL。而现在则可以让枚举类型本身带一个整理代码的方法。下面就是一个例子,包括DatabaseType枚举类型的抽象方法以及每个枚举实例中提供的实现:

public enum  DatabaseType {
  ORACLE 
{
  
public String getJdbcUrl() {}
  }
,
  MYSQL 
{
  
public String getJdbcUrl() {}
  }
;
  
public abstract String getJdbcUrl();
  }
  现在枚举类型可以直接提供它的实用方法。例如:

DatabaseType dbType = ...;
String jdbcURL = dbType.getJdbcUrl();

  要获取URL,必须预先知道该实用方法在哪里。


可变参数(Vararg)
  正确地使用可变参数确实可以清理一些垃圾代码。典型的例子是一个带有可变的String参数个数的log方法:

Log.log(String code)
Log.log(String code,  String arg)
Log.log(String code,  String arg1, String arg2)
Log.log(String code,  String[] args)
  当讨论可变参数时,比较有趣的是,如果用新的可变参数替换前四个例子,将是兼容的:
Log.log(String code, String... args)
  所有的可变参数都是源兼容的——那就是说,如果重新编译log()方法的所有调用程序,可以直接替换全部的四个方法。然而,如果需要向后的二进制兼容性,那么就需要舍去前三个方法。只有最后那个带一个字符串数组参数的方法等效于可变参数版本,因此可以被可变参数版本替换。

类型强制转换

  如果希望调用程序了解应该使用哪种类型的参数,那么应该避免用可变参数进行类型强制转换。看下面这个例子,第一项希望是String,第二项希望是Exception:
Log.log(Object  objects) {
    String message 
= (String)objects[0];
    
if (objects.length > 1{
        Exception e 
= (Exception)objects[1];
        
// Do something with the exception
    }

}
  方法签名应该如下所示,相应的可变参数分别使用String和Exception声明:

Log.log(String message, Exception e, Object... objects) {...}

  不要使用可变参数破坏类型系统。需要强类型化时才可以使用它。对于这个规则,PrintStream.printf()是一个有趣的例外:它提供类型信息作为自己的第一个参数,以便稍后可以接受那些类型。

协变返回

  协变返回的基本用法是用于在已知一个实现的返回类型比API更具体的时候避免进行类型强制转换。在下面这个例子中,有一个返回Animal对象的Zoo接口。我们的实现返回一个AnimalImpl对象,但是在JDK 1.5之前,要返回一个Animal对象就必须声明。:
public interface Zoo  {
    
public Animal getAnimal();
}

public class ZooImpl  implements Zoo {
  
public Animal getAnimal(){
     
return new AnimalImpl();
  }

}
  协变返回的使用替换了三个反模式:

  • 直接字段访问。为了规避API限制,一些实现把子类直接暴露为字段:

ZooImpl._animal

  • 另一种形式是,在知道实现的实际上是特定的子类的情况下,在调用程序中执行向下转换:

((AnimalImpl)ZooImpl.getAnimal()).implMethod();

  • 我看到的最后一种形式是一个具体的方法,该方法用来避免由一个完全不同的签名所引发的问题:

ZooImpl._getAnimal();

  这三种模式都有它们的问题和局限性。要么是不够整洁,要么就是暴露了不必要的实现细节。

协变

  协变返回模式就比较整洁、安全并且易于维护,它也不需要类型强制转换或特定的方法或字段:
public AnimalImpl getAnimal(){
return new AnimalImpl();
}
  使用结果:
ZooImpl.getAnimal().implMethod();

使用泛型
  
我们将从两个角度来了解泛型:使用泛型和构造泛型。我们不讨论List、Set和Map的显而易见的用法。知道泛型集合是强大的并且应该经常使用就足够了。
  我们将讨论泛型方法的使用以及编译器推断类型的方法。通常这些都不会出问题,但是当出问题时,错误信息会非常令人费解,所以需要了解如何修复这些问题。

泛型方法
  
除了泛型类型,Java 5还引入了泛型方法。在这个来自java.util.Collections的例子中,构造了一个单元素列表。新的List的元素类型是根据传入方法的对象的类型来推断的:
static <T> List<T> Collections.singletonList(T o)
示例用法:
public List<Integer> getListOfOne() {
    return Collections.singletonList(1);
}

  在示例用法中,我们传入了一个int。所以方法的返回类型就是List<Integer>。编译器把T推断为Integer。这和泛型类型是不同的,因为您通常不需要显式地指定类型参数。
这也显示了自动装箱和泛型的相互作用。类型参数必须是引用类型:这就是为什么我们得到的是List<Integer>而不是List<int>。

不带参数的泛型方法
  
emptyList()方法与泛型一起引入,作为java.util.Collections中EMPTY_LIST字段的类型安全置换:
static <T> List<T> Collections.emptyList()
示例用法: 
public List<Integer> getNoIntegers() {
    return Collections.emptyList();
}

  与先前的例子不同,这个方法没有参数,那么编译器如何推断T的类型呢?基本上,它将尝试使用一次参数。如果没有起作用,它再次尝试使用返回或赋值类型。在本例中,返回的是List<Integer>,所以T被推断为Integer。
  如果在返回语句或赋值语句之外的位置调用泛型方法会怎么样呢?那么编译器将无法执行类型推断的第二次传送。在下面这个例子中,emptyList()是从条件运算符内部调用的:

public List<Integer> getNoIntegers() {
    return x ? Collections.emptyList() : null;
}

  因为编译器看不到返回上下文,也不能推断T,所以它放弃并采用Object。您将看到一个错误消息,比如:“无法将List<Object>转换为List<Integer>。”
为了修复这个错误,应显式地向方法调用传递类型参数。这样,编译器就不会试图推断类型参数,就可以获得正确的结果:

return x ? Collections.<Integer>emptyList() : null;

  这种情况经常发生的另一个地方是在方法调用中。如果一个方法带一个List<String>参数,并且需要为那个参数调用这个传递的emptyList(),那么也需要使用这个语法。

集合之外
  这里有三个泛型类型的例子,它们不是集合,而是以一种新颖的方式使用泛型。这三个例子都来自标准的Java库:
  • Class<T>
    Class在类的类型上被参数化了。这就使无需类型强制转换而构造一个newInstance成为可能。
  • Comparable<T>
    Comparable被实际的比较类型参数化。这就在compareTo()调用时提供了更强的类型化。例如,String实现Comparable<String>。对除String之外的任何东西调用compareTo(),都会在编译时失败。
  • Enum<E extends Enum<E>>
    Enum被枚举类型参数化。一个名为Color的枚举类型将扩展Enum<Color>。getDeclaringClass()方法返回枚举类型的类对象,在这个例子中就是一个Color对象。它与getClass()不同,后者可能返回一个无名类。
通配符
  
泛型最复杂的部分是对通配符的理解。我们将讨论三种类型的通配符以及它们的用途。
  首先让我们了解一下数组是如何工作的。可以从一个Integer[]为一个Number[]赋值。如果尝试把一个Float写到Number[]中,那么可以编译,但在运行时会失败,出现一个ArrayStoreException:
Integer[] ia = new Integer[5];
Number[] na = ia;
na[0] = 0.5; // compiles, but fails at runtime
如果试图把该例直接转换成泛型,那么会在编译时失败,因为赋值是不被允许的:
List<Integer> iList = new ArrayList<Integer>();
List<Number> nList = iList; // not allowed
nList.add(0.5);

  如果使用泛型,只要代码在编译时没有出现警告,就不会遇到运行时ClassCastException。

上限通配符
  我们想要的是一个确切元素类型未知的列表,这一点与数组是不同的。
List<Number>是一个列表,其元素类型是具体类型Number。
List<? extends Number>是一个确切元素类型未知的列表。它是Number或其子类型。

上限
  
如果我们更新初始的例子,并赋值给List<? extends Number>,那么现在赋值就会成功了:

List<Integer> iList = new ArrayList<Integer>();
List<? extends Number> nList = iList;
Number n = nList.get(0);
nList.add(0.5); // Not allowed

  我们可以从列表中得到Number,因为无论列表的确切元素类型是什么(Float、Integer或Number),我们都可以把它赋值给Number。
  我们仍然不能把浮点类型插入列表中。这会在编译时失败,因为我们不能证明这是安全的。如果我们想要向列表中添加浮点类型,它将破坏iList的初始类型安全——它只存储Integer。
  通配符给了我们比数组更多的表达能力。

为什么使用通配符
  在下面这个例子中,通配符用于向API的用户隐藏类型信息。在内部,Set被存储为CustomerImpl。而API的用户只知道他们正在获取一个Set,从中可以读取Customer。
此处通配符是必需的,因为无法从Set<CustomerImpl>向Set<Customer>赋值:
public class CustomerFactory {
    private Set<CustomerImpl> _customers;
    public Set<? extends Customer> getCustomers() {
        return _customers;
    }
}

通配符和协变返回
  通配符的另一种常见用法是和协变返回一起使用。与赋值相同的规则可以应用到协变返回上。如果希望在重写的方法中返回一个更具体的泛型类型,声明的方法必须使用通配符:

public interface NumberGenerator {
    public List<? extends Number> generate();
}
public class FibonacciGenerator extends NumberGenerator {
    public List<Integer> generate() {
        ...
    }
}

  如果要使用数组,接口可以返回Number[],而实现可以返回Integer[]。

下限
  我们所谈的主要是关于上限通配符的。还有一个下限通配符。List<? super Number>是一个确切“元素类型”未知的列表,但是可能是Mnumber,或者Number的超类型。所以它可能是一个List<Number>或一个List<Object>。
  下限通配符远没有上限通配符那样常见,但是当需要它们的时候,它们就是必需的。

下限与上限
List<? extends Number> readList = new ArrayList<Integer>();
Number n = readList.get(0);

List<? super Number> writeList = new ArrayList<Object>();
writeList.add(new Integer(5));

  第一个是可以从中读数的列表。
  第二个是可以向其写数的列表。

无界通配符
  最后,List<?>列表的内容可以是任何类型,而且它与List<? extends Object>几乎相同。可以随时读取Object,但是不能向列表中写入内容。

公共API中的通配符
  总之,正如前面所说,通配符在向调用程序隐藏实现细节方面是非常重要的,但即使下限通配符看起来是提供只读访问,由于remove(int position)之类的非泛型方法,它们也并非如此。如果您想要一个真正不变的集合,可以使用java.util.Collection上的方法,比如unmodifiableList()。
  编写API的时候要记得通配符。通常,在传递泛型类型时,应该尝试使用通配符。它使更多的调用程序可以访问API。
  通过接收List<? extends Number>而不是List<Number>,下面的方法可以由许多不同类型的列表调用:

void removeNegatives(List<? extends Number> list);

构造泛型类型
  现在我们将讨论构造自己的泛型类型。我们将展示一些例子,其中通过使用泛型可以提高类型安全性,我们还将讨论一些实现泛型类型时的常见问题。

集合风格(Collection-like)的函数
  第一个泛型类的例子是一个集合风格的例子。Pair有两个类型参数,而且字段是类型的实例:

public final class Pair<A,B> {
    public final A first;
    public final B second;

    public Pair(A first, B second) {
        this.first = first;
        this.second = second;
    }
}

  这使从方法返回两个项而无需为每个两种类型的组合编写专用的类成为可能。另一种方法是返回Object[],而这样是类型不安全或者不整洁的。
在下面的用法中,我们从方法返回一个File和一个Boolean。方法的客户端可以直接使用字段而无需类型强制转换:

public Pair<File,Boolean> getFileAndWriteStatus(String path){
    // create file and status
    return new Pair<File,Boolean>(file, status);
}

Pair<File,Boolean> result = getFileAndWriteStatus("...");
File f = result.first;
boolean writeable = result.second;

集合之外
  在下面这个例子中,泛型被用于附加的编译时安全性。通过把DBFactory类参数化为所创建的Peer类型,您实际上是在强制Factory子类返回一个Peer的特定子类型:

public abstract class DBFactory<T extends DBPeer> {
    protected abstract T createEmptyPeer();
    public List<T> get(String constraint) {
        List<T> peers = new ArrayList<T>();
        // database magic
        return peers;
    }
}
通过实现DBFactory<Customer>,CustomerFactory必须从createEmptyPeer()返回一个Customer:
public class CustomerFactory extends DBFactory<Customer>{

    public Customer createEmptyPeer() {
        return new Customer();
    }
}

泛型方法
  不管想要对参数之间还是参数与返回类型之间的泛型类型施加约束,都可以使用泛型方法:
  例如,如果编写的反转函数是在位置上反转,那么可能不需要泛型方法。然而,如果希望反转返回一个新的List,那么可能会希望新List的元素类型与传入的List的类型相同。在这种情况下,就需要一个泛型方法:


<T> List<T> reverse(List<T> list)

具体化
  当实现一个泛型类时,您可能想要构造一个数组T[]。因为泛型是通过擦除(erasure)实现的,所以这是不允许的。
  您可以尝试把Object[]强制转换为T[]。但这是不安全的。

具体化解决方案
  
按照泛型教程的惯例,解决方案使用的是“类型令牌”,通过向构造函数添加一个Class<T>参数,可以强制客户端为类的类型参数提供正确的类对象:
public class ArrayExample<T> {
    private Class<T> clazz;

    public ArrayExample(Class<T> clazz) {
        this.clazz = clazz;
    }

    public T[] getArray(int size) {
        return (T[])Array.newInstance(clazz, size);
    }
}

  为了构造ArrayExample<String>,客户端必须把String.class传递给构造函数,因为String.class的类型是Class<String>。
拥有类对象使构造一个具有正确元素类型的数组成为可能。

结束语
  总而言之,新的语言特性有助于从根本上改变Java。通过了解在什么场景下使用以及如何使用这些新特性,您将会编写出更好的代码。

补充阅读

原文出处:Experiences with the New Java 5 Language Features http://dev2dev.bea.com/pub/a/2005/09/java_5_features.html
 作者简介
Jess Garms 是BEA Systems中Javelin编译器团队的领导者。在此之前,Jess致力于BEA的 Java IDE,WebLogic Workshop。此外,他在密码学方面也具有丰富的经验。他还与他人合著了“Professional Java Security”,由Wrox出版社出版。
Tim Hanson 是BEA Systems中Javelin编译器的架构师。Tim对BEA的Java编译器做了很多开发工作,该编译器是最早兼容1.5的实现之一。他曾经编写过许多其他的编译器,包括他在IBM时编写的CORBA/IDL编译器,以及XQuery编译器。
posted @ 2007-01-03 21:29 Welkin Hu 阅读(181) | 评论 (0)编辑 收藏

如今的XML,在文档生成方面可谓大红大紫。使用XML + XSLT可以动态生成HTML文档和表单。而XML + XSL + FO更可以动态生成PDF/RTF文档。

所谓动态生成,就是在运行,才将数据放到具有指定DTD/schema的XML文档中,使用预定义的XSL文档生成可供浏览或打印的文档。

一般来说,生成HTML和PDF的XSLT要分别定义。对于HTML和PDF表现差别较大的文档,有必要使用这种方法。

但是,对于一些格式要求较高的表单和报表,在HTML和PDF下的表现是基本一致的。这个时候就有必要用同一个样式表输出HTML和PDF。要知道,手工定义一份XSLT可是很费工夫的。

FO似乎能达到这个目标,它具备足够精细的样式定义,借助FOP等工具,可直接输出PDF等格式。可惜的是,目前的主流浏览器,如IE和firefox,并不能直接显示FO文档。必须将其转换成HTML或XHTML。然后,我没有发现任何的开源工具可以做到这一点。

 

Altove StyleVision,恰到好处的实现上述目标。

顾名思义,StyleVision就是用来设计样式表的,它提供一个非常友好的GUI设计界面。它使用一个私有的XML格式(SPS)来保存样式表,这个样式表可转换成生成HTML的XSLT和生成FO的XSLT。

这样,做为开发方,购买一份Altova StyleVision,用来设计样式表,然后将其生成的XSLT发布给用户,就可以实现同源输出报表了。而最终用户可以不购买Altova StyleVision

附图:两种动态文档生成方案(在图中体现为两条可选的路线):

 

posted @ 2006-12-30 12:26 Welkin Hu 阅读(1830) | 评论 (0)编辑 收藏

RBAC(基于角色的权限控制)是一个老话题了,但是这两天我试图设计一套表结构实现完整的RBAC时,发现存在很多困难。

我说的完整的RBAC,是指支持角色树形结构和角色分组。具体来说,应当包含如下权限控制需求:

  1. 父级角色可以访问甚至是修改其子级的数据,包含直接子级直到最终子级。
  2. 角色可以访问其所在组的数据。
  3. 父级角色可以访问其所有子级(从直接子级到最终子级)所在组的数据。

而具体到我的系统中,还应当有如下需求。

  1. 兼容多种数据库产品。只能用简单的表,视图,存储过程和函数等实现。
  2. 同时兼容单条数据处理和批量数据处理的需求。

且不论这些具体需求,RBAC的基本表应当如下四个:

  • roleList表,记录所有的角色和角色组。
    • roleId: PK, 角色/组的ID,全局唯一,不区分角色和组。
    • roleName:角色/组的名称。
    • roleType: R - 角色,G - 组
  • rolePermission表,记录每一个角色/组对每一个对象的权限。
    • permissionID: PK, 无特定意义。
    • role: 角色/组的ID。
    • object: 对象的ID。
    • permission: 权限标识,如读,写,删等。
  • roleRelationship表,记录角色/组之间的关系。
    • relationId: PK, 无特定意义。
    • superiorRole: 父角色/组的ID。
    • role:子角色,子组,成员角色,成员组的ID。
    • relationship: 关系标识,可在如下设置集中选取一个。
      • PG标识:P - 父子关系,G - 组/成员关系。
      • PPGG标识:在PG集上,再加三种:PP - 间接父级关系,GG - 组内组关系,CG - parentRole是组,childRole的子角色或间接子角色是其成员,或其子组(含间接子组)的成员
  • objectList表,记录所有的对象。
    • objectId: PK,对象ID,全局唯一。
    • objectName: 对象名称。
    • ... ...

分析上述表结构,不难发现,问题的关键在于从rolePermission表中读取数据时,如何限定角色/组的范围.

方案一

如果角色和组的总量不大,比如在100以内,采用PPGG标识关系,读取数据时是最快的。这个时候的SQL只需要一个输入参数?roleId:

SELECT object FROM rolePermission p left join roleRelationship r on p.role = r.role WHERE p.role = ?roleId or r.superiorRole = ?roleId. (尚未验证SQL的正确性)

但是,这个方案是以极度冗余roleRelationship表的数据为代价的,比如有100个角色,那么roleRelationship中将会有100 * 100 =10,000条记录。而在每次调整角色和R角色组的时候,就要在roleRelationship中一次增加或删除100条记录。这个开销是比较大的。

方案二

只标识PG,查询时接收的输入参数为一个完整的相关角色列表?roleList。

SELECT object FROM rolePermission WHERE role in (?roleList)

在系统运行时,这个?roleList通常可以从role hierarchy cache中取到,比较方便。这个方案的主要问题有二:

1)如果?roleList过长,使用in判断性能会很差。

2)在有些情况下,如报表查询和系统外查询时,取得roleList不太方便。

方案三

只标识PG,但使用如下三个数据库函数来判断角色/组之间的关系。

  • boolean isChild(role, parentRole) - 如role为parentRole的子,返回true。
  • boolean isDescendant(role, ancestorRole) - 如role为ancestorRole的子或间接子级,返回true。
  • boolean isMember(role, group) - 如role为group的成员或子组的成员,返回true。
  • boolean descendantIsMember(role, group) - 如role的子或间接子级为group的成员,返回true。
  • boolean isBelong(role, super) - 如role为super的子,间接子,成员或间接员,或者role的子(含间接子)是super的成员或子组成员,返回true。

在查询时,也只需要接收一个?roleId:SELECT object FROM rolePemission WHERE isBelong(?roleId, role)

如何写出高性能的数据库函数是实现这个方法的关键。

上述方法仅是理论分析,我倾向于方案二。

终于想到新的方案了。

方案四,

结合方案一和方案二,在roleRelationship中,对前两级(也可以是三级或四级)角色,保存其所有的下级角色和组。这样,如果以前两级角色查询数据,就使用方案一,如果以第三级及以下的角色查询数据,就使用方案二。

仍以100个角色为例,每个角色要保存三个关系:一级主管角色,二级主管角色,直接主管角色,最多有300条数据。

每往角色组中加一个角色,也需要加入三条数据:角色本身,一级主管角色,二级主管角色。

但往角色组中加一个子组,需要加入的数据量就大一些:子组本身,子组所有角色,子组所有角色的一级主管角色和二级主管角色。如在多个子组中发现同一角色,可重复保存,但应在表中附加说明是由哪个子组导入的。这样在删除子组时就可以有选择性的删除。

但重复子组的情况就比较麻烦,还有等考虑。假充有组g01,g11,g12,g21。g01包含g11和g12,g11和g12分别包含g21。从g01中删除g11时,如何判断g21的去留?看来还是应当在维护时判断应不应当删除。

Technorati :

posted @ 2006-12-27 17:12 Welkin Hu 阅读(6134) | 评论 (0)编辑 收藏

http://tb.blog.csdn.net/TrackBack.aspx?PostId=1406125

原来GUID只是UUID的一种实现。

原来UUID虽长,做数据库主键不但不会影响性能,反而对性能有所帮助。

有时间我实际测试一下。

posted @ 2006-12-26 16:59 Welkin Hu 阅读(1006) | 评论 (0)编辑 收藏

I tried some free project management programs these days.

  1. Project Engine 2007 from download.com.
  2. Air Todo from download.com. It request JRE 6.0. My product request JRE 1.4.2. I can not executed it at all.
  3. SharePlan from download.com. When I open this program, I do not know what to do.
  4. GanttProject from sf.net. This is a wonderful product. It use XML to save file. It is able to import MS project. the gantt chart  is professional.

Project Engine 2007 has lots of features and easy to create project and task. However, there are too many input fields in the task detail page. I don't know how to create and assign a task.

It does not allow directly input task's start date and end date. When you start a task, it automatically set start date; when you complete a task ,it automatically set end date.

I hope it provides following features from PSP:

1) Pause a task

2) Remember both date and time. Generally I complete many tasks in one day.

My suggests:

    No. 1 GanttProject

    No. 2 Project Engine 2007

posted @ 2006-12-19 10:14 Welkin Hu 阅读(1676) | 评论 (1)编辑 收藏

I found a serious bug when using outline feature of OpenOffice Calc.

1 Group 3 rows

2 Collapse the group, summary row (row 3#) was collapsed too.

 

3 However, I can drag and redisplay summary row (row 3#)

4 When I collapse it again, summary row (row 3#)  still be collapsed.

 

Outline of column has same bug. How could I choose OpenOffice?

posted @ 2006-12-18 22:07 Welkin Hu 阅读(241) | 评论 (0)编辑 收藏

普元的口号很响,可是网门站门面做得真差劲。乱七八糟的东西堆了一堆,想找找的东西反而点了n个页面都找不到。

我在Google上搜一个开源的需求管理工具,看了一篇文章介绍GoCom提供了一款开源的项目管理工具中包含需求管理。就跑到GoCom上去看。结果左点右点找不到那个工具。通过它的主页的搜索功能也没搜着。

最后只好在GoCom社区注册了一个账号。完子之后还是找不着,最后好不容易找到相关的介绍页面,居然没有提供下载功能。页面最左边写了一行字“立即注册,马上下载!”,字上面也没有链接。晕。

这样难以入门的门面,使我对其产品的质量产生极大的怀疑,最后决定放弃。

posted @ 2006-12-18 18:31 Welkin Hu 阅读(417) | 评论 (1)编辑 收藏

http://www.mambochina.net/content/view/7_38.html 我的内容管理系统(CMS)寻找历程 -- Mambo出鞘,谁与争锋?

http://www.dedecms.com/html/cms/2005/0405/642.html 国外流行的开源CMS解决方案

http://www.chedong.com/tech/cms.html 内容管理系统(CMS)的设计和选型

Technorati :

posted @ 2006-12-14 18:52 Welkin Hu 阅读(223) | 评论 (0)编辑 收藏

今天上网搜索了一些有关PIM和日程安排的软件,希望找到一个Outlook的替代产品。

先后简单试用了友情强档,RedBox, WinOrganizer。感觉都差强人意。友情强档这款国产软件做得非常优秀,也是最接近Outlook的,可惜在项目的说明栏中,只能输入纯文本。无法使用RTF。RedBox也是只接收纯文本。相比之下,WinOrganizer在技术上就到位得多,可以自由的输入RFT,包括表格和图形都可以输入。不过,我实在不喜欢WinOrganizer的UI风格。

天天日程安排也不支持RTF输入,但是其资料管理功能中可支持RTF。安琪个人助理的界面好难看。

Essential PIM虽然也不支持RTF,但支持多级子任务项,这点还可以。

 

不经意间还看到有人推荐Google Calendar。这个东东居然把Calendar搬到的Web上,真有意思。由于网络依赖和提醒功能两大原因,我是不知道这东东有没有大用。

posted @ 2006-12-14 00:32 Welkin Hu 阅读(278) | 评论 (0)编辑 收藏

今天安排几位高级开发员更新产品的设计文档。要求一要和代码完全一致,二要具体到类和公用方法。

不料有几位对两个要求都不理解,认为没有必要。

我解释说:咱们做的产品,几十号人,做了五六年的产品。如果不写好文档,别人就没法顺利的接手,到时候什么事情都得问你,这样对你的发展很不利。

有同事听了我这话更是漠然的说:“别老是和发展扯在一起。”

唉,真不知道该怎样激励他们。对自己的职业发展都漠然视之。别跟我说是老板不给机会。

posted @ 2006-12-11 20:39 Welkin Hu 阅读(846) | 评论 (4)编辑 收藏

使用离线blog工具,如Zoundry, Live Writer,最大的问题是不能发布到分类网站首页。这个功能是博客员独有的功能,在将来也不能期待有很多离线blog工具支持这个功能。
现在要想发布到网站首页,必须在先进入文章编辑页面。这太麻烦了。建议在文章列表上就提供一个链接,直接将文章发布到分类网站首页。
posted @ 2006-12-07 09:16 Welkin Hu 阅读(529) | 评论 (2)编辑 收藏

目前Java开源世界的主流力量来自英语国家,单纯的英语背景导致了许多著名的产品虽然号称支持Unicode,在国际化实现上表现极为糟糕。在此略举近期碰到的二三例。

  1. JRE中的zip类无法正确保存压缩文件的中文名。为此Ant项目不得不写了自己的zip类。
  2. Eclipse中code assistance的快捷键与经典的winnows输入法开关键冲突,同为Ctrl + Space。为此我不得不将code assistance键换为Alt + Z
  3. Java中很难创建一个全新的locale,必须得从rt.jar中选一个。
  4. Java的locale基本上不允许用户再做用户级别定制。
posted @ 2006-12-06 22:55 Welkin Hu 阅读(1391) | 评论 (8)编辑 收藏

今晚闲来无事,浏览了一下Eclipse的Helper,发现一个用于java调试的好工具,叫Scrapbook。这个单词的中文意思是剪贴薄。这个工具的功能有点像VB的立即窗口和VS.net中的命令窗口。当你输入一段简单的java表达式或代码时,它可以立即显示出结果值,或执行代码并输出结果到Console中。这个功能能够大大提高检测小段代码的效率。

posted @ 2006-12-06 22:38 Welkin Hu 阅读(366) | 评论 (0)编辑 收藏

     摘要: 天天的免疫接种记录已接种疫苗针次接种日期评价应种未种疫苗针次卡介苗12004-11-22及时HIB_OMPC1糖丸12005-04-05合格乙脑2糖丸22005-05-12及时糖丸32005-06-14及时百白破12005-04-05及时百白破22005-05-12及...  阅读全文
posted @ 2006-12-06 09:25 Welkin Hu 阅读(396) | 评论 (0)编辑 收藏

前段时间8:00起床,吃完早餐上班,到公司总是在9:10左右。这几天提前20分钟起床和出门,不料天天遭遇堵车,每次都要耗到整九点才能到公司。深圳的交通实在是让人七窍生烟!坐公交车最堵的地方,就是西丽镇那个新修的所谓公交快线!一座桥,周边几十个红灯,十多条人行横道。道路上人,小车,公车,货柜车混在一起,不堵才怪! 真不知道那些道路设计和审批的部门干什么吃的!


Technorati :

posted @ 2006-12-05 21:54 Welkin Hu 阅读(301) | 评论 (1)编辑 收藏

今天看央视的《垂直打击》,里面的空降作战跟我原来认识的很不一样。

空降时离机就开伞,而不是低空开伞。这两者的作战效果差太远了。

空降损失了47具伞,三部战车,12支枪,就说损失太大。如果实战中注重这点损失,这仗怎么打?

Technorati :

posted @ 2006-12-05 18:04 Welkin Hu 阅读(254) | 评论 (0)编辑 收藏



Outlook 2003中文版中,设置邮件回复为英文的"re",而不是中文的"回复"
工具->选项->邮件格式->国际选项

office 2003中去掉烦人的加载项工具栏
安装Acrobat 后,所有的Office工具都会多出单独的一行PDF工具栏,很烦人。
在注册表中找到相应的Addin,把LoadBehavior键值改为9就可以去掉它了。
LoadBehavior 指示加载行为的整数:0(无)、3(启动)、9(按需装载)或 16(只在下次启动时装载)

所有Office 2003软件注的addin注册在:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office

如:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\Access\Addins\PDFMaker.OfficeAddin

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\Excel\Addins\PDFMaker.OfficeAddin

一些Outlook网址

http://www.outlookcode.com/d/launchform.htm
http://www.outlookcode.com/d/forms/formlauncher.htm
http://support.microsoft.com/?kbid=249199
http://www.outlookcode.com/d/code/getfolder.htm

Office Outlook会自动读取Outlook Express的地址本,读取位置如下:
D:\Documents and Settings\Administrator\Application Data\Microsoft\Address Book\Administrator.wab

Technorati : , ,

posted @ 2006-12-05 18:04 Welkin Hu 阅读(1397) | 评论 (0)编辑 收藏

一、设置缺省的用户名

在"运行"对话框中输入"regedt32.exe",打开注册表编辑器。选择窗口菜单项中的"HKEY_LOCAL_MACHINE"窗口,在左边的目录树中找到"SOFTWARE\Microsoft\WindowsNT\CurrentVersion\Winlogon"子项,单击后在右边窗口中找到"DefaultUserName"条目,双击后更改为你希望系统自动登录时使用的用户名称(前提是这个用户必须存在)。

二、设置缺省的用户口令

同样在右边的窗口中找到"DefaultPassword"条目,双击更改为DefaultUserName中的用户使用的口令(如果"DefaultPassword"条目不存在,就需要选择"编辑→添加值"创建该条目)。

设置完成缺省用户口令后,就可以设置自动登录了。在"SOFTWARE\Microsoft\WindowsNT\CurrentVersion\Winlogon"子项中,找到"AutoAdminLogon"条目,双击更改该值为1时,系统使用缺省的用户名和密码自动登录;该值为0时,需要用户手工登录


Technorati : ,

posted @ 2006-12-05 18:03 Welkin Hu 阅读(514) | 评论 (1)编辑 收藏

最近工作需要将三四百个DLL文件汇入到VSS数据库中,并且一个个打上Label号,label号取的DLL的版本号(就是选中,点击鼠标邮件,属性里面可以看到的版本号),初步算了一下,这样几百个文件,一个Check out/Check in,再找到Label号,打上Label号,少说也要花上一两天的时间,这样实在是太慢了。下午希望能够通过在DotNet中编程来操作VSS数据库,于是查帮助文档,没有看到相关资料,倒是看到说VSS有命令行可以使用。于是网上搜了一下,也没看到几篇介绍VSS命令行的文章,还是看帮助文档吧,看了一个下午,一个晚上。再结合C#或者C/C++的使用,基本上以后可以实现自动Check Out/Check In并且自动打Label号了。简单总结了一下,下面是VSS的一些常用命令和操作:

1.setup environment variable: //指向ss.exe所在的路径
path=%path%;C:\Program Files\Microsoft Visual Studio\VSS\win32

2.指向VSS数据库的所在目录
set SSDIR=\\gqa-eric-lv\VSS\
set SSDIR=\\Guruvss\erp$\

3.登陆VSS:
ss CP -Yeric,eric123 -I- -s\\gqa-eric-lv\vss

4.获取任一目录的任一文件到本机(下例将$/ASP.Net/DataGridTest/index.aspx文件get到D:\tmp目录)
ss get -GLD:\tmp $/ASP.Net/DataGridTest/index.aspx
(ss get, -GLpath Copies a file to the specified folder, not to the current or working folder. )

5.分屏显示目录ASP.Net中的所有文件和文件夹(包括子文件):
ss dir $/ASP.Net -R|more (另外,有-I -V 两个参数,作用未知)

6.set Current Project:
ss cp $/SQL-sample

7.vss命令行是大小写不敏感的;命令行中的命令不需要全名,同sql一样,只要是可以识别的名字及可,如Dir就是directory的缩写;
(遵守UNC通用命名规则,Universal Naming Convention)

8.一些通用的命令行选项:
-C 为指定项(可以是多项)做注释 (Dir例外)
-O 重定向命令
-V 操作某项的指定版本
-R Perform a command recursively.
-S Turn SmartMode on or off for the command.
-G Change the way the Get command works on any file retrieved to the local drive.
-W 指明本机副本是否只读(使用此参数,表示writable)
-N 在长短文件名两种模式间切换
-I 任何环境下都不提示输入
-Y 指定用户名和密码
-?, -H 两个参数的作用都是获得在线的帮助

9.命令中有空格时,用双引号括起整个选项,如用ss CP "-Yeric Lv",eric123 而不用ss CP -Y"eric lv",eric123,

10.启动图形界面:ssexp -s\\gqa-eric-lv\vss

11.ss命令中,/表示VSS的当前目录,$/表示根目录,常用操作命令如下:
ss Add TEST.C "My long filename.H" ,把TEST.C和"My long filename.H"两个文件添加到当前项目;
ss Add -R *,把当前目录的所有文件及文件夹(包括子文件夹、文件)添加到当前项目;
ss ADD -D- *.DLL,添加当前目录的所有DLL文件到当前项目,但不保留VSS上的历史文件(以节省空间);
ss Checkout TEST.C TEST.H Checkout当前项目中的两个文件
ss Checkout $/TESTDATA/TEST.C Checkout指定项目中的文件
ss Checkout -R $/TESTDATA 循环Check项目$/TESTDATA
ss Comment TEST.C -V5 改变TEST.C的版本号为5的版本注释
ss Comment TEST.C 改变TEST.C的最新版本的注释
ss Comment $/TESTDATA 改变项目$/TESTDATA的注释
ss Create $/WORD VSS的根目录下,创建项目WORD
ss Create WORD VSS的当前目录下,创建项目WORD
ss Cp $/WORD 设置$/WORD为Current Project
ss Cp .. 跳转到当前项目的父项目
ss Delete $/PRJ/TEST.C 删除文件TEST.C (delete命令删除的文件,可以用直接add命令回复,如Add test.C)
ss Delete $/PRJ 删除项目 (不可以有两个同名的文件被delete,因为没有真正删除)
ss -S Delete *.* 删除所有文件,-S表示删除VSS上的文件之后,删除本机文件
ss Destroy $/PRJ/TEST.C 持久删除文件(不可恢复)
ss Destroy $/PRJ 持久删除项目

12.其他的更改操作有:label,merge,move,password,purge,recover,rename,rollback,share,undocheckout,workfold,branch等命令,这些命令会改变VSS数据库的内容或者环境。

13.VSS命令行中的比较/查找/显示等不改变数据库和环境的命令: diff,dir,FileType,Get,help,history,links,paths,project,properties,status,view,whoami

14.显示最近的Version,Label信息:SS properties

15.显示Checkout的文件:SS Status

Technorati : ,

posted @ 2006-12-05 18:01 Welkin Hu 阅读(847) | 评论 (1)编辑 收藏