1、首先根据Sakai开发说明.pdf上面说的所有逻辑都必须都必须打包在sakai容器中,而打包到sakai容器中则是靠pack包来实现的,所以最开始先看一下components.xml文件,所在位置是chat/chat-impl/pack/src/webapp/WEB-INF/components.xml,也是spring框架需要的。
<bean id="org.sakaiproject.chat2.model.ChatHibernateBean"
class="org.sakaiproject.springframework.orm.hibernate.impl.AdditionalHibernateMappingsImpl">
<property name="mappingResources">
<list>
<value>
org/sakaiproject/chat2/model/impl/ChatImpl.hbm.xml
</value>
</list>
</property>
</bean>
1.1、hibernate数据库映射,ChatImpl.hbm.xml主要包含内容:
<hibernate-mapping package="org.sakaiproject.chat2.model"
default-lazy="true">
<class name="ChatChannel" table="CHAT2_CHANNEL" lazy="true">
<id name="id" length="99" column="CHANNEL_ID">
<generator class="org.sakaiproject.id.hbm.IdGenerator"/>
</id>
<property name="title" type="string" length="64" />
<property name="description" type="string" length="255" />
<span style="white-space:pre"> </span>...
<property name="migratedChannelId" type="string" length="99" />
</class>
<class name="ChatMessage" table="CHAT2_MESSAGE" lazy="true">
<id name="id" length="99" column="MESSAGE_ID">
<generator class="org.sakaiproject.id.hbm.IdGenerator"/>
</id>
<property name="body" column="BODY" type="text" not-null="true" />
...
</class>
<query name="findChannelsInContext">
from ChatChannel c WHERE c.context=? order by c.title
主要包含两个bean(POJO)和一些sql查询语句的定义,其中ChatChannel和ChatMessage是数据库映射关系bean类,这两个java文件可以在chat/chat-api/src/.../model中找到,至于这些查询语句???
1.2、Spring中TransactionproxyFactoryBean生成事务代理
<bean id="org.sakaiproject.chat2.model.ChatManager"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref bean="org.sakaiproject.springframework.orm.hibernate.GlobalTransactionManager" />
</property>
<property name="target">
<ref bean="org.sakaiproject.chat2.model.impl.ChatManagerImpl" />
</property>
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<bean id="org.sakaiproject.chat2.model.impl.ChatManagerImpl"
class="org.sakaiproject.chat2.model.impl.ChatManagerImpl"
singleton="true" init-method="init" destroy-method="destroy">
<property name="sessionFactory">
<ref
bean="org.sakaiproject.springframework.orm.hibernate.GlobalSessionFactory" />
</property>
<property name="entityManager">
<ref bean="org.sakaiproject.entity.api.EntityManager" />
</property>
<property name="defaultChannelSettings">
<ref bean="defaultChatChannelSettings" />
</property>
</bean>
可以看出生成事务代理需要两个bean,一个是代理类TransactionproxyFactoryBean,另外一个是被代理类ChatManagerImpl,该被代理类可以在chat/chat-impl/impl/src/.../impl/下找到
1.3、其他逻辑类
<bean id="org.sakaiproject.chat2.model.impl.ChatChannelEntityProvider"
class="org.sakaiproject.chat2.model.impl.ChatChannelEntityProvider">
<property name="chatManager"><ref bean="org.sakaiproject.chat2.model.ChatManager"/></property>
</bean>
<bean id="org.sakaiproject.chat2.model.impl.ChatMessageEntityProvider"
class="org.sakaiproject.chat2.model.impl.ChatMessageEntityProvider">
<property name="chatManager"><ref bean="org.sakaiproject.chat2.model.ChatManager"/></property>
</bean>
这些类都可以在chat/chat-impl/impl/src/.../impl/下找到
1.4、为什么bean类(api中)
<bean id="defaultChatChannelSettings"
class="org.sakaiproject.chat2.model.ChatChannel"
singleton="true">
<property name="filterType">
<bean id="org.sakaiproject.chat2.model.ChatChannel.FILTER_ALL"
class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean">
</bean>
</property>
<property name="filterParam"><value>3</value></property>
<property name="timeParam"><value>3</value></property>
<property name="numberParam"><value>10</value></property>
<property name="enableUserOverride"><value>true</value></property>
</bean>
这个是干嘛的暂时还不知道
1.5、总结
chat/chat-impl/pack/src中只有一个一个components.xml文件,所以在将所有逻辑放到sakai容器中的时候会根据该文件进行,它包含的内容主要是api和impl中的内容
2、chat-tools主要是将war文件部署在webapp上,所以除了业务逻辑之外还需要处理页面关系等内容,他的大致结构图如下:
2.1、第①部分,主要是一些java工具类,一般供JSF使用???
2.2、第②部分主要是注册工具,例如sakai.chat.xml文件内容如下
<registration>
<tool
id="sakai.chat"
title="Chat Room"
description="For real-time conversations in written form.">
<configuration name="display-date" value="false" />
<configuration name="display-time" value="true" />
<configuration name="display-user" value="true" />
<configuration name="sound-alert" value="true" />
<configuration name="filter-type" value="SelectMessagesByTime" />
<configuration name="filter-param" value="3" />
<configuration name="channel" value="" />
<category name="course" />
<category name="project" />
<configuration name="functions.require" value="chat.read" />
</tool>
</registration>
其中最主要的是id/title,还有category,其中category表示该工具在哪个site下面展现
2.3、第③部分faces.config.xml文件,因为sakai使用的JSF框架,该文件就是JSF框架的关键配置文件。
2.3.1、application,指的是用于管理JSF应用的相关配置,ChatNavigationHandler就是2.1中的内容
<application>
<message-bundle>chat</message-bundle>
<locale-config>
<default-locale>en</default-locale>
</locale-config>
<navigation-handler>
org.sakaiproject.chat2.tool.ChatNavigationHandler
</navigation-handler>
</application>
2.3.2、managed-bean,JSF中所有托管的bean,其中的ChatTool也是2.1中的内容
<managed-bean>
<description>ChatTool</description>
<managed-bean-name>ChatTool</managed-bean-name>
<managed-bean-class>org.sakaiproject.chat2.tool.ChatTool</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
<managed-property>
<description>chatManager</description>
<property-name>chatManager</property-name>
<value>#{Components["org.sakaiproject.chat2.model.ChatManager"]}</value>
</managed-property>
<managed-property>
<description>Service Dependency: toolManager</description>
<property-name>toolManager</property-name>
<value>#{Components["org.sakaiproject.tool.api.ActiveToolManager"]}</value>
</managed-property>
</managed-bean>
2.3.3、navigation-rule,管理JSF应用的导航规则
<navigation-rule>
<from-view-id>*</from-view-id>
<navigation-case>
<from-outcome>room</from-outcome>
<to-view-id>/jsp/room.jsp</to-view-id>
<redirect/>
</navigation-case>
<navigation-case><!-- not needed if using the courier -->
<from-outcome>roomActions</from-outcome>
<to-view-id>/jsp/roomActions.jsp</to-view-id>
<redirect/>
</navigation-case>
...
</navigation-rule>
2.4、第④部分,web.xml
2.4.1、filter-mapping内容,有3个,刚好对应第②部分
<filter-mapping>
<filter-name>sakai.request</filter-name>
<servlet-name>sakai.chat</servlet-name>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>sakai.request</filter-name>
<servlet-name>sakai.synoptic.chat</servlet-name>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>sakai.request</filter-name>
<servlet-name>sakai.chat.deleteMessage</servlet-name>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>
<servlet>
<servlet-name>sakai.synoptic.chat</servlet-name>
<servlet-class>org.sakaiproject.jsf.util.HelperAwareJsfTool</servlet-class>
<init-param>
<param-name>path</param-name>
<param-value>/jsp</param-value>
</init-param>
<init-param>
<param-name>default</param-name>
<!-- the path is inserted before and .jsp inserted after -->
<param-value>synoptic</param-value>
</init-param>
<init-param>
<param-name>default.last.view</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
另外一个如下:
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup> 2 </load-on-startup>
</servlet>
FacesServlet是JSF核心控制器
2.5、最后部署的war文件