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,如需转载请自行联系原作者

目录
相关文章
|
6月前
|
移动开发 Java Unix
Android系统 自动加载自定义JAR文件
Android系统 自动加载自定义JAR文件
241 1
|
Java Android开发
SystemServer 启动新增服务APK
SystemServer 启动新增服务APK
127 0
|
jvm-sandbox Shell Java
Jvm-Sandbox源码分析--启动时加载模块
在上一篇Jvm-Sandbox源码分析--启动简析 简单介绍了一下jvm-sandbox启动流程,在这篇文章中我们来分析一下系统模块和用户的自定义模块在启动时,是怎么加载的。
4429 0