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