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    
1325                    List<String> stagedModelDataHandlerClasses = new ArrayList<String>();
1326    
1327                    for (Element stagedModelDataHandlerClassElement :
1328                                    portletElement.elements("staged-model-data-handler-class")) {
1329    
1330                            stagedModelDataHandlerClasses.add(
1331                                    stagedModelDataHandlerClassElement.getText());
1332                    }
1333    
1334                    portletModel.setStagedModelDataHandlerClasses(
1335                            stagedModelDataHandlerClasses);
1336    
1337                    portletModel.setPortletDisplayTemplateHandlerClass(
1338                            GetterUtil.getString(
1339                                    portletElement.elementText("portlet-display-template-handler"),
1340                                    portletModel.getPortletDisplayTemplateHandlerClass()));
1341                    portletModel.setPortletLayoutListenerClass(
1342                            GetterUtil.getString(
1343                                    portletElement.elementText("portlet-layout-listener-class"),
1344                                    portletModel.getPortletLayoutListenerClass()));
1345                    portletModel.setPollerProcessorClass(
1346                            GetterUtil.getString(
1347                                    portletElement.elementText("poller-processor-class"),
1348                                    portletModel.getPollerProcessorClass()));
1349                    portletModel.setPopMessageListenerClass(
1350                            GetterUtil.getString(
1351                                    portletElement.elementText("pop-message-listener-class"),
1352                                    portletModel.getPopMessageListenerClass()));
1353                    portletModel.setSocialActivityInterpreterClass(
1354                            GetterUtil.getString(
1355                                    portletElement.elementText("social-activity-interpreter-class"),
1356                                    portletModel.getSocialActivityInterpreterClass()));
1357                    portletModel.setSocialRequestInterpreterClass(
1358                            GetterUtil.getString(
1359                                    portletElement.elementText("social-request-interpreter-class"),
1360                                    portletModel.getSocialRequestInterpreterClass()));
1361                    portletModel.setWebDAVStorageToken(
1362                            GetterUtil.getString(
1363                                    portletElement.elementText("webdav-storage-token"),
1364                                    portletModel.getWebDAVStorageToken()));
1365                    portletModel.setWebDAVStorageClass(
1366                            GetterUtil.getString(
1367                                    portletElement.elementText("webdav-storage-class"),
1368                                    portletModel.getWebDAVStorageClass()));
1369                    portletModel.setXmlRpcMethodClass(
1370                            GetterUtil.getString(
1371                                    portletElement.elementText("xml-rpc-method-class"),
1372                                    portletModel.getXmlRpcMethodClass()));
1373                    portletModel.setControlPanelEntryCategory(
1374                            GetterUtil.getString(
1375                                    portletElement.elementText("control-panel-entry-category"),
1376                                    portletModel.getControlPanelEntryCategory()));
1377                    portletModel.setControlPanelEntryWeight(
1378                            GetterUtil.getDouble(
1379                                    portletElement.elementText("control-panel-entry-weight"),
1380                                    portletModel.getControlPanelEntryWeight()));
1381                    portletModel.setControlPanelEntryClass(
1382                            GetterUtil.getString(
1383                                    portletElement.elementText("control-panel-entry-class"),
1384                                    portletModel.getControlPanelEntryClass()));
1385    
1386                    List<String> assetRendererFactoryClasses = new ArrayList<String>();
1387    
1388                    for (Element assetRendererFactoryClassElement :
1389                                    portletElement.elements("asset-renderer-factory")) {
1390    
1391                            assetRendererFactoryClasses.add(
1392                                    assetRendererFactoryClassElement.getText());
1393                    }
1394    
1395                    portletModel.setAssetRendererFactoryClasses(
1396                            assetRendererFactoryClasses);
1397    
1398                    List<String> atomCollectionAdapterClasses = new ArrayList<String>();
1399    
1400                    for (Element atomCollectionAdapterClassElement :
1401                                    portletElement.elements("atom-collection-adapter")) {
1402    
1403                            atomCollectionAdapterClasses.add(
1404                                    atomCollectionAdapterClassElement.getText());
1405                    }
1406    
1407                    portletModel.setAtomCollectionAdapterClasses(
1408                            atomCollectionAdapterClasses);
1409    
1410                    List<String> customAttributesDisplayClasses = new ArrayList<String>();
1411    
1412                    for (Element customAttributesDisplayClassElement :
1413                                    portletElement.elements("custom-attributes-display")) {
1414    
1415                            customAttributesDisplayClasses.add(
1416                                    customAttributesDisplayClassElement.getText());
1417                    }
1418    
1419                    portletModel.setCustomAttributesDisplayClasses(
1420                            customAttributesDisplayClasses);
1421    
1422                    if (customAttributesDisplayClasses.isEmpty()) {
1423                            _customAttributesDisplayPortlets.remove(portletId);
1424                    }
1425                    else {
1426                            _customAttributesDisplayPortlets.put(portletId, portletModel);
1427                    }
1428    
1429                    portletModel.setPermissionPropagatorClass(
1430                            GetterUtil.getString(
1431                                    portletElement.elementText("permission-propagator"),
1432                                    portletModel.getPermissionPropagatorClass()));
1433    
1434                    List<String> trashHandlerClasses = new ArrayList<String>();
1435    
1436                    for (Element trashHandlerClassElement :
1437                                    portletElement.elements("trash-handler")) {
1438    
1439                            trashHandlerClasses.add(trashHandlerClassElement.getText());
1440                    }
1441    
1442                    portletModel.setTrashHandlerClasses(trashHandlerClasses);
1443    
1444                    List<String> workflowHandlerClasses = new ArrayList<String>();
1445    
1446                    for (Element workflowHandlerClassElement :
1447                                    portletElement.elements("workflow-handler")) {
1448    
1449                            workflowHandlerClasses.add(workflowHandlerClassElement.getText());
1450                    }
1451    
1452                    portletModel.setWorkflowHandlerClasses(workflowHandlerClasses);
1453    
1454                    portletModel.setPreferencesCompanyWide(
1455                            GetterUtil.getBoolean(
1456                                    portletElement.elementText("preferences-company-wide"),
1457                                    portletModel.isPreferencesCompanyWide()));
1458                    portletModel.setPreferencesUniquePerLayout(
1459                            GetterUtil.getBoolean(
1460                                    portletElement.elementText("preferences-unique-per-layout"),
1461                                    portletModel.isPreferencesUniquePerLayout()));
1462                    portletModel.setPreferencesOwnedByGroup(
1463                            GetterUtil.getBoolean(
1464                                    portletElement.elementText("preferences-owned-by-group"),
1465                                    portletModel.isPreferencesOwnedByGroup()));
1466                    portletModel.setUseDefaultTemplate(
1467                            GetterUtil.getBoolean(
1468                                    portletElement.elementText("use-default-template"),
1469                                    portletModel.isUseDefaultTemplate()));
1470                    portletModel.setShowPortletAccessDenied(
1471                            GetterUtil.getBoolean(
1472                                    portletElement.elementText("show-portlet-access-denied"),
1473                                    portletModel.isShowPortletAccessDenied()));
1474                    portletModel.setShowPortletInactive(
1475                            GetterUtil.getBoolean(
1476                                    portletElement.elementText("show-portlet-inactive"),
1477                                    portletModel.isShowPortletInactive()));
1478                    portletModel.setActionURLRedirect(
1479                            GetterUtil.getBoolean(
1480                                    portletElement.elementText("action-url-redirect"),
1481                                    portletModel.isActionURLRedirect()));
1482                    portletModel.setRestoreCurrentView(
1483                            GetterUtil.getBoolean(
1484                                    portletElement.elementText("restore-current-view"),
1485                                    portletModel.isRestoreCurrentView()));
1486                    portletModel.setMaximizeEdit(
1487                            GetterUtil.getBoolean(
1488                                    portletElement.elementText("maximize-edit"),
1489                                    portletModel.isMaximizeEdit()));
1490                    portletModel.setMaximizeHelp(
1491                            GetterUtil.getBoolean(
1492                                    portletElement.elementText("maximize-help"),
1493                                    portletModel.isMaximizeHelp()));
1494                    portletModel.setPopUpPrint(
1495                            GetterUtil.getBoolean(
1496                                    portletElement.elementText("pop-up-print"),
1497                                    portletModel.isPopUpPrint()));
1498                    portletModel.setLayoutCacheable(
1499                            GetterUtil.getBoolean(
1500                                    portletElement.elementText("layout-cacheable"),
1501                                    portletModel.isLayoutCacheable()));
1502                    portletModel.setInstanceable(
1503                            GetterUtil.getBoolean(
1504                                    portletElement.elementText("instanceable"),
1505                                    portletModel.isInstanceable()));
1506                    portletModel.setRemoteable(
1507                            GetterUtil.getBoolean(
1508                                    portletElement.elementText("remoteable"),
1509                                    portletModel.isRemoteable()));
1510                    portletModel.setScopeable(
1511                            GetterUtil.getBoolean(
1512                                    portletElement.elementText("scopeable"),
1513                                    portletModel.isScopeable()));
1514                    portletModel.setUserPrincipalStrategy(
1515                            GetterUtil.getString(
1516                                    portletElement.elementText("user-principal-strategy"),
1517                                    portletModel.getUserPrincipalStrategy()));
1518                    portletModel.setPrivateRequestAttributes(
1519                            GetterUtil.getBoolean(
1520                                    portletElement.elementText("private-request-attributes"),
1521                                    portletModel.isPrivateRequestAttributes()));
1522                    portletModel.setPrivateSessionAttributes(
1523                            GetterUtil.getBoolean(
1524                                    portletElement.elementText("private-session-attributes"),
1525                                    portletModel.isPrivateSessionAttributes()));
1526    
1527                    Element autopropagatedParametersElement = portletElement.element(
1528                            "autopropagated-parameters");
1529    
1530                    Set<String> autopropagatedParameters = new HashSet<String>();
1531    
1532                    if (autopropagatedParametersElement != null) {
1533                            String[] autopropagatedParametersArray = StringUtil.split(
1534                                    autopropagatedParametersElement.getText());
1535    
1536                            for (String autopropagatedParameter :
1537                                            autopropagatedParametersArray) {
1538    
1539                                    autopropagatedParameters.add(autopropagatedParameter);
1540                            }
1541                    }
1542    
1543                    portletModel.setAutopropagatedParameters(autopropagatedParameters);
1544    
1545                    portletModel.setActionTimeout(
1546                            GetterUtil.getInteger(
1547                                    portletElement.elementText("action-timeout"),
1548                                    portletModel.getActionTimeout()));
1549                    portletModel.setRenderTimeout(
1550                            GetterUtil.getInteger(
1551                                    portletElement.elementText("render-timeout"),
1552                                    portletModel.getRenderTimeout()));
1553                    portletModel.setRenderWeight(
1554                            GetterUtil.getInteger(
1555                                    portletElement.elementText("render-weight"),
1556                                    portletModel.getRenderWeight()));
1557                    portletModel.setAjaxable(
1558                            GetterUtil.getBoolean(
1559                                    portletElement.elementText("ajaxable"),
1560                                    portletModel.isAjaxable()));
1561    
1562                    List<String> headerPortalCssList = new ArrayList<String>();
1563    
1564                    for (Element headerPortalCssElement :
1565                                    portletElement.elements("header-portal-css")) {
1566    
1567                            headerPortalCssList.add(headerPortalCssElement.getText());
1568                    }
1569    
1570                    portletModel.setHeaderPortalCss(headerPortalCssList);
1571    
1572                    List<String> headerPortletCssList = new ArrayList<String>();
1573    
1574                    for (Element headerPortletCssElement :
1575                                    portletElement.elements("header-portlet-css")) {
1576    
1577                            headerPortletCssList.add(headerPortletCssElement.getText());
1578                    }
1579    
1580                    portletModel.setHeaderPortletCss(headerPortletCssList);
1581    
1582                    List<String> headerPortalJavaScriptList = new ArrayList<String>();
1583    
1584                    for (Element headerPortalJavaScriptElement :
1585                                    portletElement.elements("header-portal-javascript")) {
1586    
1587                            headerPortalJavaScriptList.add(
1588                                    headerPortalJavaScriptElement.getText());
1589                    }
1590    
1591                    portletModel.setHeaderPortalJavaScript(headerPortalJavaScriptList);
1592    
1593                    List<String> headerPortletJavaScriptList = new ArrayList<String>();
1594    
1595                    for (Element headerPortletJavaScriptElement :
1596                                    portletElement.elements("header-portlet-javascript")) {
1597    
1598                            headerPortletJavaScriptList.add(
1599                                    headerPortletJavaScriptElement.getText());
1600                    }
1601    
1602                    portletModel.setHeaderPortletJavaScript(headerPortletJavaScriptList);
1603    
1604                    List<String> footerPortalCssList = new ArrayList<String>();
1605    
1606                    for (Element footerPortalCssElement :
1607                                    portletElement.elements("footer-portal-css")) {
1608    
1609                            footerPortalCssList.add(footerPortalCssElement.getText());
1610                    }
1611    
1612                    portletModel.setFooterPortalCss(footerPortalCssList);
1613    
1614                    List<String> footerPortletCssList = new ArrayList<String>();
1615    
1616                    for (Element footerPortletCssElement :
1617                                    portletElement.elements("footer-portlet-css")) {
1618    
1619                            footerPortletCssList.add(footerPortletCssElement.getText());
1620                    }
1621    
1622                    portletModel.setFooterPortletCss(footerPortletCssList);
1623    
1624                    List<String> footerPortalJavaScriptList = new ArrayList<String>();
1625    
1626                    for (Element footerPortalJavaScriptElement :
1627                                    portletElement.elements("footer-portal-javascript")) {
1628    
1629                            footerPortalJavaScriptList.add(
1630                                    footerPortalJavaScriptElement.getText());
1631                    }
1632    
1633                    portletModel.setFooterPortalJavaScript(footerPortalJavaScriptList);
1634    
1635                    List<String> footerPortletJavaScriptList = new ArrayList<String>();
1636    
1637                    for (Element footerPortletJavaScriptElement :
1638                                    portletElement.elements("footer-portlet-javascript")) {
1639    
1640                            footerPortletJavaScriptList.add(
1641                                    footerPortletJavaScriptElement.getText());
1642                    }
1643    
1644                    portletModel.setFooterPortletJavaScript(footerPortletJavaScriptList);
1645    
1646                    portletModel.setCssClassWrapper(
1647                            GetterUtil.getString(
1648                                    portletElement.elementText("css-class-wrapper"),
1649                                    portletModel.getCssClassWrapper()));
1650                    portletModel.setFacebookIntegration(
1651                            GetterUtil.getString(
1652                                    portletElement.elementText("facebook-integration"),
1653                                    portletModel.getFacebookIntegration()));
1654                    portletModel.setAddDefaultResource(
1655                            GetterUtil.getBoolean(
1656                                    portletElement.elementText("add-default-resource"),
1657                                    portletModel.isAddDefaultResource()));
1658                    portletModel.setSystem(
1659                            GetterUtil.getBoolean(
1660                                    portletElement.elementText("system"), portletModel.isSystem()));
1661                    portletModel.setActive(
1662                            GetterUtil.getBoolean(
1663                                    portletElement.elementText("active"), portletModel.isActive()));
1664                    portletModel.setInclude(
1665                            GetterUtil.getBoolean(portletElement.elementText("include"),
1666                            portletModel.isInclude()));
1667    
1668                    if (Validator.isNull(servletContextName)) {
1669                            portletModel.setReady(true);
1670                    }
1671    
1672                    if (!portletModel.isAjaxable() &&
1673                            (portletModel.getRenderWeight() < 1)) {
1674    
1675                            portletModel.setRenderWeight(1);
1676                    }
1677    
1678                    portletModel.getRoleMappers().putAll(roleMappers);
1679                    portletModel.linkRoles();
1680            }
1681    
1682            private Set<String> _readLiferayPortletXML(
1683                            String servletContextName, String xml,
1684                            Map<String, Portlet> portletsPool)
1685                    throws Exception {
1686    
1687                    Set<String> liferayPortletIds = new HashSet<String>();
1688    
1689                    if (xml == null) {
1690                            return liferayPortletIds;
1691                    }
1692    
1693                    Document document = SAXReaderUtil.read(xml, true);
1694    
1695                    Element rootElement = document.getRootElement();
1696    
1697                    PortletApp portletApp = _getPortletApp(servletContextName);
1698    
1699                    Map<String, String> roleMappers = new HashMap<String, String>();
1700    
1701                    for (Element roleMapperElement : rootElement.elements("role-mapper")) {
1702                            String roleName = roleMapperElement.elementText("role-name");
1703                            String roleLink = roleMapperElement.elementText("role-link");
1704    
1705                            roleMappers.put(roleName, roleLink);
1706                    }
1707    
1708                    Map<String, String> customUserAttributes =
1709                            portletApp.getCustomUserAttributes();
1710    
1711                    for (Element customUserAttributeElement :
1712                                    rootElement.elements("custom-user-attribute")) {
1713    
1714                            String customClass = customUserAttributeElement.elementText(
1715                                    "custom-class");
1716    
1717                            for (Element nameElement :
1718                                            customUserAttributeElement.elements("name")) {
1719    
1720                                    String name = nameElement.getText();
1721    
1722                                    customUserAttributes.put(name, customClass);
1723                            }
1724                    }
1725    
1726                    for (Element portletElement : rootElement.elements("portlet")) {
1727                            _readLiferayPortletXML(
1728                                    servletContextName, portletsPool, liferayPortletIds,
1729                                    roleMappers, portletElement);
1730                    }
1731    
1732                    return liferayPortletIds;
1733            }
1734    
1735            private Set<String> _readPortletXML(
1736                            ServletContext servletContext, String xml,
1737                            Map<String, Portlet> portletsPool, Set<String> servletURLPatterns,
1738                            PluginPackage pluginPackage)
1739                    throws Exception {
1740    
1741                    return _readPortletXML(
1742                            StringPool.BLANK, servletContext, xml, portletsPool,
1743                            servletURLPatterns, pluginPackage);
1744            }
1745    
1746            private void _readPortletXML(
1747                    String servletContextName, Map<String, Portlet> portletsPool,
1748                    PluginPackage pluginPackage, PortletApp portletApp,
1749                    Set<String> portletIds, long timestamp, Element portletElement) {
1750    
1751                    String portletName = portletElement.elementText("portlet-name");
1752    
1753                    String portletId = portletName;
1754    
1755                    if (Validator.isNotNull(servletContextName)) {
1756                            portletId = portletId.concat(PortletConstants.WAR_SEPARATOR).concat(
1757                                    servletContextName);
1758                    }
1759    
1760                    portletId = PortalUtil.getJsSafePortletId(portletId);
1761    
1762                    if (_log.isDebugEnabled()) {
1763                            _log.debug("Reading portlet " + portletId);
1764                    }
1765    
1766                    portletIds.add(portletId);
1767    
1768                    Portlet portletModel = portletsPool.get(portletId);
1769    
1770                    if (portletModel == null) {
1771                            portletModel = new PortletImpl(CompanyConstants.SYSTEM, portletId);
1772    
1773                            portletsPool.put(portletId, portletModel);
1774                    }
1775    
1776                    portletModel.setTimestamp(timestamp);
1777    
1778                    portletModel.setPluginPackage(pluginPackage);
1779                    portletModel.setPortletApp(portletApp);
1780    
1781                    portletModel.setPortletName(portletName);
1782                    portletModel.setDisplayName(
1783                            GetterUtil.getString(
1784                                    portletElement.elementText("display-name"),
1785                                    portletModel.getDisplayName()));
1786                    portletModel.setPortletClass(
1787                            GetterUtil.getString(portletElement.elementText("portlet-class")));
1788    
1789                    Map<String, String> initParams = new HashMap<String, String>();
1790    
1791                    for (Element initParamElement : portletElement.elements("init-param")) {
1792                            initParams.put(
1793                                    initParamElement.elementText("name"),
1794                                    initParamElement.elementText("value"));
1795                    }
1796    
1797                    portletModel.setInitParams(initParams);
1798    
1799                    Element expirationCacheElement = portletElement.element(
1800                            "expiration-cache");
1801    
1802                    if (expirationCacheElement != null) {
1803                            portletModel.setExpCache(
1804                                    GetterUtil.getInteger(expirationCacheElement.getText()));
1805                    }
1806    
1807                    Map<String, Set<String>> portletModes =
1808                            new HashMap<String, Set<String>>();
1809                    Map<String, Set<String>> windowStates =
1810                            new HashMap<String, Set<String>>();
1811    
1812                    for (Element supportsElement : portletElement.elements("supports")) {
1813                            String mimeType = supportsElement.elementText("mime-type");
1814    
1815                            Set<String> mimeTypePortletModes = new HashSet<String>();
1816    
1817                            mimeTypePortletModes.add(PortletMode.VIEW.toString().toLowerCase());
1818    
1819                            for (Element portletModeElement :
1820                                            supportsElement.elements("portlet-mode")) {
1821    
1822                                    mimeTypePortletModes.add(
1823                                            portletModeElement.getTextTrim().toLowerCase());
1824                            }
1825    
1826                            portletModes.put(mimeType, mimeTypePortletModes);
1827    
1828                            Set<String> mimeTypeWindowStates = new HashSet<String>();
1829    
1830                            mimeTypeWindowStates.add(
1831                                    WindowState.NORMAL.toString().toLowerCase());
1832    
1833                            List<Element> windowStateElements = supportsElement.elements(
1834                                    "window-state");
1835    
1836                            if (windowStateElements.isEmpty()) {
1837                                    mimeTypeWindowStates.add(
1838                                            WindowState.MAXIMIZED.toString().toLowerCase());
1839                                    mimeTypeWindowStates.add(
1840                                            WindowState.MINIMIZED.toString().toLowerCase());
1841                                    mimeTypeWindowStates.add(
1842                                            LiferayWindowState.EXCLUSIVE.toString().toLowerCase());
1843                                    mimeTypeWindowStates.add(
1844                                            LiferayWindowState.POP_UP.toString().toLowerCase());
1845                            }
1846    
1847                            for (Element windowStateElement : windowStateElements) {
1848                                    mimeTypeWindowStates.add(
1849                                            windowStateElement.getTextTrim().toLowerCase());
1850                            }
1851    
1852                            windowStates.put(mimeType, mimeTypeWindowStates);
1853                    }
1854    
1855                    portletModel.setPortletModes(portletModes);
1856                    portletModel.setWindowStates(windowStates);
1857    
1858                    Set<String> supportedLocales = new HashSet<String>();
1859    
1860                    //supportedLocales.add(
1861                    //        LocaleUtil.toLanguageId(LocaleUtil.getDefault()));
1862    
1863                    for (Element supportedLocaleElement : portletElement.elements(
1864                                    "supported-locale")) {
1865    
1866                            String supportedLocale = supportedLocaleElement.getText();
1867    
1868                            supportedLocales.add(supportedLocale);
1869                    }
1870    
1871                    portletModel.setSupportedLocales(supportedLocales);
1872    
1873                    portletModel.setResourceBundle(
1874                            portletElement.elementText("resource-bundle"));
1875    
1876                    Element portletInfoElement = portletElement.element("portlet-info");
1877    
1878                    String portletInfoTitle = null;
1879                    String portletInfoShortTitle = null;
1880                    String portletInfoKeyWords = null;
1881                    String portletInfoDescription = null;
1882    
1883                    if (portletInfoElement != null) {
1884                            portletInfoTitle = portletInfoElement.elementText("title");
1885                            portletInfoShortTitle = portletInfoElement.elementText(
1886                                    "short-title");
1887                            portletInfoKeyWords = portletInfoElement.elementText("keywords");
1888                    }
1889    
1890                    PortletInfo portletInfo = new PortletInfo(
1891                            portletInfoTitle, portletInfoShortTitle, portletInfoKeyWords,
1892                            portletInfoDescription);
1893    
1894                    portletModel.setPortletInfo(portletInfo);
1895    
1896                    Element portletPreferencesElement = portletElement.element(
1897                            "portlet-preferences");
1898    
1899                    String defaultPreferences = null;
1900                    String preferencesValidator = null;
1901    
1902                    if (portletPreferencesElement != null) {
1903                            Element preferencesValidatorElement =
1904                                    portletPreferencesElement.element("preferences-validator");
1905    
1906                            if (preferencesValidatorElement != null) {
1907                                    preferencesValidator = preferencesValidatorElement.getText();
1908    
1909                                    portletPreferencesElement.remove(preferencesValidatorElement);
1910                            }
1911    
1912                            defaultPreferences = portletPreferencesElement.asXML();
1913                    }
1914    
1915                    portletModel.setDefaultPreferences(defaultPreferences);
1916                    portletModel.setPreferencesValidator(preferencesValidator);
1917    
1918                    if (!portletApp.isWARFile() &&
1919                            Validator.isNotNull(preferencesValidator) &&
1920                            PropsValues.PREFERENCE_VALIDATE_ON_STARTUP) {
1921    
1922                            try {
1923                                    PreferencesValidator preferencesValidatorObj =
1924                                            PortalUtil.getPreferencesValidator(portletModel);
1925    
1926                                    preferencesValidatorObj.validate(
1927                                            PortletPreferencesFactoryUtil.fromDefaultXML(
1928                                                    defaultPreferences));
1929                            }
1930                            catch (Exception e) {
1931                                    if (_log.isWarnEnabled()) {
1932                                            _log.warn(
1933                                                    "Portlet with the name " + portletId +
1934                                                            " does not have valid default preferences");
1935                                    }
1936                            }
1937                    }
1938    
1939                    Set<String> unlinkedRoles = new HashSet<String>();
1940    
1941                    for (Element roleElement :
1942                                    portletElement.elements("security-role-ref")) {
1943    
1944                            unlinkedRoles.add(roleElement.elementText("role-name"));
1945                    }
1946    
1947                    portletModel.setUnlinkedRoles(unlinkedRoles);
1948    
1949                    Set<QName> processingEvents = new HashSet<QName>();
1950    
1951                    for (Element supportedProcessingEventElement :
1952                                    portletElement.elements("supported-processing-event")) {
1953    
1954                            Element qNameElement = supportedProcessingEventElement.element(
1955                                    "qname");
1956                            Element nameElement = supportedProcessingEventElement.element(
1957                                    "name");
1958    
1959                            QName qName = PortletQNameUtil.getQName(
1960                                    qNameElement, nameElement, portletApp.getDefaultNamespace());
1961    
1962                            processingEvents.add(qName);
1963                    }
1964    
1965                    portletModel.setProcessingEvents(processingEvents);
1966    
1967                    Set<QName> publishingEvents = new HashSet<QName>();
1968    
1969                    for (Element supportedPublishingEventElement :
1970                                    portletElement.elements("supported-publishing-event")) {
1971    
1972                            Element qNameElement = supportedPublishingEventElement.element(
1973                                    "qname");
1974                            Element nameElement = supportedPublishingEventElement.element(
1975                                    "name");
1976    
1977                            QName qName = PortletQNameUtil.getQName(
1978                                    qNameElement, nameElement, portletApp.getDefaultNamespace());
1979    
1980                            publishingEvents.add(qName);
1981                    }
1982    
1983                    portletModel.setPublishingEvents(publishingEvents);
1984    
1985                    Set<PublicRenderParameter> publicRenderParameters =
1986                            new HashSet<PublicRenderParameter>();
1987    
1988                    for (Element supportedPublicRenderParameter :
1989                                    portletElement.elements("supported-public-render-parameter")) {
1990    
1991                            String identifier = supportedPublicRenderParameter.getTextTrim();
1992    
1993                            PublicRenderParameter publicRenderParameter =
1994                                    portletApp.getPublicRenderParameter(identifier);
1995    
1996                            if (publicRenderParameter == null) {
1997                                    _log.error(
1998                                            "Supported public render parameter references " +
1999                                                    "unnknown identifier " + identifier);
2000    
2001                                    continue;
2002                            }
2003    
2004                            publicRenderParameters.add(publicRenderParameter);
2005                    }
2006    
2007                    portletModel.setPublicRenderParameters(publicRenderParameters);
2008            }
2009    
2010            private Set<String> _readPortletXML(
2011                            String servletContextName, ServletContext servletContext,
2012                            String xml, Map<String, Portlet> portletsPool,
2013                            Set<String> servletURLPatterns, PluginPackage pluginPackage)
2014                    throws Exception {
2015    
2016                    Set<String> portletIds = new HashSet<String>();
2017    
2018                    if (xml == null) {
2019                            return portletIds;
2020                    }
2021    
2022                    Document document = SAXReaderUtil.read(
2023                            xml, PropsValues.PORTLET_XML_VALIDATE);
2024    
2025                    Element rootElement = document.getRootElement();
2026    
2027                    PortletApp portletApp = _getPortletApp(servletContextName);
2028    
2029                    portletApp.addServletURLPatterns(servletURLPatterns);
2030    
2031                    Set<String> userAttributes = portletApp.getUserAttributes();
2032    
2033                    for (Element userAttributeElement :
2034                                    rootElement.elements("user-attribute")) {
2035    
2036                            String name = userAttributeElement.elementText("name");
2037    
2038                            userAttributes.add(name);
2039                    }
2040    
2041                    String defaultNamespace = rootElement.elementText("default-namespace");
2042    
2043                    if (Validator.isNotNull(defaultNamespace)) {
2044                            portletApp.setDefaultNamespace(defaultNamespace);
2045                    }
2046    
2047                    for (Element eventDefinitionElement :
2048                                    rootElement.elements("event-definition")) {
2049    
2050                            Element qNameElement = eventDefinitionElement.element("qname");
2051                            Element nameElement = eventDefinitionElement.element("name");
2052                            String valueType = eventDefinitionElement.elementText("value-type");
2053    
2054                            QName qName = PortletQNameUtil.getQName(
2055                                    qNameElement, nameElement, portletApp.getDefaultNamespace());
2056    
2057                            EventDefinition eventDefinition = new EventDefinitionImpl(
2058                                    qName, valueType, portletApp);
2059    
2060                            portletApp.addEventDefinition(eventDefinition);
2061                    }
2062    
2063                    for (Element publicRenderParameterElement :
2064                                    rootElement.elements("public-render-parameter")) {
2065    
2066                            String identifier = publicRenderParameterElement.elementText(
2067                                    "identifier");
2068                            Element qNameElement = publicRenderParameterElement.element(
2069                                    "qname");
2070                            Element nameElement = publicRenderParameterElement.element("name");
2071    
2072                            QName qName = PortletQNameUtil.getQName(
2073                                    qNameElement, nameElement, portletApp.getDefaultNamespace());
2074    
2075                            PublicRenderParameter publicRenderParameter =
2076                                    new PublicRenderParameterImpl(identifier, qName, portletApp);
2077    
2078                            portletApp.addPublicRenderParameter(publicRenderParameter);
2079                    }
2080    
2081                    for (Element containerRuntimeOptionElement :
2082                                    rootElement.elements("container-runtime-option")) {
2083    
2084                            String name = GetterUtil.getString(
2085                                    containerRuntimeOptionElement.elementText("name"));
2086    
2087                            List<String> values = new ArrayList<String>();
2088    
2089                            for (Element valueElement :
2090                                            containerRuntimeOptionElement.elements("value")) {
2091    
2092                                    values.add(valueElement.getTextTrim());
2093                            }
2094    
2095                            Map<String, String[]> containerRuntimeOptions =
2096                                    portletApp.getContainerRuntimeOptions();
2097    
2098                            containerRuntimeOptions.put(
2099                                    name, values.toArray(new String[values.size()]));
2100    
2101                            if (name.equals(
2102                                            LiferayPortletConfig.RUNTIME_OPTION_PORTAL_CONTEXT) &&
2103                                    !values.isEmpty() && GetterUtil.getBoolean(values.get(0))) {
2104    
2105                                    portletApp.setWARFile(false);
2106                            }
2107                    }
2108    
2109                    long timestamp = ServletContextUtil.getLastModified(servletContext);
2110    
2111                    for (Element portletElement : rootElement.elements("portlet")) {
2112                            _readPortletXML(
2113                                    servletContextName, portletsPool, pluginPackage, portletApp,
2114                                    portletIds, timestamp, portletElement);
2115                    }
2116    
2117                    for (Element filterElement : rootElement.elements("filter")) {
2118                            String filterName = filterElement.elementText("filter-name");
2119                            String filterClass = filterElement.elementText("filter-class");
2120    
2121                            Set<String> lifecycles = new LinkedHashSet<String>();
2122    
2123                            for (Element lifecycleElement :
2124                                            filterElement.elements("lifecycle")) {
2125    
2126                                    lifecycles.add(lifecycleElement.getText());
2127                            }
2128    
2129                            Map<String, String> initParams = new HashMap<String, String>();
2130    
2131                            for (Element initParamElement :
2132                                            filterElement.elements("init-param")) {
2133    
2134                                    initParams.put(
2135                                            initParamElement.elementText("name"),
2136                                            initParamElement.elementText("value"));
2137                            }
2138    
2139                            PortletFilter portletFilter = new PortletFilterImpl(
2140                                    filterName, filterClass, lifecycles, initParams, portletApp);
2141    
2142                            portletApp.addPortletFilter(portletFilter);
2143                    }
2144    
2145                    for (Element filterMappingElement :
2146                                    rootElement.elements("filter-mapping")) {
2147    
2148                            String filterName = filterMappingElement.elementText("filter-name");
2149    
2150                            for (Element portletNameElement :
2151                                            filterMappingElement.elements("portlet-name")) {
2152    
2153                                    String portletName = portletNameElement.getTextTrim();
2154    
2155                                    PortletFilter portletFilter = portletApp.getPortletFilter(
2156                                            filterName);
2157    
2158                                    if (portletFilter == null) {
2159                                            _log.error(
2160                                                    "Filter mapping references unnknown filter name " +
2161                                                            filterName);
2162    
2163                                            continue;
2164                                    }
2165    
2166                                    List<Portlet> portletModels = _getPortletsByPortletName(
2167                                            portletName, servletContextName, portletsPool);
2168    
2169                                    if (portletModels.size() == 0) {
2170                                            _log.error(
2171                                                    "Filter mapping with filter name " + filterName +
2172                                                            " references unnknown portlet name " + portletName);
2173                                    }
2174    
2175                                    for (Portlet portletModel : portletModels) {
2176                                            portletModel.getPortletFilters().put(
2177                                                    filterName, portletFilter);
2178                                    }
2179                            }
2180                    }
2181    
2182                    for (Element listenerElement : rootElement.elements("listener")) {
2183                            String listenerClass = listenerElement.elementText(
2184                                    "listener-class");
2185    
2186                            PortletURLListener portletURLListener = new PortletURLListenerImpl(
2187                                    listenerClass, portletApp);
2188    
2189                            portletApp.addPortletURLListener(portletURLListener);
2190                    }
2191    
2192                    return portletIds;
2193            }
2194    
2195            private Set<String> _readWebXML(String xml) throws Exception {
2196                    Set<String> servletURLPatterns = new LinkedHashSet<String>();
2197    
2198                    if (xml == null) {
2199                            return servletURLPatterns;
2200                    }
2201    
2202                    Document document = SAXReaderUtil.read(xml);
2203    
2204                    Element rootElement = document.getRootElement();
2205    
2206                    for (Element servletMappingElement :
2207                                    rootElement.elements("servlet-mapping")) {
2208    
2209                            String urlPattern = servletMappingElement.elementText(
2210                                    "url-pattern");
2211    
2212                            servletURLPatterns.add(urlPattern);
2213                    }
2214    
2215                    return servletURLPatterns;
2216            }
2217    
2218            private void _setSpriteImages(
2219                            ServletContext servletContext, PortletApp portletApp,
2220                            String resourcePath)
2221                    throws Exception {
2222    
2223                    Set<String> resourcePaths = servletContext.getResourcePaths(
2224                            resourcePath);
2225    
2226                    if ((resourcePaths == null) || resourcePaths.isEmpty()) {
2227                            return;
2228                    }
2229    
2230                    List<URL> imageURLs = new ArrayList<URL>(resourcePaths.size());
2231    
2232                    for (String curResourcePath : resourcePaths) {
2233                            if (curResourcePath.endsWith(StringPool.SLASH)) {
2234                                    _setSpriteImages(servletContext, portletApp, curResourcePath);
2235                            }
2236                            else if (curResourcePath.endsWith(".png")) {
2237                                    URL imageURL = servletContext.getResource(curResourcePath);
2238    
2239                                    if (imageURL != null) {
2240                                            imageURLs.add(imageURL);
2241                                    }
2242                                    else {
2243                                            _log.error(
2244                                                    "Resource URL for " + curResourcePath + " is null");
2245                                    }
2246                            }
2247                    }
2248    
2249                    String spriteRootDirName = PropsValues.SPRITE_ROOT_DIR;
2250                    String spriteFileName = resourcePath.concat(
2251                            PropsValues.SPRITE_FILE_NAME);
2252                    String spritePropertiesFileName = resourcePath.concat(
2253                            PropsValues.SPRITE_PROPERTIES_FILE_NAME);
2254                    String rootPath = ServletContextUtil.getRootPath(servletContext);
2255    
2256                    Properties spriteProperties = SpriteProcessorUtil.generate(
2257                            servletContext, imageURLs, spriteRootDirName, spriteFileName,
2258                            spritePropertiesFileName, rootPath, 16, 16, 10240);
2259    
2260                    if (spriteProperties == null) {
2261                            return;
2262                    }
2263    
2264                    String contextPath = ContextPathUtil.getContextPath(servletContext);
2265    
2266                    spriteFileName = contextPath.concat(SpriteProcessor.PATH).concat(
2267                            spriteFileName);
2268    
2269                    portletApp.setSpriteImages(spriteFileName, spriteProperties);
2270            }
2271    
2272            private static Log _log = LogFactoryUtil.getLog(
2273                    PortletLocalServiceImpl.class);
2274    
2275            private static Map<Long, Map<String, Portlet>> _companyPortletsPool =
2276                    new ConcurrentHashMap<Long, Map<String, Portlet>>();
2277            private static Map<String, Portlet> _customAttributesDisplayPortlets =
2278                    new ConcurrentHashMap<String, Portlet>();
2279            private static Map<String, Portlet> _friendlyURLMapperPortlets =
2280                    new ConcurrentHashMap<String, Portlet>();
2281            private static Map<String, PortletApp> _portletAppsPool =
2282                    new ConcurrentHashMap<String, PortletApp>();
2283            private static Map<String, String> _portletIdsByStrutsPath =
2284                    new ConcurrentHashMap<String, String>();
2285            private static Map<String, Portlet> _portletsPool =
2286                    new ConcurrentHashMap<String, Portlet>();
2287    
2288    }