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