1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.portal.service.impl;
16  
17  import com.liferay.portal.kernel.cache.MultiVMPoolUtil;
18  import com.liferay.portal.kernel.cache.PortalCache;
19  import com.liferay.portal.kernel.exception.PortalException;
20  import com.liferay.portal.kernel.exception.SystemException;
21  import com.liferay.portal.kernel.image.SpriteProcessorUtil;
22  import com.liferay.portal.kernel.log.Log;
23  import com.liferay.portal.kernel.log.LogFactoryUtil;
24  import com.liferay.portal.kernel.plugin.PluginPackage;
25  import com.liferay.portal.kernel.portlet.FriendlyURLMapper;
26  import com.liferay.portal.kernel.portlet.LiferayPortletConfig;
27  import com.liferay.portal.kernel.portlet.LiferayWindowState;
28  import com.liferay.portal.kernel.scheduler.SchedulerEntry;
29  import com.liferay.portal.kernel.scheduler.SchedulerEntryImpl;
30  import com.liferay.portal.kernel.scheduler.TimeUnit;
31  import com.liferay.portal.kernel.scheduler.TriggerType;
32  import com.liferay.portal.kernel.servlet.ServletContextUtil;
33  import com.liferay.portal.kernel.util.ContentTypes;
34  import com.liferay.portal.kernel.util.GetterUtil;
35  import com.liferay.portal.kernel.util.ListUtil;
36  import com.liferay.portal.kernel.util.ServerDetector;
37  import com.liferay.portal.kernel.util.StringPool;
38  import com.liferay.portal.kernel.util.Validator;
39  import com.liferay.portal.kernel.xml.Document;
40  import com.liferay.portal.kernel.xml.Element;
41  import com.liferay.portal.kernel.xml.QName;
42  import com.liferay.portal.kernel.xml.SAXReaderUtil;
43  import com.liferay.portal.model.CompanyConstants;
44  import com.liferay.portal.model.EventDefinition;
45  import com.liferay.portal.model.Portlet;
46  import com.liferay.portal.model.PortletApp;
47  import com.liferay.portal.model.PortletCategory;
48  import com.liferay.portal.model.PortletConstants;
49  import com.liferay.portal.model.PortletFilter;
50  import com.liferay.portal.model.PortletInfo;
51  import com.liferay.portal.model.PortletURLListener;
52  import com.liferay.portal.model.PublicRenderParameter;
53  import com.liferay.portal.model.ResourceConstants;
54  import com.liferay.portal.model.Role;
55  import com.liferay.portal.model.impl.EventDefinitionImpl;
56  import com.liferay.portal.model.impl.PortletAppImpl;
57  import com.liferay.portal.model.impl.PortletFilterImpl;
58  import com.liferay.portal.model.impl.PortletImpl;
59  import com.liferay.portal.model.impl.PortletURLListenerImpl;
60  import com.liferay.portal.model.impl.PublicRenderParameterImpl;
61  import com.liferay.portal.security.permission.ActionKeys;
62  import com.liferay.portal.security.permission.ResourceActionsUtil;
63  import com.liferay.portal.service.base.PortletLocalServiceBaseImpl;
64  import com.liferay.portal.util.ContentUtil;
65  import com.liferay.portal.util.PortalUtil;
66  import com.liferay.portal.util.PortletKeys;
67  import com.liferay.portal.util.PropsValues;
68  import com.liferay.portal.util.WebAppPool;
69  import com.liferay.portal.util.WebKeys;
70  import com.liferay.portlet.PortletInstanceFactoryUtil;
71  import com.liferay.portlet.PortletPreferencesSerializer;
72  import com.liferay.portlet.PortletQNameUtil;
73  import com.liferay.portlet.expando.model.CustomAttributesDisplay;
74  import com.liferay.util.bridges.mvc.MVCPortlet;
75  
76  import java.io.File;
77  
78  import java.util.ArrayList;
79  import java.util.HashMap;
80  import java.util.HashSet;
81  import java.util.Iterator;
82  import java.util.LinkedHashSet;
83  import java.util.List;
84  import java.util.Map;
85  import java.util.Properties;
86  import java.util.Set;
87  import java.util.concurrent.ConcurrentHashMap;
88  
89  import javax.portlet.PortletMode;
90  import javax.portlet.PreferencesValidator;
91  import javax.portlet.WindowState;
92  
93  import javax.servlet.ServletContext;
94  
95  /**
96   * <a href="PortletLocalServiceImpl.java.html"><b><i>View Source</i></b></a>
97   *
98   * @author Brian Wing Shun Chan
99   * @author Raymond Augé
100  * @author Eduardo Lundgren
101  * @author Wesley Gong
102  */
103 public class PortletLocalServiceImpl extends PortletLocalServiceBaseImpl {
104 
105     public void checkPortlet(Portlet portlet)
106         throws PortalException, SystemException {
107 
108         if (portlet.isSystem()) {
109             return;
110         }
111 
112         String[] roleNames = portlet.getRolesArray();
113 
114         if (roleNames.length == 0) {
115             return;
116         }
117 
118         long companyId = portlet.getCompanyId();
119         String name = portlet.getPortletId();
120         int scope = ResourceConstants.SCOPE_COMPANY;
121         String primKey = String.valueOf(companyId);
122         String actionId = ActionKeys.ADD_TO_PAGE;
123 
124         List<String> actionIds = ResourceActionsUtil.getPortletResourceActions(
125             name);
126 
127         if (actionIds.contains(actionId)) {
128             for (String roleName : roleNames) {
129                 Role role = roleLocalService.getRole(companyId, roleName);
130 
131                 if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 6) {
132                     resourcePermissionLocalService.addResourcePermission(
133                         companyId, name, scope, primKey, role.getRoleId(),
134                         actionId);
135                 }
136                 else {
137                     permissionLocalService.setRolePermission(
138                         role.getRoleId(), companyId, name, scope, primKey,
139                         actionId);
140                 }
141             }
142         }
143 
144         updatePortlet(
145             companyId, portlet.getPortletId(), StringPool.BLANK,
146             portlet.isActive());
147     }
148 
149     public void checkPortlets(long companyId)
150         throws PortalException, SystemException {
151 
152         List<Portlet> portlets = getPortlets(companyId);
153 
154         for (Portlet portlet : portlets) {
155             checkPortlet(portlet);
156         }
157     }
158 
159     public void clearCache() {
160 
161         // Refresh security path to portlet id mapping for all portlets
162 
163         _portletIdsByStrutsPath.clear();
164 
165         // Refresh company portlets
166 
167         _companyPortletsPool.removeAll();
168     }
169 
170     public Portlet clonePortlet(long companyId, String portletId)
171         throws SystemException {
172 
173         Portlet portlet = portletLocalService.getPortletById(
174             companyId, portletId);
175 
176         return (Portlet)portlet.clone();
177     }
178 
179     public Portlet deployRemotePortlet(Portlet portlet, String categoryName)
180         throws SystemException {
181 
182         Map<String, Portlet> portletsPool = _getPortletsPool();
183 
184         portletsPool.put(portlet.getPortletId(), portlet);
185 
186         clearCache();
187 
188         PortletCategory newPortletCategory = new PortletCategory();
189 
190         PortletCategory oldPortletCategory = new PortletCategory(categoryName);
191 
192         newPortletCategory.addCategory(oldPortletCategory);
193 
194         oldPortletCategory.getPortletIds().add(portlet.getPortletId());
195 
196         long companyId = portlet.getCompanyId();
197 
198         PortletCategory portletCategory = (PortletCategory)WebAppPool.get(
199             String.valueOf(companyId), WebKeys.PORTLET_CATEGORY);
200 
201         if (portletCategory != null) {
202             portletCategory.merge(newPortletCategory);
203         }
204         else {
205             _log.error(
206                 "Unable to register remote portlet for company " + companyId +
207                     " because it does not exist");
208         }
209 
210         List<String> portletActions =
211             ResourceActionsUtil.getPortletResourceActions(
212                 portlet.getPortletId());
213 
214         resourceActionLocalService.checkResourceActions(
215             portlet.getPortletId(), portletActions);
216 
217         return portlet;
218     }
219 
220     public void destroyPortlet(Portlet portlet) {
221         Map<String, Portlet> portletsPool = _getPortletsPool();
222 
223         portletsPool.remove(portlet.getRootPortletId());
224 
225         PortletApp portletApp = portlet.getPortletApp();
226 
227         if (portletApp != null) {
228             _portletAppsPool.remove(portletApp.getServletContextName());
229         }
230 
231         clearCache();
232     }
233 
234     public void destroyRemotePortlet(Portlet portlet) {
235         Map<String, Portlet> portletsPool = _getPortletsPool();
236 
237         portletsPool.remove(portlet.getRootPortletId());
238 
239         PortletApp portletApp = portlet.getPortletApp();
240 
241         _portletAppsPool.remove(portletApp.getServletContextName());
242 
243         clearCache();
244     }
245 
246     public List<CustomAttributesDisplay> getCustomAttributesDisplays() {
247         List<CustomAttributesDisplay> customAttributesDisplays =
248             new ArrayList<CustomAttributesDisplay>(
249                 _customAttributesDisplayPortlets.size());
250 
251         Iterator<Map.Entry<String, Portlet>> itr =
252             _customAttributesDisplayPortlets.entrySet().iterator();
253 
254         while (itr.hasNext()) {
255             Map.Entry<String, Portlet> entry = itr.next();
256 
257             Portlet portlet = entry.getValue();
258 
259             List<CustomAttributesDisplay> portletCustomAttributesDisplays =
260                 portlet.getCustomAttributesDisplayInstances();
261 
262             if ((portletCustomAttributesDisplays != null) &&
263                 (!portletCustomAttributesDisplays.isEmpty())) {
264 
265                 customAttributesDisplays.addAll(
266                     portletCustomAttributesDisplays);
267             }
268         }
269 
270         return customAttributesDisplays;
271     }
272 
273     public PortletCategory getEARDisplay(String xml) throws SystemException {
274         try {
275             return _readLiferayDisplayXML(xml);
276         }
277         catch (Exception e) {
278             throw new SystemException(e);
279         }
280     }
281 
282     public List<Portlet> getFriendlyURLMapperPortlets() {
283         List<Portlet> portlets = new ArrayList<Portlet>(
284             _friendlyURLMapperPortlets.size());
285 
286         Iterator<Map.Entry<String, Portlet>> itr =
287             _friendlyURLMapperPortlets.entrySet().iterator();
288 
289         while (itr.hasNext()) {
290             Map.Entry<String, Portlet> entry = itr.next();
291 
292             Portlet portlet = entry.getValue();
293 
294             FriendlyURLMapper friendlyURLMapper =
295                 portlet.getFriendlyURLMapperInstance();
296 
297             if (friendlyURLMapper != null) {
298                 portlets.add(portlet);
299             }
300         }
301 
302         return portlets;
303     }
304 
305     public List<FriendlyURLMapper> getFriendlyURLMappers() {
306         List<FriendlyURLMapper> friendlyURLMappers =
307             new ArrayList<FriendlyURLMapper>(_friendlyURLMapperPortlets.size());
308 
309         Iterator<Map.Entry<String, Portlet>> itr =
310             _friendlyURLMapperPortlets.entrySet().iterator();
311 
312         while (itr.hasNext()) {
313             Map.Entry<String, Portlet> entry = itr.next();
314 
315             Portlet portlet = entry.getValue();
316 
317             FriendlyURLMapper friendlyURLMapper =
318                 portlet.getFriendlyURLMapperInstance();
319 
320             if (friendlyURLMapper != null) {
321                 friendlyURLMappers.add(friendlyURLMapper);
322             }
323         }
324 
325         return friendlyURLMappers;
326     }
327 
328     public PortletApp getPortletApp(String servletContextName) {
329         return _getPortletApp(servletContextName);
330     }
331 
332     public Portlet getPortletById(long companyId, String portletId)
333         throws SystemException {
334 
335         portletId = PortalUtil.getJsSafePortletId(portletId);
336 
337         Portlet portlet = null;
338 
339         Map<String, Portlet> companyPortletsPool = _getPortletsPool(companyId);
340 
341         String rootPortletId = PortletConstants.getRootPortletId(portletId);
342 
343         if (portletId.equals(rootPortletId)) {
344             portlet = companyPortletsPool.get(portletId);
345         }
346         else {
347             portlet = companyPortletsPool.get(rootPortletId);
348 
349             if (portlet != null) {
350                 portlet = portlet.getClonedInstance(portletId);
351             }
352         }
353 
354         if ((portlet == null) &&
355             (!portletId.equals(PortletKeys.LIFERAY_PORTAL))) {
356 
357             if (_portletsPool.isEmpty()) {
358                 if (_log.isDebugEnabled()) {
359                     _log.debug("No portlets are installed");
360                 }
361             }
362             else {
363                 if (_log.isInfoEnabled()) {
364                     _log.info(
365                         "Portlet not found for " + companyId + " " + portletId);
366                 }
367 
368                 portlet = new PortletImpl(CompanyConstants.SYSTEM, portletId);
369 
370                 portlet.setTimestamp(System.currentTimeMillis());
371 
372                 PortletApp portletApp = _getPortletApp(StringPool.BLANK);
373 
374                 portlet.setPortletApp(portletApp);
375 
376                 portlet.setPortletName(portletId);
377                 portlet.setDisplayName(portletId);
378                 portlet.setPortletClass(MVCPortlet.class.getName());
379 
380                 Map<String, String> initParams = portlet.getInitParams();
381 
382                 initParams.put(
383                     "view-jsp", "/html/portal/undeployed_portlet.jsp");
384 
385                 Set<String> mimeTypePortletModes = new HashSet<String>();
386 
387                 mimeTypePortletModes.add(
388                     PortletMode.VIEW.toString().toLowerCase());
389 
390                 portlet.getPortletModes().put(
391                     ContentTypes.TEXT_HTML, mimeTypePortletModes);
392 
393                 Set<String> mimeTypeWindowStates = new HashSet<String>();
394 
395                 mimeTypeWindowStates.add(
396                     WindowState.NORMAL.toString().toLowerCase());
397 
398                 portlet.getWindowStates().put(
399                     ContentTypes.TEXT_HTML, mimeTypeWindowStates);
400 
401                 portlet.setPortletInfo(
402                     new PortletInfo(
403                         portletId, portletId, portletId, portletId));
404 
405                 if (portletId.indexOf("_INSTANCE_") != -1) {
406                     portlet.setInstanceable(true);
407                 }
408 
409                 portlet.setActive(true);
410                 portlet.setUndeployedPortlet(true);
411             }
412         }
413 
414         return portlet;
415     }
416 
417     public Portlet getPortletById(String portletId) {
418         Map<String, Portlet> portletsPool = _getPortletsPool();
419 
420         return portletsPool.get(portletId);
421     }
422 
423     public Portlet getPortletByStrutsPath(long companyId, String strutsPath)
424         throws SystemException {
425 
426         return getPortletById(companyId, _getPortletId(strutsPath));
427     }
428 
429     public List<Portlet> getPortlets() {
430         Map<String, Portlet> portletsPool = _getPortletsPool();
431 
432         return ListUtil.fromCollection(portletsPool.values());
433     }
434 
435     public List<Portlet> getPortlets(long companyId) throws SystemException {
436         return getPortlets(companyId, true, true);
437     }
438 
439     public List<Portlet> getPortlets(
440             long companyId, boolean showSystem, boolean showPortal)
441         throws SystemException {
442 
443         Map<String, Portlet> portletsPool = _getPortletsPool(companyId);
444 
445         List<Portlet> portlets = ListUtil.fromCollection(portletsPool.values());
446 
447         if (!showSystem || !showPortal) {
448             Iterator<Portlet> itr = portlets.iterator();
449 
450             while (itr.hasNext()) {
451                 Portlet portlet = itr.next();
452 
453                 if (showPortal &&
454                     portlet.getPortletId().equals(PortletKeys.PORTAL)) {
455 
456                 }
457                 else if (!showPortal &&
458                          portlet.getPortletId().equals(PortletKeys.PORTAL)) {
459 
460                     itr.remove();
461                 }
462                 else if (!showSystem && portlet.isSystem()) {
463                     itr.remove();
464                 }
465             }
466         }
467 
468         return portlets;
469     }
470 
471     public PortletCategory getWARDisplay(String servletContextName, String xml)
472         throws SystemException {
473 
474         try {
475             return _readLiferayDisplayXML(servletContextName, xml);
476         }
477         catch (Exception e) {
478             throw new SystemException(e);
479         }
480     }
481 
482     public boolean hasPortlet(long companyId, String portletId)
483         throws SystemException {
484 
485         portletId = PortalUtil.getJsSafePortletId(portletId);
486 
487         Portlet portlet = null;
488 
489         Map<String, Portlet> companyPortletsPool = _getPortletsPool(companyId);
490 
491         String rootPortletId = PortletConstants.getRootPortletId(portletId);
492 
493         if (portletId.equals(rootPortletId)) {
494             portlet = companyPortletsPool.get(portletId);
495         }
496         else {
497             portlet = companyPortletsPool.get(rootPortletId);
498         }
499 
500         if (portlet == null) {
501             return false;
502         }
503         else {
504             return true;
505         }
506     }
507 
508     public void initEAR(
509         ServletContext servletContext, String[] xmls,
510         PluginPackage pluginPackage) {
511 
512         // Clear pools every time initEAR is called. See LEP-5452.
513 
514         _portletAppsPool.clear();
515         _portletsPool.clear();
516         _companyPortletsPool.removeAll();
517         _portletIdsByStrutsPath.clear();
518         _friendlyURLMapperPortlets.clear();
519 
520         Map<String, Portlet> portletsPool = _getPortletsPool();
521 
522         try {
523             List<String> servletURLPatterns = _readWebXML(xmls[4]);
524 
525             Set<String> portletIds = _readPortletXML(
526                 servletContext, xmls[0], portletsPool, servletURLPatterns,
527                 pluginPackage);
528 
529             portletIds.addAll(
530                 _readPortletXML(
531                     servletContext, xmls[1], portletsPool, servletURLPatterns,
532                     pluginPackage));
533 
534             Set<String> liferayPortletIds =
535                 _readLiferayPortletXML(xmls[2], portletsPool);
536 
537             liferayPortletIds.addAll(
538                 _readLiferayPortletXML(xmls[3], portletsPool));
539 
540             // Check for missing entries in liferay-portlet.xml
541 
542             Iterator<String> portletIdsItr = portletIds.iterator();
543 
544             while (portletIdsItr.hasNext()) {
545                 String portletId = portletIdsItr.next();
546 
547                 if (_log.isWarnEnabled() &&
548                     !liferayPortletIds.contains(portletId)) {
549 
550                     _log.warn(
551                         "Portlet with the name " + portletId +
552                             " is described in portlet.xml but does not " +
553                                 "have a matching entry in liferay-portlet.xml");
554                 }
555             }
556 
557             // Check for missing entries in portlet.xml
558 
559             Iterator<String> liferayPortletIdsItr =
560                 liferayPortletIds.iterator();
561 
562             while (liferayPortletIdsItr.hasNext()) {
563                 String portletId = liferayPortletIdsItr.next();
564 
565                 if (_log.isWarnEnabled() && !portletIds.contains(portletId)) {
566                     _log.warn(
567                         "Portlet with the name " + portletId +
568                             " is described in liferay-portlet.xml but does " +
569                                 "not have a matching entry in portlet.xml");
570                 }
571             }
572 
573             // Remove portlets that should not be included
574 
575             Iterator<Map.Entry<String, Portlet>> portletPoolsItr =
576                 portletsPool.entrySet().iterator();
577 
578             while (portletPoolsItr.hasNext()) {
579                 Map.Entry<String, Portlet> entry = portletPoolsItr.next();
580 
581                 Portlet portletModel = entry.getValue();
582 
583                 if (!portletModel.getPortletId().equals(PortletKeys.ADMIN) &&
584                     !portletModel.getPortletId().equals(
585                         PortletKeys.MY_ACCOUNT) &&
586                     !portletModel.isInclude()) {
587 
588                     portletPoolsItr.remove();
589                 }
590             }
591 
592             // Sprite images
593 
594             PortletApp portletApp = _getPortletApp(StringPool.BLANK);
595 
596             _setSpriteImages(servletContext, portletApp, "/html/icons/");
597         }
598         catch (Exception e) {
599             _log.error(e, e);
600         }
601     }
602 
603     public List<Portlet> initWAR(
604         String servletContextName, ServletContext servletContext, String[] xmls,
605         PluginPackage pluginPackage) {
606 
607         List<Portlet> portlets = new ArrayList<Portlet>();
608 
609         Map<String, Portlet> portletsPool = _getPortletsPool();
610 
611         try {
612             List<String> servletURLPatterns = _readWebXML(xmls[3]);
613 
614             Set<String> portletIds = _readPortletXML(
615                 servletContextName, servletContext, xmls[0], portletsPool,
616                 servletURLPatterns, pluginPackage);
617 
618             portletIds.addAll(
619                 _readPortletXML(
620                     servletContextName, servletContext, xmls[1], portletsPool,
621                     servletURLPatterns, pluginPackage));
622 
623             Set<String> liferayPortletIds = _readLiferayPortletXML(
624                 servletContextName, xmls[2], portletsPool);
625 
626             // Check for missing entries in liferay-portlet.xml
627 
628             Iterator<String> itr = portletIds.iterator();
629 
630             while (itr.hasNext()) {
631                 String portletId = itr.next();
632 
633                 if (_log.isWarnEnabled() &&
634                     !liferayPortletIds.contains(portletId)) {
635 
636                     _log.warn(
637                         "Portlet with the name " + portletId +
638                             " is described in portlet.xml but does not " +
639                                 "have a matching entry in liferay-portlet.xml");
640                 }
641             }
642 
643             // Check for missing entries in portlet.xml
644 
645             itr = liferayPortletIds.iterator();
646 
647             while (itr.hasNext()) {
648                 String portletId = itr.next();
649 
650                 if (_log.isWarnEnabled() && !portletIds.contains(portletId)) {
651                     _log.warn(
652                         "Portlet with the name " + portletId +
653                             " is described in liferay-portlet.xml but does " +
654                                 "not have a matching entry in portlet.xml");
655                 }
656             }
657 
658             // Return the new portlets
659 
660             itr = portletIds.iterator();
661 
662             while (itr.hasNext()) {
663                 String portletId = itr.next();
664 
665                 Portlet portlet = _getPortletsPool().get(portletId);
666 
667                 portlets.add(portlet);
668 
669                 PortletInstanceFactoryUtil.clear(portlet);
670             }
671 
672             // Sprite images
673 
674             PortletApp portletApp = _getPortletApp(servletContextName);
675 
676             _setSpriteImages(servletContext, portletApp, "/icons/");
677         }
678         catch (Exception e) {
679             _log.error(e, e);
680         }
681 
682         clearCache();
683 
684         return portlets;
685     }
686 
687     public Portlet updatePortlet(
688             long companyId, String portletId, String roles, boolean active)
689         throws SystemException {
690 
691         portletId = PortalUtil.getJsSafePortletId(portletId);
692 
693         Portlet portlet = portletPersistence.fetchByC_P(companyId, portletId);
694 
695         if (portlet == null) {
696             long id = counterLocalService.increment();
697 
698             portlet = portletPersistence.create(id);
699 
700             portlet.setCompanyId(companyId);
701             portlet.setPortletId(portletId);
702         }
703 
704         portlet.setRoles(roles);
705         portlet.setActive(active);
706 
707         portletPersistence.update(portlet, false);
708 
709         portlet = getPortletById(companyId, portletId);
710 
711         portlet.setRoles(roles);
712         portlet.setActive(active);
713 
714         _updateCompanyPortletsPool(companyId);
715 
716         return portlet;
717     }
718 
719     private String _encodeKey(long companyId) {
720         return _keyPrefix.concat(String.valueOf(companyId));
721     }
722 
723     private PortletApp _getPortletApp(String servletContextName) {
724         PortletApp portletApp = _portletAppsPool.get(servletContextName);
725 
726         if (portletApp == null) {
727             portletApp = new PortletAppImpl(servletContextName);
728 
729             _portletAppsPool.put(servletContextName, portletApp);
730         }
731 
732         return portletApp;
733     }
734 
735     private String _getPortletId(String securityPath) {
736         if (_portletIdsByStrutsPath.size() == 0) {
737             Iterator<Portlet> itr = _getPortletsPool().values().iterator();
738 
739             while (itr.hasNext()) {
740                 Portlet portlet = itr.next();
741 
742                 _portletIdsByStrutsPath.put(
743                     portlet.getStrutsPath(), portlet.getPortletId());
744             }
745         }
746 
747         String portletId = _portletIdsByStrutsPath.get(securityPath);
748 
749         if (Validator.isNull(portletId)) {
750             _log.error(
751                 "Struts path " + securityPath + " is not mapped to a portlet " +
752                     "in liferay-portlet.xml");
753         }
754 
755         return portletId;
756     }
757 
758     private List<Portlet> _getPortletsByPortletName(
759         String portletName, String servletContextName,
760         Map<String, Portlet> portletsPool) {
761 
762         List<Portlet> portlets = null;
763 
764         int pos = portletName.indexOf(StringPool.STAR);
765 
766         if (pos == -1) {
767             portlets = new ArrayList<Portlet>();
768 
769             String portletId = portletName;
770 
771             if (Validator.isNotNull(servletContextName)) {
772                 portletId =
773                     portletId + PortletConstants.WAR_SEPARATOR +
774                         servletContextName;
775             }
776 
777             portletId = PortalUtil.getJsSafePortletId(portletId);
778 
779             Portlet portlet = portletsPool.get(portletId);
780 
781             if (portlet != null) {
782                 portlets.add(portlet);
783             }
784 
785             return portlets;
786         }
787 
788         String portletNamePrefix = portletName.substring(0, pos);
789 
790         portlets = _getPortletsByServletContextName(
791             servletContextName, portletsPool);
792 
793         Iterator<Portlet> itr = portlets.iterator();
794 
795         while (itr.hasNext()) {
796             Portlet portlet = itr.next();
797 
798             if (!portlet.getPortletId().startsWith(portletNamePrefix)) {
799                 itr.remove();
800             }
801         }
802 
803         return portlets;
804     }
805 
806     private List<Portlet> _getPortletsByServletContextName(
807         String servletContextName, Map<String, Portlet> portletsPool) {
808 
809         List<Portlet> portlets = new ArrayList<Portlet>();
810 
811         Iterator<Map.Entry<String, Portlet>> itr =
812             portletsPool.entrySet().iterator();
813 
814         while (itr.hasNext()) {
815             Map.Entry<String, Portlet> entry = itr.next();
816 
817             String portletId = entry.getKey();
818             Portlet portlet = entry.getValue();
819 
820             if (Validator.isNotNull(servletContextName)) {
821                 if (portletId.endsWith(
822                         PortletConstants.WAR_SEPARATOR + servletContextName)) {
823 
824                     portlets.add(portlet);
825                 }
826             }
827             else {
828                 if (portletId.indexOf(PortletConstants.WAR_SEPARATOR) == -1) {
829                     portlets.add(portlet);
830                 }
831             }
832         }
833 
834         return portlets;
835     }
836 
837     private Map<String, Portlet> _getPortletsPool() {
838         return _portletsPool;
839     }
840 
841     private Map<String, Portlet> _getPortletsPool(long companyId)
842         throws SystemException {
843 
844         String key = _encodeKey(companyId);
845 
846         Map<String, Portlet> portletsPool =
847             (Map<String, Portlet>)_companyPortletsPool.get(key);
848 
849         if (portletsPool == null) {
850             portletsPool = new ConcurrentHashMap<String, Portlet>();
851 
852             Map<String, Portlet> parentPortletsPool = _getPortletsPool();
853 
854             if (parentPortletsPool == null) {
855 
856                 // The Upgrade scripts sometimes try to access portlet
857                 // preferences before the portal's been initialized. Return an
858                 // empty pool.
859 
860                 return portletsPool;
861             }
862 
863             Iterator<Portlet> itr = parentPortletsPool.values().iterator();
864 
865             while (itr.hasNext()) {
866                 Portlet portlet = itr.next();
867 
868                 portlet = (Portlet)portlet.clone();
869 
870                 portlet.setCompanyId(companyId);
871 
872                 portletsPool.put(portlet.getPortletId(), portlet);
873             }
874 
875             itr = portletPersistence.findByCompanyId(companyId).iterator();
876 
877             while (itr.hasNext()) {
878                 Portlet portlet = itr.next();
879 
880                 Portlet portletModel = portletsPool.get(portlet.getPortletId());
881 
882                 // Portlet may be null if it exists in the database but its
883                 // portlet WAR is not yet loaded
884 
885                 if (portletModel != null) {
886                     portletModel.setPluginPackage(portlet.getPluginPackage());
887                     portletModel.setDefaultPluginSetting(
888                         portlet.getDefaultPluginSetting());
889                     portletModel.setRoles(portlet.getRoles());
890                     portletModel.setActive(portlet.getActive());
891                 }
892             }
893 
894             _companyPortletsPool.put(key, portletsPool);
895         }
896 
897         return portletsPool;
898     }
899 
900     private void _readLiferayDisplay(
901         String servletContextName, Element el, PortletCategory portletCategory,
902         Set<String> portletIds) {
903 
904         Iterator<Element> itr1 = el.elements("category").iterator();
905 
906         while (itr1.hasNext()) {
907             Element category = itr1.next();
908 
909             String name = category.attributeValue("name");
910 
911             PortletCategory curPortletCategory = new PortletCategory(name);
912 
913             portletCategory.addCategory(curPortletCategory);
914 
915             Set<String> curPortletIds = curPortletCategory.getPortletIds();
916 
917             Iterator<Element> itr2 = category.elements("portlet").iterator();
918 
919             while (itr2.hasNext()) {
920                 Element portlet = itr2.next();
921 
922                 String portletId = portlet.attributeValue("id");
923 
924                 if (Validator.isNotNull(servletContextName)) {
925                     portletId =
926                         portletId + PortletConstants.WAR_SEPARATOR +
927                             servletContextName;
928                 }
929 
930                 portletId = PortalUtil.getJsSafePortletId(portletId);
931 
932                 portletIds.add(portletId);
933                 curPortletIds.add(portletId);
934             }
935 
936             _readLiferayDisplay(
937                 servletContextName, category, curPortletCategory, portletIds);
938         }
939     }
940 
941     private PortletCategory _readLiferayDisplayXML(String xml)
942         throws Exception {
943 
944         return _readLiferayDisplayXML(null, xml);
945     }
946 
947     private PortletCategory _readLiferayDisplayXML(
948             String servletContextName, String xml)
949         throws Exception {
950 
951         PortletCategory portletCategory = new PortletCategory();
952 
953         if (xml == null) {
954             xml = ContentUtil.get(
955                 "com/liferay/portal/deploy/dependencies/liferay-display.xml");
956         }
957 
958         Document doc = SAXReaderUtil.read(xml, true);
959 
960         Element root = doc.getRootElement();
961 
962         Set<String> portletIds = new HashSet<String>();
963 
964         _readLiferayDisplay(
965             servletContextName, root, portletCategory, portletIds);
966 
967         // Portlets that do not belong to any categories should default to the
968         // Undefined category
969 
970         Set<String> undefinedPortletIds = new HashSet<String>();
971 
972         Iterator<Portlet> itr = _getPortletsPool().values().iterator();
973 
974         while (itr.hasNext()) {
975             Portlet portlet = itr.next();
976 
977             String portletId = portlet.getPortletId();
978 
979             PortletApp portletApp = portlet.getPortletApp();
980 
981             if ((servletContextName != null) && (portletApp.isWARFile()) &&
982                 (portletId.endsWith(
983                     PortletConstants.WAR_SEPARATOR +
984                         PortalUtil.getJsSafePortletId(servletContextName)) &&
985                 (!portletIds.contains(portletId)))) {
986 
987                 undefinedPortletIds.add(portletId);
988             }
989             else if ((servletContextName == null) &&
990                      (!portletApp.isWARFile()) &&
991                      (portletId.indexOf(
992                         PortletConstants.WAR_SEPARATOR) == -1) &&
993                      (!portletIds.contains(portletId))) {
994 
995                 undefinedPortletIds.add(portletId);
996             }
997         }
998 
999         if (undefinedPortletIds.size() > 0) {
1000            PortletCategory undefinedCategory = new PortletCategory(
1001                "category.undefined");
1002
1003            portletCategory.addCategory(undefinedCategory);
1004
1005            undefinedCategory.getPortletIds().addAll(undefinedPortletIds);
1006        }
1007
1008        return portletCategory;
1009    }
1010
1011    private Set<String> _readLiferayPortletXML(
1012            String xml, Map<String, Portlet> portletsPool)
1013        throws Exception {
1014
1015        return _readLiferayPortletXML(StringPool.BLANK, xml, portletsPool);
1016    }
1017
1018    private Set<String> _readLiferayPortletXML(
1019            String servletContextName, String xml,
1020            Map<String, Portlet> portletsPool)
1021        throws Exception {
1022
1023        Set<String> liferayPortletIds = new HashSet<String>();
1024
1025        if (xml == null) {
1026            return liferayPortletIds;
1027        }
1028
1029        Document doc = SAXReaderUtil.read(xml, true);
1030
1031        Element root = doc.getRootElement();
1032
1033        PortletApp portletApp = _getPortletApp(servletContextName);
1034
1035        Map<String, String> roleMappers = new HashMap<String, String>();
1036
1037        Iterator<Element> itr1 = root.elements("role-mapper").iterator();
1038
1039        while (itr1.hasNext()) {
1040            Element roleMapper = itr1.next();
1041
1042            String roleName = roleMapper.elementText("role-name");
1043            String roleLink = roleMapper.elementText("role-link");
1044
1045            roleMappers.put(roleName, roleLink);
1046        }
1047
1048        Map<String, String> customUserAttributes =
1049            portletApp.getCustomUserAttributes();
1050
1051        itr1 = root.elements("custom-user-attribute").iterator();
1052
1053        while (itr1.hasNext()) {
1054            Element customUserAttribute = itr1.next();
1055
1056            String customClass = customUserAttribute.elementText(
1057                "custom-class");
1058
1059            Iterator<Element> itr2 = customUserAttribute.elements(
1060                "name").iterator();
1061
1062            while (itr2.hasNext()) {
1063                Element nameEl = itr2.next();
1064
1065                String name = nameEl.getText();
1066
1067                customUserAttributes.put(name, customClass);
1068            }
1069        }
1070
1071        itr1 = root.elements("portlet").iterator();
1072
1073        while (itr1.hasNext()) {
1074            Element portlet = itr1.next();
1075
1076            String portletId = portlet.elementText("portlet-name");
1077
1078            if (Validator.isNotNull(servletContextName)) {
1079                portletId =
1080                    portletId + PortletConstants.WAR_SEPARATOR +
1081                        servletContextName;
1082            }
1083
1084            portletId = PortalUtil.getJsSafePortletId(portletId);
1085
1086            if (_log.isDebugEnabled()) {
1087                _log.debug("Reading portlet extension " + portletId);
1088            }
1089
1090            liferayPortletIds.add(portletId);
1091
1092            Portlet portletModel = portletsPool.get(portletId);
1093
1094            if (portletModel != null) {
1095                portletModel.setIcon(GetterUtil.getString(
1096                    portlet.elementText("icon"), portletModel.getIcon()));
1097                portletModel.setVirtualPath(GetterUtil.getString(
1098                    portlet.elementText("virtual-path"),
1099                    portletModel.getVirtualPath()));
1100                portletModel.setStrutsPath(GetterUtil.getString(
1101                    portlet.elementText("struts-path"),
1102                    portletModel.getStrutsPath()));
1103
1104                if (Validator.isNotNull(
1105                        portlet.elementText("configuration-path"))) {
1106
1107                    _log.error(
1108                        "The configuration-path element is no longer " +
1109                            "supported. Use configuration-action-class " +
1110                                "instead.");
1111                }
1112
1113                portletModel.setConfigurationActionClass(GetterUtil.getString(
1114                    portlet.elementText("configuration-action-class"),
1115                    portletModel.getConfigurationActionClass()));
1116                portletModel.setIndexerClass(GetterUtil.getString(
1117                    portlet.elementText("indexer-class"),
1118                    portletModel.getIndexerClass()));
1119                portletModel.setOpenSearchClass(GetterUtil.getString(
1120                    portlet.elementText("open-search-class"),
1121                    portletModel.getOpenSearchClass()));
1122
1123                Iterator<Element> itr2 = portlet.elementIterator(
1124                    "scheduler-entry");
1125
1126                while (itr2.hasNext()){
1127                    Element schedulerEntryEl = itr2.next();
1128
1129                    SchedulerEntry schedulerEntry = new SchedulerEntryImpl();
1130
1131                    String schedulerDescription = schedulerEntryEl.elementText(
1132                        "scheduler-description");
1133
1134                    schedulerEntry.setDescription(GetterUtil.getString(
1135                        schedulerDescription));
1136                    schedulerEntry.setEventListenerClass(GetterUtil.getString(
1137                        schedulerEntryEl.elementText(
1138                            "scheduler-event-listener-class"),
1139                        schedulerEntry.getEventListenerClass()));
1140
1141                    Element triggerEl = schedulerEntryEl.element("trigger");
1142
1143                    Element cronEl = triggerEl.element("cron");
1144                    Element simpleEl = triggerEl.element("simple");
1145
1146                    if (cronEl != null) {
1147                        schedulerEntry.setTriggerType(TriggerType.CRON);
1148
1149                        Element propertyKeyEl = cronEl.element("property-key");
1150
1151                        if (propertyKeyEl != null) {
1152                            schedulerEntry.setReadProperty(true);
1153
1154                            schedulerEntry.setTriggerValue(
1155                                propertyKeyEl.getTextTrim());
1156                        }
1157                        else {
1158                            schedulerEntry.setTriggerValue(
1159                                cronEl.elementText("cron-trigger-value"));
1160                        }
1161                    }
1162                    else if (simpleEl != null) {
1163                        schedulerEntry.setTriggerType(TriggerType.SIMPLE);
1164
1165                        Element propertyKeyEl = simpleEl.element(
1166                            "property-key");
1167
1168                        if (propertyKeyEl != null) {
1169                            schedulerEntry.setReadProperty(true);
1170
1171                            schedulerEntry.setTriggerValue(
1172                                propertyKeyEl.getTextTrim());
1173                        }
1174                        else {
1175                            Element simpleTriggerValueEl = simpleEl.element(
1176                                "simple-trigger-value");
1177
1178                            schedulerEntry.setTriggerValue(
1179                                simpleTriggerValueEl.getTextTrim());
1180                        }
1181
1182                        String timeUnit = GetterUtil.getString(
1183                            simpleEl.elementText("time-unit"),
1184                            TimeUnit.SECOND.getValue());
1185
1186                        schedulerEntry.setTimeUnit(
1187                            TimeUnit.parse(timeUnit.toLowerCase()));
1188                    }
1189
1190                    portletModel.addSchedulerEntry(schedulerEntry);
1191                }
1192
1193                portletModel.setPortletURLClass(GetterUtil.getString(
1194                    portlet.elementText("portlet-url-class"),
1195                    portletModel.getPortletURLClass()));
1196
1197                portletModel.setFriendlyURLMapperClass(GetterUtil.getString(
1198                    portlet.elementText("friendly-url-mapper-class"),
1199                    portletModel.getFriendlyURLMapperClass()));
1200
1201                if (Validator.isNull(
1202                        portletModel.getFriendlyURLMapperClass())) {
1203
1204                    _friendlyURLMapperPortlets.remove(portletId);
1205                }
1206                else {
1207                    _friendlyURLMapperPortlets.put(portletId, portletModel);
1208                }
1209
1210                portletModel.setURLEncoderClass(GetterUtil.getString(
1211                    portlet.elementText("url-encoder-class"),
1212                    portletModel.getURLEncoderClass()));
1213                portletModel.setPortletDataHandlerClass(GetterUtil.getString(
1214                    portlet.elementText("portlet-data-handler-class"),
1215                    portletModel.getPortletDataHandlerClass()));
1216                portletModel.setPortletLayoutListenerClass(GetterUtil.getString(
1217                    portlet.elementText("portlet-layout-listener-class"),
1218                    portletModel.getPortletLayoutListenerClass()));
1219                portletModel.setPollerProcessorClass(GetterUtil.getString(
1220                    portlet.elementText("poller-processor-class"),
1221                    portletModel.getPollerProcessorClass()));
1222                portletModel.setPopMessageListenerClass(GetterUtil.getString(
1223                    portlet.elementText("pop-message-listener-class"),
1224                    portletModel.getPopMessageListenerClass()));
1225                portletModel.setSocialActivityInterpreterClass(
1226                    GetterUtil.getString(
1227                        portlet.elementText(
1228                            "social-activity-interpreter-class"),
1229                            portletModel.getSocialActivityInterpreterClass()));
1230                portletModel.setSocialRequestInterpreterClass(
1231                    GetterUtil.getString(
1232                        portlet.elementText(
1233                            "social-request-interpreter-class"),
1234                            portletModel.getSocialRequestInterpreterClass()));
1235                portletModel.setWebDAVStorageToken(GetterUtil.getString(
1236                    portlet.elementText("webdav-storage-token"),
1237                    portletModel.getWebDAVStorageToken()));
1238                portletModel.setWebDAVStorageClass(GetterUtil.getString(
1239                    portlet.elementText("webdav-storage-class"),
1240                    portletModel.getWebDAVStorageClass()));
1241                portletModel.setXmlRpcMethodClass(GetterUtil.getString(
1242                    portlet.elementText("xml-rpc-method-class"),
1243                    portletModel.getXmlRpcMethodClass()));
1244                portletModel.setControlPanelEntryCategory(GetterUtil.getString(
1245                    portlet.elementText("control-panel-entry-category"),
1246                    portletModel.getControlPanelEntryCategory()));
1247                portletModel.setControlPanelEntryWeight(GetterUtil.getDouble(
1248                    portlet.elementText("control-panel-entry-weight"),
1249                    portletModel.getControlPanelEntryWeight()));
1250                portletModel.setControlPanelEntryClass(GetterUtil.getString(
1251                    portlet.elementText("control-panel-entry-class"),
1252                    portletModel.getControlPanelEntryClass()));
1253
1254                List<String> assetRendererFactoryClasses =
1255                    portletModel.getAssetRendererFactoryClasses();
1256
1257                itr2 = portlet.elements("asset-renderer-factory").iterator();
1258
1259                while (itr2.hasNext()) {
1260                    Element assetRendererFactoryClassEl = itr2.next();
1261
1262                    assetRendererFactoryClasses.add(
1263                        assetRendererFactoryClassEl.getText());
1264                }
1265
1266                List<String> customAttributesDisplayClasses =
1267                    portletModel.getCustomAttributesDisplayClasses();
1268
1269                itr2 = portlet.elements("custom-attributes-display").iterator();
1270
1271                while (itr2.hasNext()) {
1272                    Element customAttributesDisplayClassEl = itr2.next();
1273
1274                    customAttributesDisplayClasses.add(
1275                        customAttributesDisplayClassEl.getText());
1276                }
1277
1278                if (portletModel.getCustomAttributesDisplayClasses().
1279                    isEmpty()) {
1280
1281                    _customAttributesDisplayPortlets.remove(portletId);
1282                }
1283                else {
1284                    _customAttributesDisplayPortlets.put(
1285                        portletId, portletModel);
1286                }
1287
1288                List<String> workflowHandlerClasses =
1289                    portletModel.getWorkflowHandlerClasses();
1290
1291                itr2 = portlet.elements("workflow-handler").iterator();
1292
1293                while (itr2.hasNext()) {
1294                    Element workflowHandlerClassEl = itr2.next();
1295
1296                    workflowHandlerClasses.add(
1297                        workflowHandlerClassEl.getText());
1298                }
1299
1300                portletModel.setPreferencesCompanyWide(GetterUtil.getBoolean(
1301                    portlet.elementText("preferences-company-wide"),
1302                    portletModel.isPreferencesCompanyWide()));
1303                portletModel.setPreferencesUniquePerLayout(
1304                    GetterUtil.getBoolean(
1305                        portlet.elementText("preferences-unique-per-layout"),
1306                        portletModel.isPreferencesUniquePerLayout()));
1307                portletModel.setPreferencesOwnedByGroup(GetterUtil.getBoolean(
1308                    portlet.elementText("preferences-owned-by-group"),
1309                    portletModel.isPreferencesOwnedByGroup()));
1310                portletModel.setUseDefaultTemplate(GetterUtil.getBoolean(
1311                    portlet.elementText("use-default-template"),
1312                    portletModel.isUseDefaultTemplate()));
1313                portletModel.setShowPortletAccessDenied(GetterUtil.getBoolean(
1314                    portlet.elementText("show-portlet-access-denied"),
1315                    portletModel.isShowPortletAccessDenied()));
1316                portletModel.setShowPortletInactive(GetterUtil.getBoolean(
1317                    portlet.elementText("show-portlet-inactive"),
1318                    portletModel.isShowPortletInactive()));
1319                portletModel.setActionURLRedirect(GetterUtil.getBoolean(
1320                    portlet.elementText("action-url-redirect"),
1321                    portletModel.isActionURLRedirect()));
1322                portletModel.setRestoreCurrentView(GetterUtil.getBoolean(
1323                    portlet.elementText("restore-current-view"),
1324                    portletModel.isRestoreCurrentView()));
1325                portletModel.setMaximizeEdit(GetterUtil.getBoolean(
1326                    portlet.elementText("maximize-edit"),
1327                    portletModel.isMaximizeEdit()));
1328                portletModel.setMaximizeHelp(GetterUtil.getBoolean(
1329                    portlet.elementText("maximize-help"),
1330                    portletModel.isMaximizeHelp()));
1331                portletModel.setPopUpPrint(GetterUtil.getBoolean(
1332                    portlet.elementText("pop-up-print"),
1333                    portletModel.isPopUpPrint()));
1334                portletModel.setLayoutCacheable(GetterUtil.getBoolean(
1335                    portlet.elementText("layout-cacheable"),
1336                    portletModel.isLayoutCacheable()));
1337                portletModel.setInstanceable(GetterUtil.getBoolean(
1338                    portlet.elementText("instanceable"),
1339                    portletModel.isInstanceable()));
1340                portletModel.setScopeable(GetterUtil.getBoolean(
1341                    portlet.elementText("scopeable"),
1342                    portletModel.isScopeable()));
1343                portletModel.setUserPrincipalStrategy(GetterUtil.getString(
1344                    portlet.elementText("user-principal-strategy"),
1345                    portletModel.getUserPrincipalStrategy()));
1346                portletModel.setPrivateRequestAttributes(GetterUtil.getBoolean(
1347                    portlet.elementText("private-request-attributes"),
1348                    portletModel.isPrivateRequestAttributes()));
1349                portletModel.setPrivateSessionAttributes(GetterUtil.getBoolean(
1350                    portlet.elementText("private-session-attributes"),
1351                    portletModel.isPrivateSessionAttributes()));
1352                portletModel.setRenderWeight(GetterUtil.getInteger(
1353                    portlet.elementText("render-weight"),
1354                    portletModel.getRenderWeight()));
1355                portletModel.setAjaxable(GetterUtil.getBoolean(
1356                    portlet.elementText("ajaxable"),
1357                    portletModel.isAjaxable()));
1358
1359                List<String> headerPortalCssList =
1360                    portletModel.getHeaderPortalCss();
1361
1362                itr2 = portlet.elements("header-portal-css").iterator();
1363
1364                while (itr2.hasNext()) {
1365                    Element headerPortalCssEl = itr2.next();
1366
1367                    headerPortalCssList.add(headerPortalCssEl.getText());
1368                }
1369
1370                List<String> headerPortletCssList =
1371                    portletModel.getHeaderPortletCss();
1372
1373                List<Element> list = new ArrayList<Element>();
1374
1375                list.addAll(portlet.elements("header-css"));
1376                list.addAll(portlet.elements("header-portlet-css"));
1377
1378                itr2 = list.iterator();
1379
1380                while (itr2.hasNext()) {
1381                    Element headerPortletCssEl = itr2.next();
1382
1383                    headerPortletCssList.add(headerPortletCssEl.getText());
1384                }
1385
1386                List<String> headerPortalJavaScriptList =
1387                    portletModel.getHeaderPortalJavaScript();
1388
1389                itr2 = portlet.elements("header-portal-javascript").iterator();
1390
1391                while (itr2.hasNext()) {
1392                    Element headerPortalJavaScriptEl = itr2.next();
1393
1394                    headerPortalJavaScriptList.add(
1395                        headerPortalJavaScriptEl.getText());
1396                }
1397
1398                List<String> headerPortletJavaScriptList =
1399                    portletModel.getHeaderPortletJavaScript();
1400
1401                list.clear();
1402
1403                list.addAll(portlet.elements("header-javascript"));
1404                list.addAll(portlet.elements("header-portlet-javascript"));
1405
1406                itr2 = list.iterator();
1407
1408                while (itr2.hasNext()) {
1409                    Element headerPortletJavaScriptEl = itr2.next();
1410
1411                    headerPortletJavaScriptList.add(
1412                        headerPortletJavaScriptEl.getText());
1413                }
1414
1415                List<String> footerPortalCssList =
1416                    portletModel.getFooterPortalCss();
1417
1418                itr2 = portlet.elements("footer-portal-css").iterator();
1419
1420                while (itr2.hasNext()) {
1421                    Element footerPortalCssEl = itr2.next();
1422
1423                    footerPortalCssList.add(footerPortalCssEl.getText());
1424                }
1425
1426                List<String> footerPortletCssList =
1427                    portletModel.getFooterPortletCss();
1428
1429                itr2 = portlet.elements("footer-portlet-css").iterator();
1430
1431                while (itr2.hasNext()) {
1432                    Element footerPortletCssEl = itr2.next();
1433
1434                    footerPortletCssList.add(footerPortletCssEl.getText());
1435                }
1436
1437                List<String> footerPortalJavaScriptList =
1438                    portletModel.getFooterPortalJavaScript();
1439
1440                itr2 = portlet.elements("footer-portal-javascript").iterator();
1441
1442                while (itr2.hasNext()) {
1443                    Element footerPortalJavaScriptEl = itr2.next();
1444
1445                    footerPortalJavaScriptList.add(
1446                        footerPortalJavaScriptEl.getText());
1447                }
1448
1449                List<String> footerPortletJavaScriptList =
1450                    portletModel.getFooterPortletJavaScript();
1451
1452                itr2 = portlet.elements("footer-portlet-javascript").iterator();
1453
1454                while (itr2.hasNext()) {
1455                    Element footerPortletJavaScriptEl = itr2.next();
1456
1457                    footerPortletJavaScriptList.add(
1458                        footerPortletJavaScriptEl.getText());
1459                }
1460
1461                portletModel.setCssClassWrapper(GetterUtil.getString(
1462                    portlet.elementText("css-class-wrapper"),
1463                    portletModel.getCssClassWrapper()));
1464                portletModel.setFacebookIntegration(GetterUtil.getString(
1465                    portlet.elementText("facebook-integration"),
1466                    portletModel.getFacebookIntegration()));
1467                portletModel.setAddDefaultResource(GetterUtil.getBoolean(
1468                    portlet.elementText("add-default-resource"),
1469                    portletModel.isAddDefaultResource()));
1470                portletModel.setSystem(GetterUtil.getBoolean(
1471                    portlet.elementText("system"),
1472                    portletModel.isSystem()));
1473                portletModel.setActive(GetterUtil.getBoolean(
1474                    portlet.elementText("active"),
1475                    portletModel.isActive()));
1476                portletModel.setInclude(GetterUtil.getBoolean(
1477                    portlet.elementText("include"),
1478                    portletModel.isInclude()));
1479
1480                if (!portletModel.isAjaxable() &&
1481                    (portletModel.getRenderWeight() < 1)) {
1482
1483                    portletModel.setRenderWeight(1);
1484                }
1485
1486                portletModel.getRoleMappers().putAll(roleMappers);
1487                portletModel.linkRoles();
1488            }
1489        }
1490
1491        return liferayPortletIds;
1492    }
1493
1494    private Set<String> _readPortletXML(
1495            ServletContext servletContext, String xml,
1496            Map<String, Portlet> portletsPool, List<String> servletURLPatterns,
1497            PluginPackage pluginPackage)
1498        throws Exception {
1499
1500        return _readPortletXML(
1501            StringPool.BLANK, servletContext, xml, portletsPool,
1502            servletURLPatterns, pluginPackage);
1503    }
1504
1505    private Set<String> _readPortletXML(
1506            String servletContextName, ServletContext servletContext,
1507            String xml, Map<String, Portlet> portletsPool,
1508            List<String> servletURLPatterns, PluginPackage pluginPackage)
1509        throws Exception {
1510
1511        Set<String> portletIds = new HashSet<String>();
1512
1513        if (xml == null) {
1514            return portletIds;
1515        }
1516
1517        Document doc = SAXReaderUtil.read(
1518            xml, PropsValues.PORTLET_XML_VALIDATE);
1519
1520        Element root = doc.getRootElement();
1521
1522        PortletApp portletApp = _getPortletApp(servletContextName);
1523
1524        portletApp.getServletURLPatterns().addAll(servletURLPatterns);
1525
1526        Set<String> userAttributes = portletApp.getUserAttributes();
1527
1528        Iterator<Element> itr1 = root.elements("user-attribute").iterator();
1529
1530        while (itr1.hasNext()) {
1531            Element userAttribute = itr1.next();
1532
1533            String name = userAttribute.elementText("name");
1534
1535            userAttributes.add(name);
1536        }
1537
1538        String defaultNamespace = root.elementText("default-namespace");
1539
1540        if (Validator.isNotNull(defaultNamespace)) {
1541            portletApp.setDefaultNamespace(defaultNamespace);
1542        }
1543
1544        itr1 = root.elements("event-definition").iterator();
1545
1546        while (itr1.hasNext()) {
1547            Element eventDefinitionEl = itr1.next();
1548
1549            Element qNameEl = eventDefinitionEl.element("qname");
1550            Element nameEl = eventDefinitionEl.element("name");
1551            String valueType = eventDefinitionEl.elementText("value-type");
1552
1553            QName qName = PortletQNameUtil.getQName(
1554                qNameEl, nameEl, portletApp.getDefaultNamespace());
1555
1556            EventDefinition eventDefinition = new EventDefinitionImpl(
1557                qName, valueType, portletApp);
1558
1559            portletApp.addEventDefinition(eventDefinition);
1560        }
1561
1562        itr1 = root.elements("public-render-parameter").iterator();
1563
1564        while (itr1.hasNext()) {
1565            Element publicRenderParameterEl = itr1.next();
1566
1567            String identifier = publicRenderParameterEl.elementText(
1568                "identifier");
1569            Element qNameEl = publicRenderParameterEl.element("qname");
1570            Element nameEl = publicRenderParameterEl.element("name");
1571
1572            QName qName = PortletQNameUtil.getQName(
1573                qNameEl, nameEl, portletApp.getDefaultNamespace());
1574
1575            PublicRenderParameter publicRenderParameter =
1576                new PublicRenderParameterImpl(identifier, qName, portletApp);
1577
1578            portletApp.addPublicRenderParameter(publicRenderParameter);
1579        }
1580
1581        itr1 = root.elements("container-runtime-option").iterator();
1582
1583        while (itr1.hasNext()) {
1584            Element containerRuntimeOption = itr1.next();
1585
1586            String name = GetterUtil.getString(
1587                containerRuntimeOption.elementText("name"));
1588
1589            List<String> values = new ArrayList<String>();
1590
1591            for (Element value : containerRuntimeOption.elements("value")) {
1592                values.add(value.getTextTrim());
1593            }
1594
1595            portletApp.getContainerRuntimeOptions().put(
1596                name, values.toArray(new String[values.size()]));
1597
1598            if (name.equals(
1599                    LiferayPortletConfig.RUNTIME_OPTION_PORTAL_CONTEXT) &&
1600                !values.isEmpty() && GetterUtil.getBoolean(values.get(0))) {
1601
1602                portletApp.setWARFile(false);
1603            }
1604        }
1605
1606        long timestamp = ServletContextUtil.getLastModified(servletContext);
1607
1608        itr1 = root.elements("portlet").iterator();
1609
1610        while (itr1.hasNext()) {
1611            Element portlet = itr1.next();
1612
1613            String portletName = portlet.elementText("portlet-name");
1614
1615            String portletId = portletName;
1616
1617            if (Validator.isNotNull(servletContextName)) {
1618                portletId =
1619                    portletId + PortletConstants.WAR_SEPARATOR +
1620                        servletContextName;
1621            }
1622
1623            portletId = PortalUtil.getJsSafePortletId(portletId);
1624
1625            if (_log.isDebugEnabled()) {
1626                _log.debug("Reading portlet " + portletId);
1627            }
1628
1629            portletIds.add(portletId);
1630
1631            Portlet portletModel = portletsPool.get(portletId);
1632
1633            if (portletModel == null) {
1634                portletModel = new PortletImpl(
1635                    CompanyConstants.SYSTEM, portletId);
1636
1637                portletsPool.put(portletId, portletModel);
1638            }
1639
1640            portletModel.setTimestamp(timestamp);
1641
1642            portletModel.setPluginPackage(pluginPackage);
1643            portletModel.setPortletApp(portletApp);
1644
1645            portletModel.setPortletName(portletName);
1646            portletModel.setDisplayName(GetterUtil.getString(
1647                portlet.elementText("display-name"),
1648                portletModel.getDisplayName()));
1649            portletModel.setPortletClass(GetterUtil.getString(
1650                portlet.elementText("portlet-class")));
1651
1652            Iterator<Element> itr2 = portlet.elements("init-param").iterator();
1653
1654            while (itr2.hasNext()) {
1655                Element initParam = itr2.next();
1656
1657                portletModel.getInitParams().put(
1658                    initParam.elementText("name"),
1659                    initParam.elementText("value"));
1660            }
1661
1662            Element expirationCache = portlet.element("expiration-cache");
1663
1664            if (expirationCache != null) {
1665                portletModel.setExpCache(new Integer(GetterUtil.getInteger(
1666                    expirationCache.getText())));
1667            }
1668
1669            itr2 = portlet.elements("supports").iterator();
1670
1671            while (itr2.hasNext()) {
1672                Element supports = itr2.next();
1673
1674                String mimeType = supports.elementText("mime-type");
1675
1676                Set<String> mimeTypePortletModes =
1677                    portletModel.getPortletModes().get(mimeType);
1678
1679                if (mimeTypePortletModes == null) {
1680                    mimeTypePortletModes = new HashSet<String>();
1681
1682                    portletModel.getPortletModes().put(
1683                        mimeType, mimeTypePortletModes);
1684                }
1685
1686                mimeTypePortletModes.add(
1687                    PortletMode.VIEW.toString().toLowerCase());
1688
1689                Iterator<Element> itr3 = supports.elements(
1690                    "portlet-mode").iterator();
1691
1692                while (itr3.hasNext()) {
1693                    Element portletMode = itr3.next();
1694
1695                    mimeTypePortletModes.add(
1696                        portletMode.getTextTrim().toLowerCase());
1697                }
1698
1699                Set<String> mimeTypeWindowStates =
1700                    portletModel.getWindowStates().get(mimeType);
1701
1702                if (mimeTypeWindowStates == null) {
1703                    mimeTypeWindowStates = new HashSet<String>();
1704
1705                    portletModel.getWindowStates().put(
1706                        mimeType, mimeTypeWindowStates);
1707                }
1708
1709                mimeTypeWindowStates.add(
1710                    WindowState.NORMAL.toString().toLowerCase());
1711
1712                itr3 = supports.elements("window-state").iterator();
1713
1714                if (!itr3.hasNext()) {
1715                    mimeTypeWindowStates.add(
1716                        WindowState.MAXIMIZED.toString().toLowerCase());
1717                    mimeTypeWindowStates.add(
1718                        WindowState.MINIMIZED.toString().toLowerCase());
1719                    mimeTypeWindowStates.add(
1720                        LiferayWindowState.EXCLUSIVE.toString().toLowerCase());
1721                    mimeTypeWindowStates.add(
1722                        LiferayWindowState.POP_UP.toString().toLowerCase());
1723                }
1724
1725                while (itr3.hasNext()) {
1726                    Element windowState = itr3.next();
1727
1728                    mimeTypeWindowStates.add(
1729                        windowState.getTextTrim().toLowerCase());
1730                }
1731            }
1732
1733            Set<String> supportedLocales = portletModel.getSupportedLocales();
1734
1735            //supportedLocales.add(
1736            //  LocaleUtil.toLanguageId(LocaleUtil.getDefault()));
1737
1738            itr2 = portlet.elements("supported-locale").iterator();
1739
1740            while (itr2.hasNext()) {
1741                Element supportedLocaleEl = itr2.next();
1742
1743                String supportedLocale = supportedLocaleEl.getText();
1744
1745                supportedLocales.add(supportedLocale);
1746            }
1747
1748            portletModel.setResourceBundle(
1749                portlet.elementText("resource-bundle"));
1750
1751            Element portletInfo = portlet.element("portlet-info");
1752
1753            String portletInfoTitle = null;
1754            String portletInfoShortTitle = null;
1755            String portletInfoKeyWords = null;
1756            String portletInfoDescription = null;
1757
1758            if (portletInfo != null) {
1759                portletInfoTitle = portletInfo.elementText("title");
1760                portletInfoShortTitle = portletInfo.elementText("short-title");
1761                portletInfoKeyWords = portletInfo.elementText("keywords");
1762            }
1763
1764            portletModel.setPortletInfo(
1765                new PortletInfo(
1766                    portletInfoTitle, portletInfoShortTitle,
1767                    portletInfoKeyWords, portletInfoDescription));
1768
1769            Element portletPreferences = portlet.element("portlet-preferences");
1770
1771            String defaultPreferences = null;
1772            String preferencesValidator = null;
1773
1774            if (portletPreferences != null) {
1775                Element preferencesValidatorEl =
1776                    portletPreferences.element("preferences-validator");
1777
1778                if (preferencesValidatorEl != null) {
1779                    preferencesValidator = preferencesValidatorEl.getText();
1780
1781                    portletPreferences.remove(preferencesValidatorEl);
1782                }
1783
1784                defaultPreferences = portletPreferences.asXML();
1785            }
1786
1787            portletModel.setDefaultPreferences(defaultPreferences);
1788            portletModel.setPreferencesValidator(preferencesValidator);
1789
1790            if (!portletApp.isWARFile() &&
1791                Validator.isNotNull(preferencesValidator) &&
1792                PropsValues.PREFERENCE_VALIDATE_ON_STARTUP) {
1793
1794                try {
1795                    PreferencesValidator preferencesValidatorObj =
1796                        PortalUtil.getPreferencesValidator(portletModel);
1797
1798                    preferencesValidatorObj.validate(
1799                        PortletPreferencesSerializer.fromDefaultXML(
1800                            defaultPreferences));
1801                }
1802                catch (Exception e) {
1803                    if (_log.isWarnEnabled()) {
1804                        _log.warn(
1805                            "Portlet with the name " + portletId +
1806                                " does not have valid default preferences");
1807                    }
1808                }
1809            }
1810
1811            Set<String> unlikedRoles = portletModel.getUnlinkedRoles();
1812
1813            itr2 = portlet.elements("security-role-ref").iterator();
1814
1815            while (itr2.hasNext()) {
1816                Element role = itr2.next();
1817
1818                unlikedRoles.add(role.elementText("role-name"));
1819            }
1820
1821            itr2 = portlet.elements("supported-processing-event").iterator();
1822
1823            while (itr2.hasNext()) {
1824                Element supportedProcessingEvent = itr2.next();
1825
1826                Element qNameEl = supportedProcessingEvent.element("qname");
1827                Element nameEl = supportedProcessingEvent.element("name");
1828
1829                QName qName = PortletQNameUtil.getQName(
1830                    qNameEl, nameEl, portletApp.getDefaultNamespace());
1831
1832                portletModel.addProcessingEvent(qName);
1833            }
1834
1835            itr2 = portlet.elements("supported-publishing-event").iterator();
1836
1837            while (itr2.hasNext()) {
1838                Element supportedPublishingEvent = itr2.next();
1839
1840                Element qNameEl = supportedPublishingEvent.element("qname");
1841                Element nameEl = supportedPublishingEvent.element("name");
1842
1843                QName qName = PortletQNameUtil.getQName(
1844                    qNameEl, nameEl, portletApp.getDefaultNamespace());
1845
1846                portletModel.addPublishingEvent(qName);
1847            }
1848
1849            itr2 = portlet.elements(
1850                "supported-public-render-parameter").iterator();
1851
1852            while (itr2.hasNext()) {
1853                Element supportedPublicRenderParameter = itr2.next();
1854
1855                String identifier =
1856                    supportedPublicRenderParameter.getTextTrim();
1857
1858                PublicRenderParameter publicRenderParameter =
1859                    portletApp.getPublicRenderParameter(identifier);
1860
1861                if (publicRenderParameter == null) {
1862                    _log.error(
1863                        "Supported public render parameter references " +
1864                            "unnknown identifier " + identifier);
1865
1866                    continue;
1867                }
1868
1869                portletModel.addPublicRenderParameter(publicRenderParameter);
1870            }
1871        }
1872
1873        itr1 = root.elements("filter").iterator();
1874
1875        while (itr1.hasNext()) {
1876            Element filter = itr1.next();
1877
1878            String filterName = filter.elementText("filter-name");
1879            String filterClass = filter.elementText("filter-class");
1880
1881            Set<String> lifecycles = new LinkedHashSet<String>();
1882
1883            Iterator<Element> itr2 = filter.elements("lifecycle").iterator();
1884
1885            while (itr2.hasNext()) {
1886                Element lifecycle = itr2.next();
1887
1888                lifecycles.add(lifecycle.getText());
1889            }
1890
1891            Map<String, String> initParams = new HashMap<String, String>();
1892
1893            itr2 = filter.elements("init-param").iterator();
1894
1895            while (itr2.hasNext()) {
1896                Element initParam = itr2.next();
1897
1898                initParams.put(
1899                    initParam.elementText("name"),
1900                    initParam.elementText("value"));
1901            }
1902
1903            PortletFilter portletFilter = new PortletFilterImpl(
1904                filterName, filterClass, lifecycles, initParams, portletApp);
1905
1906            portletApp.addPortletFilter(portletFilter);
1907        }
1908
1909        itr1 = root.elements("filter-mapping").iterator();
1910
1911        while (itr1.hasNext()) {
1912            Element filterMapping = itr1.next();
1913
1914            String filterName = filterMapping.elementText("filter-name");
1915
1916            Iterator<Element> itr2 = filterMapping.elements(
1917                "portlet-name").iterator();
1918
1919            while (itr2.hasNext()) {
1920                Element portletNameEl = itr2.next();
1921
1922                String portletName = portletNameEl.getTextTrim();
1923
1924                PortletFilter portletFilter = portletApp.getPortletFilter(
1925                    filterName);
1926
1927                if (portletFilter == null) {
1928                    _log.error(
1929                        "Filter mapping references unnknown filter name " +
1930                            filterName);
1931
1932                    continue;
1933                }
1934
1935                List<Portlet> portletModels = _getPortletsByPortletName(
1936                    portletName, servletContextName, portletsPool);
1937
1938                if (portletModels.size() == 0) {
1939                    _log.error(
1940                        "Filter mapping with filter name " + filterName +
1941                            " references unnknown portlet name " + portletName);
1942                }
1943
1944                for (Portlet portletModel : portletModels) {
1945                    portletModel.getPortletFilters().put(
1946                        filterName, portletFilter);
1947                }
1948            }
1949        }
1950
1951        itr1 = root.elements("listener").iterator();
1952
1953        while (itr1.hasNext()) {
1954            Element listener = itr1.next();
1955
1956            String listenerClass = listener.elementText("listener-class");
1957
1958            PortletURLListener portletURLListener = new PortletURLListenerImpl(
1959                listenerClass, portletApp);
1960
1961            portletApp.addPortletURLListener(portletURLListener);
1962        }
1963
1964        return portletIds;
1965    }
1966
1967    private List<String> _readWebXML(String xml) throws Exception {
1968        List<String> servletURLPatterns = new ArrayList<String>();
1969
1970        if (xml == null) {
1971            return servletURLPatterns;
1972        }
1973
1974        Document doc = SAXReaderUtil.read(xml);
1975
1976        Element root = doc.getRootElement();
1977
1978        Iterator<Element> itr = root.elements("servlet-mapping").iterator();
1979
1980        while (itr.hasNext()) {
1981            Element servletMapping = itr.next();
1982
1983            String urlPattern = servletMapping.elementText("url-pattern");
1984
1985            servletURLPatterns.add(urlPattern);
1986        }
1987
1988        return servletURLPatterns;
1989
1990    }
1991
1992    private void _setSpriteImages(
1993            ServletContext servletContext, PortletApp portletApp,
1994            String resourcePath)
1995        throws Exception {
1996
1997        Set<String> resourcePaths = servletContext.getResourcePaths(
1998            resourcePath);
1999
2000        if (resourcePaths == null) {
2001            return;
2002        }
2003
2004        List<File> images = new ArrayList<File>(resourcePaths.size());
2005
2006        for (String curResourcePath : resourcePaths) {
2007            if (curResourcePath.endsWith(StringPool.SLASH)) {
2008                _setSpriteImages(servletContext, portletApp, curResourcePath);
2009            }
2010            else if (curResourcePath.endsWith(".png")) {
2011                String realPath = ServletContextUtil.getRealPath(
2012                    servletContext, curResourcePath);
2013
2014                if (realPath != null) {
2015                    images.add(new File(realPath));
2016                }
2017                else {
2018                    if (ServerDetector.isTomcat()) {
2019                        if (_log.isInfoEnabled()) {
2020                            _log.info(ServletContextUtil.LOG_INFO_SPRITES);
2021                        }
2022                    }
2023                    else {
2024                        _log.error(
2025                            "Real path for " + curResourcePath + " is null");
2026                    }
2027                }
2028            }
2029        }
2030
2031        String spriteFileName = ".sprite.png";
2032        String spritePropertiesFileName = ".sprite.properties";
2033        String spritePropertiesRootPath = ServletContextUtil.getRealPath(
2034            servletContext, StringPool.SLASH);
2035
2036        Properties spriteProperties = SpriteProcessorUtil.generate(
2037            images, spriteFileName, spritePropertiesFileName,
2038            spritePropertiesRootPath, 16, 16, 10240);
2039
2040        if (spriteProperties == null) {
2041            return;
2042        }
2043
2044        spriteFileName =
2045            resourcePath.substring(0, resourcePath.length()) + spriteFileName;
2046
2047        portletApp.setSpriteImages(spriteFileName, spriteProperties);
2048    }
2049
2050    private void _updateCompanyPortletsPool(long companyId) {
2051        String key = _encodeKey(companyId);
2052
2053        Map<String, Portlet> portletsPool =
2054            (Map<String, Portlet>)_companyPortletsPool.get(key);
2055
2056        _companyPortletsPool.put(key, portletsPool);
2057    }
2058
2059    private static Log _log = LogFactoryUtil.getLog(
2060        PortletLocalServiceImpl.class);
2061
2062    private static PortalCache _companyPortletsPool =
2063        MultiVMPoolUtil.getCache(Portlet.class.getName());
2064    private static Map<String, Portlet> _customAttributesDisplayPortlets =
2065        new ConcurrentHashMap<String, Portlet>();
2066    private static Map<String, Portlet> _friendlyURLMapperPortlets =
2067        new ConcurrentHashMap<String, Portlet>();
2068    private static String _keyPrefix = Portlet.class.getName().concat(
2069        StringPool.POUND);
2070    private static Map<String, PortletApp> _portletAppsPool =
2071        new ConcurrentHashMap<String, PortletApp>();
2072    private static Map<String, String> _portletIdsByStrutsPath =
2073        new ConcurrentHashMap<String, String>();
2074    private static Map<String, Portlet> _portletsPool =
2075        new ConcurrentHashMap<String, Portlet>();
2076
2077}