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