MainServlet在初始化布局模板之后,就开始初始化社交了,对应代码是:
- if (_log.isDebugEnabled()) {
- _log.debug("Initialize social");
- }
- try {
- initSocial(pluginPackage);
- }
- ..
它会去调用initSocial方法:
- protected void initSocial(PluginPackage pluginPackage) throws Exception {
- ClassLoader classLoader = PortalClassLoaderUtil.getClassLoader();
- ServletContext servletContext = getServletContext();
- String[] xmls = new String[] {
- HttpUtil.URLtoString(
- servletContext.getResource("/WEB-INF/liferay-social.xml")),
- HttpUtil.URLtoString(
- servletContext.getResource("/WEB-INF/liferay-social-ext.xml"))
- };
- SocialConfigurationUtil.read(classLoader, xmls);
- }
我们看出来,它还是先取得servletContext(04行),然后读取2个和social相关的xml配置文件,关于Liferay的社交概念,我自从上个月学习Liferay以来一直不明确,今天刚好看了下liferay-social.xml,发现每个社交都对应一个<activity>,从大体上,大概分为博客 (Blog),消息板(Message Board),维基(Wiki).
然后,它会去调用SocialConfigurationUtil类的read方法来分析这些Social相关的配置文件:
- public static List<Object> read(ClassLoader classLoader, String[] xmls)
- throws Exception {
- List<Object> objects = new ArrayList<Object>();
- for (String xml : xmls) {
- _read(classLoader, xml, objects);
- }
- return objects;
- }
它遍历xml配置文件,并且对于每个xml文件,调用私有的_read方法:
- private static void _read(
- ClassLoader classLoader, String xml, List<Object> objects)
- throws Exception {
- ..
- List<Element> activityElements = rootElement.elements("activity");
- for (Element activityElement : activityElements) {
- _readActivity(classLoader, objects, activityElement);
- }
- }
正如我所料,它回去读取每个xml元素的<activity>元素,然后调用私有的方法_readActivity()来进行读取。被读取的<activity>元素我们可以参照下面这个:
- <activity>
- <model-name>com.liferay.portlet.wiki.model.WikiPage</model-name>
- <activity-type>${com.liferay.portlet.wiki.social.WikiActivityKeys.UPDATE_PAGE}</activity-type>
- <language-key>UPDATE_PAGE</language-key>
- <log-activity>true</log-activity>
- <participation-value>1</participation-value>
- <participation-limit period="period">10</participation-limit>
- <counter>
- <name>user.wiki-updates</name>
- <owner-type>actor</owner-type>
- </counter>
- </activity>
我们现在具体分析_readActivity()方法是如何具体来解析这段<activity>元素的。
首先,它去解析<model-name>元素,并且获取匹配的SocialActivityDefinition对象,如果没有则创建:
- String modelName = GetterUtil.getString(
- activityElement.elementText("model-name"));
- Map<Integer, SocialActivityDefinition> activityDefinitions =
- _activityDefinitions.get(modelName);
- if (activityDefinitions == null) {
- activityDefinitions =
- new HashMap<Integer, SocialActivityDefinition>();
- _activityDefinitions.put(modelName, activityDefinitions);
- }
然后,它去解析<activity-type>元素,这个元素对应的值都可以在codebase中找到,是个整数,然后搜索是否有匹配的SocialActivityDefinition对象,如果没有则创建:
- int activityType = GetterUtil.getInteger(
- activityElement.elementText("activity-type"));
- SocialActivityDefinition activityDefinition = activityDefinitions.get(
- activityType);
- if (activityDefinition == null) {
- activityDefinition = new SocialActivityDefinition();
- ...
- objects.add(activityDefinition);
- }
然后,它去解析<counter>元素,一个activity可以有多个counter元素:
- List<Element> counterElements = activityElement.elements("counter");
- for (Element counterElement : counterElements) {
- _readCounter(objects, activityDefinition, counterElement);
- }
最后,它去解析<achievement>元素,一个activity可以有多个achievement元素:
- List<Element> achievementElements = activityElement.elements(
- "achievement");
- for (Element achievementElement : achievementElements) {
- _readAchievement(
- classLoader, objects, activityDefinition, achievementElement);
- }
等这些元素都解析完,则所有social相关的信息都是可用的了。