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