001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.service.impl;
016    
017    import com.liferay.portal.kernel.cluster.Clusterable;
018    import com.liferay.portal.kernel.exception.PortalException;
019    import com.liferay.portal.kernel.exception.SystemException;
020    import com.liferay.portal.kernel.image.SpriteProcessor;
021    import com.liferay.portal.kernel.image.SpriteProcessorUtil;
022    import com.liferay.portal.kernel.log.Log;
023    import com.liferay.portal.kernel.log.LogFactoryUtil;
024    import com.liferay.portal.kernel.plugin.PluginPackage;
025    import com.liferay.portal.kernel.portlet.FriendlyURLMapper;
026    import com.liferay.portal.kernel.portlet.LiferayPortletConfig;
027    import com.liferay.portal.kernel.portlet.LiferayWindowState;
028    import com.liferay.portal.kernel.portlet.PortletLayoutListener;
029    import com.liferay.portal.kernel.scheduler.SchedulerEntry;
030    import com.liferay.portal.kernel.scheduler.SchedulerEntryImpl;
031    import com.liferay.portal.kernel.scheduler.TimeUnit;
032    import com.liferay.portal.kernel.scheduler.TriggerType;
033    import com.liferay.portal.kernel.servlet.ServletContextUtil;
034    import com.liferay.portal.kernel.spring.aop.Skip;
035    import com.liferay.portal.kernel.transaction.Transactional;
036    import com.liferay.portal.kernel.util.CharPool;
037    import com.liferay.portal.kernel.util.ContentTypes;
038    import com.liferay.portal.kernel.util.ContextPathUtil;
039    import com.liferay.portal.kernel.util.GetterUtil;
040    import com.liferay.portal.kernel.util.ListUtil;
041    import com.liferay.portal.kernel.util.StringPool;
042    import com.liferay.portal.kernel.util.StringUtil;
043    import com.liferay.portal.kernel.util.Validator;
044    import com.liferay.portal.kernel.xml.Document;
045    import com.liferay.portal.kernel.xml.Element;
046    import com.liferay.portal.kernel.xml.QName;
047    import com.liferay.portal.kernel.xml.SAXReaderUtil;
048    import com.liferay.portal.model.CompanyConstants;
049    import com.liferay.portal.model.EventDefinition;
050    import com.liferay.portal.model.Portlet;
051    import com.liferay.portal.model.PortletApp;
052    import com.liferay.portal.model.PortletCategory;
053    import com.liferay.portal.model.PortletConstants;
054    import com.liferay.portal.model.PortletFilter;
055    import com.liferay.portal.model.PortletInfo;
056    import com.liferay.portal.model.PortletPreferences;
057    import com.liferay.portal.model.PortletURLListener;
058    import com.liferay.portal.model.PublicRenderParameter;
059    import com.liferay.portal.model.ResourceConstants;
060    import com.liferay.portal.model.Role;
061    import com.liferay.portal.model.impl.EventDefinitionImpl;
062    import com.liferay.portal.model.impl.PortletAppImpl;
063    import com.liferay.portal.model.impl.PortletFilterImpl;
064    import com.liferay.portal.model.impl.PortletImpl;
065    import com.liferay.portal.model.impl.PortletURLListenerImpl;
066    import com.liferay.portal.model.impl.PublicRenderParameterImpl;
067    import com.liferay.portal.security.permission.ActionKeys;
068    import com.liferay.portal.security.permission.ResourceActionsUtil;
069    import com.liferay.portal.service.base.PortletLocalServiceBaseImpl;
070    import com.liferay.portal.service.permission.PortletPermissionUtil;
071    import com.liferay.portal.util.PortalUtil;
072    import com.liferay.portal.util.PortletKeys;
073    import com.liferay.portal.util.PropsValues;
074    import com.liferay.portal.util.WebAppPool;
075    import com.liferay.portal.util.WebKeys;
076    import com.liferay.portlet.PortletConfigFactoryUtil;
077    import com.liferay.portlet.PortletContextFactory;
078    import com.liferay.portlet.PortletInstanceFactoryUtil;
079    import com.liferay.portlet.PortletPreferencesFactoryUtil;
080    import com.liferay.portlet.PortletQNameUtil;
081    import com.liferay.portlet.expando.model.CustomAttributesDisplay;
082    import com.liferay.util.ContentUtil;
083    import com.liferay.util.bridges.mvc.MVCPortlet;
084    
085    import java.net.URL;
086    
087    import java.util.ArrayList;
088    import java.util.HashMap;
089    import java.util.HashSet;
090    import java.util.Iterator;
091    import java.util.LinkedHashSet;
092    import java.util.List;
093    import java.util.Map;
094    import java.util.Properties;
095    import java.util.Set;
096    import java.util.concurrent.ConcurrentHashMap;
097    
098    import javax.portlet.PortletMode;
099    import javax.portlet.PreferencesValidator;
100    import javax.portlet.WindowState;
101    
102    import javax.servlet.ServletContext;
103    
104    /**
105     * @author Brian Wing Shun Chan
106     * @author Raymond Augé
107     * @author Eduardo Lundgren
108     * @author Wesley Gong
109     * @author Shuyang Zhou
110     */
111    public class PortletLocalServiceImpl extends PortletLocalServiceBaseImpl {
112    
113            @Skip
114            public void addPortletCategory(long companyId, String categoryName) {
115                    PortletCategory portletCategory = (PortletCategory)WebAppPool.get(
116                            companyId, WebKeys.PORTLET_CATEGORY);
117    
118                    if (portletCategory == null) {
119                            _log.error(
120                                    "Unable to add portlet category for company " + companyId +
121                                            " because it does not exist");
122    
123                            return;
124                    }
125    
126                    PortletCategory newPortletCategory = new PortletCategory(categoryName);
127    
128                    if (newPortletCategory.getParentCategory() == null) {
129                            PortletCategory rootPortletCategory = new PortletCategory();
130    
131                            rootPortletCategory.addCategory(newPortletCategory);
132                    }
133    
134                    portletCategory.merge(newPortletCategory.getRootCategory());
135            }
136    
137            public void checkPortlet(Portlet portlet)
138                    throws PortalException, SystemException {
139    
140                    if (portlet.isSystem()) {
141                            return;
142                    }
143    
144                    String[] roleNames = portlet.getRolesArray();
145    
146                    if (roleNames.length == 0) {
147                            return;
148                    }
149    
150                    long companyId = portlet.getCompanyId();
151                    String name = portlet.getPortletId();
152                    int scope = ResourceConstants.SCOPE_COMPANY;
153                    String primKey = String.valueOf(companyId);
154                    String actionId = ActionKeys.ADD_TO_PAGE;
155    
156                    List<String> actionIds = ResourceActionsUtil.getPortletResourceActions(
157                            name);
158    
159                    if (actionIds.contains(actionId)) {
160                            for (String roleName : roleNames) {
161                                    Role role = roleLocalService.getRole(companyId, roleName);
162    
163                                    if (resourceBlockLocalService.isSupported(name)) {
164                                            resourceBlockLocalService.addCompanyScopePermission(
165                                                    companyId, name, role.getRoleId(), actionId);
166                                    }
167                                    else {
168                                            resourcePermissionLocalService.addResourcePermission(
169                                                    companyId, name, scope, primKey, role.getRoleId(),
170                                                    actionId);
171                                    }
172                            }
173                    }
174    
175                    updatePortlet(
176                            companyId, portlet.getPortletId(), StringPool.BLANK,
177                            portlet.isActive());
178            }
179    
180            public void checkPortlets(long companyId)
181                    throws PortalException, SystemException {
182    
183                    List<Portlet> portlets = getPortlets(companyId);
184    
185                    for (Portlet portlet : portlets) {
186                            checkPortlet(portlet);
187                    }
188            }
189    
190            @Skip
191            public void clearCache() {
192    
193                    // Refresh security path to portlet id mapping for all portlets
194    
195                    _portletIdsByStrutsPath.clear();
196    
197                    // Refresh company portlets
198    
199                    portletLocalService.clearCompanyPortletsPool();
200            }
201    
202            @Clusterable
203            @Transactional(enabled = false)
204            public void clearCompanyPortletsPool() {
205                    _companyPortletsPool.clear();
206            }
207    
208            /**
209             * @deprecated {@link #clonePortlet(String)}
210             */
211            @Skip
212            public Portlet clonePortlet(long companyId, String portletId) {
213                    return clonePortlet(portletId);
214            }
215    
216            @Skip
217            public Portlet clonePortlet(String portletId) {
218                    Portlet portlet = getPortletById(portletId);
219    
220                    return (Portlet)portlet.clone();
221            }
222    
223            public void deletePortlet(long companyId, String portletId, long plid)
224                    throws PortalException, SystemException {
225    
226                    String rootPortletId = PortletConstants.getRootPortletId(portletId);
227    
228                    resourceLocalService.deleteResource(
229                            companyId, rootPortletId, ResourceConstants.SCOPE_INDIVIDUAL,
230                            PortletPermissionUtil.getPrimaryKey(plid, portletId));
231    
232                    List<PortletPreferences> portletPreferencesList =
233                            portletPreferencesLocalService.getPortletPreferences(
234                                    PortletKeys.PREFS_OWNER_TYPE_LAYOUT, plid, portletId);
235    
236                    Portlet portlet = getPortletById(companyId, portletId);
237    
238                    PortletLayoutListener portletLayoutListener = null;
239    
240                    if (portlet != null) {
241                            portletLayoutListener = portlet.getPortletLayoutListenerInstance();
242    
243                            PortletInstanceFactoryUtil.delete(portlet);
244                    }
245    
246                    for (PortletPreferences portletPreferences : portletPreferencesList) {
247                            if (portletLayoutListener != null) {
248                                    portletLayoutListener.onRemoveFromLayout(
249                                            portletPreferences.getPortletId(), plid);
250                            }
251    
252                            portletPreferencesLocalService.deletePortletPreferences(
253                                    portletPreferences.getPortletPreferencesId());
254                    }
255            }
256    
257            public void deletePortlets(long companyId, String[] portletIds, long plid)
258                    throws PortalException, SystemException {
259    
260                    for (String portletId : portletIds) {
261                            deletePortlet(companyId, portletId, plid);
262                    }
263            }
264    
265            public Portlet deployRemotePortlet(Portlet portlet, String categoryName)
266                    throws PortalException, SystemException {
267    
268                    return deployRemotePortlet(portlet, new String[] {categoryName});
269            }
270    
271            public Portlet deployRemotePortlet(Portlet portlet, String[] categoryNames)
272                    throws PortalException, SystemException {
273    
274                    Map<String, Portlet> portletsPool = _getPortletsPool();
275    
276                    portletsPool.put(portlet.getPortletId(), portlet);
277    
278                    PortletInstanceFactoryUtil.clear(portlet, false);
279    
280                    PortletConfigFactoryUtil.destroy(portlet);
281    
282                    clearCache();
283    
284                    List<String> portletActions =
285                            ResourceActionsUtil.getPortletResourceActions(
286                                    portlet.getPortletId());
287    
288                    resourceActionLocalService.checkResourceActions(
289                            portlet.getPortletId(), portletActions);
290    
291                    PortletCategory portletCategory = (PortletCategory)WebAppPool.get(
292                            portlet.getCompanyId(), WebKeys.PORTLET_CATEGORY);
293    
294                    if (portletCategory == null) {
295                            _log.error(
296                                    "Unable to register remote portlet for company " +
297                                            portlet.getCompanyId() + " because it does not exist");
298    
299                            return portlet;
300                    }
301    
302                    portletCategory.separate(portlet.getPortletId());
303    
304                    for (String categoryName : categoryNames) {
305                            PortletCategory newPortletCategory = new PortletCategory(
306                                    categoryName);
307    
308                            if (newPortletCategory.getParentCategory() == null) {
309                                    PortletCategory rootPortletCategory = new PortletCategory();
310    
311                                    rootPortletCategory.addCategory(newPortletCategory);
312                            }
313    
314                            Set<String> portletIds = newPortletCategory.getPortletIds();
315    
316                            portletIds.add(portlet.getPortletId());
317    
318                            portletCategory.merge(newPortletCategory.getRootCategory());
319                    }
320    
321                    checkPortlet(portlet);
322    
323                    return portlet;
324            }
325    
326            @Skip
327            public void destroyPortlet(Portlet portlet) {
328                    String portletId = portlet.getRootPortletId();
329    
330                    _friendlyURLMapperPortlets.remove(portletId);
331    
332                    Map<String, Portlet> portletsPool = _getPortletsPool();
333    
334                    portletsPool.remove(portletId);
335    
336                    PortletApp portletApp = portlet.getPortletApp();
337    
338                    if (portletApp != null) {
339                            _portletAppsPool.remove(portletApp.getServletContextName());
340                    }
341    
342                    clearCache();
343            }
344    
345            @Skip
346            public void destroyRemotePortlet(Portlet portlet) {
347                    destroyPortlet(portlet);
348            }
349    
350            @Skip
351            public List<CustomAttributesDisplay> getCustomAttributesDisplays() {
352                    List<CustomAttributesDisplay> customAttributesDisplays =
353                            new ArrayList<CustomAttributesDisplay>(
354                                    _customAttributesDisplayPortlets.size());
355    
356                    for (Map.Entry<String, Portlet> entry :
357                                    _customAttributesDisplayPortlets.entrySet()) {
358    
359                            Portlet portlet = entry.getValue();
360    
361                            List<CustomAttributesDisplay> portletCustomAttributesDisplays =
362                                    portlet.getCustomAttributesDisplayInstances();
363    
364                            if ((portletCustomAttributesDisplays != null) &&
365                                    !portletCustomAttributesDisplays.isEmpty()) {
366    
367                                    customAttributesDisplays.addAll(
368                                            portletCustomAttributesDisplays);
369                            }
370                    }
371    
372                    return customAttributesDisplays;
373            }
374    
375            @Skip
376            public PortletCategory getEARDisplay(String xml) throws SystemException {
377                    try {
378                            return _readLiferayDisplayXML(xml);
379                    }
380                    catch (Exception e) {
381                            throw new SystemException(e);
382                    }
383            }
384    
385            @Skip
386            public List<Portlet> getFriendlyURLMapperPortlets() {
387                    List<Portlet> portlets = new ArrayList<Portlet>(
388                            _friendlyURLMapperPortlets.size());
389    
390                    for (Map.Entry<String, Portlet> entry :
391                                    _friendlyURLMapperPortlets.entrySet()) {
392    
393                            Portlet portlet = entry.getValue();
394    
395                            FriendlyURLMapper friendlyURLMapper =
396                                    portlet.getFriendlyURLMapperInstance();
397    
398                            if (friendlyURLMapper != null) {
399                                    portlets.add(portlet);
400                            }
401                    }
402    
403                    return portlets;
404            }
405    
406            @Skip
407            public List<FriendlyURLMapper> getFriendlyURLMappers() {
408                    List<FriendlyURLMapper> friendlyURLMappers =
409                            new ArrayList<FriendlyURLMapper>(_friendlyURLMapperPortlets.size());
410    
411                    for (Map.Entry<String, Portlet> entry :
412                                    _friendlyURLMapperPortlets.entrySet()) {
413    
414                            Portlet portlet = entry.getValue();
415    
416                            FriendlyURLMapper friendlyURLMapper =
417                                    portlet.getFriendlyURLMapperInstance();
418    
419                            if (friendlyURLMapper != null) {
420                                    friendlyURLMappers.add(friendlyURLMapper);
421                            }
422                    }
423    
424                    return friendlyURLMappers;
425            }
426    
427            @Skip
428            public PortletApp getPortletApp(String servletContextName) {
429                    return _getPortletApp(servletContextName);
430            }
431    
432            @Skip
433            public Portlet getPortletById(long companyId, String portletId)
434                    throws SystemException {
435    
436                    portletId = PortalUtil.getJsSafePortletId(portletId);
437    
438                    Portlet portlet = null;
439    
440                    Map<String, Portlet> companyPortletsPool = _getPortletsPool(companyId);
441    
442                    String rootPortletId = PortletConstants.getRootPortletId(portletId);
443    
444                    if (portletId.equals(rootPortletId)) {
445                            portlet = companyPortletsPool.get(portletId);
446                    }
447                    else {
448                            portlet = companyPortletsPool.get(rootPortletId);
449    
450                            if (portlet != null) {
451                                    portlet = portlet.getClonedInstance(portletId);
452                            }
453                    }
454    
455                    if (portlet != null) {
456                            return portlet;
457                    }
458    
459                    if (portletId.equals(PortletKeys.LIFERAY_PORTAL)) {
460                            return portlet;
461                    }
462    
463                    if (_portletsPool.isEmpty()) {
464                            if (_log.isDebugEnabled()) {
465                                    _log.debug("No portlets are installed");
466                            }
467                    }
468                    else {
469                            if (_log.isInfoEnabled()) {
470                                    _log.info(
471                                            "Portlet not found for " + companyId + " " + portletId);
472                            }
473    
474                            portlet = new PortletImpl(CompanyConstants.SYSTEM, portletId);
475    
476                            portlet.setTimestamp(System.currentTimeMillis());
477    
478                            PortletApp portletApp = _getPortletApp(StringPool.BLANK);
479    
480                            portlet.setPortletApp(portletApp);
481    
482                            portlet.setPortletName(portletId);
483                            portlet.setDisplayName(portletId);
484                            portlet.setPortletClass(MVCPortlet.class.getName());
485    
486                            Map<String, String> initParams = portlet.getInitParams();
487    
488                            initParams.put("view-jsp", "/html/portal/undeployed_portlet.jsp");
489    
490                            Set<String> mimeTypePortletModes = new HashSet<String>();
491    
492                            mimeTypePortletModes.add(PortletMode.VIEW.toString().toLowerCase());
493    
494                            Map<String, Set<String>> portletModes = portlet.getPortletModes();
495    
496                            portletModes.put(ContentTypes.TEXT_HTML, mimeTypePortletModes);
497    
498                            Set<String> mimeTypeWindowStates = new HashSet<String>();
499    
500                            mimeTypeWindowStates.add(
501                                    WindowState.NORMAL.toString().toLowerCase());
502    
503                            Map<String, Set<String>> windowStates = portlet.getWindowStates();
504    
505                            windowStates.put(ContentTypes.TEXT_HTML, mimeTypeWindowStates);
506    
507                            portlet.setPortletInfo(
508                                    new PortletInfo(portletId, portletId, portletId, portletId));
509    
510                            if (PortletConstants.hasInstanceId(portletId)) {
511                                    portlet.setInstanceable(true);
512                            }
513    
514                            portlet.setActive(true);
515                            portlet.setUndeployedPortlet(true);
516                    }
517    
518                    return portlet;
519            }
520    
521            @Skip
522            public Portlet getPortletById(String portletId) {
523                    Map<String, Portlet> portletsPool = _getPortletsPool();
524    
525                    return portletsPool.get(portletId);
526            }
527    
528            @Skip
529            public Portlet getPortletByStrutsPath(long companyId, String strutsPath)
530                    throws SystemException {
531    
532                    return getPortletById(companyId, _getPortletId(strutsPath));
533            }
534    
535            @Skip
536            public List<Portlet> getPortlets() {
537                    Map<String, Portlet> portletsPool = _getPortletsPool();
538    
539                    return ListUtil.fromMapValues(portletsPool);
540            }
541    
542            @Skip
543            public List<Portlet> getPortlets(long companyId) throws SystemException {
544                    return getPortlets(companyId, true, true);
545            }
546    
547            @Skip
548            public List<Portlet> getPortlets(
549                            long companyId, boolean showSystem, boolean showPortal)
550                    throws SystemException {
551    
552                    Map<String, Portlet> portletsPool = _getPortletsPool(companyId);
553    
554                    List<Portlet> portlets = ListUtil.fromMapValues(portletsPool);
555    
556                    if (!showSystem || !showPortal) {
557                            Iterator<Portlet> itr = portlets.iterator();
558    
559                            while (itr.hasNext()) {
560                                    Portlet portlet = itr.next();
561    
562                                    if (showPortal &&
563                                            portlet.getPortletId().equals(PortletKeys.PORTAL)) {
564    
565                                    }
566                                    else if (!showPortal &&
567                                                     portlet.getPortletId().equals(PortletKeys.PORTAL)) {
568    
569                                            itr.remove();
570                                    }
571                                    else if (!showSystem && portlet.isSystem()) {
572                                            itr.remove();
573                                    }
574                            }
575                    }
576    
577                    return portlets;
578            }
579    
580            @Skip
581            public List<Portlet> getScopablePortlets() {
582                    Map<String, Portlet> portletsPool = _getPortletsPool();
583    
584                    List<Portlet> portlets = ListUtil.fromMapValues(portletsPool);
585    
586                    Iterator<Portlet> itr = portlets.iterator();
587    
588                    while (itr.hasNext()) {
589                            Portlet portlet = itr.next();
590    
591                            if (!portlet.isScopeable()) {
592                                    itr.remove();
593                            }
594                    }
595    
596                    return portlets;
597            }
598    
599            @Skip
600            public PortletCategory getWARDisplay(String servletContextName, String xml)
601                    throws SystemException {
602    
603                    try {
604                            return _readLiferayDisplayXML(servletContextName, xml);
605                    }
606                    catch (Exception e) {
607                            throw new SystemException(e);
608                    }
609            }
610    
611            @Skip
612            public boolean hasPortlet(long companyId, String portletId)
613                    throws SystemException {
614    
615                    portletId = PortalUtil.getJsSafePortletId(portletId);
616    
617                    Portlet portlet = null;
618    
619                    Map<String, Portlet> companyPortletsPool = _getPortletsPool(companyId);
620    
621                    String rootPortletId = PortletConstants.getRootPortletId(portletId);
622    
623                    if (portletId.equals(rootPortletId)) {
624                            portlet = companyPortletsPool.get(portletId);
625                    }
626                    else {
627                            portlet = companyPortletsPool.get(rootPortletId);
628                    }
629    
630                    if (portlet == null) {
631                            return false;
632                    }
633                    else {
634                            return true;
635                    }
636            }
637    
638            @Skip
639            public void initEAR(
640                    ServletContext servletContext, String[] xmls,
641                    PluginPackage pluginPackage) {
642    
643                    // Clear pools every time initEAR is called. See LEP-5452.
644    
645                    portletLocalService.clearCompanyPortletsPool();
646    
647                    _portletAppsPool.clear();
648                    _portletsPool.clear();
649                    _portletIdsByStrutsPath.clear();
650                    _friendlyURLMapperPortlets.clear();
651    
652                    Map<String, Portlet> portletsPool = _getPortletsPool();
653    
654                    try {
655                            Set<String> servletURLPatterns = _readWebXML(xmls[4]);
656    
657                            Set<String> portletIds = _readPortletXML(
658                                    servletContext, xmls[0], portletsPool, servletURLPatterns,
659                                    pluginPackage);
660    
661                            portletIds.addAll(
662                                    _readPortletXML(
663                                            servletContext, xmls[1], portletsPool, servletURLPatterns,
664                                            pluginPackage));
665    
666                            Set<String> liferayPortletIds = _readLiferayPortletXML(
667                                    xmls[2], portletsPool);
668    
669                            liferayPortletIds.addAll(
670                                    _readLiferayPortletXML(xmls[3], portletsPool));
671    
672                            // Check for missing entries in liferay-portlet.xml
673    
674                            for (String portletId : portletIds) {
675                                    if (_log.isWarnEnabled() &&
676                                            !liferayPortletIds.contains(portletId)) {
677    
678                                            _log.warn(
679                                                    "Portlet with the name " + portletId +
680                                                            " is described in portlet.xml but does not " +
681                                                                    "have a matching entry in liferay-portlet.xml");
682                                    }
683                            }
684    
685                            // Check for missing entries in portlet.xml
686    
687                            for (String portletId : liferayPortletIds) {
688                                    if (_log.isWarnEnabled() && !portletIds.contains(portletId)) {
689                                            _log.warn(
690                                                    "Portlet with the name " + portletId +
691                                                            " is described in liferay-portlet.xml but does " +
692                                                                    "not have a matching entry in portlet.xml");
693                                    }
694                            }
695    
696                            // Remove portlets that should not be included
697    
698                            Iterator<Map.Entry<String, Portlet>> portletPoolsItr =
699                                    portletsPool.entrySet().iterator();
700    
701                            while (portletPoolsItr.hasNext()) {
702                                    Map.Entry<String, Portlet> entry = portletPoolsItr.next();
703    
704                                    Portlet portletModel = entry.getValue();
705    
706                                    if (!portletModel.getPortletId().equals(PortletKeys.ADMIN) &&
707                                            !portletModel.getPortletId().equals(
708                                                    PortletKeys.MY_ACCOUNT) &&
709                                            !portletModel.isInclude()) {
710    
711                                            portletPoolsItr.remove();
712    
713                                            _friendlyURLMapperPortlets.remove(
714                                                    portletModel.getPortletId());
715                                    }
716                            }
717    
718                            // Sprite images
719    
720                            PortletApp portletApp = _getPortletApp(StringPool.BLANK);
721    
722                            _setSpriteImages(servletContext, portletApp, "/html/icons/");
723                    }
724                    catch (Exception e) {
725                            _log.error(e, e);
726                    }
727            }
728    
729            @Skip
730            public List<Portlet> initWAR(
731                    String servletContextName, ServletContext servletContext, String[] xmls,
732                    PluginPackage pluginPackage) {
733    
734                    List<Portlet> portlets = new ArrayList<Portlet>();
735    
736                    Map<String, Portlet> portletsPool = _getPortletsPool();
737    
738                    try {
739                            Set<String> servletURLPatterns = _readWebXML(xmls[3]);
740    
741                            Set<String> portletIds = _readPortletXML(
742                                    servletContextName, servletContext, xmls[0], portletsPool,
743                                    servletURLPatterns, pluginPackage);
744    
745                            portletIds.addAll(
746                                    _readPortletXML(
747                                            servletContextName, servletContext, xmls[1], portletsPool,
748                                            servletURLPatterns, pluginPackage));
749    
750                            Set<String> liferayPortletIds = _readLiferayPortletXML(
751                                    servletContextName, xmls[2], portletsPool);
752    
753                            // Check for missing entries in liferay-portlet.xml
754    
755                            for (String portletId : portletIds) {
756                                    if (_log.isWarnEnabled() &&
757                                            !liferayPortletIds.contains(portletId)) {
758    
759                                            _log.warn(
760                                                    "Portlet with the name " + portletId +
761                                                            " is described in portlet.xml but does not " +
762                                                                    "have a matching entry in liferay-portlet.xml");
763                                    }
764                            }
765    
766                            // Check for missing entries in portlet.xml
767    
768                            for (String portletId : liferayPortletIds) {
769                                    if (_log.isWarnEnabled() && !portletIds.contains(portletId)) {
770                                            _log.warn(
771                                                    "Portlet with the name " + portletId +
772                                                            " is described in liferay-portlet.xml but does " +
773                                                                    "not have a matching entry in portlet.xml");
774                                    }
775                            }
776    
777                            // Return the new portlets
778    
779                            for (String portletId : portletIds) {
780                                    Portlet portlet = _getPortletsPool().get(portletId);
781    
782                                    portlets.add(portlet);
783    
784                                    PortletInstanceFactoryUtil.clear(portlet);
785    
786                                    PortletConfigFactoryUtil.destroy(portlet);
787                                    PortletContextFactory.destroy(portlet);
788                            }
789    
790                            // Sprite images
791    
792                            PortletApp portletApp = _getPortletApp(servletContextName);
793    
794                            _setSpriteImages(servletContext, portletApp, "/icons/");
795                    }
796                    catch (Exception e) {
797                            _log.error(e, e);
798                    }
799    
800                    clearCache();
801    
802                    return portlets;
803            }
804    
805            public Map<String, Portlet> loadGetPortletsPool(long companyId)
806                    throws SystemException {
807    
808                    Map<String, Portlet> portletsPool =
809                            new ConcurrentHashMap<String, Portlet>();
810    
811                    Map<String, Portlet> parentPortletsPool = _getPortletsPool();
812    
813                    if (parentPortletsPool == null) {
814    
815                            // The Upgrade scripts sometimes try to access portlet preferences
816                            // before the portal's been initialized. Return an empty pool.
817    
818                            return portletsPool;
819                    }
820    
821                    for (Portlet portlet : parentPortletsPool.values()) {
822                            portlet = (Portlet)portlet.clone();
823    
824                            portlet.setCompanyId(companyId);
825    
826                            portletsPool.put(portlet.getPortletId(), portlet);
827                    }
828    
829                    List<Portlet> portlets = portletPersistence.findByCompanyId(companyId);
830    
831                    for (Portlet portlet : portlets) {
832                            Portlet portletModel = portletsPool.get(portlet.getPortletId());
833    
834                            // Portlet may be null if it exists in the database but its portlet
835                            // WAR is not yet loaded
836    
837                            if (portletModel != null) {
838                                    portletModel.setPluginPackage(portlet.getPluginPackage());
839                                    portletModel.setDefaultPluginSetting(
840                                            portlet.getDefaultPluginSetting());
841                                    portletModel.setRoles(portlet.getRoles());
842                                    portletModel.setActive(portlet.getActive());
843                            }
844                    }
845    
846                    return portletsPool;
847            }
848    
849            @Clusterable
850            @Transactional(enabled = false)
851            public void removeCompanyPortletsPool(long companyId) {
852                    _companyPortletsPool.remove(companyId);
853            }
854    
855            public Portlet updatePortlet(
856                            long companyId, String portletId, String roles, boolean active)
857                    throws SystemException {
858    
859                    portletId = PortalUtil.getJsSafePortletId(portletId);
860    
861                    Portlet portlet = portletPersistence.fetchByC_P(companyId, portletId);
862    
863                    if (portlet == null) {
864                            long id = counterLocalService.increment();
865    
866                            portlet = portletPersistence.create(id);
867    
868                            portlet.setCompanyId(companyId);
869                            portlet.setPortletId(portletId);
870                    }
871    
872                    portlet.setRoles(roles);
873                    portlet.setActive(active);
874    
875                    portletPersistence.update(portlet);
876    
877                    portlet = getPortletById(companyId, portletId);
878    
879                    portlet.setRoles(roles);
880                    portlet.setActive(active);
881    
882                    portletLocalService.removeCompanyPortletsPool(companyId);
883    
884                    return portlet;
885            }
886    
887            private PortletApp _getPortletApp(String servletContextName) {
888                    PortletApp portletApp = _portletAppsPool.get(servletContextName);
889    
890                    if (portletApp == null) {
891                            portletApp = new PortletAppImpl(servletContextName);
892    
893                            _portletAppsPool.put(servletContextName, portletApp);
894                    }
895    
896                    return portletApp;
897            }
898    
899            private String _getPortletId(String securityPath) {
900                    if (_portletIdsByStrutsPath.isEmpty()) {
901                            for (Portlet portlet : _getPortletsPool().values()) {
902                                    String strutsPath = portlet.getStrutsPath();
903    
904                                    if (_portletIdsByStrutsPath.containsKey(strutsPath)) {
905                                            _log.warn("Duplicate struts path " + strutsPath);
906                                    }
907    
908                                    _portletIdsByStrutsPath.put(strutsPath, portlet.getPortletId());
909                            }
910                    }
911    
912                    String portletId = _portletIdsByStrutsPath.get(securityPath);
913    
914                    if (Validator.isNull(portletId)) {
915                            for (String strutsPath : _portletIdsByStrutsPath.keySet()) {
916                                    if (securityPath.startsWith(
917                                                    strutsPath.concat(StringPool.SLASH))) {
918    
919                                            portletId = _portletIdsByStrutsPath.get(strutsPath);
920    
921                                            break;
922                                    }
923                            }
924                    }
925    
926                    if (Validator.isNull(portletId)) {
927                            _log.error(
928                                    "Struts path " + securityPath + " is not mapped to a portlet " +
929                                            "in liferay-portlet.xml");
930                    }
931    
932                    return portletId;
933            }
934    
935            private List<Portlet> _getPortletsByPortletName(
936                    String portletName, String servletContextName,
937                    Map<String, Portlet> portletsPool) {
938    
939                    List<Portlet> portlets = null;
940    
941                    int pos = portletName.indexOf(CharPool.STAR);
942    
943                    if (pos == -1) {
944                            portlets = new ArrayList<Portlet>();
945    
946                            String portletId = portletName;
947    
948                            if (Validator.isNotNull(servletContextName)) {
949                                    portletId =
950                                            portletId + PortletConstants.WAR_SEPARATOR +
951                                                    servletContextName;
952                            }
953    
954                            portletId = PortalUtil.getJsSafePortletId(portletId);
955    
956                            Portlet portlet = portletsPool.get(portletId);
957    
958                            if (portlet != null) {
959                                    portlets.add(portlet);
960                            }
961    
962                            return portlets;
963                    }
964    
965                    String portletNamePrefix = portletName.substring(0, pos);
966    
967                    portlets = _getPortletsByServletContextName(
968                            servletContextName, portletsPool);
969    
970                    Iterator<Portlet> itr = portlets.iterator();
971    
972                    while (itr.hasNext()) {
973                            Portlet portlet = itr.next();
974    
975                            String portletId = portlet.getPortletId();
976    
977                            if (!portletId.startsWith(portletNamePrefix)) {
978                                    itr.remove();
979                            }
980                    }
981    
982                    return portlets;
983            }
984    
985            private List<Portlet> _getPortletsByServletContextName(
986                    String servletContextName, Map<String, Portlet> portletsPool) {
987    
988                    List<Portlet> portlets = new ArrayList<Portlet>();
989    
990                    String servletContextNameSuffix = servletContextName;
991    
992                    if (Validator.isNotNull(servletContextName)) {
993                            servletContextNameSuffix = PortalUtil.getJsSafePortletId(
994                                    PortletConstants.WAR_SEPARATOR.concat(servletContextName));
995                    }
996    
997                    for (Map.Entry<String, Portlet> entry : portletsPool.entrySet()) {
998                            String portletId = entry.getKey();
999                            Portlet portlet = entry.getValue();
1000    
1001                            if (Validator.isNotNull(servletContextNameSuffix)) {
1002                                    if (portletId.endsWith(servletContextNameSuffix)) {
1003    
1004                                            portlets.add(portlet);
1005                                    }
1006                            }
1007                            else {
1008                                    if (!portletId.contains(PortletConstants.WAR_SEPARATOR)) {
1009                                            portlets.add(portlet);
1010                                    }
1011                            }
1012                    }
1013    
1014                    return portlets;
1015            }
1016    
1017            private Map<String, Portlet> _getPortletsPool() {
1018                    return _portletsPool;
1019            }
1020    
1021            private Map<String, Portlet> _getPortletsPool(long companyId)
1022                    throws SystemException {
1023    
1024                    Map<String, Portlet> portletsPool = _companyPortletsPool.get(companyId);
1025    
1026                    if (portletsPool == null) {
1027                            portletsPool = portletLocalService.loadGetPortletsPool(companyId);
1028    
1029                            _companyPortletsPool.put(companyId, portletsPool);
1030                    }
1031    
1032                    return portletsPool;
1033            }
1034    
1035            private void _readLiferayDisplay(
1036                    String servletContextName, Element element,
1037                    PortletCategory portletCategory, Set<String> portletIds) {
1038    
1039                    for (Element categoryElement : element.elements("category")) {
1040                            String name = categoryElement.attributeValue("name");
1041    
1042                            PortletCategory curPortletCategory = new PortletCategory(name);
1043    
1044                            portletCategory.addCategory(curPortletCategory);
1045    
1046                            Set<String> curPortletIds = curPortletCategory.getPortletIds();
1047    
1048                            for (Element portletElement : categoryElement.elements("portlet")) {
1049                                    String portletId = portletElement.attributeValue("id");
1050    
1051                                    if (Validator.isNotNull(servletContextName)) {
1052                                            portletId =
1053                                                    portletId + PortletConstants.WAR_SEPARATOR +
1054                                                            servletContextName;
1055                                    }
1056    
1057                                    portletId = PortalUtil.getJsSafePortletId(portletId);
1058    
1059                                    portletIds.add(portletId);
1060                                    curPortletIds.add(portletId);
1061                            }
1062    
1063                            _readLiferayDisplay(
1064                                    servletContextName, categoryElement, curPortletCategory,
1065                                    portletIds);
1066                    }
1067            }
1068    
1069            private PortletCategory _readLiferayDisplayXML(String xml)
1070                    throws Exception {
1071    
1072                    return _readLiferayDisplayXML(null, xml);
1073            }
1074    
1075            private PortletCategory _readLiferayDisplayXML(
1076                            String servletContextName, String xml)
1077                    throws Exception {
1078    
1079                    PortletCategory portletCategory = new PortletCategory();
1080    
1081                    if (xml == null) {
1082                            xml = ContentUtil.get(
1083                                    "com/liferay/portal/deploy/dependencies/liferay-display.xml");
1084                    }
1085    
1086                    Document document = SAXReaderUtil.read(xml, true);
1087    
1088                    Element rootElement = document.getRootElement();
1089    
1090                    Set<String> portletIds = new HashSet<String>();
1091    
1092                    _readLiferayDisplay(
1093                            servletContextName, rootElement, portletCategory, portletIds);
1094    
1095                    // Portlets that do not belong to any categories should default to the
1096                    // Undefined category
1097    
1098                    Set<String> undefinedPortletIds = new HashSet<String>();
1099    
1100                    for (Portlet portlet : _getPortletsPool().values()) {
1101                            String portletId = portlet.getPortletId();
1102    
1103                            PortletApp portletApp = portlet.getPortletApp();
1104    
1105                            if ((servletContextName != null) && portletApp.isWARFile() &&
1106                                    (portletId.endsWith(
1107                                            PortletConstants.WAR_SEPARATOR +
1108                                                    PortalUtil.getJsSafePortletId(servletContextName)) &&
1109                                     !portletIds.contains(portletId))) {
1110    
1111                                    undefinedPortletIds.add(portletId);
1112                            }
1113                            else if ((servletContextName == null) &&
1114                                             !portletApp.isWARFile() &&
1115                                             !portletId.contains(PortletConstants.WAR_SEPARATOR) &&
1116                                             !portletIds.contains(portletId)) {
1117    
1118                                    undefinedPortletIds.add(portletId);
1119                            }
1120                    }
1121    
1122                    if (!undefinedPortletIds.isEmpty()) {
1123                            PortletCategory undefinedCategory = new PortletCategory(
1124                                    "category.undefined");
1125    
1126                            portletCategory.addCategory(undefinedCategory);
1127    
1128                            undefinedCategory.getPortletIds().addAll(undefinedPortletIds);
1129                    }
1130    
1131                    return portletCategory;
1132            }
1133    
1134            private Set<String> _readLiferayPortletXML(
1135                            String xml, Map<String, Portlet> portletsPool)
1136                    throws Exception {
1137    
1138                    return _readLiferayPortletXML(StringPool.BLANK, xml, portletsPool);
1139            }
1140    
1141            private void _readLiferayPortletXML(
1142                    String servletContextName, Map<String, Portlet> portletsPool,
1143                    Set<String> liferayPortletIds, Map<String, String> roleMappers,
1144                    Element portletElement) {
1145    
1146                    String portletId = portletElement.elementText("portlet-name");
1147    
1148                    if (Validator.isNotNull(servletContextName)) {
1149                            portletId = portletId.concat(PortletConstants.WAR_SEPARATOR).concat(
1150                                    servletContextName);
1151                    }
1152    
1153                    portletId = PortalUtil.getJsSafePortletId(portletId);
1154    
1155                    if (_log.isDebugEnabled()) {
1156                            _log.debug("Reading portlet extension " + portletId);
1157                    }
1158    
1159                    liferayPortletIds.add(portletId);
1160    
1161                    Portlet portletModel = portletsPool.get(portletId);
1162    
1163                    if (portletModel == null) {
1164                            return;
1165                    }
1166    
1167                    portletModel.setIcon(
1168                            GetterUtil.getString(
1169                                    portletElement.elementText("icon"), portletModel.getIcon()));
1170                    portletModel.setVirtualPath(
1171                            GetterUtil.getString(
1172                                    portletElement.elementText("virtual-path"),
1173                                    portletModel.getVirtualPath()));
1174                    portletModel.setStrutsPath(
1175                            GetterUtil.getString(
1176                                    portletElement.elementText("struts-path"),
1177                                    portletModel.getStrutsPath()));
1178    
1179                    String strutsPath = portletModel.getStrutsPath();
1180    
1181                    if (Validator.isNotNull(strutsPath)) {
1182                            if (_portletIdsByStrutsPath.containsKey(strutsPath)) {
1183                                    String strutsPathPortletId = _portletIdsByStrutsPath.get(
1184                                            strutsPath);
1185    
1186                                    if (!strutsPathPortletId.equals(portletId)) {
1187                                            _log.warn("Duplicate struts path " + strutsPath);
1188                                    }
1189                            }
1190    
1191                            _portletIdsByStrutsPath.put(strutsPath, portletId);
1192                    }
1193    
1194                    portletModel.setParentStrutsPath(
1195                            GetterUtil.getString(
1196                                    portletElement.elementText("parent-struts-path"),
1197                                    portletModel.getParentStrutsPath()));
1198    
1199                    if (Validator.isNotNull(
1200                                    portletElement.elementText("configuration-path"))) {
1201    
1202                            _log.error(
1203                                    "The configuration-path element is no longer supported. Use " +
1204                                            "configuration-action-class instead.");
1205                    }
1206    
1207                    portletModel.setConfigurationActionClass(
1208                            GetterUtil.getString(
1209                                    portletElement.elementText("configuration-action-class"),
1210                                    portletModel.getConfigurationActionClass()));
1211    
1212                    List<String> indexerClasses = new ArrayList<String>();
1213    
1214                    for (Element indexerClassElement :
1215                                    portletElement.elements("indexer-class")) {
1216    
1217                            indexerClasses.add(indexerClassElement.getText());
1218                    }
1219    
1220                    portletModel.setIndexerClasses(indexerClasses);
1221    
1222                    portletModel.setOpenSearchClass(
1223                            GetterUtil.getString(
1224                                    portletElement.elementText("open-search-class"),
1225                                    portletModel.getOpenSearchClass()));
1226    
1227                    for (Element schedulerEntryElement :
1228                                    portletElement.elements("scheduler-entry")) {
1229    
1230                            SchedulerEntry schedulerEntry = new SchedulerEntryImpl();
1231    
1232                            schedulerEntry.setDescription(
1233                                    GetterUtil.getString(
1234                                            schedulerEntryElement.elementText(
1235                                                    "scheduler-description")));
1236                            schedulerEntry.setEventListenerClass(
1237                                    GetterUtil.getString(
1238                                            schedulerEntryElement.elementText(
1239                                                    "scheduler-event-listener-class"),
1240                                            schedulerEntry.getEventListenerClass()));
1241    
1242                            Element triggerElement = schedulerEntryElement.element("trigger");
1243    
1244                            Element cronElement = triggerElement.element("cron");
1245                            Element simpleElement = triggerElement.element("simple");
1246    
1247                            if (cronElement != null) {
1248                                    schedulerEntry.setTriggerType(TriggerType.CRON);
1249    
1250                                    Element propertyKeyElement = cronElement.element(
1251                                            "property-key");
1252    
1253                                    if (propertyKeyElement != null) {
1254                                            schedulerEntry.setPropertyKey(
1255                                                    propertyKeyElement.getTextTrim());
1256                                    }
1257                                    else {
1258                                            schedulerEntry.setTriggerValue(
1259                                                    cronElement.elementText("cron-trigger-value"));
1260                                    }
1261                            }
1262                            else if (simpleElement != null) {
1263                                    schedulerEntry.setTriggerType(TriggerType.SIMPLE);
1264    
1265                                    Element propertyKeyElement = simpleElement.element(
1266                                            "property-key");
1267    
1268                                    if (propertyKeyElement != null) {
1269                                            schedulerEntry.setPropertyKey(
1270                                                    propertyKeyElement.getTextTrim());
1271                                    }
1272                                    else {
1273                                            Element simpleTriggerValueElement = simpleElement.element(
1274                                                    "simple-trigger-value");
1275    
1276                                            schedulerEntry.setTriggerValue(
1277                                                    simpleTriggerValueElement.getTextTrim());
1278                                    }
1279    
1280                                    String timeUnit = GetterUtil.getString(
1281                                            simpleElement.elementText("time-unit"),
1282                                            TimeUnit.SECOND.getValue());
1283    
1284                                    schedulerEntry.setTimeUnit(
1285                                            TimeUnit.parse(timeUnit.toLowerCase()));
1286                            }
1287    
1288                            portletModel.addSchedulerEntry(schedulerEntry);
1289                    }
1290    
1291                    portletModel.setPortletURLClass(
1292                            GetterUtil.getString(
1293                                    portletElement.elementText("portlet-url-class"),
1294                                    portletModel.getPortletURLClass()));
1295    
1296                    portletModel.setFriendlyURLMapperClass(
1297                            GetterUtil.getString(
1298                                    portletElement.elementText("friendly-url-mapper-class"),
1299                                    portletModel.getFriendlyURLMapperClass()));
1300    
1301                    if (Validator.isNull(portletModel.getFriendlyURLMapperClass())) {
1302                            _friendlyURLMapperPortlets.remove(portletId);
1303                    }
1304                    else {
1305                            _friendlyURLMapperPortlets.put(portletId, portletModel);
1306                    }
1307    
1308                    portletModel.setFriendlyURLMapping(
1309                            GetterUtil.getString(
1310                                    portletElement.elementText("friendly-url-mapping"),
1311                                    portletModel.getFriendlyURLMapping()));
1312                    portletModel.setFriendlyURLRoutes(
1313                            GetterUtil.getString(
1314                                    portletElement.elementText("friendly-url-routes"),
1315                                    portletModel.getFriendlyURLRoutes()));
1316                    portletModel.setURLEncoderClass(
1317                            GetterUtil.getString(
1318                                    portletElement.elementText("url-encoder-class"),
1319                                    portletModel.getURLEncoderClass()));
1320                    portletModel.setPortletDataHandlerClass(
1321                            GetterUtil.getString(
1322                                    portletElement.elementText("portlet-data-handler-class"),
1323                                    portletModel.getPortletDataHandlerClass()));
1324                    portletModel.setPortletDisplayTemplateHandlerClass(
1325                            GetterUtil.getString(
1326                                    portletElement.elementText("portlet-display-template-handler"),
1327                                    portletModel.getPortletDisplayTemplateHandlerClass()));
1328                    portletModel.setPortletLayoutListenerClass(
1329                            GetterUtil.getString(
1330                                    portletElement.elementText("portlet-layout-listener-class"),
1331                                    portletModel.getPortletLayoutListenerClass()));
1332                    portletModel.setPollerProcessorClass(
1333                            GetterUtil.getString(
1334                                    portletElement.elementText("poller-processor-class"),
1335                                    portletModel.getPollerProcessorClass()));
1336                    portletModel.setPopMessageListenerClass(
1337                            GetterUtil.getString(
1338                                    portletElement.elementText("pop-message-listener-class"),
1339                                    portletModel.getPopMessageListenerClass()));
1340                    portletModel.setSocialActivityInterpreterClass(
1341                            GetterUtil.getString(
1342                                    portletElement.elementText("social-activity-interpreter-class"),
1343                                    portletModel.getSocialActivityInterpreterClass()));
1344                    portletModel.setSocialRequestInterpreterClass(
1345                            GetterUtil.getString(
1346                                    portletElement.elementText("social-request-interpreter-class"),
1347                                    portletModel.getSocialRequestInterpreterClass()));
1348                    portletModel.setWebDAVStorageToken(
1349                            GetterUtil.getString(
1350                                    portletElement.elementText("webdav-storage-token"),
1351                                    portletModel.getWebDAVStorageToken()));
1352                    portletModel.setWebDAVStorageClass(
1353                            GetterUtil.getString(
1354                                    portletElement.elementText("webdav-storage-class"),
1355                                    portletModel.getWebDAVStorageClass()));
1356                    portletModel.setXmlRpcMethodClass(
1357                            GetterUtil.getString(
1358                                    portletElement.elementText("xml-rpc-method-class"),
1359                                    portletModel.getXmlRpcMethodClass()));
1360                    portletModel.setControlPanelEntryCategory(
1361                            GetterUtil.getString(
1362                                    portletElement.elementText("control-panel-entry-category"),
1363                                    portletModel.getControlPanelEntryCategory()));
1364                    portletModel.setControlPanelEntryWeight(
1365                            GetterUtil.getDouble(
1366                                    portletElement.elementText("control-panel-entry-weight"),
1367                                    portletModel.getControlPanelEntryWeight()));
1368                    portletModel.setControlPanelEntryClass(
1369                            GetterUtil.getString(
1370                                    portletElement.elementText("control-panel-entry-class"),
1371                                    portletModel.getControlPanelEntryClass()));
1372    
1373                    List<String> assetRendererFactoryClasses = new ArrayList<String>();
1374    
1375                    for (Element assetRendererFactoryClassElement :
1376                                    portletElement.elements("asset-renderer-factory")) {
1377    
1378                            assetRendererFactoryClasses.add(
1379                                    assetRendererFactoryClassElement.getText());
1380                    }
1381    
1382                    portletModel.setAssetRendererFactoryClasses(
1383                            assetRendererFactoryClasses);
1384    
1385                    List<String> atomCollectionAdapterClasses = new ArrayList<String>();
1386    
1387                    for (Element atomCollectionAdapterClassElement :
1388                                    portletElement.elements("atom-collection-adapter")) {
1389    
1390                            atomCollectionAdapterClasses.add(
1391                                    atomCollectionAdapterClassElement.getText());
1392                    }
1393    
1394                    portletModel.setAtomCollectionAdapterClasses(
1395                            atomCollectionAdapterClasses);
1396    
1397                    List<String> customAttributesDisplayClasses = new ArrayList<String>();
1398    
1399                    for (Element customAttributesDisplayClassElement :
1400                                    portletElement.elements("custom-attributes-display")) {
1401    
1402                            customAttributesDisplayClasses.add(
1403                                    customAttributesDisplayClassElement.getText());
1404                    }
1405    
1406                    portletModel.setCustomAttributesDisplayClasses(
1407                            customAttributesDisplayClasses);
1408    
1409                    if (customAttributesDisplayClasses.isEmpty()) {
1410                            _customAttributesDisplayPortlets.remove(portletId);
1411                    }
1412                    else {
1413                            _customAttributesDisplayPortlets.put(portletId, portletModel);
1414                    }
1415    
1416                    portletModel.setPermissionPropagatorClass(
1417                            GetterUtil.getString(
1418                                    portletElement.elementText("permission-propagator"),
1419                                    portletModel.getPermissionPropagatorClass()));
1420    
1421                    List<String> trashHandlerClasses = new ArrayList<String>();
1422    
1423                    for (Element trashHandlerClassElement :
1424                                    portletElement.elements("trash-handler")) {
1425    
1426                            trashHandlerClasses.add(trashHandlerClassElement.getText());
1427                    }
1428    
1429                    portletModel.setTrashHandlerClasses(trashHandlerClasses);
1430    
1431                    List<String> workflowHandlerClasses = new ArrayList<String>();
1432    
1433                    for (Element workflowHandlerClassElement :
1434                                    portletElement.elements("workflow-handler")) {
1435    
1436                            workflowHandlerClasses.add(workflowHandlerClassElement.getText());
1437                    }
1438    
1439                    portletModel.setWorkflowHandlerClasses(workflowHandlerClasses);
1440    
1441                    portletModel.setPreferencesCompanyWide(
1442                            GetterUtil.getBoolean(
1443                                    portletElement.elementText("preferences-company-wide"),
1444                                    portletModel.isPreferencesCompanyWide()));
1445                    portletModel.setPreferencesUniquePerLayout(
1446                            GetterUtil.getBoolean(
1447                                    portletElement.elementText("preferences-unique-per-layout"),
1448                                    portletModel.isPreferencesUniquePerLayout()));
1449                    portletModel.setPreferencesOwnedByGroup(
1450                            GetterUtil.getBoolean(
1451                                    portletElement.elementText("preferences-owned-by-group"),
1452                                    portletModel.isPreferencesOwnedByGroup()));
1453                    portletModel.setUseDefaultTemplate(
1454                            GetterUtil.getBoolean(
1455                                    portletElement.elementText("use-default-template"),
1456                                    portletModel.isUseDefaultTemplate()));
1457                    portletModel.setShowPortletAccessDenied(
1458                            GetterUtil.getBoolean(
1459                                    portletElement.elementText("show-portlet-access-denied"),
1460                                    portletModel.isShowPortletAccessDenied()));
1461                    portletModel.setShowPortletInactive(
1462                            GetterUtil.getBoolean(
1463                                    portletElement.elementText("show-portlet-inactive"),
1464                                    portletModel.isShowPortletInactive()));
1465                    portletModel.setActionURLRedirect(
1466                            GetterUtil.getBoolean(
1467                                    portletElement.elementText("action-url-redirect"),
1468                                    portletModel.isActionURLRedirect()));
1469                    portletModel.setRestoreCurrentView(
1470                            GetterUtil.getBoolean(
1471                                    portletElement.elementText("restore-current-view"),
1472                                    portletModel.isRestoreCurrentView()));
1473                    portletModel.setMaximizeEdit(
1474                            GetterUtil.getBoolean(
1475                                    portletElement.elementText("maximize-edit"),
1476                                    portletModel.isMaximizeEdit()));
1477                    portletModel.setMaximizeHelp(
1478                            GetterUtil.getBoolean(
1479                                    portletElement.elementText("maximize-help"),
1480                                    portletModel.isMaximizeHelp()));
1481                    portletModel.setPopUpPrint(
1482                            GetterUtil.getBoolean(
1483                                    portletElement.elementText("pop-up-print"),
1484                                    portletModel.isPopUpPrint()));
1485                    portletModel.setLayoutCacheable(
1486                            GetterUtil.getBoolean(
1487                                    portletElement.elementText("layout-cacheable"),
1488                                    portletModel.isLayoutCacheable()));
1489                    portletModel.setInstanceable(
1490                            GetterUtil.getBoolean(
1491                                    portletElement.elementText("instanceable"),
1492                                    portletModel.isInstanceable()));
1493                    portletModel.setRemoteable(
1494                            GetterUtil.getBoolean(
1495                                    portletElement.elementText("remoteable"),
1496                                    portletModel.isRemoteable()));
1497                    portletModel.setScopeable(
1498                            GetterUtil.getBoolean(
1499                                    portletElement.elementText("scopeable"),
1500                                    portletModel.isScopeable()));
1501                    portletModel.setUserPrincipalStrategy(
1502                            GetterUtil.getString(
1503                                    portletElement.elementText("user-principal-strategy"),
1504                                    portletModel.getUserPrincipalStrategy()));
1505                    portletModel.setPrivateRequestAttributes(
1506                            GetterUtil.getBoolean(
1507                                    portletElement.elementText("private-request-attributes"),
1508                                    portletModel.isPrivateRequestAttributes()));
1509                    portletModel.setPrivateSessionAttributes(
1510                            GetterUtil.getBoolean(
1511                                    portletElement.elementText("private-session-attributes"),
1512                                    portletModel.isPrivateSessionAttributes()));
1513    
1514                    Element autopropagatedParametersElement = portletElement.element(
1515                            "autopropagated-parameters");
1516    
1517                    Set<String> autopropagatedParameters = new HashSet<String>();
1518    
1519                    if (autopropagatedParametersElement != null) {
1520                            String[] autopropagatedParametersArray = StringUtil.split(
1521                                    autopropagatedParametersElement.getText());
1522    
1523                            for (String autopropagatedParameter :
1524                                            autopropagatedParametersArray) {
1525    
1526                                    autopropagatedParameters.add(autopropagatedParameter);
1527                            }
1528                    }
1529    
1530                    portletModel.setAutopropagatedParameters(autopropagatedParameters);
1531    
1532                    portletModel.setActionTimeout(
1533                            GetterUtil.getInteger(
1534                                    portletElement.elementText("action-timeout"),
1535                                    portletModel.getActionTimeout()));
1536                    portletModel.setRenderTimeout(
1537                            GetterUtil.getInteger(
1538                                    portletElement.elementText("render-timeout"),
1539                                    portletModel.getRenderTimeout()));
1540                    portletModel.setRenderWeight(
1541                            GetterUtil.getInteger(
1542                                    portletElement.elementText("render-weight"),
1543                                    portletModel.getRenderWeight()));
1544                    portletModel.setAjaxable(
1545                            GetterUtil.getBoolean(
1546                                    portletElement.elementText("ajaxable"),
1547                                    portletModel.isAjaxable()));
1548    
1549                    List<String> headerPortalCssList = new ArrayList<String>();
1550    
1551                    for (Element headerPortalCssElement :
1552                                    portletElement.elements("header-portal-css")) {
1553    
1554                            headerPortalCssList.add(headerPortalCssElement.getText());
1555                    }
1556    
1557                    portletModel.setHeaderPortalCss(headerPortalCssList);
1558    
1559                    List<String> headerPortletCssList = new ArrayList<String>();
1560    
1561                    for (Element headerPortletCssElement :
1562                                    portletElement.elements("header-portlet-css")) {
1563    
1564                            headerPortletCssList.add(headerPortletCssElement.getText());
1565                    }
1566    
1567                    portletModel.setHeaderPortletCss(headerPortletCssList);
1568    
1569                    List<String> headerPortalJavaScriptList = new ArrayList<String>();
1570    
1571                    for (Element headerPortalJavaScriptElement :
1572                                    portletElement.elements("header-portal-javascript")) {
1573    
1574                            headerPortalJavaScriptList.add(
1575                                    headerPortalJavaScriptElement.getText());
1576                    }
1577    
1578                    portletModel.setHeaderPortalJavaScript(headerPortalJavaScriptList);
1579    
1580                    List<String> headerPortletJavaScriptList = new ArrayList<String>();
1581    
1582                    for (Element headerPortletJavaScriptElement :
1583                                    portletElement.elements("header-portlet-javascript")) {
1584    
1585                            headerPortletJavaScriptList.add(
1586                                    headerPortletJavaScriptElement.getText());
1587                    }
1588    
1589                    portletModel.setHeaderPortletJavaScript(headerPortletJavaScriptList);
1590    
1591                    List<String> footerPortalCssList = new ArrayList<String>();
1592    
1593                    for (Element footerPortalCssElement :
1594                                    portletElement.elements("footer-portal-css")) {
1595    
1596                            footerPortalCssList.add(footerPortalCssElement.getText());
1597                    }
1598    
1599                    portletModel.setFooterPortalCss(footerPortalCssList);
1600    
1601                    List<String> footerPortletCssList = new ArrayList<String>();
1602    
1603                    for (Element footerPortletCssElement :
1604                                    portletElement.elements("footer-portlet-css")) {
1605    
1606                            footerPortletCssList.add(footerPortletCssElement.getText());
1607                    }
1608    
1609                    portletModel.setFooterPortletCss(footerPortletCssList);
1610    
1611                    List<String> footerPortalJavaScriptList = new ArrayList<String>();
1612    
1613                    for (Element footerPortalJavaScriptElement :
1614                                    portletElement.elements("footer-portal-javascript")) {
1615    
1616                            footerPortalJavaScriptList.add(
1617                                    footerPortalJavaScriptElement.getText());
1618                    }
1619    
1620                    portletModel.setFooterPortalJavaScript(footerPortalJavaScriptList);
1621    
1622                    List<String> footerPortletJavaScriptList = new ArrayList<String>();
1623    
1624                    for (Element footerPortletJavaScriptElement :
1625                                    portletElement.elements("footer-portlet-javascript")) {
1626    
1627                            footerPortletJavaScriptList.add(
1628                                    footerPortletJavaScriptElement.getText());
1629                    }
1630    
1631                    portletModel.setFooterPortletJavaScript(footerPortletJavaScriptList);
1632    
1633                    portletModel.setCssClassWrapper(
1634                            GetterUtil.getString(
1635                                    portletElement.elementText("css-class-wrapper"),
1636                                    portletModel.getCssClassWrapper()));
1637                    portletModel.setFacebookIntegration(
1638                            GetterUtil.getString(
1639                                    portletElement.elementText("facebook-integration"),
1640                                    portletModel.getFacebookIntegration()));
1641                    portletModel.setAddDefaultResource(
1642                            GetterUtil.getBoolean(
1643                                    portletElement.elementText("add-default-resource"),
1644                                    portletModel.isAddDefaultResource()));
1645                    portletModel.setSystem(
1646                            GetterUtil.getBoolean(
1647                                    portletElement.elementText("system"), portletModel.isSystem()));
1648                    portletModel.setActive(
1649                            GetterUtil.getBoolean(
1650                                    portletElement.elementText("active"), portletModel.isActive()));
1651                    portletModel.setInclude(
1652                            GetterUtil.getBoolean(portletElement.elementText("include"),
1653                            portletModel.isInclude()));
1654    
1655                    if (Validator.isNull(servletContextName)) {
1656                            portletModel.setReady(true);
1657                    }
1658    
1659                    if (!portletModel.isAjaxable() &&
1660                            (portletModel.getRenderWeight() < 1)) {
1661    
1662                            portletModel.setRenderWeight(1);
1663                    }
1664    
1665                    portletModel.getRoleMappers().putAll(roleMappers);
1666                    portletModel.linkRoles();
1667            }
1668    
1669            private Set<String> _readLiferayPortletXML(
1670                            String servletContextName, String xml,
1671                            Map<String, Portlet> portletsPool)
1672                    throws Exception {
1673    
1674                    Set<String> liferayPortletIds = new HashSet<String>();
1675    
1676                    if (xml == null) {
1677                            return liferayPortletIds;
1678                    }
1679    
1680                    Document document = SAXReaderUtil.read(xml, true);
1681    
1682                    Element rootElement = document.getRootElement();
1683    
1684                    PortletApp portletApp = _getPortletApp(servletContextName);
1685    
1686                    Map<String, String> roleMappers = new HashMap<String, String>();
1687    
1688                    for (Element roleMapperElement : rootElement.elements("role-mapper")) {
1689                            String roleName = roleMapperElement.elementText("role-name");
1690                            String roleLink = roleMapperElement.elementText("role-link");
1691    
1692                            roleMappers.put(roleName, roleLink);
1693                    }
1694    
1695                    Map<String, String> customUserAttributes =
1696                            portletApp.getCustomUserAttributes();
1697    
1698                    for (Element customUserAttributeElement :
1699                                    rootElement.elements("custom-user-attribute")) {
1700    
1701                            String customClass = customUserAttributeElement.elementText(
1702                                    "custom-class");
1703    
1704                            for (Element nameElement :
1705                                            customUserAttributeElement.elements("name")) {
1706    
1707                                    String name = nameElement.getText();
1708    
1709                                    customUserAttributes.put(name, customClass);
1710                            }
1711                    }
1712    
1713                    for (Element portletElement : rootElement.elements("portlet")) {
1714                            _readLiferayPortletXML(
1715                                    servletContextName, portletsPool, liferayPortletIds,
1716                                    roleMappers, portletElement);
1717                    }
1718    
1719                    return liferayPortletIds;
1720            }
1721    
1722            private Set<String> _readPortletXML(
1723                            ServletContext servletContext, String xml,
1724                            Map<String, Portlet> portletsPool, Set<String> servletURLPatterns,
1725                            PluginPackage pluginPackage)
1726                    throws Exception {
1727    
1728                    return _readPortletXML(
1729                            StringPool.BLANK, servletContext, xml, portletsPool,
1730                            servletURLPatterns, pluginPackage);
1731            }
1732    
1733            private void _readPortletXML(
1734                    String servletContextName, Map<String, Portlet> portletsPool,
1735                    PluginPackage pluginPackage, PortletApp portletApp,
1736                    Set<String> portletIds, long timestamp, Element portletElement) {
1737    
1738                    String portletName = portletElement.elementText("portlet-name");
1739    
1740                    String portletId = portletName;
1741    
1742                    if (Validator.isNotNull(servletContextName)) {
1743                            portletId = portletId.concat(PortletConstants.WAR_SEPARATOR).concat(
1744                                    servletContextName);
1745                    }
1746    
1747                    portletId = PortalUtil.getJsSafePortletId(portletId);
1748    
1749                    if (_log.isDebugEnabled()) {
1750                            _log.debug("Reading portlet " + portletId);
1751                    }
1752    
1753                    portletIds.add(portletId);
1754    
1755                    Portlet portletModel = portletsPool.get(portletId);
1756    
1757                    if (portletModel == null) {
1758                            portletModel = new PortletImpl(CompanyConstants.SYSTEM, portletId);
1759    
1760                            portletsPool.put(portletId, portletModel);
1761                    }
1762    
1763                    portletModel.setTimestamp(timestamp);
1764    
1765                    portletModel.setPluginPackage(pluginPackage);
1766                    portletModel.setPortletApp(portletApp);
1767    
1768                    portletModel.setPortletName(portletName);
1769                    portletModel.setDisplayName(
1770                            GetterUtil.getString(
1771                                    portletElement.elementText("display-name"),
1772                                    portletModel.getDisplayName()));
1773                    portletModel.setPortletClass(
1774                            GetterUtil.getString(portletElement.elementText("portlet-class")));
1775    
1776                    Map<String, String> initParams = new HashMap<String, String>();
1777    
1778                    for (Element initParamElement : portletElement.elements("init-param")) {
1779                            initParams.put(
1780                                    initParamElement.elementText("name"),
1781                                    initParamElement.elementText("value"));
1782                    }
1783    
1784                    portletModel.setInitParams(initParams);
1785    
1786                    Element expirationCacheElement = portletElement.element(
1787                            "expiration-cache");
1788    
1789                    if (expirationCacheElement != null) {
1790                            portletModel.setExpCache(
1791                                    GetterUtil.getInteger(expirationCacheElement.getText()));
1792                    }
1793    
1794                    Map<String, Set<String>> portletModes =
1795                            new HashMap<String, Set<String>>();
1796                    Map<String, Set<String>> windowStates =
1797                            new HashMap<String, Set<String>>();
1798    
1799                    for (Element supportsElement : portletElement.elements("supports")) {
1800                            String mimeType = supportsElement.elementText("mime-type");
1801    
1802                            Set<String> mimeTypePortletModes = new HashSet<String>();
1803    
1804                            mimeTypePortletModes.add(PortletMode.VIEW.toString().toLowerCase());
1805    
1806                            for (Element portletModeElement :
1807                                            supportsElement.elements("portlet-mode")) {
1808    
1809                                    mimeTypePortletModes.add(
1810                                            portletModeElement.getTextTrim().toLowerCase());
1811                            }
1812    
1813                            portletModes.put(mimeType, mimeTypePortletModes);
1814    
1815                            Set<String> mimeTypeWindowStates = new HashSet<String>();
1816    
1817                            mimeTypeWindowStates.add(
1818                                    WindowState.NORMAL.toString().toLowerCase());
1819    
1820                            List<Element> windowStateElements = supportsElement.elements(
1821                                    "window-state");
1822    
1823                            if (windowStateElements.isEmpty()) {
1824                                    mimeTypeWindowStates.add(
1825                                            WindowState.MAXIMIZED.toString().toLowerCase());
1826                                    mimeTypeWindowStates.add(
1827                                            WindowState.MINIMIZED.toString().toLowerCase());
1828                                    mimeTypeWindowStates.add(
1829                                            LiferayWindowState.EXCLUSIVE.toString().toLowerCase());
1830                                    mimeTypeWindowStates.add(
1831                                            LiferayWindowState.POP_UP.toString().toLowerCase());
1832                            }
1833    
1834                            for (Element windowStateElement : windowStateElements) {
1835                                    mimeTypeWindowStates.add(
1836                                            windowStateElement.getTextTrim().toLowerCase());
1837                            }
1838    
1839                            windowStates.put(mimeType, mimeTypeWindowStates);
1840                    }
1841    
1842                    portletModel.setPortletModes(portletModes);
1843                    portletModel.setWindowStates(windowStates);
1844    
1845                    Set<String> supportedLocales = new HashSet<String>();
1846    
1847                    //supportedLocales.add(
1848                    //        LocaleUtil.toLanguageId(LocaleUtil.getDefault()));
1849    
1850                    for (Element supportedLocaleElement : portletElement.elements(
1851                                    "supported-locale")) {
1852    
1853                            String supportedLocale = supportedLocaleElement.getText();
1854    
1855                            supportedLocales.add(supportedLocale);
1856                    }
1857    
1858                    portletModel.setSupportedLocales(supportedLocales);
1859    
1860                    portletModel.setResourceBundle(
1861                            portletElement.elementText("resource-bundle"));
1862    
1863                    Element portletInfoElement = portletElement.element("portlet-info");
1864    
1865                    String portletInfoTitle = null;
1866                    String portletInfoShortTitle = null;
1867                    String portletInfoKeyWords = null;
1868                    String portletInfoDescription = null;
1869    
1870                    if (portletInfoElement != null) {
1871                            portletInfoTitle = portletInfoElement.elementText("title");
1872                            portletInfoShortTitle = portletInfoElement.elementText(
1873                                    "short-title");
1874                            portletInfoKeyWords = portletInfoElement.elementText("keywords");
1875                    }
1876    
1877                    PortletInfo portletInfo = new PortletInfo(
1878                            portletInfoTitle, portletInfoShortTitle, portletInfoKeyWords,
1879                            portletInfoDescription);
1880    
1881                    portletModel.setPortletInfo(portletInfo);
1882    
1883                    Element portletPreferencesElement = portletElement.element(
1884                            "portlet-preferences");
1885    
1886                    String defaultPreferences = null;
1887                    String preferencesValidator = null;
1888    
1889                    if (portletPreferencesElement != null) {
1890                            Element preferencesValidatorElement =
1891                                    portletPreferencesElement.element("preferences-validator");
1892    
1893                            if (preferencesValidatorElement != null) {
1894                                    preferencesValidator = preferencesValidatorElement.getText();
1895    
1896                                    portletPreferencesElement.remove(preferencesValidatorElement);
1897                            }
1898    
1899                            defaultPreferences = portletPreferencesElement.asXML();
1900                    }
1901    
1902                    portletModel.setDefaultPreferences(defaultPreferences);
1903                    portletModel.setPreferencesValidator(preferencesValidator);
1904    
1905                    if (!portletApp.isWARFile() &&
1906                            Validator.isNotNull(preferencesValidator) &&
1907                            PropsValues.PREFERENCE_VALIDATE_ON_STARTUP) {
1908    
1909                            try {
1910                                    PreferencesValidator preferencesValidatorObj =
1911                                            PortalUtil.getPreferencesValidator(portletModel);
1912    
1913                                    preferencesValidatorObj.validate(
1914                                            PortletPreferencesFactoryUtil.fromDefaultXML(
1915                                                    defaultPreferences));
1916                            }
1917                            catch (Exception e) {
1918                                    if (_log.isWarnEnabled()) {
1919                                            _log.warn(
1920                                                    "Portlet with the name " + portletId +
1921                                                            " does not have valid default preferences");
1922                                    }
1923                            }
1924                    }
1925    
1926                    Set<String> unlinkedRoles = new HashSet<String>();
1927    
1928                    for (Element roleElement :
1929                                    portletElement.elements("security-role-ref")) {
1930    
1931                            unlinkedRoles.add(roleElement.elementText("role-name"));
1932                    }
1933    
1934                    portletModel.setUnlinkedRoles(unlinkedRoles);
1935    
1936                    Set<QName> processingEvents = new HashSet<QName>();
1937    
1938                    for (Element supportedProcessingEventElement :
1939                                    portletElement.elements("supported-processing-event")) {
1940    
1941                            Element qNameElement = supportedProcessingEventElement.element(
1942                                    "qname");
1943                            Element nameElement = supportedProcessingEventElement.element(
1944                                    "name");
1945    
1946                            QName qName = PortletQNameUtil.getQName(
1947                                    qNameElement, nameElement, portletApp.getDefaultNamespace());
1948    
1949                            processingEvents.add(qName);
1950                    }
1951    
1952                    portletModel.setProcessingEvents(processingEvents);
1953    
1954                    Set<QName> publishingEvents = new HashSet<QName>();
1955    
1956                    for (Element supportedPublishingEventElement :
1957                                    portletElement.elements("supported-publishing-event")) {
1958    
1959                            Element qNameElement = supportedPublishingEventElement.element(
1960                                    "qname");
1961                            Element nameElement = supportedPublishingEventElement.element(
1962                                    "name");
1963    
1964                            QName qName = PortletQNameUtil.getQName(
1965                                    qNameElement, nameElement, portletApp.getDefaultNamespace());
1966    
1967                            publishingEvents.add(qName);
1968                    }
1969    
1970                    portletModel.setPublishingEvents(publishingEvents);
1971    
1972                    Set<PublicRenderParameter> publicRenderParameters =
1973                            new HashSet<PublicRenderParameter>();
1974    
1975                    for (Element supportedPublicRenderParameter :
1976                                    portletElement.elements("supported-public-render-parameter")) {
1977    
1978                            String identifier = supportedPublicRenderParameter.getTextTrim();
1979    
1980                            PublicRenderParameter publicRenderParameter =
1981                                    portletApp.getPublicRenderParameter(identifier);
1982    
1983                            if (publicRenderParameter == null) {
1984                                    _log.error(
1985                                            "Supported public render parameter references " +
1986                                                    "unnknown identifier " + identifier);
1987    
1988                                    continue;
1989                            }
1990    
1991                            publicRenderParameters.add(publicRenderParameter);
1992                    }
1993    
1994                    portletModel.setPublicRenderParameters(publicRenderParameters);
1995            }
1996    
1997            private Set<String> _readPortletXML(
1998                            String servletContextName, ServletContext servletContext,
1999                            String xml, Map<String, Portlet> portletsPool,
2000                            Set<String> servletURLPatterns, PluginPackage pluginPackage)
2001                    throws Exception {
2002    
2003                    Set<String> portletIds = new HashSet<String>();
2004    
2005                    if (xml == null) {
2006                            return portletIds;
2007                    }
2008    
2009                    Document document = SAXReaderUtil.read(
2010                            xml, PropsValues.PORTLET_XML_VALIDATE);
2011    
2012                    Element rootElement = document.getRootElement();
2013    
2014                    PortletApp portletApp = _getPortletApp(servletContextName);
2015    
2016                    portletApp.addServletURLPatterns(servletURLPatterns);
2017    
2018                    Set<String> userAttributes = portletApp.getUserAttributes();
2019    
2020                    for (Element userAttributeElement :
2021                                    rootElement.elements("user-attribute")) {
2022    
2023                            String name = userAttributeElement.elementText("name");
2024    
2025                            userAttributes.add(name);
2026                    }
2027    
2028                    String defaultNamespace = rootElement.elementText("default-namespace");
2029    
2030                    if (Validator.isNotNull(defaultNamespace)) {
2031                            portletApp.setDefaultNamespace(defaultNamespace);
2032                    }
2033    
2034                    for (Element eventDefinitionElement :
2035                                    rootElement.elements("event-definition")) {
2036    
2037                            Element qNameElement = eventDefinitionElement.element("qname");
2038                            Element nameElement = eventDefinitionElement.element("name");
2039                            String valueType = eventDefinitionElement.elementText("value-type");
2040    
2041                            QName qName = PortletQNameUtil.getQName(
2042                                    qNameElement, nameElement, portletApp.getDefaultNamespace());
2043    
2044                            EventDefinition eventDefinition = new EventDefinitionImpl(
2045                                    qName, valueType, portletApp);
2046    
2047                            portletApp.addEventDefinition(eventDefinition);
2048                    }
2049    
2050                    for (Element publicRenderParameterElement :
2051                                    rootElement.elements("public-render-parameter")) {
2052    
2053                            String identifier = publicRenderParameterElement.elementText(
2054                                    "identifier");
2055                            Element qNameElement = publicRenderParameterElement.element(
2056                                    "qname");
2057                            Element nameElement = publicRenderParameterElement.element("name");
2058    
2059                            QName qName = PortletQNameUtil.getQName(
2060                                    qNameElement, nameElement, portletApp.getDefaultNamespace());
2061    
2062                            PublicRenderParameter publicRenderParameter =
2063                                    new PublicRenderParameterImpl(identifier, qName, portletApp);
2064    
2065                            portletApp.addPublicRenderParameter(publicRenderParameter);
2066                    }
2067    
2068                    for (Element containerRuntimeOptionElement :
2069                                    rootElement.elements("container-runtime-option")) {
2070    
2071                            String name = GetterUtil.getString(
2072                                    containerRuntimeOptionElement.elementText("name"));
2073    
2074                            List<String> values = new ArrayList<String>();
2075    
2076                            for (Element valueElement :
2077                                            containerRuntimeOptionElement.elements("value")) {
2078    
2079                                    values.add(valueElement.getTextTrim());
2080                            }
2081    
2082                            Map<String, String[]> containerRuntimeOptions =
2083                                    portletApp.getContainerRuntimeOptions();
2084    
2085                            containerRuntimeOptions.put(
2086                                    name, values.toArray(new String[values.size()]));
2087    
2088                            if (name.equals(
2089                                            LiferayPortletConfig.RUNTIME_OPTION_PORTAL_CONTEXT) &&
2090                                    !values.isEmpty() && GetterUtil.getBoolean(values.get(0))) {
2091    
2092                                    portletApp.setWARFile(false);
2093                            }
2094                    }
2095    
2096                    long timestamp = ServletContextUtil.getLastModified(servletContext);
2097    
2098                    for (Element portletElement : rootElement.elements("portlet")) {
2099                            _readPortletXML(
2100                                    servletContextName, portletsPool, pluginPackage, portletApp,
2101                                    portletIds, timestamp, portletElement);
2102                    }
2103    
2104                    for (Element filterElement : rootElement.elements("filter")) {
2105                            String filterName = filterElement.elementText("filter-name");
2106                            String filterClass = filterElement.elementText("filter-class");
2107    
2108                            Set<String> lifecycles = new LinkedHashSet<String>();
2109    
2110                            for (Element lifecycleElement :
2111                                            filterElement.elements("lifecycle")) {
2112    
2113                                    lifecycles.add(lifecycleElement.getText());
2114                            }
2115    
2116                            Map<String, String> initParams = new HashMap<String, String>();
2117    
2118                            for (Element initParamElement :
2119                                            filterElement.elements("init-param")) {
2120    
2121                                    initParams.put(
2122                                            initParamElement.elementText("name"),
2123                                            initParamElement.elementText("value"));
2124                            }
2125    
2126                            PortletFilter portletFilter = new PortletFilterImpl(
2127                                    filterName, filterClass, lifecycles, initParams, portletApp);
2128    
2129                            portletApp.addPortletFilter(portletFilter);
2130                    }
2131    
2132                    for (Element filterMappingElement :
2133                                    rootElement.elements("filter-mapping")) {
2134    
2135                            String filterName = filterMappingElement.elementText("filter-name");
2136    
2137                            for (Element portletNameElement :
2138                                            filterMappingElement.elements("portlet-name")) {
2139    
2140                                    String portletName = portletNameElement.getTextTrim();
2141    
2142                                    PortletFilter portletFilter = portletApp.getPortletFilter(
2143                                            filterName);
2144    
2145                                    if (portletFilter == null) {
2146                                            _log.error(
2147                                                    "Filter mapping references unnknown filter name " +
2148                                                            filterName);
2149    
2150                                            continue;
2151                                    }
2152    
2153                                    List<Portlet> portletModels = _getPortletsByPortletName(
2154                                            portletName, servletContextName, portletsPool);
2155    
2156                                    if (portletModels.size() == 0) {
2157                                            _log.error(
2158                                                    "Filter mapping with filter name " + filterName +
2159                                                            " references unnknown portlet name " + portletName);
2160                                    }
2161    
2162                                    for (Portlet portletModel : portletModels) {
2163                                            portletModel.getPortletFilters().put(
2164                                                    filterName, portletFilter);
2165                                    }
2166                            }
2167                    }
2168    
2169                    for (Element listenerElement : rootElement.elements("listener")) {
2170                            String listenerClass = listenerElement.elementText(
2171                                    "listener-class");
2172    
2173                            PortletURLListener portletURLListener = new PortletURLListenerImpl(
2174                                    listenerClass, portletApp);
2175    
2176                            portletApp.addPortletURLListener(portletURLListener);
2177                    }
2178    
2179                    return portletIds;
2180            }
2181    
2182            private Set<String> _readWebXML(String xml) throws Exception {
2183                    Set<String> servletURLPatterns = new LinkedHashSet<String>();
2184    
2185                    if (xml == null) {
2186                            return servletURLPatterns;
2187                    }
2188    
2189                    Document document = SAXReaderUtil.read(xml);
2190    
2191                    Element rootElement = document.getRootElement();
2192    
2193                    for (Element servletMappingElement :
2194                                    rootElement.elements("servlet-mapping")) {
2195    
2196                            String urlPattern = servletMappingElement.elementText(
2197                                    "url-pattern");
2198    
2199                            servletURLPatterns.add(urlPattern);
2200                    }
2201    
2202                    return servletURLPatterns;
2203            }
2204    
2205            private void _setSpriteImages(
2206                            ServletContext servletContext, PortletApp portletApp,
2207                            String resourcePath)
2208                    throws Exception {
2209    
2210                    Set<String> resourcePaths = servletContext.getResourcePaths(
2211                            resourcePath);
2212    
2213                    if ((resourcePaths == null) || resourcePaths.isEmpty()) {
2214                            return;
2215                    }
2216    
2217                    List<URL> imageURLs = new ArrayList<URL>(resourcePaths.size());
2218    
2219                    for (String curResourcePath : resourcePaths) {
2220                            if (curResourcePath.endsWith(StringPool.SLASH)) {
2221                                    _setSpriteImages(servletContext, portletApp, curResourcePath);
2222                            }
2223                            else if (curResourcePath.endsWith(".png")) {
2224                                    URL imageURL = servletContext.getResource(curResourcePath);
2225    
2226                                    if (imageURL != null) {
2227                                            imageURLs.add(imageURL);
2228                                    }
2229                                    else {
2230                                            _log.error(
2231                                                    "Resource URL for " + curResourcePath + " is null");
2232                                    }
2233                            }
2234                    }
2235    
2236                    String spriteRootDirName = PropsValues.SPRITE_ROOT_DIR;
2237                    String spriteFileName = resourcePath.concat(
2238                            PropsValues.SPRITE_FILE_NAME);
2239                    String spritePropertiesFileName = resourcePath.concat(
2240                            PropsValues.SPRITE_PROPERTIES_FILE_NAME);
2241                    String rootPath = ServletContextUtil.getRootPath(servletContext);
2242    
2243                    Properties spriteProperties = SpriteProcessorUtil.generate(
2244                            servletContext, imageURLs, spriteRootDirName, spriteFileName,
2245                            spritePropertiesFileName, rootPath, 16, 16, 10240);
2246    
2247                    if (spriteProperties == null) {
2248                            return;
2249                    }
2250    
2251                    String contextPath = ContextPathUtil.getContextPath(servletContext);
2252    
2253                    spriteFileName = contextPath.concat(SpriteProcessor.PATH).concat(
2254                            spriteFileName);
2255    
2256                    portletApp.setSpriteImages(spriteFileName, spriteProperties);
2257            }
2258    
2259            private static Log _log = LogFactoryUtil.getLog(
2260                    PortletLocalServiceImpl.class);
2261    
2262            private static Map<Long, Map<String, Portlet>> _companyPortletsPool =
2263                    new ConcurrentHashMap<Long, Map<String, Portlet>>();
2264            private static Map<String, Portlet> _customAttributesDisplayPortlets =
2265                    new ConcurrentHashMap<String, Portlet>();
2266            private static Map<String, Portlet> _friendlyURLMapperPortlets =
2267                    new ConcurrentHashMap<String, Portlet>();
2268            private static Map<String, PortletApp> _portletAppsPool =
2269                    new ConcurrentHashMap<String, PortletApp>();
2270            private static Map<String, String> _portletIdsByStrutsPath =
2271                    new ConcurrentHashMap<String, String>();
2272            private static Map<String, Portlet> _portletsPool =
2273                    new ConcurrentHashMap<String, Portlet>();
2274    
2275    }