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