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