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