Liferay 启动过程分析5-初始化插件包

简介:

 在MainServlet中,初始化ServletContextPool之后,就开始初始化plugin package:

 
 
  1. .. 
  2.     PluginPackage pluginPackage = null
  3.  
  4.         try { 
  5.             pluginPackage = initPluginPackage(); 
  6.         } 
  7. .. 

它会调用同类的initPluginPackage()方法:

 
 
  1. protected PluginPackage initPluginPackage() throws Exception { 
  2.         ServletContext servletContext = getServletContext(); 
  3.  
  4.         return PluginPackageUtil.readPluginPackageServletContext( 
  5.             servletContext); 
  6.     } 

这段代码会进而调用PluginPackageUtil类的readPluginPackageServletContext方法,这里做了一个封装:

 
 
  1. public static PluginPackage readPluginPackageServletContext( 
  2.             ServletContext servletContext) 
  3.         throws DocumentException, IOException { 
  4.  
  5.         return _instance._readPluginPackageServletContext(servletContext); 
  6.     } 

最终会调用PluginPackageUtil的私有方法_readPluginPackageServletContext方法:

 
 
  1. private PluginPackage _readPluginPackageServletContext( 
  2.             ServletContext servletContext) 
  3.         throws DocumentException, IOException { 
  4.  
  5.         String servletContextName = servletContext.getServletContextName(); 
  6.  
  7.         String xml = HttpUtil.URLtoString( 
  8.             servletContext.getResource("/WEB-INF/liferay-plugin-package.xml")); 
  9.  
  10.         if (_log.isInfoEnabled()) { 
  11.             if (servletContextName == null) { 
  12.                 _log.info("Reading plugin package for the root context"); 
  13.             } 
  14.             else { 
  15.                 _log.info("Reading plugin package for " + servletContextName); 
  16.             } 
  17.         } 
  18.  
  19.         PluginPackage pluginPackage = null
  20.  
  21.         if (xml == null) { 
  22.             String propertiesString = HttpUtil.URLtoString( 
  23.                 servletContext.getResource( 
  24.                     "/WEB-INF/liferay-plugin-package.properties")); 
  25.  
  26.             if (propertiesString != null) { 
  27.                 if (_log.isDebugEnabled()) { 
  28.                     _log.debug( 
  29.                         "Reading plugin package from " + 
  30.                             "liferay-plugin-package.properties"); 
  31.                 } 
  32.  
  33.                 Properties properties = PropertiesUtil.load(propertiesString); 
  34.  
  35.                 String displayName = servletContextName; 
  36.  
  37.                 if (displayName.startsWith(StringPool.SLASH)) { 
  38.                     displayName = displayName.substring(1); 
  39.                 } 
  40.  
  41.                 pluginPackage = _readPluginPackageProperties( 
  42.                     displayName, properties); 
  43.             } 
  44.  
  45.             if (pluginPackage == null) { 
  46.                 if (_log.isDebugEnabled()) { 
  47.                     _log.debug("Reading plugin package from MANIFEST.MF"); 
  48.                 } 
  49.  
  50.                 pluginPackage =_readPluginPackageServletManifest( 
  51.                     servletContext); 
  52.             } 
  53.         } 
  54.         else { 
  55.             if (_log.isDebugEnabled()) { 
  56.                 _log.debug( 
  57.                     "Reading plugin package from liferay-plugin-package.xml"); 
  58.             } 
  59.  
  60.             pluginPackage = _readPluginPackageXml(xml); 
  61.         } 
  62.  
  63.         pluginPackage.setContext(servletContextName); 
  64.  
  65.         return pluginPackage; 
  66.     } 

 

读取XML格式的配置文件还是.properties格式的配置文件:

我们先看到在第08行,会去读取ROOT应用下的liferay-plugin-package.xml文件+MANIFEST.MF文件,如果没有这个xml扩展名的文件,则会去读取liferay-plugin-package.properties文件,(PS,难怪我用了一个月的Liferay,有些portlet用xml文件有些用properties文件配置的,都可以)。

 

读取MANIFEST.MF文件:(ROOT应用下没有,所以不用读)

