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