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