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