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