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