More后弹出的Portlet以及分类文本分析(2)

从这段代码可以看出来,它08-09行会先去判断这个值是否已经在WebAppPool中有,对于第一次访问,池中显然是没有的,所以第15行构造了一个新的PortletCategory对象,并且让其读取WEB-INF/liferay-display.xml中的设定,最后和空的PortletCategory对象merge起来。

我们追述到PortletLocalServiceUtilgetEARDisplay方法中:

public static com.liferay.portal.model.PortletCategory getEARDisplay(         java.lang.String xml)         throws com.liferay.portal.kernel.exception.SystemException {         return getService().getEARDisplay(xml);     } 

它最终会去调用PortletLocalServiceImplgetEARDisplay方法:

public PortletCategory getEARDisplay(String xml) throws SystemException {         try {             return _readLiferayDisplayXML(xml);         }         ..     } 

进入调用_readLiferayDisplayXML方法,然后调用重载的_readLiferayDisplayXML(servletContextName,xml)方法:

private PortletCategory _readLiferayDisplayXML(             String servletContextName, String xml)         throws Exception {          PortletCategory portletCategory = new PortletCategory();          if (xml == null) {             xml = ContentUtil.get(                 "com/liferay/portal/deploy/dependencies/liferay-display.xml");         }          Document document = SAXReaderUtil.read(xml, true);          Element rootElement = document.getRootElement();          Set<String> portletIds = new HashSet<String>();          _readLiferayDisplay(             servletContextName, rootElement, portletCategory, portletIds);          // Portlets that do not belong to any categories should default to the         // Undefined category          Set<String> undefinedPortletIds = new HashSet<String>();          for (Portlet portlet : _getPortletsPool().values()) {             String portletId = portlet.getPortletId();              PortletApp portletApp = portlet.getPortletApp();              if ((servletContextName != null) && (portletApp.isWARFile()) &&                 (portletId.endsWith(                     PortletConstants.WAR_SEPARATOR +                         PortalUtil.getJsSafePortletId(servletContextName)) &&                  (!portletIds.contains(portletId)))) {                  undefinedPortletIds.add(portletId);             }             else if ((servletContextName == null) &&                      (!portletApp.isWARFile()) &&                      (portletId.indexOf(                         PortletConstants.WAR_SEPARATOR) == -1) &&                      (!portletIds.contains(portletId))) {                  undefinedPortletIds.add(portletId);             }         }          if (!undefinedPortletIds.isEmpty()) {             PortletCategory undefinedCategory = new PortletCategory(                 "category.undefined");              portletCategory.addCategory(undefinedCategory);              undefinedCategory.getPortletIds().addAll(undefinedPortletIds);         }          return portletCategory;     } 

从这段代码我们可以清晰的对于category的处理分为两种情况:

(1)对于liferay-display.xml中有<category>元素的分类,我们跟进第18行:

private void _readLiferayDisplay(         String servletContextName, Element element,         PortletCategory portletCategory, Set<String> portletIds) {          for (Element categoryElement : element.elements("category")) {             String name = categoryElement.attributeValue("name");              PortletCategory curPortletCategory = new PortletCategory(name);              portletCategory.addCategory(curPortletCategory);              Set<String> curPortletIds = curPortletCategory.getPortletIds();              for (Element portletElement : categoryElement.elements("portlet")) {                 String portletId = portletElement.attributeValue("id");                  if (Validator.isNotNull(servletContextName)) {                     portletId =                         portletId + PortletConstants.WAR_SEPARATOR +                             servletContextName;                 }                  portletId = PortalUtil.getJsSafePortletId(portletId);                  portletIds.add(portletId);                 curPortletIds.add(portletId);             }              _readLiferayDisplay(                 servletContextName, categoryElement, curPortletCategory,                 portletIds);         }     } 

可以看出,它会循环的遍历liferay-display.xml中所有<category>元素,然后依次读取它们的<name>属性,并且把这些name属性都分别封装在PortletCategory对象中,然后把这些对象放入参数的PortletCategory中,然后递归继续读下去(PS:这是GOF中典型的Composite 设计模式)

(2) 对于liferay-display.xml中没有分类的Portlet,会归结到category.undefined分类中

PortletCategory undefinedCategory = new PortletCategory(                  "category.undefined"); 

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/3c799d9c291c7734ca632bd629012b82.html