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