因为我们ROOT应用下有liferay-plugin-package.xml,所以跳转到45行,它会去读取ROOT应用下的MANIFEST.MF:

 
 
  1. private PluginPackage _readPluginPackageServletManifest( 
  2.             ServletContext servletContext) 
  3.         throws IOException { 
  4.             Attributes attributes = null
  5.  
  6.         String servletContextName = servletContext.getServletContextName(); 
  7.  
  8.         InputStream inputStream = servletContext.getResourceAsStream( 
  9.             "/META-INF/MANIFEST.MF"); 
  10.  
  11.         if (inputStream != null) { 
  12.             Manifest manifest = new Manifest(inputStream); 
  13.  
  14.             attributes = manifest.getMainAttributes(); 
  15.         } 
  16.         else { 
  17.             attributes = new Attributes(); 
  18.         } 
  19.  
  20.         String artifactGroupId = attributes.getValue( 
  21.             "Implementation-Vendor-Id"); 
  22.  
  23.         if (Validator.isNull(artifactGroupId)) { 
  24.             artifactGroupId = attributes.getValue("Implementation-Vendor"); 
  25.         } 
  26.  
  27.         if (Validator.isNull(artifactGroupId)) { 
  28.             artifactGroupId = GetterUtil.getString( 
  29.                 attributes.getValue("Bundle-Vendor"), servletContextName); 
  30.         } 
  31.  
  32.         String artifactId = attributes.getValue("Implementation-Title"); 
  33.  
  34.         if (Validator.isNull(artifactId)) { 
  35.             artifactId = GetterUtil.getString( 
  36.                 attributes.getValue("Bundle-Name"), servletContextName); 
  37.         } 
  38.  
  39.         String version = attributes.getValue("Implementation-Version"); 
  40.  
  41.         if (Validator.isNull(version)) { 
  42.             version = GetterUtil.getString( 
  43.                 attributes.getValue("Bundle-Version"), Version.UNKNOWN); 
  44.         } 
  45.  
  46.         if (version.equals(Version.UNKNOWN) && _log.isWarnEnabled()) { 
  47.             _log.warn( 
  48.                 "Plugin package on context " + servletContextName + 
  49.                     " cannot be tracked because this WAR does not contain a " + 
  50.                         "liferay-plugin-package.xml file"); 
  51.         } 
  52.  
  53.         PluginPackage pluginPackage = new PluginPackageImpl( 
  54.             artifactGroupId + StringPool.SLASH + artifactId + StringPool.SLASH + 
  55.                 version + StringPool.SLASH + "war"); 
  56.  
  57.         pluginPackage.setName(artifactId); 
  58.  
  59.         String shortDescription = attributes.getValue("Bundle-Description"); 
  60.  
  61.         if (Validator.isNotNull(shortDescription)) { 
  62.             pluginPackage.setShortDescription(shortDescription); 
  63.         } 
  64.  
  65.         String pageURL = attributes.getValue("Bundle-DocURL"); 
  66.  
  67.         if (Validator.isNotNull(pageURL)) { 
  68.             pluginPackage.setPageURL(pageURL); 
  69.         } 
  70.  
  71.         return pluginPackage; 
  72.     } 

从这里代码,我们可以看出,它吧这个文件的一些信息都读取出来,但是对于ROOT引用没有这个MANIFEST.MF文件,所以忽略。

 

读取liferay-plugin-package.xml文件:

然后,它会去解析liferay-plugin-package.xml文件,即开始进入_readPluginPackageServletContext方法的第60行。解析代码为:

 
 
  1. private PluginPackage _readPluginPackageXml(String xml) 
  2.         throws DocumentException { 
  3.  
  4.         Document document = SAXReaderUtil.read(xml); 
  5.  
  6.         Element rootElement = document.getRootElement(); 
  7.  
  8.         return _readPluginPackageXml(rootElement); 
  9.     } 

