在Liferay Enterprise中,对于License的使用和控制是十分讲究的,因为lincense决定了产品的使用能力和使用期限,我们现在就来深入分析下license.
License的部署:
首先又要回到Listener了,见http://supercharles888.blog.51cto.com/609344/907286博客所说,在Liferay的MainServlet的启动过程中,当处理全局启动事件时,它会注册所有的antoDeployListener,其中,LicenseAutoDeployListener也位列其中:
- auto.deploy.listeners=\
- com.liferay.portal.deploy.auto.OSGiAutoDeployListener,\
- com.liferay.portal.deploy.auto.ExtAutoDeployListener,\
- com.liferay.portal.deploy.auto.HookAutoDeployListener,\
- com.liferay.portal.deploy.auto.LayoutTemplateAutoDeployListener,\
- com.liferay.portal.deploy.auto.LiferayPackageAutoDeployListener,\
- com.liferay.portal.deploy.auto.PortletAutoDeployListener,\
- com.liferay.portal.deploy.auto.ThemeAutoDeployListener,\
- com.liferay.portal.deploy.auto.WebAutoDeployListener,\
- com.liferay.portal.deploy.auto.exploded.tomcat.HookExplodedTomcatListener,\
- com.liferay.portal.deploy.auto.exploded.tomcat.LayoutTemplateExplodedTomcatListener,\
- com.liferay.portal.deploy.auto.exploded.tomcat.PortletExplodedTomcatListener,\
- com.liferay.portal.license.deploy.auto.LicenseAutoDeployListener,com.liferay.portal.deploy.auto.exploded.tomcat.ThemeExplodedTomcatListener
所以,当我们初次吧License文件放在$LIFERAY_HOME/deploy目录下,就会触发LicenseAutoDeployListener做出响应,而它实现了AutoDeployListener接口,所以放license文件到deploy目录会触发它的deploy方法:
- public void deploy(File paramFile, String paramString)
- {
- if (a.isDebugEnabled())
- a.debug("Invoking deploy for " + paramFile.getPath());
- String str1 = FileUtil.getExtension(paramFile.getName());
- if (!str1.equals("xml"))
- return;
- try
- {
- String str2 = FileUtil.read(paramFile);
- Document localDocument = SAXReaderUtil.read(str2);
- Element localElement = localDocument.getRootElement();
- String str3 = localElement.getName();
- if (!str3.equals("license"))
- return;
- }
- catch (Exception localException)
- {
- return;
- }
- if (a.isInfoEnabled())
- a.info("Copying license for " + paramFile.getPath());
- this.b.autoDeploy(paramFile, paramString);
- }
从这里我们可以看到,它05-07行首先会去检查license文件的扩展名是否为xml 。然后第10-13行会利用SAXReadUtil来读取这个文件,并且第14行判定根元素是否为license。然后在22行打印出一行信息(因为默认日志的info级别是开启的,所以我们可以看到这行日志):
- 06:25:14,380 INFO [LicenseAutoDeployListener:?] Copying license for D:\Liferay_Cluster_Enterprise\Node1\liferay-portal-tomcat-6.1.10-ee-ga1\liferay-portal-6.1.10-ee-ga1\deploy\license-portaldevelopment-developer-6.1-triallicenses.xml
最后,第23行它去调用autoDeploy方法来进行部署工作,我们继续跟进。
这个b是LicenseAutoDeployer的一个实例,它才具体完成license的具体部署工作:
- public class LicenseAutoDeployer extends a
- implements AutoDeployer
- {
- public void autoDeploy(File paramFile, String paramString)
- {
- try
- {
- this.a = FileUtil.read(paramFile);
- a();
- }
- ...
- }
- }
它首先在第08行用FileUtil来读取license文件,具体处理逻辑在a类的b()方法中:
- private com.liferay.portal.license.a b()
- {
- Document localDocument = SAXReaderUtil.read(this.a);
- Element localElement1 = localDocument.getRootElement();
- String str1 = GetterUtil.getString(localElement1.elementTextTrim("account-name"));
- String str2 = GetterUtil.getString(localElement1.elementTextTrim("owner"));
- String str3 = GetterUtil.getString(localElement1.elementTextTrim("description"));
- String str4 = GetterUtil.getString(localElement1.elementTextTrim("product-name"));
- String str5 = GetterUtil.getString(localElement1.elementTextTrim("product-id"), "Portal");
- String str6 = GetterUtil.getString(localElement1.elementTextTrim("product-version"));
- String str7 = GetterUtil.getString(localElement1.elementTextTrim("license-name"));
- String str8 = GetterUtil.getString(localElement1.elementTextTrim("license-type"));
- String str9 = GetterUtil.getString(localElement1.elementTextTrim("license-version"));
- DateFormat localDateFormat = DateFormat.getDateTimeInstance(0, 0, Locale.US);
- Date localDate1 = null;
- if (str8.equals("trial"))
- localDate1 = new Date();
- else
- localDate1 = localDateFormat.parse(localElement1.elementTextTrim("start-date"));
- Date localDate2 = null;
- if (str8.equals("trial"))
- {
- long l1 = GetterUtil.getLong(localElement1.elementTextTrim("lifetime"));
- localDate2 = new Date(localDate1.getTime() + l1);
- }
- else
- {
- localDate2 = localDateFormat.parse(localElement1.elementTextTrim("expiration-date"));
- }
- int i = GetterUtil.getInteger(localElement1.elementTextTrim("max-servers"));
- int j = GetterUtil.getInteger(localElement1.elementTextTrim("max-http-sessions"));
- long l2 = GetterUtil.getLong(localElement1.elementTextTrim("max-concurrent-users"));
- long l3 = GetterUtil.getLong(localElement1.elementTextTrim("max-users"));
- ArrayList localArrayList1 = new ArrayList();
- ArrayList localArrayList2 = new ArrayList();
- ArrayList localArrayList3 = new ArrayList();
- ArrayList localArrayList4 = new ArrayList();
- a(localArrayList1, localElement1.element("host-names"), "host-name");
- a(localArrayList2, localElement1.element("ip-addresses"), "ip-address");
- a(localArrayList3, localElement1.element("mac-addresses"), "mac-address");
- a(localArrayList4, localElement1.element("server-ids"), "server-id");
- Element localElement2 = localElement1.element("servers");
- if (localElement2 != null)
- {
- localObject1 = localElement2.elements("server");
- Iterator localIterator = ((List)localObject1).iterator();
- while (localIterator.hasNext())
- {
- localObject2 = (Element)localIterator.next();
- a(localArrayList1, ((Element)localObject2).element("host-names"), "host-name");
- a(localArrayList2, ((Element)localObject2).element("ip-addresses"), "ip-address");
- a(localArrayList3, ((Element)localObject2).element("mac-addresses"), "mac-address");
- a(localArrayList4, ((Element)localObject2).element("server-ids"), "server-id");
- }
- }
- Object localObject1 = localElement1.elementTextTrim("key");
- Object localObject2 = new com.liferay.portal.license.a(str1, str2, str3, str4, str5, str6, str7, str8, str9, localDate1, localDate2, i, j, l2, l3, (String[])localArrayList1.toArray(new String[localArrayList1.size()]), (String[])localArrayList2.toArray(new String[localArrayList2.size()]), (String[])localArrayList3.toArray(new String[localArrayList3.size()]), (String[])localArrayList4.toArray(new String[localArrayList4.size()]), (String)localObject1);
- if (str8.equals("trial"))
- localObject2 = d.b((com.liferay.portal.license.a)localObject2);
- return (com.liferay.portal.license.a)(com.liferay.portal.license.a)localObject2;
- }
这里可以看出,从第03-13行依次读取一些通用元素。然后第16行对是否是trial版本的license进行判断,一个license如下图所示:
- <?xml version="1.0"?>
- <license>
- <account-name>Liferay Trial</account-name>
- <owner>Charles Wang</owner>
- <description>30-Day Trial License</description>
- <product-name>Portal Development</product-name>
- <product-version>6.1</product-version>
- <license-name>Portal Developer</license-name>
- <license-type>developer</license-type>
- <license-version>3</license-version>
- <start-date>Sunday, June 17, 2012 7:00:00 AM GMT</start-date>
- <expiration-date>Tuesday, July 17, 2012 7:00:00 AM GMT</expiration-date>
- <max-http-sessions>10</max-http-sessions>
- <key>96af591fbfd1b507446223f679df4bbc4d8f51e9824f5424c0f83c42130c4c9180837cca5e9fc2e8dca0dffdae1cc0f1ca993f421c8c55f22153a28b970a6a6508ab22fa6180e7b66634451a1f8dd81eeb34ad936d1e13de77df4f6e216bed19e3ff69a01744b3b6258a17bcee435bed13820c5c00e2158553568cb9b2623c474508a3aa</key>
- </license>
从这里可以看出,我们的<license-type>是developer, 不是trail,所以代码会执行第19行和28行,这2行会分别读取<start-date>和<expiration-date>这2个元素。第30-55行会读取集群license的一些配置信息,因为我们的license是免费申请的,所以没有这些信息,所以跳过。然后就执行第56行,它会去读取<key>元素的信息。最终把所有必要信息填充到a对象中以便 以后使用。
License的管理:
对于License的管理主要在LicenseManager类中。主要方法之一为checkLicense,它会对license做合法性检查: