在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(
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) {
_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(
throws IOException {
Attributes attributes = null;
InputStream inputStream = servletContext.getResourceAsStream(
"/META-INF/MANIFEST.MF");
if (inputStream != null) {
Manifest manifest = new Manifest(inputStream);
attributes = manifest.getMainAttributes();
attributes = new Attributes();
String artifactGroupId = attributes.getValue(
"Implementation-Vendor-Id");
if (Validator.isNull(artifactGroupId)) {
artifactGroupId = attributes.getValue("Implementation-Vendor");
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);
從這裡代碼,我們可以看出,它吧這個檔案的一些資訊都讀取出來,但是對于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);
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"));
從這裡看出來,它就是建立一個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被架構所使用了。
本文轉自 charles_wang888 51CTO部落格,原文連結:http://blog.51cto.com/supercharles888/906049,如需轉載請自行聯系原作者