MainServlet中,当初始化社交结束之后,就开始初始化主题了,对应代码是:

 
  
  1.     if (_log.isDebugEnabled()) { 
  2.             _log.debug("Initialize themes"); 
  3.         } 
  4.  
  5.         try { 
  6.             initThemes(pluginPackage, portlets); 
  7.         } 
  8. .. 

 

它对应的代码在initThemes方法中:

 
  
  1. protected void initThemes( 
  2.             PluginPackage pluginPackage, List<Portlet> portlets) 
  3.         throws Exception { 
  4.  
  5.         ServletContext servletContext = getServletContext(); 
  6.  
  7.         String[] xmls = new String[] { 
  8.             HttpUtil.URLtoString( 
  9.                 servletContext.getResource( 
  10.                     "/WEB-INF/liferay-look-and-feel.xml")), 
  11.             HttpUtil.URLtoString( 
  12.                 servletContext.getResource( 
  13.                     "/WEB-INF/liferay-look-and-feel-ext.xml")) 
  14.         }; 
  15.  
  16.         ThemeLocalServiceUtil.init( 
  17.             servletContext, nulltrue, xmls, pluginPackage); 
  18.     } 

这里可以看出,它仍然是先获取servletContext,然后获得theme有关的配置文件,然后从第16行开始来解析这些配置文件:

 

解析是调用ThemLocalServiceUtil的init方法:

 
  
  1. public static java.util.List<java.lang.String> init( 
  2.         javax.servlet.ServletContext servletContext, 
  3.         java.lang.String themesPath, boolean loadFromServletContext, 
  4.         java.lang.String[] xmls, 
  5.         com.liferay.portal.kernel.plugin.PluginPackage pluginPackage) { 
  6.         return getService() 
  7.                    .init(servletContext, themesPath, loadFromServletContext, 
  8.             xmls, pluginPackage); 
  9.     } 

 

作为封装,实际是调用的ThemeLocalServiceImpl的5参数的init方法,而它又调用重载的6参数的init方法:

 
  
  1. public List<String> init( 
  2.         String servletContextName, ServletContext servletContext, 
  3.         String themesPath, boolean loadFromServletContext, String[] xmls, 
  4.         PluginPackage pluginPackage) { 
  5.  
  6.         List<String> themeIdsList = new ArrayList<String>(); 
  7.  
  8.         try { 
  9.             for (String xml : xmls) { 
  10.                 Set<String> themeIds = _readThemes( 
  11.                     servletContextName, servletContext, themesPath, 
  12.                     loadFromServletContext, xml, pluginPackage); 
  13.  
  14.                 for (String themeId : themeIds) { 
  15.                     if (!themeIdsList.contains(themeId)) { 
  16.                         themeIdsList.add(themeId); 
  17.                     } 
  18.                 } 
  19.             } 
  20.         } 
  21.         catch (Exception e) { 
  22.             e.printStackTrace(); 
  23.         } 
  24.  
  25.         _themesPool.clear(); 
  26.  
  27.         return themeIdsList; 
  28.     } 

它会遍历xml配置文件(1个或2个),然后对于每个xml文件调用_readThemes方法,然后把合法theme的id添加到列表中并且返回。

 

所以我们现在来研究_readthemes方法:

首先,它会进行兼容性判断,它先获取Liferay服务器的version,然后读取配置文件中的<compatibility>元素,然后获取<compatibility>元素的所有<version>元素,然后比较Liferay服务器的version是否被包含在兼容列表中:

 
  
  1. Version portalVersion = _getVersion(ReleaseInfo.getVersion()); 
  2.  
  3.         boolean compatible = false
  4.  
  5.         Element compatibilityElement = rootElement.element("compatibility"); 
  6.  
  7.         if (compatibilityElement != null) { 
  8.             List<Element> versionElements = compatibilityElement.elements( 
  9.                 "version"); 
  10.  
  11.             for (Element versionElement : versionElements) { 
  12.                 Version version = _getVersion(versionElement.getTextTrim()); 
  13.  
  14.                 if (version.includes(portalVersion)) { 
  15.                     compatible = true
  16.  
  17.                     break
  18.                 } 
  19.             } 
  20.         } 

 

然后,它分析<company-limits>字段,并且吧其中的includes,excludes信息都填充到ThemeCompanyLimit对象中:

 
  
  1. ThemeCompanyLimit companyLimit = null
  2.  
  3.         Element companyLimitElement = rootElement.element("company-limit"); 
  4.  
  5.         if (companyLimitElement != null) { 
  6.             companyLimit = new ThemeCompanyLimit(); 
  7.  
  8.             Element companyIncludesElement = companyLimitElement.element( 
  9.                 "company-includes"); 
  10.  
  11.             if (companyIncludesElement != null) { 
  12.                 companyLimit.setIncludes( 
  13.                     _getCompanyLimitIncludes(companyIncludesElement)); 
  14.             } 
  15.  
  16.             Element companyExcludesElement = companyLimitElement.element( 
  17.                 "company-excludes"); 
  18.  
  19.             if (companyExcludesElement != null) { 
  20.                 companyLimit.setExcludes( 
  21.                     _getCompanyLimitExcludes(companyExcludesElement)); 
  22.             } 
  23.         } 

 

然后它分析<group-limits>字段,并且吧其中的includes,excludes信息都填充到ThemeGroupLimit对象中:

 
  
  1. ThemeGroupLimit groupLimit = null
  2.  
  3.         Element groupLimitElement = rootElement.element("group-limit"); 
  4.  
  5.         if (groupLimitElement != null) { 
  6.             groupLimit = new ThemeGroupLimit(); 
  7.  
  8.             Element groupIncludesElement = groupLimitElement.element( 
  9.                 "group-includes"); 
  10.  
  11.             if (groupIncludesElement != null) { 
  12.                 groupLimit.setIncludes( 
  13.                     _getGroupLimitIncludes(groupIncludesElement)); 
  14.             } 
  15.  
  16.             Element groupExcludesElement = groupLimitElement.element( 
  17.                 "group-excludes"); 
  18.  
  19.             if (groupExcludesElement != null) { 
  20.                 groupLimit.setExcludes( 
  21.                     _getGroupLimitExcludes(groupExcludesElement)); 
  22.             } 
  23.         } 

 

其实,以上3部分就是用于标识theme的使用范围,下面开始正式解析<theme>元素,因为一个xml配置文件中会有多个<theme>元素,因此它会进行遍历,并且吧其中的各个信息都去填充Theme对象:

 
  
  1. ContextReplace themeContextReplace = new ContextReplace(); 
  2.  
  3.             themeContextReplace.addValue("themes-path", themesPath); 
  4.  
  5.             String themeId = themeElement.attributeValue("id"); 
  6.  
  7.             ... 
  8.  
  9.             if (!theme.isWapTheme()) { 
  10.                 _setSpriteImages(servletContext, theme, p_w_picpathsPath); 
  11.             } 
  12.  
  13.             if (!_themes.containsKey(themeId)) { 
  14.                 _themes.put(themeId, theme); 
  15.             } 
  16.         } 
  17.  
  18.         return themeIds; 
  19.     } 

 

最终,这些Theme就都是可用状态了。