在MainServlet中,初始化ServletContextPool之后,就开始初始化plugin package:
- ..
- PluginPackage pluginPackage = null;
- try {
- pluginPackage = initPluginPackage();
- }
- ..
它会调用同类的initPluginPackage()方法:
- protected PluginPackage initPluginPackage() throws Exception {
- ServletContext servletContext = getServletContext();
- return PluginPackageUtil.readPluginPackageServletContext(
- servletContext);
- }
这段代码会进而调用PluginPackageUtil类的readPluginPackageServletContext方法,这里做了一个封装:
- public static PluginPackage readPluginPackageServletContext(
- ServletContext servletContext)
- throws DocumentException, IOException {
- return _instance._readPluginPackageServletContext(servletContext);
- }
最终会调用PluginPackageUtil的私有方法_readPluginPackageServletContext方法:
- private PluginPackage _readPluginPackageServletContext(
- ServletContext servletContext)
- throws DocumentException, IOException {
- String servletContextName = servletContext.getServletContextName();
- String xml = HttpUtil.URLtoString(
- servletContext.getResource("/WEB-INF/liferay-plugin-package.xml"));
- if (_log.isInfoEnabled()) {
- if (servletContextName == null) {
- _log.info("Reading plugin package for the root context");
- }
- else {
- _log.info("Reading plugin package for " + servletContextName);
- }
- }
- PluginPackage pluginPackage = null;
- if (xml == null) {
- String propertiesString = HttpUtil.URLtoString(
- servletContext.getResource(
- "/WEB-INF/liferay-plugin-package.properties"));
- if (propertiesString != null) {
- if (_log.isDebugEnabled()) {
- _log.debug(
- "Reading plugin package from " +
- "liferay-plugin-package.properties");
- }
- Properties properties = PropertiesUtil.load(propertiesString);
- String displayName = servletContextName;
- if (displayName.startsWith(StringPool.SLASH)) {
- displayName = displayName.substring(1);
- }
- pluginPackage = _readPluginPackageProperties(
- displayName, properties);
- }
- if (pluginPackage == null) {
- if (_log.isDebugEnabled()) {
- _log.debug("Reading plugin package from MANIFEST.MF");
- }
- pluginPackage =_readPluginPackageServletManifest(
- servletContext);
- }
- }
- else {
- if (_log.isDebugEnabled()) {
- _log.debug(
- "Reading plugin package from liferay-plugin-package.xml");
- }
- pluginPackage = _readPluginPackageXml(xml);
- }
- pluginPackage.setContext(servletContextName);
- return pluginPackage;
- }
读取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:
- private PluginPackage _readPluginPackageServletManifest(
- ServletContext servletContext)
- throws IOException {
- Attributes attributes = null;
- String servletContextName = servletContext.getServletContextName();
- InputStream inputStream = servletContext.getResourceAsStream(
- "/META-INF/MANIFEST.MF");
- if (inputStream != null) {
- Manifest manifest = new Manifest(inputStream);
- attributes = manifest.getMainAttributes();
- }
- else {
- attributes = new Attributes();
- }
- String artifactGroupId = attributes.getValue(
- "Implementation-Vendor-Id");
- if (Validator.isNull(artifactGroupId)) {
- artifactGroupId = attributes.getValue("Implementation-Vendor");
- }
- if (Validator.isNull(artifactGroupId)) {
- artifactGroupId = GetterUtil.getString(
- attributes.getValue("Bundle-Vendor"), servletContextName);
- }
- String artifactId = attributes.getValue("Implementation-Title");
- if (Validator.isNull(artifactId)) {
- artifactId = GetterUtil.getString(
- attributes.getValue("Bundle-Name"), servletContextName);
- }
- String version = attributes.getValue("Implementation-Version");
- if (Validator.isNull(version)) {
- version = GetterUtil.getString(
- attributes.getValue("Bundle-Version"), Version.UNKNOWN);
- }
- if (version.equals(Version.UNKNOWN) && _log.isWarnEnabled()) {
- _log.warn(
- "Plugin package on context " + servletContextName +
- " cannot be tracked because this WAR does not contain a " +
- "liferay-plugin-package.xml file");
- }
- PluginPackage pluginPackage = new PluginPackageImpl(
- artifactGroupId + StringPool.SLASH + artifactId + StringPool.SLASH +
- version + StringPool.SLASH + "war");
- pluginPackage.setName(artifactId);
- String shortDescription = attributes.getValue("Bundle-Description");
- if (Validator.isNotNull(shortDescription)) {
- pluginPackage.setShortDescription(shortDescription);
- }
- String pageURL = attributes.getValue("Bundle-DocURL");
- if (Validator.isNotNull(pageURL)) {
- pluginPackage.setPageURL(pageURL);
- }
- return pluginPackage;
- }
从这里代码,我们可以看出,它吧这个文件的一些信息都读取出来,但是对于ROOT引用没有这个MANIFEST.MF文件,所以忽略。
读取liferay-plugin-package.xml文件:
然后,它会去解析liferay-plugin-package.xml文件,即开始进入_readPluginPackageServletContext方法的第60行。解析代码为:
- private PluginPackage _readPluginPackageXml(String xml)
- throws DocumentException {
- Document document = SAXReaderUtil.read(xml);
- Element rootElement = document.getRootElement();
- return _readPluginPackageXml(rootElement);
- }
它会委托另一个重载方法,只不过入参是Element而不是String了:
- private PluginPackage _readPluginPackageXml(Element pluginPackageElement) {
- String name = pluginPackageElement.elementText("name");
- if (_log.isDebugEnabled()) {
- _log.debug("Reading pluginPackage definition " + name);
- }
- PluginPackage pluginPackage = new PluginPackageImpl(
- GetterUtil.getString(
- pluginPackageElement.elementText("module-id")));
- List<String> liferayVersions = _readList(
- pluginPackageElement.element("liferay-versions"),
- "liferay-version");
- List<String> types = _readList(
- pluginPackageElement.element("types"), "type");
- pluginPackage.setName(_readText(name));
- pluginPackage.setRecommendedDeploymentContext(
- _readText(
- pluginPackageElement.elementText(
- "recommended-deployment-context")));
- pluginPackage.setModifiedDate(
- _readDate(pluginPackageElement.elementText("modified-date")));
- pluginPackage.setAuthor(
- _readText(pluginPackageElement.elementText("author")));
- pluginPackage.setTypes(types);
- pluginPackage.setLicenses(
- _readLicenseList(
- pluginPackageElement.element("licenses"), "license"));
- pluginPackage.setLiferayVersions(liferayVersions);
- pluginPackage.setTags(
- _readList(pluginPackageElement.element("tags"), "tag"));
- pluginPackage.setShortDescription(
- _readText(pluginPackageElement.elementText("short-description")));
- pluginPackage.setLongDescription(
- _readHtml(pluginPackageElement.elementText("long-description")));
- pluginPackage.setChangeLog(
- _readHtml(pluginPackageElement.elementText("change-log")));
- pluginPackage.setScreenshots(
- _readScreenshots(pluginPackageElement.element("screenshots")));
- pluginPackage.setPageURL(
- _readText(pluginPackageElement.elementText("page-url")));
- pluginPackage.setDownloadURL(
- _readText(pluginPackageElement.elementText("download-url")));
- pluginPackage.setDeploymentSettings(
- _readProperties(
- pluginPackageElement.element("deployment-settings"),
- "setting"));
- return pluginPackage;
- }
从这里看出来,它就是创建一个PluginPackage对象,然后用这个XML文件中的信息往其中填充信息而已:
我们ROOT应用的liferay-plugin-package.xml如下所示:
- <?xml version="1.0"?>
- <!DOCTYPE plugin-package PUBLIC "-//Liferay//DTD Plugin Package 6.1.0//EN" "http://www.liferay.com/dtd/liferay-plugin-package_6_1_0.dtd">
- <plugin-package>
- <name>Liferay Core Plugins</name>
- <module-id>liferay/core-plugins/6.1.0/war</module-id>
- <types>
- <type>layout-template</type>
- <type>portlet</type>
- <type>theme</type>
- </types>
- <short-description>
- Portlets, themes, and layout templates included with Liferay Portal.
- </short-description>
- <change-log>
- Adapted to the latest version of Liferay.
- </change-log>
- <page-url>http://www.liferay.com/web/guest/downloads</page-url>
- <author>Liferay, Inc.</author>
- <licenses>
- <license osi-approved="true">LGPL</license>
- </licenses>
- <liferay-versions>
- <liferay-version>6.1.0</liferay-version>
- </liferay-versions>
- </plugin-package>
绑定这个Liferay Core Plugin到ROOT context:
当解析完ROOT应用下的PluginPackage之后,它会绑定到ROOT Context,通过执行_readPluginPackageServletContext方法的第60行:
- pluginPackage.setContext(servletContextName);
于是,现在Core Plugin就作为第一个PluginPackage被框架所使用了。