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