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