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