开发人员指南
本指南旨在帮助系统集成开发人员理解并掌握本社区的界面、资源文件以及系统集成等方面开发方法

内容一栏表

- 系统架构概览
- 界面设计
- 系统国际化
- 扩展属性的使用与管理
- 验证系统及与现有用户系统集成
- 在JSP等其它表现层中使用本系统

系统架构概览

本软件是一款基于J2EE轻量级架构的社区系统，具有如下特点：

- 表示层：基于Apache Tapestry组件化页面技术，对客户界面进行模块设计。由于页面模板中只有简单的类似if-else和for 循环逻辑，并且所有标签都是标准的HTML标签，因此页面可以放在任何所见所得的HTML编辑器中进行很轻松的编辑、美化。当然，Tapestry只是整个系统的表现部分，如果需要，此部分也可由其它技术实现，如JSP，Velocity等。
- 权限系统：在客户界面与业务核心层间，存在一套完整的权限系统。每个用户在系统中都有自己的权限，这些权限细致限定了该用户可以使用哪些服务或者可以访问哪些业务对象。
- 过滤器系统：此系统由一系列过滤器组成，对表示层要显示的社区内容执行过滤。
- 社区核心层：这里完成几乎所有的业务逻辑。
- 后台数据库系统：存储社区各项数据。数据层服务由Hibernate提供数据连接。
- 模块化、可配置、伸缩性强：您可广泛程度上的定义多数社区子系统：如用户、组、权限系统、过滤器、拦截器、等级积分算法、社区属性(如体力值、魅力值)等。

界面设计
本系统采用基于 布局 ＞ 模板 ＞ 风格 三级设计体系，可令系统同时拥有任意页面布局风格的显示界面。
所有页面模板都放在Context目录下onetforums目录中，客户端模板组织方式为：

    	onetforums
    		skins
    			layout1
    			layout2
    			layout3
    				skin1
    				skin2
    				skin3
    					images(此为模板skin3的图片目录)
    					styles
    						style1.css
    						style2.css
    						style3.css
    						images

上述模板拓扑清晰展现了客户端页面模板在文件系统中的组织方式，其中layouts、skins、styles分别代表布局目录、模板目录和风格目录。
官方每发布一种布局时，将至少包含一种模板(skin)和若干种风格(style)。您可以调整模板和风格。
如何修改并新增模板与风格？
举个例子：在skin3的基础上修改并增加模板skin4。 步骤如下：

1. 在 layout3 下复制skin3并更名为skin4
2. 在所见所得HTML编辑器中(确定UTF-8编码方式)编辑skin4下的*.html模板文件，并调替换images中的对应图片
3. 更新skin4下的所有风格/图片
4. 文件系统中的操作完成，接着在系统管理工具中完成如下操作：
5. 管理员身份登录进入管理工具，依次进入界面管理 ＞ 模板风格，从而进入模板风格视图（以下简称视图）
6. 在layout1对应的布局下点击进入新增模板，输入模板名称、描述和路径名称skin4。完成后系统将自动缺省风格，此风格设置与当前系统缺省风格一致
7. 视图中于skin4下点击编辑风格，修改各项风格参数。
8. 视图中进入skin4的“显示设置”，定义此模板的页眉、页脚、发贴心情表情等参数
9. 在 界面设置 ＞ 全局设置 中修改“用户界面中皮肤选择范围”参数
10. 设置完成！

系统国际化

需要注意的地方：

页面模板的编辑、自定义类的编译以及国际化资源文件编辑等，务必采用UTF-8编码

如何增加国际化语言资源包？

1. 选择一个支持UTF-8编码的文本编辑器，调整当前文件编码为UTF-8，与系统编码一致 ；
2. 解压缩WEB-INF/lib/下的onetforums-resources.jar文件，取出onetforums_i18n.properties等资源文件；
3. 以之为模板编辑您需要的资源文件；
4. 翻译编辑完毕，将新语言包命名为onetforums_i18n_XXX.properties。XXX代表语言区域，例如中国台湾：zh_TW，美国英语：en_US；
5. 将onetforums_i18n_XXX.properties复制到classes目录中，启动系统。通过客户界面进入控制面板，更改语言区域设置，查看新语言资源文件的翻译是否正确、完整；
6. 编辑测试完毕，通过命令：jar uvf onetforums-resources.jar onetforums_i18n_XXX.properties 更新资源文件即可。

扩展属性的使用与管理
本系统几乎所有的业务对象都有自己的属性数据，如User,Group,ForumMessage等，它们用来保存业务对象的相关数据、 状态等。譬如用户的“自传”就以“biography”属性保存在OnetUserProp属性表中。属性是通过IPropertyManager和IProperties 两个接口进行管理的，前者有两个方法： IProperties getProperties()和 boolean updateProperties() ，后者则有一组操作属性的方法。 下面以User为例说明属性的使用和管理：