它会委托另一个重载方法,只不过入参是Element而不是String了:

 
 
  1. private PluginPackage _readPluginPackageXml(Element pluginPackageElement) { 
  2.         String name = pluginPackageElement.elementText("name"); 
  3.  
  4.         if (_log.isDebugEnabled()) { 
  5.             _log.debug("Reading pluginPackage definition " + name); 
  6.         } 
  7.  
  8.         PluginPackage pluginPackage = new PluginPackageImpl( 
  9.             GetterUtil.getString( 
  10.                 pluginPackageElement.elementText("module-id"))); 
  11.  
  12.         List<String> liferayVersions = _readList( 
  13.             pluginPackageElement.element("liferay-versions"), 
  14.             "liferay-version"); 
  15.  
  16.         List<String> types = _readList( 
  17.             pluginPackageElement.element("types"), "type"); 
  18.  
  19.         pluginPackage.setName(_readText(name)); 
  20.         pluginPackage.setRecommendedDeploymentContext( 
  21.             _readText( 
  22.                 pluginPackageElement.elementText( 
  23.                     "recommended-deployment-context"))); 
  24.         pluginPackage.setModifiedDate( 
  25.             _readDate(pluginPackageElement.elementText("modified-date"))); 
  26.         pluginPackage.setAuthor( 
  27.             _readText(pluginPackageElement.elementText("author"))); 
  28.         pluginPackage.setTypes(types); 
  29.         pluginPackage.setLicenses( 
  30.             _readLicenseList( 
  31.                 pluginPackageElement.element("licenses"), "license")); 
  32.         pluginPackage.setLiferayVersions(liferayVersions); 
  33.         pluginPackage.setTags( 
  34.             _readList(pluginPackageElement.element("tags"), "tag")); 
  35.         pluginPackage.setShortDescription( 
  36.             _readText(pluginPackageElement.elementText("short-description"))); 
  37.         pluginPackage.setLongDescription( 
  38.             _readHtml(pluginPackageElement.elementText("long-description"))); 
  39.         pluginPackage.setChangeLog( 
  40.             _readHtml(pluginPackageElement.elementText("change-log"))); 
  41.         pluginPackage.setScreenshots( 
  42.             _readScreenshots(pluginPackageElement.element("screenshots"))); 
  43.         pluginPackage.setPageURL( 
  44.             _readText(pluginPackageElement.elementText("page-url"))); 
  45.         pluginPackage.setDownloadURL( 
  46.             _readText(pluginPackageElement.elementText("download-url"))); 
  47.         pluginPackage.setDeploymentSettings( 
  48.             _readProperties( 
  49.                 pluginPackageElement.element("deployment-settings"), 
  50.                 "setting")); 
  51.  
  52.         return pluginPackage; 
  53.     } 

从这里看出来,它就是创建一个PluginPackage对象,然后用这个XML文件中的信息往其中填充信息而已:

我们ROOT应用的liferay-plugin-package.xml如下所示:

 
 
  1. <?xml version="1.0"?> 
  2. <!DOCTYPE plugin-package PUBLIC "-//Liferay//DTD Plugin Package 6.1.0//EN" "http://www.liferay.com/dtd/liferay-plugin-package_6_1_0.dtd"> 
  3.  
  4. <plugin-package> 
  5.     <name>Liferay Core Plugins</name> 
  6.     <module-id>liferay/core-plugins/6.1.0/war</module-id> 
  7.     <types> 
  8.         <type>layout-template</type> 
  9.         <type>portlet</type> 
  10.         <type>theme</type> 
  11.     </types> 
  12.     <short-description> 
  13.         Portlets, themes, and layout templates included with Liferay Portal. 
  14.     </short-description> 
  15.     <change-log> 
  16.         Adapted to the latest version of Liferay. 
  17.     </change-log> 
  18.     <page-url>http://www.liferay.com/web/guest/downloads</page-url> 
  19.     <author>Liferay, Inc.</author> 
  20.     <licenses> 
  21.         <license osi-approved="true">LGPL</license> 
  22.     </licenses> 
  23.     <liferay-versions> 
  24.         <liferay-version>6.1.0</liferay-version> 
  25.     </liferay-versions> 
  26. </plugin-package> 

 

 

绑定这个Liferay Core Plugin到ROOT context:

当解析完ROOT应用下的PluginPackage之后,它会绑定到ROOT Context,通过执行_readPluginPackageServletContext方法的第60行:

 
 
  1. pluginPackage.setContext(servletContextName); 

 

于是,现在Core Plugin就作为第一个PluginPackage被框架所使用了。

 





本文转自 charles_wang888 51CTO博客,原文链接:http://blog.51cto.com/supercharles888/906049,如需转载请自行联系原作者

目录
相关文章
|
Java Android开发 消息中间件
Android系统默认Home应用程序(Launcher)的启动过程源代码分析
转自 :http://blog.csdn.net/luoshengyang/article/details/6767736    在前面一篇文章中,我们分析了Android系统在启动时安装应用程序的过程,这些应用程序安装好之后,还需要有一个Home应用程序来负责把它们在桌面上展示出来,在Android系统中,这个默认的Home应用程序就是Launcher了,本文将详细分析Laun
2136 0