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