1. 取得属性：如取得String类型数据biography,
   IProperties p=user.getProperties();
   String biography=p.getString("biography","default-value")
2. 添加属性：如添加属性
   IProperties p=user.getProperties();
   p.setString("biography","new value"); ;
   user.updateProperties();
3. 修改属性：譬如修改自传
   IProperties p=user.getProperties();
   p.setString("biography","new value"); ;
   user.updateProperties();
4. 删除属性：譬如删除自传
   IProperties p=user.getProperties();
   p.removeProperty("biography");
   user.updateProperties();

属性接口IProperties有一系列的getXXX方法，可操作各类主要类型的数据，更多请参考Javadoc。
同样，属性也纳入了权限保护范围，没有属性操作权限的用户将无法完成属性的添加、删除、修改等操作。

验证系统及与现有用户系统集成

若你已经有了一套用户管理系统以及大量的注册用户，通过本指导可帮助你将社区系统与您的现有系统无缝集成。
请扩展实现三个抽象类AuthManager、AbstractUser和AbstractUserManager ，分别说明如下：

- AuthManager 抽象验证管理类
  实现方法 protected long authenticateInDb(String username, String password) throws UnauthorizedException
  此方法用于在数据库检测的方式验证用户名和密码是否正确，若正确，返回userID，否则抛出UnauthorizedException
  定义完成后在通过管理工具 系统管理 ＞ 全局属性 添加属性：key=security.AuthManager.class vlaue=mypackage.CustomAuthManager
- AbstractUser 抽象用户类
  扩展实现 IProperties loadPropertiesFromDb() 和boolean updateProperties() 与现有用户系统的相关资料对接：
  例如：譬如现有系统中已有了biography这个字段了，要将这个字段与社区系统集成，做法如下：
  1、在社区载入属性时置入biography，代码如下：
  protected IProperties loadPropertiesFromDb() {
  IProperties proterties= super.loadPropertiesFromDb();
  /*取得属性值*/
  proterties.fillProperty(propertyName,propertyValue);

  return proterties;
  }
  2、在更新属性时注意先行更新当前系统关心的属性参数：
  public synchronized boolean updateProperties() {
  IProperties properties = getProperties();

  if (!(properties.hasUnsavedProperties() || properties.hasRemovedProperties())) return true;

  String propName = null;

  //save updated or new properties
  if (properties.hasUnsavedProperties()) {
  List list = new ArrayList();
  for (Iterator ite = properties.iterateUnsavedKeys(); ite.hasNext();) {
  propName = (String) ite.next();
  list.add(propName);

  if (properties.checkExists(propName)) {
  String value = properties.getUnsavedProperty(propName);
  /*保存更新的属性 ....*/
  } else {
  String value = properties.getUnsavedProperty(propName);
  /*保存新的属性 ....*/
  }
  }

  //清除变动属性，防止保存到社区系统
  for (int i = 0; i < list.size(); i++) {
  properties.cleanUnsavedProperty((String) list.get(i));
  }
  }

  //remove properties
  if (properties.hasRemovedProperties()) {
  List list = new ArrayList();
  for (Iterator ite = properties.iterateRemovedKeys(); ite.hasNext();) {
  String key = (String) ite.next();
  list.add(key);
  /*删除属性 . ....*/
  }
  //清除变动属性，防止社区系统再操作此属性
  for (int i = 0; i < list.size(); i++) {
  properties.cleanRemovedProperty((String) list.get(i));
  }
  }
  return super.updateProperties();
  }
  3、在自定义UserManager中实现如下：
  public IUser createBlankUser() {
  return new CustomUser(); //自定义实现的用户类
  }

- AbstractUserManager 抽象用户管理系统
  继承此类实现数据层操作方法即可
  定义完成后在通过管理工具 系统管理 ＞ 全局属性 添加属性：key=security.UserManager.class vlaue=mypackage.CustomUserManager

在JSP等其它系统中使用本系统

在其它表示层技术系统中，如JSP，你同样可以使用本社区系统，提取社区内容。
请运行demo.jsp文件，参考有关网站整合所需的代码支持。

- 通过下面代码进入系统API
  long userID = AuthManager.authenticate(username, password);
  IAcl acl = ACLFactory.getACL(userID);
  ForumFactory factory = ForumFactory.instance(acl);
- 构造页面访问链接
  为方便构造各页面的访问，可通过new StaticLink(PageCons.XXX).append(parameter1).append(parameter2)......getURL()构造某页面的访问url连接href
  其中PageCons.XXX代表某页面名称。对于常用页面，也可通过LinkBuilder.construct.....静态方法来构造。
- 在其它页面中登录社区系统
  请参考demo.jsp

需要更多开发支持和社区配置服务，请与我们联系。

Copyright © Onetsoft.com 2005