portlet.xml
portlet定義描述文件,它描述portlet的類型,支持Mode, preferenes和role等,遵循JSR168標準實現,以便于移植(需要針對性的做一些小改過)。
下面是一個簡單的定義:
〈portlet〉 〈portlet-name〉2〈/portlet-name〉 〈display-name〉My Account〈/display-name〉 〈!-- portlet的實現類 --〉 〈portlet-class〉com.liferay.portlet.StrutsPortlet〈/portlet-class〉 〈init-param〉 〈name〉view-action〈/name〉 〈value〉/my_account/view〈/value〉 〈/init-param〉 〈expiration-cache〉0〈/expiration-cache〉 〈supports〉 〈mime-type〉text/html〈/mime-type〉 〈/supports〉 〈resource-bundle〉com.liferay.portlet.StrutsResourceBundle〈/resource-bundle〉 〈/portlet〉
在JSR168標準中,定義了view/edit/help三種模式, liferay對其進行了擴展,增加了config/about/preview/print等模式。
liferay-portlet.xml
liferay的portlet定義描述文件,是liferay對portlet.xml的擴展描述,允許我們對portlet的呈現、功能和行為進行更深入的定制。 它與com.liferay.portal.model.Portlet類對應,
下面是一個較為詳細的liferay-portlet定義: 〈portlet〉 〈portlet-name〉19〈/portlet-name〉 〈!-- struts路徑 --〉 〈struts-path〉message_boards〈/struts-path〉 〈!-- 配置路徑 --〉 〈configuration-path〉/message_boards/edit_configuration〈/configuration-path〉 〈!-- lucene索引類 --〉 〈indexer-class〉com.liferay.portlet.messageboards.util.Indexer〈/indexer-class〉 〈!-- url處理類 --〉 〈portlet-url-class〉com.liferay.portlet.messageboards.MBFriendlyPortletURL〈/portlet-url-class〉 〈!-- 友好url插件類 --〉 〈friendly-url-plugin-class〉com.liferay.portlet.messageboards.MBFriendlyURLPortletPlugin〈/friendly-url-plugin-class〉 〈preferences-unique-per-layout〉false〈/preferences-unique-per-layout〉 〈use-default-template〉false〈/use-default-template〉 〈restore-current-view〉false〈/restore-current-view〉 〈private-request-attributes〉false〈/private-request-attributes〉 〈/portlet〉
portlet類中常用的屬性:
// strtus 路徑,對portlet的請求應該限制在這個路徑下 private String _strutsPath;
// 配置路徑,即action定義 private String _configurationPath;
// portlet實現類 private String _portletClass;
// lucene索引類 private String _indexerClass;
// scheduler類 private String _schedulerClass;
// portletURL處理類 private String _portletURLClass;
// friendURL插件 private String _friendlyURLPluginClass;
// 默認的preferences private String _defaultPreferences;
// preferences的驗證類 private String _prefsValidator;
// 是否實例化,為true時可添加多個portlet到layout上 private boolean _instanceable;
// 是否為系統portlet, private boolean _system;
// 初始化參數 private Map _initParams;
// portlet支持的模式 private Map _portletModes;
// portlet支持的語言 private Set _supportedLocales;
// PortletInfo private PortletInfo _portletInfo;
// 是否靜態portlet, 靜態portlet不能移動. private boolean _staticPortlet;
// 是否為開始的靜態portlet. private boolean _staticPortletStart;
portlet解析
com.liferay.portal.service.impl.PortletLocalServiceImpl
public void initEAR(String[] xmls) { String scpId = PortletServiceImpl.class.getName() + "." + _SHARED_KEY;
Map portletsPool = (Map)SimpleCachePool.get(scpId);
if (portletsPool == null) { portletsPool = CollectionFactory.getSyncHashMap(); SimpleCachePool.put(scpId, portletsPool); }
try { List servletURLPatterns = _readWebXML(xmls[4]);
Set portletIds = _readPortletXML(xmls[0], portletsPool, servletURLPatterns); portletIds.addAll( _readPortletXML(xmls[1], portletsPool, servletURLPatterns));
Set liferayPortletIds = _readLiferayPortletXML(xmls[2], portletsPool); liferayPortletIds.addAll( _readLiferayPortletXML(xmls[3], portletsPool));
// Check for missing entries in liferay-portlet.xml // 檢查在liferay-portlet中丟失的portlet實體...
// Remove portlets that should not be included // 移去不應該包括的portlet實體... } catch (Exception e) { _log.error(StackTraceUtil.getStackTrace(e)); } }
// 解析portlet.xml private Set _readPortletXML( String servletContextName, String xml, Map portletsPool, List servletURLPatterns) throws DocumentException, IOException {
Set portletIds = new HashSet();
if (xml == null) { return portletIds; }
SAXReader reader = SAXReaderFactory.getInstance();
Document doc = reader.read(new StringReader(xml));
Element root = doc.getRootElement();
Set userAttributes = new HashSet();
Iterator itr1 = root.elements("user-attribute").iterator(); // 用戶屬性處理...
itr1 = root.elements("portlet").iterator();
while (itr1.hasNext()) { Element portlet = (Element)itr1.next();
String portletId = portlet.elementText("portlet-name");
if (servletContextName != null) { portletId = portletId + Portlet.WAR_SEPARATor + servletContextName; }
portletId = PortalUtil.getJsSafePortletName(portletId);
if (_log.isDebugEnabled()) { _log.debug("Reading portlet " + portletId); }
portletIds.add(portletId);
Portlet portletModel = (Portlet)portletsPool.get(portletId);
if (portletModel == null) { portletModel = new Portlet( new PortletPK(portletId, _SHARED_KEY));
portletsPool.put(portletId, portletModel); }
if (servletContextName != null) { portletModel.setWARFile(true); }
if (servletURLPatterns != null) { portletModel.setServletURLPatterns(servletURLPatterns); }
portletModel.setPortletClass(portlet.elementText("portlet-class"));
Iterator itr2 = portlet.elements("init-param").iterator(); // 初始化參數處理...
Element expirationCache = portlet.element("expiration-cache"); // cache過期處理...
itr2 = portlet.elements("supports").iterator(); // 支持模式處理...
Set supportedLocales = portletModel.getSupportedLocales(); // 支持語言處理...
// 資源 portletModel.setResourceBundle( portlet.elementText("resource-bundle"));
Element portletInfo = portlet.element("portlet-info"); // portlet-info處理...
Element portletPreferences = portlet.element("portlet-preferences"); // preferences處理...
Set unlikedRoles = portletModel.getUnlinkedRoles(); itr2 = portlet.elements("security-role-ref").iterator(); // role處理...
portletModel.getUserAttributes().addAll(userAttributes); }
return portletIds; }
// 解析liferay-portlet.xml private Set _readLiferayPortletXML( String servletContextName, String xml, Map portletsPool) throws DocumentException, IOException {
Set liferayPortletIds = new HashSet();
if (xml == null) { return liferayPortletIds; }
SAXReader reader = SAXReaderFactory.getInstance();
Document doc = reader.read(new StringReader(xml));
Element root = doc.getRootElement();
Map roleMappers = new HashMap();
Iterator itr1 = root.elements("role-mapper").iterator(); // role-mapper處理...
Map customUserAttributes = new HashMap();
itr1 = root.elements("custom-user-attribute").iterator(); // 定制用戶屬性處理...
Map friendlyURLPlugins = _getFriendlyURLPlugins();
itr1 = root.elements("portlet").iterator();
while (itr1.hasNext()) { Element portlet = (Element)itr1.next();
String portletId = portlet.elementText("portlet-name");
if (servletContextName != null) { portletId = portletId + Portlet.WAR_SEPARATor + servletContextName; }
portletId = PortalUtil.getJsSafePortletName(portletId);
if (_log.isDebugEnabled()) { _log.debug("Reading portlet extension " + portletId); }
liferayPortletIds.add(portletId);
Portlet portletModel = (Portlet)portletsPool.get(portletId);
if (portletModel != null) { // 設置portlet屬性...
// 處理FriendURL插件 portletModel.setFriendlyURLPluginClass(GetterUtil.getString( portlet.elementText("friendly-url-plugin-class"), portletModel.getFriendlyURLPluginClass()));
if (Validator.isNull( portletModel.getFriendlyURLPluginClass())) {
friendlyURLPlugins.remove(portletId); } else { friendlyURLPlugins.put( portletId, portletModel.getFriendlyURLPluginClass()); }
// 綁定role. portletModel.getRoleMappers().putAll(roleMappers); portletModel.linkRoles();
portletModel.getCustomUserAttributes().putAll( customUserAttributes); } }
return liferayPortletIds; }
從上面的代碼可看出,liferay將portlet的描述定義存儲在一個Map中.
liferay-display.xml
portlet的類別定義文件,下面是一個簡單的例子:
〈category name="category.admin"〉 〈portlet id="9" /〉 〈portlet id="40" /〉 〈portlet id="79" /〉 〈portlet id="80" /〉 〈/category〉
要注意的是,在portlet.xml/liferay-portlet.xml/liferay-display.xml三個文件中的portlet-name, portlet-id必須是一致的。
liferay-layout-templates.xml
layout模板定義文件.
liferay-look-and-feel.xml
主題定義文件.
portlet的web.xml
如果以war的方式發布portlet,那么它的web.xml也要進行一些特定的說明,
下面是liferay中sample-jsp-portlet示例的web.xml: 〈web-app〉 〈display-name〉sample-jsp-portlet〈/display-name〉 〈context-param〉 〈param-name〉company_id〈/param-name〉 〈param-value〉liferay.com〈/param-value〉 〈/context-param〉 〈listener〉 〈listener-class〉com.liferay.portal.kernel.servlet.PortletContextListener〈/listener-class〉 〈/listener〉 〈servlet〉 〈servlet-name〉sample_jsp_portlet〈/servlet-name〉 〈servlet-class〉com.liferay.portal.kernel.servlet.PortletServlet〈/servlet-class〉 〈init-param〉 〈param-name〉portlet-class〈/param-name〉 〈param-value〉com.sample.jsp.portlet.JSPPortlet〈/param-value〉 〈/init-param〉 〈load-on-startup〉0〈/load-on-startup〉 〈/servlet〉 〈servlet-mapping〉 〈servlet-name〉sample_jsp_portlet〈/servlet-name〉 〈url-pattern〉/sample_jsp_portlet/*〈/url-pattern〉 〈/servlet-mapping〉 〈taglib〉 〈taglib-uri〉http://java.sun.com/portlet〈/taglib-uri〉 〈taglib-location〉/WEB-INF/tld/liferay-portlet.tld〈/taglib-location〉 〈/taglib〉 〈/web-app〉 上面的listener是必須的,它用于通知liferay進行熱部署, portlet-class指定Portlet的實現類,它必須遵循JSR168標準,直接或間接的從javax.portlet.GenericPortlet繼承。
相關文章:
liferay中的圖片處理
使用liferay中的struts+tiles來開發portlet(一)
Liferay中外部war方式整合portlet的處理流程
liferay中layout的處理
|