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