1   /**
2    * Copyright (c) 2000-2007 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portal.service.impl;
24  
25  import com.liferay.counter.service.CounterLocalServiceUtil;
26  import com.liferay.portal.PortalException;
27  import com.liferay.portal.SystemException;
28  import com.liferay.portal.kernel.plugin.PluginPackage;
29  import com.liferay.portal.kernel.portlet.FriendlyURLMapper;
30  import com.liferay.portal.kernel.util.GetterUtil;
31  import com.liferay.portal.kernel.util.LocaleUtil;
32  import com.liferay.portal.kernel.util.Validator;
33  import com.liferay.portal.model.Portlet;
34  import com.liferay.portal.model.PortletCategory;
35  import com.liferay.portal.model.PortletInfo;
36  import com.liferay.portal.model.impl.CompanyImpl;
37  import com.liferay.portal.model.impl.PortletImpl;
38  import com.liferay.portal.service.base.PortletLocalServiceBaseImpl;
39  import com.liferay.portal.service.persistence.PortletUtil;
40  import com.liferay.portal.util.ContentUtil;
41  import com.liferay.portal.util.PortalUtil;
42  import com.liferay.portal.util.PortletKeys;
43  import com.liferay.portal.util.PropsUtil;
44  import com.liferay.portlet.PortletPreferencesSerializer;
45  import com.liferay.util.CollectionFactory;
46  import com.liferay.util.ListUtil;
47  
48  import java.io.IOException;
49  import java.io.StringWriter;
50  
51  import java.util.ArrayList;
52  import java.util.HashMap;
53  import java.util.HashSet;
54  import java.util.Iterator;
55  import java.util.List;
56  import java.util.Map;
57  import java.util.Set;
58  
59  import javax.portlet.PortletMode;
60  import javax.portlet.PreferencesValidator;
61  
62  import org.apache.commons.logging.Log;
63  import org.apache.commons.logging.LogFactory;
64  
65  import org.dom4j.Document;
66  import org.dom4j.DocumentException;
67  import org.dom4j.Element;
68  import org.dom4j.io.OutputFormat;
69  import org.dom4j.io.XMLWriter;
70  
71  /**
72   * <a href="PortletLocalServiceImpl.java.html"><b><i>View Source</i></b></a>
73   *
74   * @author Brian Wing Shun Chan
75   * @author Raymond Augé
76   *
77   */
78  public class PortletLocalServiceImpl extends PortletLocalServiceBaseImpl {
79  
80      public PortletCategory getEARDisplay(String xml) throws SystemException {
81          try {
82              return _readLiferayDisplayXML(xml);
83          }
84          catch (DocumentException de) {
85              throw new SystemException(de);
86          }
87          catch (IOException ioe) {
88              throw new SystemException(ioe);
89          }
90      }
91  
92      public PortletCategory getWARDisplay(String servletContextName, String xml)
93          throws SystemException {
94  
95          try {
96              return _readLiferayDisplayXML(servletContextName, xml);
97          }
98          catch (DocumentException de) {
99              throw new SystemException(de);
100         }
101         catch (IOException ioe) {
102             throw new SystemException(ioe);
103         }
104     }
105 
106     public List getFriendlyURLMappers() {
107         return _getFriendlyURLMappers();
108     }
109 
110     public Portlet getPortletById(long companyId, String portletId)
111         throws SystemException {
112 
113         portletId = PortalUtil.getJsSafePortletId(portletId);
114 
115         Portlet portlet = null;
116 
117         Map companyPortletsPool = _getPortletsPool(companyId);
118 
119         String rootPortletId = PortletImpl.getRootPortletId(portletId);
120 
121         if (portletId.equals(rootPortletId)) {
122             portlet = (Portlet)companyPortletsPool.get(portletId);
123         }
124         else {
125             portlet = (Portlet)companyPortletsPool.get(rootPortletId);
126 
127             if (portlet != null) {
128                 portlet = portlet.getClonedInstance(portletId);
129             }
130         }
131 
132         if ((portlet == null) &&
133             (!portletId.equals(PortletKeys.LIFERAY_PORTAL))) {
134 
135             if (_log.isWarnEnabled()) {
136                 _log.warn(
137                     "Portlet not found for " + companyId + " " + portletId);
138             }
139         }
140 
141         return portlet;
142     }
143 
144     public Portlet getPortletByStrutsPath(long companyId, String strutsPath)
145         throws SystemException {
146 
147         return getPortletById(companyId, _getPortletId(strutsPath));
148     }
149 
150     public List getPortlets(long companyId) throws SystemException {
151         return getPortlets(companyId, true, true);
152     }
153 
154     public List getPortlets(
155             long companyId, boolean showSystem, boolean showPortal)
156         throws SystemException {
157 
158         Map portletsPool = _getPortletsPool(companyId);
159 
160         List portlets = ListUtil.fromCollection(portletsPool.values());
161 
162         if (!showSystem || !showPortal) {
163             Iterator itr = portlets.iterator();
164 
165             while (itr.hasNext()) {
166                 Portlet portlet = (Portlet)itr.next();
167 
168                 if (showPortal &&
169                     portlet.getPortletId().equals(PortletKeys.PORTAL)) {
170 
171                 }
172                 else if (!showPortal &&
173                          portlet.getPortletId().equals(PortletKeys.PORTAL)) {
174 
175                     itr.remove();
176                 }
177                 else if (!showSystem && portlet.isSystem()) {
178                     itr.remove();
179                 }
180             }
181         }
182 
183         return portlets;
184     }
185 
186     public boolean hasPortlet(long companyId, String portletId)
187         throws SystemException {
188 
189         portletId = PortalUtil.getJsSafePortletId(portletId);
190 
191         Portlet portlet = null;
192 
193         Map companyPortletsPool = _getPortletsPool(companyId);
194 
195         String rootPortletId = PortletImpl.getRootPortletId(portletId);
196 
197         if (portletId.equals(rootPortletId)) {
198             portlet = (Portlet)companyPortletsPool.get(portletId);
199         }
200         else {
201             portlet = (Portlet)companyPortletsPool.get(rootPortletId);
202         }
203 
204         if (portlet == null) {
205             return false;
206         }
207         else {
208             return true;
209         }
210     }
211 
212     public void initEAR(String[] xmls, PluginPackage pluginPackage) {
213         Map portletsPool = _getPortletsPool();
214 
215         try {
216             List servletURLPatterns = _readWebXML(xmls[4]);
217 
218             Set portletIds = _readPortletXML(
219                 xmls[0], portletsPool, servletURLPatterns, pluginPackage);
220 
221             portletIds.addAll(_readPortletXML(
222                 xmls[1], portletsPool, servletURLPatterns, pluginPackage));
223 
224             Set liferayPortletIds =
225                 _readLiferayPortletXML(xmls[2], portletsPool);
226 
227             liferayPortletIds.addAll(
228                 _readLiferayPortletXML(xmls[3], portletsPool));
229 
230             // Check for missing entries in liferay-portlet.xml
231 
232             Iterator itr = portletIds.iterator();
233 
234             while (itr.hasNext()) {
235                 String portletId = (String)itr.next();
236 
237                 if (_log.isWarnEnabled() &&
238                     !liferayPortletIds.contains(portletId)) {
239 
240                     _log.warn(
241                         "Portlet with the name " + portletId +
242                             " is described in portlet.xml but does not " +
243                                 "have a matching entry in liferay-portlet.xml");
244                 }
245             }
246 
247             // Check for missing entries in portlet.xml
248 
249             itr = liferayPortletIds.iterator();
250 
251             while (itr.hasNext()) {
252                 String portletId = (String)itr.next();
253 
254                 if (_log.isWarnEnabled() && !portletIds.contains(portletId)) {
255                     _log.warn(
256                         "Portlet with the name " + portletId +
257                             " is described in liferay-portlet.xml but does " +
258                                 "not have a matching entry in portlet.xml");
259                 }
260             }
261 
262             // Remove portlets that should not be included
263 
264             itr = portletsPool.entrySet().iterator();
265 
266             while (itr.hasNext()) {
267                 Map.Entry entry = (Map.Entry)itr.next();
268 
269                 Portlet portletModel = (Portlet)entry.getValue();
270 
271                 if (!portletModel.getPortletId().equals(PortletKeys.ADMIN) &&
272                     !portletModel.getPortletId().equals(
273                         PortletKeys.MY_ACCOUNT) &&
274                     !portletModel.isInclude()) {
275 
276                     itr.remove();
277                 }
278             }
279         }
280         catch (Exception e) {
281             _log.error(e, e);
282         }
283     }
284 
285     public List initWAR(
286         String servletContextName, String[] xmls, PluginPackage pluginPackage) {
287 
288         List portlets = new ArrayList();
289 
290         Map portletsPool = _getPortletsPool();
291 
292         try {
293             List servletURLPatterns = _readWebXML(xmls[3]);
294 
295             Set portletIds = _readPortletXML(
296                 servletContextName, xmls[0], portletsPool, servletURLPatterns,
297                 pluginPackage);
298 
299             portletIds.addAll(_readPortletXML(
300                 servletContextName, xmls[1], portletsPool, servletURLPatterns,
301                 pluginPackage));
302 
303             Set liferayPortletIds = _readLiferayPortletXML(
304                 servletContextName, xmls[2], portletsPool);
305 
306             // Check for missing entries in liferay-portlet.xml
307 
308             Iterator itr = portletIds.iterator();
309 
310             while (itr.hasNext()) {
311                 String portletId = (String)itr.next();
312 
313                 if (_log.isWarnEnabled() &&
314                     !liferayPortletIds.contains(portletId)) {
315 
316                     _log.warn(
317                         "Portlet with the name " + portletId +
318                             " is described in portlet.xml but does not " +
319                                 "have a matching entry in liferay-portlet.xml");
320                 }
321             }
322 
323             // Check for missing entries in portlet.xml
324 
325             itr = liferayPortletIds.iterator();
326 
327             while (itr.hasNext()) {
328                 String portletId = (String)itr.next();
329 
330                 if (_log.isWarnEnabled() && !portletIds.contains(portletId)) {
331                     _log.warn(
332                         "Portlet with the name " + portletId +
333                             " is described in liferay-portlet.xml but does " +
334                                 "not have a matching entry in portlet.xml");
335                 }
336             }
337 
338             // Return the new portlets
339 
340             itr = portletIds.iterator();
341 
342             while (itr.hasNext()) {
343                 String portletId = (String)itr.next();
344 
345                 Portlet portlet = (Portlet)_getPortletsPool().get(portletId);
346 
347                 portlets.add(portlet);
348             }
349         }
350         catch (Exception e) {
351             _log.error(e, e);
352         }
353 
354         // Refresh security path to portlet id mapping for all portlets
355 
356         _portletIdsByStrutsPath.clear();
357 
358         // Refresh company portlets
359 
360         _companyPortletsPool.clear();
361 
362         return portlets;
363     }
364 
365     public Portlet updatePortlet(
366             long companyId, String portletId, String roles, boolean active)
367         throws PortalException, SystemException {
368 
369         portletId = PortalUtil.getJsSafePortletId(portletId);
370 
371         Portlet portlet = PortletUtil.fetchByC_P(companyId, portletId);
372 
373         if (portlet == null) {
374             long id = CounterLocalServiceUtil.increment();
375 
376             portlet = PortletUtil.create(id);
377 
378             portlet.setCompanyId(companyId);
379             portlet.setPortletId(portletId);
380         }
381 
382         portlet.setRoles(roles);
383         portlet.setActive(active);
384 
385         PortletUtil.update(portlet);
386 
387         portlet = getPortletById(companyId, portletId);
388 
389         portlet.setRoles(roles);
390         portlet.setActive(active);
391 
392         return portlet;
393     }
394 
395     private List _getFriendlyURLMappers() {
396         List friendlyURLMappers = new ArrayList(
397             _friendlyURLMapperPortlets.size());
398 
399         Iterator itr = _friendlyURLMapperPortlets.entrySet().iterator();
400 
401         while (itr.hasNext()) {
402             Map.Entry entry = (Map.Entry)itr.next();
403 
404             Portlet portlet = (Portlet)entry.getValue();
405 
406             FriendlyURLMapper friendlyURLMapper =
407                 portlet.getFriendlyURLMapperInstance();
408 
409             if (friendlyURLMapper != null) {
410                 friendlyURLMappers.add(friendlyURLMapper);
411             }
412         }
413 
414         return friendlyURLMappers;
415     }
416 
417     private String _getPortletId(String securityPath) throws SystemException {
418         if (_portletIdsByStrutsPath.size() == 0) {
419             Iterator itr = _getPortletsPool().values().iterator();
420 
421             while (itr.hasNext()) {
422                 Portlet portlet = (Portlet)itr.next();
423 
424                 _portletIdsByStrutsPath.put(
425                     portlet.getStrutsPath(), portlet.getPortletId());
426             }
427         }
428 
429         String portletId = (String)_portletIdsByStrutsPath.get(securityPath);
430 
431         if (Validator.isNull(portletId)) {
432             _log.error(
433                 "Struts path " + securityPath + " is not mapped to a portlet " +
434                     "in liferay-portlet.xml");
435         }
436 
437         return portletId;
438     }
439 
440     private Map _getPortletsPool() {
441         return _portletsPool;
442     }
443 
444     private Map _getPortletsPool(long companyId) throws SystemException {
445         Long companyIdObj = new Long(companyId);
446 
447         Map portletsPool = (Map)_companyPortletsPool.get(companyIdObj);
448 
449         if (portletsPool == null) {
450             portletsPool = CollectionFactory.getSyncHashMap();
451 
452             Map parentPortletsPool = _getPortletsPool();
453 
454             if (parentPortletsPool == null) {
455 
456                 // The Upgrade scripts sometimes try to access portlet
457                 // preferences before the portal's been initialized. Return an
458                 // empty pool.
459 
460                 return portletsPool;
461             }
462 
463             Iterator itr = parentPortletsPool.values().iterator();
464 
465             while (itr.hasNext()) {
466                 Portlet portlet = (Portlet)((Portlet)itr.next()).clone();
467 
468                 portlet.setCompanyId(companyId);
469 
470                 portletsPool.put(portlet.getPortletId(), portlet);
471             }
472 
473             itr = PortletUtil.findByCompanyId(companyId).iterator();
474 
475             while (itr.hasNext()) {
476                 Portlet portlet = (Portlet)itr.next();
477 
478                 Portlet portletModel =
479                     (Portlet)portletsPool.get(portlet.getPortletId());
480 
481                 // Portlet may be null if it exists in the database but its
482                 // portlet WAR is not yet loaded
483 
484                 if (portletModel != null) {
485                     portletModel.setPluginPackage(portlet.getPluginPackage());
486                     portletModel.setDefaultPluginSetting(
487                         portlet.getDefaultPluginSetting());
488                     portletModel.setRoles(portlet.getRoles());
489                     portletModel.setActive(portlet.getActive());
490                 }
491             }
492 
493             _companyPortletsPool.put(companyIdObj, portletsPool);
494         }
495 
496         return portletsPool;
497     }
498 
499     private Set _readPortletXML(
500             String xml, Map portletsPool, List servletURLPatterns,
501             PluginPackage pluginPackage)
502         throws DocumentException, IOException {
503 
504         return _readPortletXML(
505             null, xml, portletsPool, servletURLPatterns, pluginPackage);
506     }
507 
508     private Set _readPortletXML(
509             String servletContextName, String xml, Map portletsPool,
510             List servletURLPatterns, PluginPackage pluginPackage)
511         throws DocumentException, IOException {
512 
513         Set portletIds = new HashSet();
514 
515         if (xml == null) {
516             return portletIds;
517         }
518 
519         Document doc = PortalUtil.readDocumentFromXML(xml);
520 
521         Element root = doc.getRootElement();
522 
523         Set userAttributes = new HashSet();
524 
525         Iterator itr1 = root.elements("user-attribute").iterator();
526 
527         while (itr1.hasNext()) {
528             Element userAttribute = (Element)itr1.next();
529 
530             String name = userAttribute.elementText("name");
531 
532             userAttributes.add(name);
533         }
534 
535         itr1 = root.elements("portlet").iterator();
536 
537         while (itr1.hasNext()) {
538             Element portlet = (Element)itr1.next();
539 
540             String portletId = portlet.elementText("portlet-name");
541 
542             if (servletContextName != null) {
543                 portletId =
544                     portletId + PortletImpl.WAR_SEPARATOR + servletContextName;
545             }
546 
547             portletId = PortalUtil.getJsSafePortletId(portletId);
548 
549             if (_log.isDebugEnabled()) {
550                 _log.debug("Reading portlet " + portletId);
551             }
552 
553             portletIds.add(portletId);
554 
555             Portlet portletModel = (Portlet)portletsPool.get(portletId);
556 
557             if (portletModel == null) {
558                 portletModel = new PortletImpl(CompanyImpl.SYSTEM, portletId);
559 
560                 portletsPool.put(portletId, portletModel);
561             }
562 
563             portletModel.setPluginPackage(pluginPackage);
564 
565             if (servletContextName != null) {
566                 portletModel.setServletContextName(servletContextName);
567             }
568 
569             if (servletURLPatterns != null) {
570                 portletModel.setServletURLPatterns(servletURLPatterns);
571             }
572 
573             portletModel.setDisplayName(GetterUtil.getString(
574                 portlet.elementText("display-name"),
575                 portletModel.getDisplayName()));
576             portletModel.setPortletClass(GetterUtil.getString(
577                 portlet.elementText("portlet-class")));
578 
579             Iterator itr2 = portlet.elements("init-param").iterator();
580 
581             while (itr2.hasNext()) {
582                 Element initParam = (Element)itr2.next();
583 
584                 portletModel.getInitParams().put(
585                     initParam.elementText("name"),
586                     initParam.elementText("value"));
587             }
588 
589             Element expirationCache = portlet.element("expiration-cache");
590 
591             if (expirationCache != null) {
592                 portletModel.setExpCache(new Integer(GetterUtil.getInteger(
593                     expirationCache.getText())));
594             }
595 
596             itr2 = portlet.elements("supports").iterator();
597 
598             while (itr2.hasNext()) {
599                 Element supports = (Element)itr2.next();
600 
601                 String mimeType = supports.elementText("mime-type");
602 
603                 Set mimeTypeModes =
604                     (Set)portletModel.getPortletModes().get(mimeType);
605 
606                 if (mimeTypeModes == null) {
607                     mimeTypeModes = new HashSet();
608 
609                     portletModel.getPortletModes().put(mimeType, mimeTypeModes);
610                 }
611 
612                 mimeTypeModes.add(PortletMode.VIEW.toString().toLowerCase());
613 
614                 Iterator itr3 = supports.elements("portlet-mode").iterator();
615 
616                 while (itr3.hasNext()) {
617                     Element portletMode = (Element)itr3.next();
618 
619                     mimeTypeModes.add(portletMode.getTextTrim().toLowerCase());
620                 }
621             }
622 
623             Set supportedLocales = portletModel.getSupportedLocales();
624 
625             supportedLocales.add(
626                 LocaleUtil.toLanguageId(LocaleUtil.getDefault()));
627 
628             itr2 = portlet.elements("supported-locale").iterator();
629 
630             while (itr2.hasNext()) {
631                 Element supportedLocaleEl = (Element)itr2.next();
632 
633                 String supportedLocale = supportedLocaleEl.getText();
634 
635                 supportedLocales.add(supportedLocale);
636             }
637 
638             portletModel.setResourceBundle(
639                 portlet.elementText("resource-bundle"));
640 
641             Element portletInfo = portlet.element("portlet-info");
642 
643             String portletInfoTitle = null;
644             String portletInfoShortTitle = null;
645             String portletInfoKeyWords = null;
646 
647             if (portletInfo != null) {
648                 portletInfoTitle = portletInfo.elementText("title");
649                 portletInfoShortTitle = portletInfo.elementText("short-title");
650                 portletInfoKeyWords = portletInfo.elementText("keywords");
651             }
652 
653             portletModel.setPortletInfo(new PortletInfo(
654                 portletInfoTitle, portletInfoShortTitle, portletInfoKeyWords));
655 
656             Element portletPreferences = portlet.element("portlet-preferences");
657 
658             String defaultPreferences = null;
659             String prefsValidator = null;
660 
661             if (portletPreferences != null) {
662                 Element prefsValidatorEl =
663                     portletPreferences.element("preferences-validator");
664 
665                 if (prefsValidatorEl != null) {
666                     prefsValidator = prefsValidatorEl.getText();
667 
668                     portletPreferences.remove(prefsValidatorEl);
669                 }
670 
671                 StringWriter sw = new StringWriter();
672 
673                 XMLWriter writer = new XMLWriter(
674                     sw, OutputFormat.createCompactFormat());
675 
676                 writer.write(portletPreferences);
677 
678                 defaultPreferences = sw.toString();
679             }
680 
681             portletModel.setDefaultPreferences(defaultPreferences);
682             portletModel.setPreferencesValidator(prefsValidator);
683 
684             if (!portletModel.isWARFile() &&
685                 Validator.isNotNull(prefsValidator) &&
686                 GetterUtil.getBoolean(PropsUtil.get(
687                     PropsUtil.PREFERENCE_VALIDATE_ON_STARTUP))) {
688 
689                 try {
690                     PreferencesValidator prefsValidatorObj =
691                         PortalUtil.getPreferencesValidator(portletModel);
692 
693                     prefsValidatorObj.validate(
694                         PortletPreferencesSerializer.fromDefaultXML(
695                             defaultPreferences));
696                 }
697                 catch (Exception e) {
698                     if (_log.isWarnEnabled()) {
699                         _log.warn(
700                             "Portlet with the name " + portletId +
701                                 " does not have valid default preferences");
702                     }
703                 }
704             }
705 
706             Set unlikedRoles = portletModel.getUnlinkedRoles();
707 
708             itr2 = portlet.elements("security-role-ref").iterator();
709 
710             while (itr2.hasNext()) {
711                 Element role = (Element)itr2.next();
712 
713                 unlikedRoles.add(role.elementText("role-name"));
714             }
715 
716             portletModel.getUserAttributes().addAll(userAttributes);
717         }
718 
719         return portletIds;
720     }
721 
722     private void _readLiferayDisplay(
723         String servletContextName, Element el, PortletCategory portletCategory,
724         Set portletIds) {
725 
726         Iterator itr1 = el.elements("category").iterator();
727 
728         while (itr1.hasNext()) {
729             Element category = (Element)itr1.next();
730 
731             String name = category.attributeValue("name");
732 
733             PortletCategory curPortletCategory = new PortletCategory(name);
734 
735             portletCategory.addCategory(curPortletCategory);
736 
737             Set curPortletIds = curPortletCategory.getPortlets();
738 
739             Iterator itr2 = category.elements("portlet").iterator();
740 
741             while (itr2.hasNext()) {
742                 Element portlet = (Element)itr2.next();
743 
744                 String portletId = portlet.attributeValue("id");
745 
746                 if (servletContextName != null) {
747                     portletId =
748                         portletId + PortletImpl.WAR_SEPARATOR +
749                             servletContextName;
750                 }
751 
752                 portletId = PortalUtil.getJsSafePortletId(portletId);
753 
754                 portletIds.add(portletId);
755                 curPortletIds.add(portletId);
756             }
757 
758             _readLiferayDisplay(
759                 servletContextName, category, curPortletCategory, portletIds);
760         }
761     }
762 
763     private PortletCategory _readLiferayDisplayXML(String xml)
764         throws DocumentException, IOException {
765 
766         return _readLiferayDisplayXML(null, xml);
767     }
768 
769     private PortletCategory _readLiferayDisplayXML(
770             String servletContextName, String xml)
771         throws DocumentException, IOException {
772 
773         PortletCategory portletCategory = new PortletCategory();
774 
775         if (xml == null) {
776             xml = ContentUtil.get(
777                 "com/liferay/portal/deploy/dependencies/liferay-display.xml");
778         }
779 
780         Document doc = PortalUtil.readDocumentFromXML(xml, true);
781 
782         Element root = doc.getRootElement();
783 
784         Set portletIds = new HashSet();
785 
786         _readLiferayDisplay(
787             servletContextName, root, portletCategory, portletIds);
788 
789         // Portlets that do not belong to any categories should default to the
790         // Undefined category
791 
792         Set undefinedPortletIds = new HashSet();
793 
794         Iterator itr = _getPortletsPool().values().iterator();
795 
796         while (itr.hasNext()) {
797             Portlet portlet = (Portlet)itr.next();
798 
799             String portletId = portlet.getPortletId();
800 
801             if ((servletContextName != null) && (portlet.isWARFile()) &&
802                 (portletId.endsWith(
803                     PortletImpl.WAR_SEPARATOR +
804                         PortalUtil.getJsSafePortletId(servletContextName)) &&
805                 (!portletIds.contains(portletId)))) {
806 
807                 undefinedPortletIds.add(portletId);
808             }
809             else if ((servletContextName == null) && (!portlet.isWARFile()) &&
810                      (portletId.indexOf(PortletImpl.WAR_SEPARATOR) == -1) &&
811                      (!portletIds.contains(portletId))) {
812 
813                 undefinedPortletIds.add(portletId);
814             }
815         }
816 
817         if (undefinedPortletIds.size() > 0) {
818             PortletCategory undefinedCategory =
819                 new PortletCategory("category.undefined");
820 
821             portletCategory.addCategory(undefinedCategory);
822 
823             undefinedCategory.getPortlets().addAll(undefinedPortletIds);
824         }
825 
826         return portletCategory;
827     }
828 
829     private Set _readLiferayPortletXML(String xml, Map portletsPool)
830         throws DocumentException, IOException {
831 
832         return _readLiferayPortletXML(null, xml, portletsPool);
833     }
834 
835     private Set _readLiferayPortletXML(
836             String servletContextName, String xml, Map portletsPool)
837         throws DocumentException, IOException {
838 
839         Set liferayPortletIds = new HashSet();
840 
841         if (xml == null) {
842             return liferayPortletIds;
843         }
844 
845         Document doc = PortalUtil.readDocumentFromXML(xml, true);
846 
847         Element root = doc.getRootElement();
848 
849         Map roleMappers = new HashMap();
850 
851         Iterator itr1 = root.elements("role-mapper").iterator();
852 
853         while (itr1.hasNext()) {
854             Element roleMapper = (Element)itr1.next();
855 
856             String roleName = roleMapper.elementText("role-name");
857             String roleLink = roleMapper.elementText("role-link");
858 
859             roleMappers.put(roleName, roleLink);
860         }
861 
862         Map customUserAttributes = new HashMap();
863 
864         itr1 = root.elements("custom-user-attribute").iterator();
865 
866         while (itr1.hasNext()) {
867             Element customUserAttribute = (Element)itr1.next();
868 
869             String customClass = customUserAttribute.elementText(
870                 "custom-class");
871 
872             Iterator itr2 = customUserAttribute.elements("name").iterator();
873 
874             while (itr2.hasNext()) {
875                 Element nameEl = (Element)itr2.next();
876 
877                 String name = nameEl.getText();
878 
879                 customUserAttributes.put(name, customClass);
880             }
881         }
882 
883         itr1 = root.elements("portlet").iterator();
884 
885         while (itr1.hasNext()) {
886             Element portlet = (Element)itr1.next();
887 
888             String portletId = portlet.elementText("portlet-name");
889 
890             if (servletContextName != null) {
891                 portletId =
892                     portletId + PortletImpl.WAR_SEPARATOR + servletContextName;
893             }
894 
895             portletId = PortalUtil.getJsSafePortletId(portletId);
896 
897             if (_log.isDebugEnabled()) {
898                 _log.debug("Reading portlet extension " + portletId);
899             }
900 
901             liferayPortletIds.add(portletId);
902 
903             Portlet portletModel = (Portlet)portletsPool.get(portletId);
904 
905             if (portletModel != null) {
906                 portletModel.setIcon(GetterUtil.getString(
907                     portlet.elementText("icon"), portletModel.getIcon()));
908                 portletModel.setVirtualPath(GetterUtil.getString(
909                     portlet.elementText("virtual-path"),
910                     portletModel.getVirtualPath()));
911                 portletModel.setStrutsPath(GetterUtil.getString(
912                     portlet.elementText("struts-path"),
913                     portletModel.getStrutsPath()));
914 
915                 if (Validator.isNotNull(
916                         portlet.elementText("configuration-path"))) {
917 
918                     _log.error(
919                         "The configuration-path element is no longer " +
920                             "supported. Use configuration-action-class " +
921                                 "instead.");
922                 }
923 
924                 portletModel.setConfigurationActionClass(GetterUtil.getString(
925                     portlet.elementText("configuration-action-class"),
926                     portletModel.getConfigurationActionClass()));
927                 portletModel.setIndexerClass(GetterUtil.getString(
928                     portlet.elementText("indexer-class"),
929                     portletModel.getIndexerClass()));
930                 portletModel.setOpenSearchClass(GetterUtil.getString(
931                     portlet.elementText("open-search-class"),
932                     portletModel.getOpenSearchClass()));
933                 portletModel.setSchedulerClass(GetterUtil.getString(
934                     portlet.elementText("scheduler-class"),
935                     portletModel.getSchedulerClass()));
936                 portletModel.setPortletURLClass(GetterUtil.getString(
937                     portlet.elementText("portlet-url-class"),
938                     portletModel.getPortletURLClass()));
939 
940                 portletModel.setFriendlyURLMapperClass(GetterUtil.getString(
941                     portlet.elementText("friendly-url-mapper-class"),
942                     portletModel.getFriendlyURLMapperClass()));
943 
944                 if (Validator.isNull(
945                         portletModel.getFriendlyURLMapperClass())) {
946 
947                     _friendlyURLMapperPortlets.remove(portletId);
948                 }
949                 else {
950                     _friendlyURLMapperPortlets.put(portletId, portletModel);
951                 }
952 
953                 portletModel.setURLEncoderClass(GetterUtil.getString(
954                     portlet.elementText("url-encoder-class"),
955                     portletModel.getURLEncoderClass()));
956                 portletModel.setPortletDataHandlerClass(GetterUtil.getString(
957                     portlet.elementText("portlet-data-handler-class"),
958                     portletModel.getPortletDataHandlerClass()));
959                 portletModel.setPortletLayoutListenerClass(GetterUtil.getString(
960                     portlet.elementText("portlet-layout-listener-class"),
961                     portletModel.getPortletLayoutListenerClass()));
962                 portletModel.setSmtpMessageListenerClass(GetterUtil.getString(
963                     portlet.elementText("smtp-message-listener-class"),
964                     portletModel.getSmtpMessageListenerClass()));
965                 portletModel.setPreferencesCompanyWide(GetterUtil.getBoolean(
966                     portlet.elementText("preferences-company-wide"),
967                     portletModel.isPreferencesCompanyWide()));
968                 portletModel.setPreferencesUniquePerLayout(
969                     GetterUtil.getBoolean(
970                         portlet.elementText("preferences-unique-per-layout"),
971                         portletModel.isPreferencesUniquePerLayout()));
972                 portletModel.setPreferencesOwnedByGroup(GetterUtil.getBoolean(
973                     portlet.elementText("preferences-owned-by-group"),
974                     portletModel.isPreferencesOwnedByGroup()));
975                 portletModel.setUseDefaultTemplate(GetterUtil.getBoolean(
976                     portlet.elementText("use-default-template"),
977                     portletModel.isUseDefaultTemplate()));
978                 portletModel.setShowPortletAccessDenied(GetterUtil.getBoolean(
979                     portlet.elementText("show-portlet-access-denied"),
980                     portletModel.isShowPortletAccessDenied()));
981                 portletModel.setShowPortletInactive(GetterUtil.getBoolean(
982                     portlet.elementText("show-portlet-inactive"),
983                     portletModel.isShowPortletInactive()));
984                 portletModel.setActionURLRedirect(GetterUtil.getBoolean(
985                     portlet.elementText("action-url-redirect"),
986                     portletModel.isActionURLRedirect()));
987                 portletModel.setRestoreCurrentView(GetterUtil.getBoolean(
988                     portlet.elementText("restore-current-view"),
989                     portletModel.isRestoreCurrentView()));
990                 portletModel.setMaximizeEdit(GetterUtil.getBoolean(
991                     portlet.elementText("maximize-edit"),
992                     portletModel.isMaximizeEdit()));
993                 portletModel.setMaximizeHelp(GetterUtil.getBoolean(
994                     portlet.elementText("maximize-help"),
995                     portletModel.isMaximizeHelp()));
996                 portletModel.setPopUpPrint(GetterUtil.getBoolean(
997                     portlet.elementText("pop-up-print"),
998                     portletModel.isPopUpPrint()));
999                 portletModel.setLayoutCacheable(GetterUtil.getBoolean(
1000                    portlet.elementText("layout-cacheable"),
1001                    portletModel.isLayoutCacheable()));
1002                portletModel.setInstanceable(GetterUtil.getBoolean(
1003                    portlet.elementText("instanceable"),
1004                    portletModel.isInstanceable()));
1005                portletModel.setUserPrincipalStrategy(GetterUtil.getString(
1006                    portlet.elementText("user-principal-strategy"),
1007                    portletModel.getUserPrincipalStrategy()));
1008                portletModel.setPrivateRequestAttributes(GetterUtil.getBoolean(
1009                    portlet.elementText("private-request-attributes"),
1010                    portletModel.isPrivateRequestAttributes()));
1011                portletModel.setPrivateSessionAttributes(GetterUtil.getBoolean(
1012                    portlet.elementText("private-session-attributes"),
1013                    portletModel.isPrivateSessionAttributes()));
1014                portletModel.setRenderWeight(GetterUtil.getInteger(
1015                    portlet.elementText("render-weight"),
1016                    portletModel.getRenderWeight()));
1017                portletModel.setAjaxable(GetterUtil.getBoolean(
1018                    portlet.elementText("ajaxable"),
1019                    portletModel.isAjaxable()));
1020
1021                List headerPortalCssList = portletModel.getHeaderPortalCss();
1022
1023                Iterator itr2 = portlet.elements(
1024                    "header-portal-css").iterator();
1025
1026                while (itr2.hasNext()) {
1027                    Element headerPortalCssEl = (Element)itr2.next();
1028
1029                    headerPortalCssList.add(headerPortalCssEl.getText());
1030                }
1031
1032                List headerPortletCssList = portletModel.getHeaderPortletCss();
1033
1034                List list = new ArrayList();
1035
1036                list.addAll(portlet.elements("header-css"));
1037                list.addAll(portlet.elements("header-portlet-css"));
1038
1039                itr2 = list.iterator();
1040
1041                while (itr2.hasNext()) {
1042                    Element headerPortletCssEl = (Element)itr2.next();
1043
1044                    headerPortletCssList.add(headerPortletCssEl.getText());
1045                }
1046
1047                List headerPortalJavaScriptList =
1048                    portletModel.getHeaderPortalJavaScript();
1049
1050                itr2 = portlet.elements("header-portal-javascript").iterator();
1051
1052                while (itr2.hasNext()) {
1053                    Element headerPortalJavaScriptEl = (Element)itr2.next();
1054
1055                    headerPortalJavaScriptList.add(
1056                        headerPortalJavaScriptEl.getText());
1057                }
1058
1059                List headerPortletJavaScriptList =
1060                    portletModel.getHeaderPortletJavaScript();
1061
1062                list.clear();
1063
1064                list.addAll(portlet.elements("header-javascript"));
1065                list.addAll(portlet.elements("header-portlet-javascript"));
1066
1067                itr2 = list.iterator();
1068
1069                while (itr2.hasNext()) {
1070                    Element headerPortletJavaScriptEl = (Element)itr2.next();
1071
1072                    headerPortletJavaScriptList.add(
1073                        headerPortletJavaScriptEl.getText());
1074                }
1075
1076                List footerPortalCssList = portletModel.getFooterPortalCss();
1077
1078                itr2 = portlet.elements("footer-portal-css").iterator();
1079
1080                while (itr2.hasNext()) {
1081                    Element footerPortalCssEl = (Element)itr2.next();
1082
1083                    footerPortalCssList.add(footerPortalCssEl.getText());
1084                }
1085
1086                List footerPortletCssList = portletModel.getFooterPortletCss();
1087
1088                itr2 = portlet.elements("footer-portlet-css").iterator();
1089
1090                while (itr2.hasNext()) {
1091                    Element footerPortletCssEl = (Element)itr2.next();
1092
1093                    footerPortletCssList.add(footerPortletCssEl.getText());
1094                }
1095
1096                List footerPortalJavaScriptList =
1097                    portletModel.getFooterPortalJavaScript();
1098
1099                itr2 = portlet.elements("footer-portal-javascript").iterator();
1100
1101                while (itr2.hasNext()) {
1102                    Element footerPortalJavaScriptEl = (Element)itr2.next();
1103
1104                    footerPortalJavaScriptList.add(
1105                        footerPortalJavaScriptEl.getText());
1106                }
1107
1108                List footerPortletJavaScriptList =
1109                    portletModel.getFooterPortletJavaScript();
1110
1111                itr2 = portlet.elements("footer-portlet-javascript").iterator();
1112
1113                while (itr2.hasNext()) {
1114                    Element footerPortletJavaScriptEl = (Element)itr2.next();
1115
1116                    footerPortletJavaScriptList.add(
1117                        footerPortletJavaScriptEl.getText());
1118                }
1119
1120                portletModel.setAddDefaultResource(GetterUtil.getBoolean(
1121                    portlet.elementText("add-default-resource"),
1122                    portletModel.isAddDefaultResource()));
1123                portletModel.setSystem(GetterUtil.getBoolean(
1124                    portlet.elementText("system"),
1125                    portletModel.isSystem()));
1126                portletModel.setActive(GetterUtil.getBoolean(
1127                    portlet.elementText("active"),
1128                    portletModel.isActive()));
1129                portletModel.setInclude(GetterUtil.getBoolean(
1130                    portlet.elementText("include"),
1131                    portletModel.isInclude()));
1132
1133                if (!portletModel.isAjaxable() &&
1134                    (portletModel.getRenderWeight() < 1)) {
1135
1136                    portletModel.setRenderWeight(1);
1137                }
1138
1139                portletModel.getRoleMappers().putAll(roleMappers);
1140                portletModel.linkRoles();
1141
1142                portletModel.getCustomUserAttributes().putAll(
1143                    customUserAttributes);
1144            }
1145        }
1146
1147        return liferayPortletIds;
1148    }
1149
1150    private List _readWebXML(String xml) throws DocumentException, IOException {
1151        List servletURLPatterns = new ArrayList();
1152
1153        if (xml == null) {
1154            return servletURLPatterns;
1155        }
1156
1157        Document doc = PortalUtil.readDocumentFromXML(xml);
1158
1159        Element root = doc.getRootElement();
1160
1161        Iterator itr = root.elements("servlet-mapping").iterator();
1162
1163        while (itr.hasNext()) {
1164            Element servletMapping = (Element)itr.next();
1165
1166            String urlPattern = servletMapping.elementText("url-pattern");
1167
1168            servletURLPatterns.add(urlPattern);
1169        }
1170
1171        return servletURLPatterns;
1172
1173    }
1174
1175    private static Log _log = LogFactory.getLog(PortletLocalServiceImpl.class);
1176
1177    private static Map _portletsPool = CollectionFactory.getSyncHashMap();
1178    private static Map _companyPortletsPool =
1179        CollectionFactory.getSyncHashMap();
1180    private static Map _portletIdsByStrutsPath =
1181        CollectionFactory.getSyncHashMap();
1182    private static Map _friendlyURLMapperPortlets =
1183        CollectionFactory.getSyncHashMap();
1184
1185}