001    /**
002     * Copyright (c) 2000-2012 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 = _readLiferayPortletXML(
628                                    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                            for (String strutsPath : _portletIdsByStrutsPath.keySet()) {
877                                    if (securityPath.startsWith(
878                                                    strutsPath.concat(StringPool.SLASH))) {
879    
880                                            portletId = _portletIdsByStrutsPath.get(strutsPath);
881    
882                                            break;
883                                    }
884                            }
885                    }
886    
887                    if (Validator.isNull(portletId)) {
888                            _log.error(
889                                    "Struts path " + securityPath + " is not mapped to a portlet " +
890                                            "in liferay-portlet.xml");
891                    }
892    
893                    return portletId;
894            }
895    
896            private List<Portlet> _getPortletsByPortletName(
897                    String portletName, String servletContextName,
898                    Map<String, Portlet> portletsPool) {
899    
900                    List<Portlet> portlets = null;
901    
902                    int pos = portletName.indexOf(CharPool.STAR);
903    
904                    if (pos == -1) {
905                            portlets = new ArrayList<Portlet>();
906    
907                            String portletId = portletName;
908    
909                            if (Validator.isNotNull(servletContextName)) {
910                                    portletId =
911                                            portletId + PortletConstants.WAR_SEPARATOR +
912                                                    servletContextName;
913                            }
914    
915                            portletId = PortalUtil.getJsSafePortletId(portletId);
916    
917                            Portlet portlet = portletsPool.get(portletId);
918    
919                            if (portlet != null) {
920                                    portlets.add(portlet);
921                            }
922    
923                            return portlets;
924                    }
925    
926                    String portletNamePrefix = portletName.substring(0, pos);
927    
928                    portlets = _getPortletsByServletContextName(
929                            servletContextName, portletsPool);
930    
931                    Iterator<Portlet> itr = portlets.iterator();
932    
933                    while (itr.hasNext()) {
934                            Portlet portlet = itr.next();
935    
936                            String portletId = portlet.getPortletId();
937    
938                            if (!portletId.startsWith(portletNamePrefix)) {
939                                    itr.remove();
940                            }
941                    }
942    
943                    return portlets;
944            }
945    
946            private List<Portlet> _getPortletsByServletContextName(
947                    String servletContextName, Map<String, Portlet> portletsPool) {
948    
949                    List<Portlet> portlets = new ArrayList<Portlet>();
950    
951                    String servletContextNameSuffix = servletContextName;
952    
953                    if (Validator.isNotNull(servletContextName)) {
954                            servletContextNameSuffix = PortalUtil.getJsSafePortletId(
955                                    PortletConstants.WAR_SEPARATOR.concat(servletContextName));
956                    }
957    
958                    for (Map.Entry<String, Portlet> entry : portletsPool.entrySet()) {
959                            String portletId = entry.getKey();
960                            Portlet portlet = entry.getValue();
961    
962                            if (Validator.isNotNull(servletContextNameSuffix)) {
963                                    if (portletId.endsWith(servletContextNameSuffix)) {
964    
965                                            portlets.add(portlet);
966                                    }
967                            }
968                            else {
969                                    if (!portletId.contains(PortletConstants.WAR_SEPARATOR)) {
970                                            portlets.add(portlet);
971                                    }
972                            }
973                    }
974    
975                    return portlets;
976            }
977    
978            private Map<String, Portlet> _getPortletsPool() {
979                    return _portletsPool;
980            }
981    
982            private Map<String, Portlet> _getPortletsPool(long companyId)
983                    throws SystemException {
984    
985                    Map<String, Portlet> portletsPool = _companyPortletsPool.get(companyId);
986    
987                    if (portletsPool == null) {
988                            portletsPool = portletLocalService.loadGetPortletsPool(companyId);
989    
990                            _companyPortletsPool.put(companyId, portletsPool);
991                    }
992    
993                    return portletsPool;
994            }
995    
996            private void _readLiferayDisplay(
997                    String servletContextName, Element element,
998                    PortletCategory portletCategory, Set<String> portletIds) {
999    
1000                    for (Element categoryElement : element.elements("category")) {
1001                            String name = categoryElement.attributeValue("name");
1002    
1003                            PortletCategory curPortletCategory = new PortletCategory(name);
1004    
1005                            portletCategory.addCategory(curPortletCategory);
1006    
1007                            Set<String> curPortletIds = curPortletCategory.getPortletIds();
1008    
1009                            for (Element portletElement : categoryElement.elements("portlet")) {
1010                                    String portletId = portletElement.attributeValue("id");
1011    
1012                                    if (Validator.isNotNull(servletContextName)) {
1013                                            portletId =
1014                                                    portletId + PortletConstants.WAR_SEPARATOR +
1015                                                            servletContextName;
1016                                    }
1017    
1018                                    portletId = PortalUtil.getJsSafePortletId(portletId);
1019    
1020                                    portletIds.add(portletId);
1021                                    curPortletIds.add(portletId);
1022                            }
1023    
1024                            _readLiferayDisplay(
1025                                    servletContextName, categoryElement, curPortletCategory,
1026                                    portletIds);
1027                    }
1028            }
1029    
1030            private PortletCategory _readLiferayDisplayXML(String xml)
1031                    throws Exception {
1032    
1033                    return _readLiferayDisplayXML(null, xml);
1034            }
1035    
1036            private PortletCategory _readLiferayDisplayXML(
1037                            String servletContextName, String xml)
1038                    throws Exception {
1039    
1040                    PortletCategory portletCategory = new PortletCategory();
1041    
1042                    if (xml == null) {
1043                            xml = ContentUtil.get(
1044                                    "com/liferay/portal/deploy/dependencies/liferay-display.xml");
1045                    }
1046    
1047                    Document document = SAXReaderUtil.read(xml, true);
1048    
1049                    Element rootElement = document.getRootElement();
1050    
1051                    Set<String> portletIds = new HashSet<String>();
1052    
1053                    _readLiferayDisplay(
1054                            servletContextName, rootElement, portletCategory, portletIds);
1055    
1056                    // Portlets that do not belong to any categories should default to the
1057                    // Undefined category
1058    
1059                    Set<String> undefinedPortletIds = new HashSet<String>();
1060    
1061                    for (Portlet portlet : _getPortletsPool().values()) {
1062                            String portletId = portlet.getPortletId();
1063    
1064                            PortletApp portletApp = portlet.getPortletApp();
1065    
1066                            if ((servletContextName != null) && (portletApp.isWARFile()) &&
1067                                    (portletId.endsWith(
1068                                            PortletConstants.WAR_SEPARATOR +
1069                                                    PortalUtil.getJsSafePortletId(servletContextName)) &&
1070                                     (!portletIds.contains(portletId)))) {
1071    
1072                                    undefinedPortletIds.add(portletId);
1073                            }
1074                            else if ((servletContextName == null) &&
1075                                             (!portletApp.isWARFile()) &&
1076                                             (portletId.indexOf(
1077                                                    PortletConstants.WAR_SEPARATOR) == -1) &&
1078                                             (!portletIds.contains(portletId))) {
1079    
1080                                    undefinedPortletIds.add(portletId);
1081                            }
1082                    }
1083    
1084                    if (!undefinedPortletIds.isEmpty()) {
1085                            PortletCategory undefinedCategory = new PortletCategory(
1086                                    "category.undefined");
1087    
1088                            portletCategory.addCategory(undefinedCategory);
1089    
1090                            undefinedCategory.getPortletIds().addAll(undefinedPortletIds);
1091                    }
1092    
1093                    return portletCategory;
1094            }
1095    
1096            private Set<String> _readLiferayPortletXML(
1097                            String xml, Map<String, Portlet> portletsPool)
1098                    throws Exception {
1099    
1100                    return _readLiferayPortletXML(StringPool.BLANK, xml, portletsPool);
1101            }
1102    
1103            private void _readLiferayPortletXML(
1104                    String servletContextName, Map<String, Portlet> portletsPool,
1105                    Set<String> liferayPortletIds, Map<String, String> roleMappers,
1106                    Element portletElement) {
1107    
1108                    String portletId = portletElement.elementText("portlet-name");
1109    
1110                    if (Validator.isNotNull(servletContextName)) {
1111                            portletId = portletId.concat(PortletConstants.WAR_SEPARATOR).concat(
1112                                    servletContextName);
1113                    }
1114    
1115                    portletId = PortalUtil.getJsSafePortletId(portletId);
1116    
1117                    if (_log.isDebugEnabled()) {
1118                            _log.debug("Reading portlet extension " + portletId);
1119                    }
1120    
1121                    liferayPortletIds.add(portletId);
1122    
1123                    Portlet portletModel = portletsPool.get(portletId);
1124    
1125                    if (portletModel == null) {
1126                            return;
1127                    }
1128    
1129                    portletModel.setIcon(
1130                            GetterUtil.getString(
1131                                    portletElement.elementText("icon"), portletModel.getIcon()));
1132                    portletModel.setVirtualPath(
1133                            GetterUtil.getString(
1134                                    portletElement.elementText("virtual-path"),
1135                                    portletModel.getVirtualPath()));
1136                    portletModel.setStrutsPath(
1137                            GetterUtil.getString(
1138                                    portletElement.elementText("struts-path"),
1139                                    portletModel.getStrutsPath()));
1140    
1141                    String strutsPath = portletModel.getStrutsPath();
1142    
1143                    if (Validator.isNotNull(strutsPath)) {
1144                            if (_portletIdsByStrutsPath.containsKey(strutsPath)) {
1145                                    _log.warn("Duplicate struts path " + strutsPath);
1146                            }
1147    
1148                            _portletIdsByStrutsPath.put(strutsPath, portletId);
1149                    }
1150    
1151                    portletModel.setParentStrutsPath(
1152                            GetterUtil.getString(
1153                                    portletElement.elementText("parent-struts-path"),
1154                                    portletModel.getParentStrutsPath()));
1155    
1156                    if (Validator.isNotNull(
1157                                    portletElement.elementText("configuration-path"))) {
1158    
1159                            _log.error(
1160                                    "The configuration-path element is no longer supported. Use " +
1161                                            "configuration-action-class instead.");
1162                    }
1163    
1164                    portletModel.setConfigurationActionClass(
1165                            GetterUtil.getString(
1166                                    portletElement.elementText("configuration-action-class"),
1167                                    portletModel.getConfigurationActionClass()));
1168    
1169                    List<String> indexerClasses = portletModel.getIndexerClasses();
1170    
1171                    for (Element indexerClassElement :
1172                                    portletElement.elements("indexer-class")) {
1173    
1174                            indexerClasses.add(indexerClassElement.getText());
1175                    }
1176    
1177                    portletModel.setOpenSearchClass(
1178                            GetterUtil.getString(
1179                                    portletElement.elementText("open-search-class"),
1180                                    portletModel.getOpenSearchClass()));
1181    
1182                    for (Element schedulerEntryElement :
1183                                    portletElement.elements("scheduler-entry")) {
1184    
1185                            SchedulerEntry schedulerEntry = new SchedulerEntryImpl();
1186    
1187                            schedulerEntry.setContextPath(portletModel.getContextPath());
1188                            schedulerEntry.setDescription(
1189                                    GetterUtil.getString(
1190                                            schedulerEntryElement.elementText(
1191                                                    "scheduler-description")));
1192                            schedulerEntry.setEventListenerClass(
1193                                    GetterUtil.getString(
1194                                            schedulerEntryElement.elementText(
1195                                                    "scheduler-event-listener-class"),
1196                                            schedulerEntry.getEventListenerClass()));
1197    
1198                            Element triggerElement = schedulerEntryElement.element("trigger");
1199    
1200                            Element cronElement = triggerElement.element("cron");
1201                            Element simpleElement = triggerElement.element("simple");
1202    
1203                            if (cronElement != null) {
1204                                    schedulerEntry.setTriggerType(TriggerType.CRON);
1205    
1206                                    Element propertyKeyElement = cronElement.element(
1207                                            "property-key");
1208    
1209                                    if (propertyKeyElement != null) {
1210                                            schedulerEntry.setPropertyKey(
1211                                                    propertyKeyElement.getTextTrim());
1212                                    }
1213                                    else {
1214                                            schedulerEntry.setTriggerValue(
1215                                                    cronElement.elementText("cron-trigger-value"));
1216                                    }
1217                            }
1218                            else if (simpleElement != null) {
1219                                    schedulerEntry.setTriggerType(TriggerType.SIMPLE);
1220    
1221                                    Element propertyKeyElement = simpleElement.element(
1222                                            "property-key");
1223    
1224                                    if (propertyKeyElement != null) {
1225                                            schedulerEntry.setPropertyKey(
1226                                                    propertyKeyElement.getTextTrim());
1227                                    }
1228                                    else {
1229                                            Element simpleTriggerValueElement = simpleElement.element(
1230                                                    "simple-trigger-value");
1231    
1232                                            schedulerEntry.setTriggerValue(
1233                                                    simpleTriggerValueElement.getTextTrim());
1234                                    }
1235    
1236                                    String timeUnit = GetterUtil.getString(
1237                                            simpleElement.elementText("time-unit"),
1238                                            TimeUnit.SECOND.getValue());
1239    
1240                                    schedulerEntry.setTimeUnit(
1241                                            TimeUnit.parse(timeUnit.toLowerCase()));
1242                            }
1243    
1244                            portletModel.addSchedulerEntry(schedulerEntry);
1245                    }
1246    
1247                    portletModel.setPortletURLClass(
1248                            GetterUtil.getString(
1249                                    portletElement.elementText("portlet-url-class"),
1250                                    portletModel.getPortletURLClass()));
1251    
1252                    portletModel.setFriendlyURLMapperClass(
1253                            GetterUtil.getString(
1254                                    portletElement.elementText("friendly-url-mapper-class"),
1255                                    portletModel.getFriendlyURLMapperClass()));
1256    
1257                    if (Validator.isNull(portletModel.getFriendlyURLMapperClass())) {
1258                            _friendlyURLMapperPortlets.remove(portletId);
1259                    }
1260                    else {
1261                            _friendlyURLMapperPortlets.put(portletId, portletModel);
1262                    }
1263    
1264                    portletModel.setFriendlyURLMapping(
1265                            GetterUtil.getString(
1266                                    portletElement.elementText("friendly-url-mapping"),
1267                                    portletModel.getFriendlyURLMapping()));
1268                    portletModel.setFriendlyURLRoutes(
1269                            GetterUtil.getString(
1270                                    portletElement.elementText("friendly-url-routes"),
1271                                    portletModel.getFriendlyURLRoutes()));
1272                    portletModel.setURLEncoderClass(
1273                            GetterUtil.getString(
1274                                    portletElement.elementText("url-encoder-class"),
1275                                    portletModel.getURLEncoderClass()));
1276                    portletModel.setPortletDataHandlerClass(
1277                            GetterUtil.getString(
1278                                    portletElement.elementText("portlet-data-handler-class"),
1279                                    portletModel.getPortletDataHandlerClass()));
1280                    portletModel.setPortletLayoutListenerClass(
1281                            GetterUtil.getString(
1282                                    portletElement.elementText("portlet-layout-listener-class"),
1283                                    portletModel.getPortletLayoutListenerClass()));
1284                    portletModel.setPollerProcessorClass(
1285                            GetterUtil.getString(
1286                                    portletElement.elementText("poller-processor-class"),
1287                                    portletModel.getPollerProcessorClass()));
1288                    portletModel.setPopMessageListenerClass(
1289                            GetterUtil.getString(
1290                                    portletElement.elementText("pop-message-listener-class"),
1291                                    portletModel.getPopMessageListenerClass()));
1292                    portletModel.setSocialActivityInterpreterClass(
1293                            GetterUtil.getString(
1294                                    portletElement.elementText("social-activity-interpreter-class"),
1295                                    portletModel.getSocialActivityInterpreterClass()));
1296                    portletModel.setSocialRequestInterpreterClass(
1297                            GetterUtil.getString(
1298                                    portletElement.elementText("social-request-interpreter-class"),
1299                                    portletModel.getSocialRequestInterpreterClass()));
1300                    portletModel.setWebDAVStorageToken(
1301                            GetterUtil.getString(
1302                                    portletElement.elementText("webdav-storage-token"),
1303                                    portletModel.getWebDAVStorageToken()));
1304                    portletModel.setWebDAVStorageClass(
1305                            GetterUtil.getString(
1306                                    portletElement.elementText("webdav-storage-class"),
1307                                    portletModel.getWebDAVStorageClass()));
1308                    portletModel.setXmlRpcMethodClass(
1309                            GetterUtil.getString(
1310                                    portletElement.elementText("xml-rpc-method-class"),
1311                                    portletModel.getXmlRpcMethodClass()));
1312                    portletModel.setControlPanelEntryCategory(
1313                            GetterUtil.getString(
1314                                    portletElement.elementText("control-panel-entry-category"),
1315                                    portletModel.getControlPanelEntryCategory()));
1316                    portletModel.setControlPanelEntryWeight(
1317                            GetterUtil.getDouble(
1318                                    portletElement.elementText("control-panel-entry-weight"),
1319                                    portletModel.getControlPanelEntryWeight()));
1320                    portletModel.setControlPanelEntryClass(
1321                            GetterUtil.getString(
1322                                    portletElement.elementText("control-panel-entry-class"),
1323                                    portletModel.getControlPanelEntryClass()));
1324    
1325                    List<String> assetRendererFactoryClasses =
1326                            portletModel.getAssetRendererFactoryClasses();
1327    
1328                    for (Element assetRendererFactoryClassElement :
1329                                    portletElement.elements("asset-renderer-factory")) {
1330    
1331                            assetRendererFactoryClasses.add(
1332                                    assetRendererFactoryClassElement.getText());
1333                    }
1334    
1335                    List<String> atomCollectionAdapterClasses =
1336                            portletModel.getAtomCollectionAdapterClasses();
1337    
1338                    for (Element atomCollectionAdapterClassElement :
1339                                    portletElement.elements("atom-collection-adapter")) {
1340    
1341                            atomCollectionAdapterClasses.add(
1342                                    atomCollectionAdapterClassElement.getText());
1343                    }
1344    
1345                    List<String> customAttributesDisplayClasses =
1346                            portletModel.getCustomAttributesDisplayClasses();
1347    
1348                    for (Element customAttributesDisplayClassElement :
1349                                    portletElement.elements("custom-attributes-display")) {
1350    
1351                            customAttributesDisplayClasses.add(
1352                                    customAttributesDisplayClassElement.getText());
1353                    }
1354    
1355                    if (customAttributesDisplayClasses.isEmpty()) {
1356                            _customAttributesDisplayPortlets.remove(portletId);
1357                    }
1358                    else {
1359                            _customAttributesDisplayPortlets.put(portletId, portletModel);
1360                    }
1361    
1362                    portletModel.setPermissionPropagatorClass(
1363                            GetterUtil.getString(
1364                                    portletElement.elementText("permission-propagator"),
1365                                    portletModel.getPermissionPropagatorClass()));
1366    
1367                    List<String> workflowHandlerClasses =
1368                            portletModel.getWorkflowHandlerClasses();
1369    
1370                    for (Element workflowHandlerClassElement :
1371                                    portletElement.elements("workflow-handler")) {
1372    
1373                            workflowHandlerClasses.add(workflowHandlerClassElement.getText());
1374                    }
1375    
1376                    portletModel.setPreferencesCompanyWide(
1377                            GetterUtil.getBoolean(
1378                                    portletElement.elementText("preferences-company-wide"),
1379                                    portletModel.isPreferencesCompanyWide()));
1380                    portletModel.setPreferencesUniquePerLayout(
1381                            GetterUtil.getBoolean(
1382                                    portletElement.elementText("preferences-unique-per-layout"),
1383                                    portletModel.isPreferencesUniquePerLayout()));
1384                    portletModel.setPreferencesOwnedByGroup(
1385                            GetterUtil.getBoolean(
1386                                    portletElement.elementText("preferences-owned-by-group"),
1387                                    portletModel.isPreferencesOwnedByGroup()));
1388                    portletModel.setUseDefaultTemplate(
1389                            GetterUtil.getBoolean(
1390                                    portletElement.elementText("use-default-template"),
1391                                    portletModel.isUseDefaultTemplate()));
1392                    portletModel.setShowPortletAccessDenied(
1393                            GetterUtil.getBoolean(
1394                                    portletElement.elementText("show-portlet-access-denied"),
1395                                    portletModel.isShowPortletAccessDenied()));
1396                    portletModel.setShowPortletInactive(
1397                            GetterUtil.getBoolean(
1398                                    portletElement.elementText("show-portlet-inactive"),
1399                                    portletModel.isShowPortletInactive()));
1400                    portletModel.setActionURLRedirect(
1401                            GetterUtil.getBoolean(
1402                                    portletElement.elementText("action-url-redirect"),
1403                                    portletModel.isActionURLRedirect()));
1404                    portletModel.setRestoreCurrentView(
1405                            GetterUtil.getBoolean(
1406                                    portletElement.elementText("restore-current-view"),
1407                                    portletModel.isRestoreCurrentView()));
1408                    portletModel.setMaximizeEdit(
1409                            GetterUtil.getBoolean(
1410                                    portletElement.elementText("maximize-edit"),
1411                                    portletModel.isMaximizeEdit()));
1412                    portletModel.setMaximizeHelp(
1413                            GetterUtil.getBoolean(
1414                                    portletElement.elementText("maximize-help"),
1415                                    portletModel.isMaximizeHelp()));
1416                    portletModel.setPopUpPrint(
1417                            GetterUtil.getBoolean(
1418                                    portletElement.elementText("pop-up-print"),
1419                                    portletModel.isPopUpPrint()));
1420                    portletModel.setLayoutCacheable(
1421                            GetterUtil.getBoolean(
1422                                    portletElement.elementText("layout-cacheable"),
1423                                    portletModel.isLayoutCacheable()));
1424                    portletModel.setInstanceable(
1425                            GetterUtil.getBoolean(
1426                                    portletElement.elementText("instanceable"),
1427                                    portletModel.isInstanceable()));
1428                    portletModel.setRemoteable(
1429                            GetterUtil.getBoolean(
1430                                    portletElement.elementText("remoteable"),
1431                                    portletModel.isRemoteable()));
1432                    portletModel.setScopeable(
1433                            GetterUtil.getBoolean(
1434                                    portletElement.elementText("scopeable"),
1435                                    portletModel.isScopeable()));
1436                    portletModel.setUserPrincipalStrategy(
1437                            GetterUtil.getString(
1438                                    portletElement.elementText("user-principal-strategy"),
1439                                    portletModel.getUserPrincipalStrategy()));
1440                    portletModel.setPrivateRequestAttributes(
1441                            GetterUtil.getBoolean(
1442                                    portletElement.elementText("private-request-attributes"),
1443                                    portletModel.isPrivateRequestAttributes()));
1444                    portletModel.setPrivateSessionAttributes(
1445                            GetterUtil.getBoolean(
1446                                    portletElement.elementText("private-session-attributes"),
1447                                    portletModel.isPrivateSessionAttributes()));
1448    
1449                    Element autopropagatedParametersElement = portletElement.element(
1450                            "autopropagated-parameters");
1451    
1452                    if (autopropagatedParametersElement != null) {
1453                            Set<String> autopropagatedParameters =
1454                                    portletModel.getAutopropagatedParameters();
1455    
1456                            String[] autopropagatedParametersArray = StringUtil.split(
1457                                    autopropagatedParametersElement.getText());
1458    
1459                            for (String autopropagatedParameter :
1460                                            autopropagatedParametersArray) {
1461    
1462                                    autopropagatedParameters.add(autopropagatedParameter);
1463                            }
1464                    }
1465    
1466                    portletModel.setActionTimeout(
1467                            GetterUtil.getInteger(
1468                                    portletElement.elementText("action-timeout"),
1469                                    portletModel.getActionTimeout()));
1470                    portletModel.setRenderTimeout(
1471                            GetterUtil.getInteger(
1472                                    portletElement.elementText("render-timeout"),
1473                                    portletModel.getRenderTimeout()));
1474                    portletModel.setRenderWeight(
1475                            GetterUtil.getInteger(
1476                                    portletElement.elementText("render-weight"),
1477                                    portletModel.getRenderWeight()));
1478                    portletModel.setAjaxable(
1479                            GetterUtil.getBoolean(
1480                                    portletElement.elementText("ajaxable"),
1481                                    portletModel.isAjaxable()));
1482    
1483                    List<String> headerPortalCssList = portletModel.getHeaderPortalCss();
1484    
1485                    for (Element headerPortalCssElement :
1486                                    portletElement.elements("header-portal-css")) {
1487    
1488                            headerPortalCssList.add(headerPortalCssElement.getText());
1489                    }
1490    
1491                    List<String> headerPortletCssList = portletModel.getHeaderPortletCss();
1492    
1493                    for (Element headerPortletCssElement :
1494                                    portletElement.elements("header-portlet-css")) {
1495    
1496                            headerPortletCssList.add(headerPortletCssElement.getText());
1497                    }
1498    
1499                    List<String> headerPortalJavaScriptList =
1500                            portletModel.getHeaderPortalJavaScript();
1501    
1502                    for (Element headerPortalJavaScriptElement :
1503                                    portletElement.elements("header-portal-javascript")) {
1504    
1505                            headerPortalJavaScriptList.add(
1506                                    headerPortalJavaScriptElement.getText());
1507                    }
1508    
1509                    List<String> headerPortletJavaScriptList =
1510                            portletModel.getHeaderPortletJavaScript();
1511    
1512                    for (Element headerPortletJavaScriptElement :
1513                                    portletElement.elements("header-portlet-javascript")) {
1514    
1515                            headerPortletJavaScriptList.add(
1516                                    headerPortletJavaScriptElement.getText());
1517                    }
1518    
1519                    List<String> footerPortalCssList = portletModel.getFooterPortalCss();
1520    
1521                    for (Element footerPortalCssElement :
1522                                    portletElement.elements("footer-portal-css")) {
1523    
1524                            footerPortalCssList.add(footerPortalCssElement.getText());
1525                    }
1526    
1527                    List<String> footerPortletCssList = portletModel.getFooterPortletCss();
1528    
1529                    for (Element footerPortletCssElement :
1530                                    portletElement.elements("footer-portlet-css")) {
1531    
1532                            footerPortletCssList.add(footerPortletCssElement.getText());
1533                    }
1534    
1535                    List<String> footerPortalJavaScriptList =
1536                            portletModel.getFooterPortalJavaScript();
1537    
1538                    for (Element footerPortalJavaScriptElement :
1539                                    portletElement.elements("footer-portal-javascript")) {
1540    
1541                            footerPortalJavaScriptList.add(
1542                                    footerPortalJavaScriptElement.getText());
1543                    }
1544    
1545                    List<String> footerPortletJavaScriptList =
1546                            portletModel.getFooterPortletJavaScript();
1547    
1548                    for (Element footerPortletJavaScriptElement :
1549                                    portletElement.elements("footer-portlet-javascript")) {
1550    
1551                            footerPortletJavaScriptList.add(
1552                                    footerPortletJavaScriptElement.getText());
1553                    }
1554    
1555                    portletModel.setCssClassWrapper(
1556                            GetterUtil.getString(
1557                                    portletElement.elementText("css-class-wrapper"),
1558                                    portletModel.getCssClassWrapper()));
1559                    portletModel.setFacebookIntegration(
1560                            GetterUtil.getString(
1561                                    portletElement.elementText("facebook-integration"),
1562                                    portletModel.getFacebookIntegration()));
1563                    portletModel.setAddDefaultResource(
1564                            GetterUtil.getBoolean(
1565                                    portletElement.elementText("add-default-resource"),
1566                                    portletModel.isAddDefaultResource()));
1567                    portletModel.setSystem(
1568                            GetterUtil.getBoolean(
1569                                    portletElement.elementText("system"), portletModel.isSystem()));
1570                    portletModel.setActive(
1571                            GetterUtil.getBoolean(
1572                                    portletElement.elementText("active"), portletModel.isActive()));
1573                    portletModel.setInclude(
1574                            GetterUtil.getBoolean(portletElement.elementText("include"),
1575                            portletModel.isInclude()));
1576    
1577                    if (Validator.isNull(servletContextName)) {
1578                            portletModel.setReady(true);
1579                    }
1580    
1581                    if (!portletModel.isAjaxable() &&
1582                            (portletModel.getRenderWeight() < 1)) {
1583    
1584                            portletModel.setRenderWeight(1);
1585                    }
1586    
1587                    portletModel.getRoleMappers().putAll(roleMappers);
1588                    portletModel.linkRoles();
1589            }
1590    
1591            private Set<String> _readLiferayPortletXML(
1592                            String servletContextName, String xml,
1593                            Map<String, Portlet> portletsPool)
1594                    throws Exception {
1595    
1596                    Set<String> liferayPortletIds = new HashSet<String>();
1597    
1598                    if (xml == null) {
1599                            return liferayPortletIds;
1600                    }
1601    
1602                    Document document = SAXReaderUtil.read(xml, true);
1603    
1604                    Element rootElement = document.getRootElement();
1605    
1606                    PortletApp portletApp = _getPortletApp(servletContextName);
1607    
1608                    Map<String, String> roleMappers = new HashMap<String, String>();
1609    
1610                    for (Element roleMapperElement : rootElement.elements("role-mapper")) {
1611                            String roleName = roleMapperElement.elementText("role-name");
1612                            String roleLink = roleMapperElement.elementText("role-link");
1613    
1614                            roleMappers.put(roleName, roleLink);
1615                    }
1616    
1617                    Map<String, String> customUserAttributes =
1618                            portletApp.getCustomUserAttributes();
1619    
1620                    for (Element customUserAttributeElement :
1621                                    rootElement.elements("custom-user-attribute")) {
1622    
1623                            String customClass = customUserAttributeElement.elementText(
1624                                    "custom-class");
1625    
1626                            for (Element nameElement :
1627                                            customUserAttributeElement.elements("name")) {
1628    
1629                                    String name = nameElement.getText();
1630    
1631                                    customUserAttributes.put(name, customClass);
1632                            }
1633                    }
1634    
1635                    for (Element portletElement : rootElement.elements("portlet")) {
1636                            _readLiferayPortletXML(
1637                                    servletContextName, portletsPool, liferayPortletIds,
1638                                    roleMappers, portletElement);
1639                    }
1640    
1641                    return liferayPortletIds;
1642            }
1643    
1644            private Set<String> _readPortletXML(
1645                            ServletContext servletContext, String xml,
1646                            Map<String, Portlet> portletsPool, Set<String> servletURLPatterns,
1647                            PluginPackage pluginPackage)
1648                    throws Exception {
1649    
1650                    return _readPortletXML(
1651                            StringPool.BLANK, servletContext, xml, portletsPool,
1652                            servletURLPatterns, pluginPackage);
1653            }
1654    
1655            private void _readPortletXML(
1656                    String servletContextName, Map<String, Portlet> portletsPool,
1657                    PluginPackage pluginPackage, PortletApp portletApp,
1658                    Set<String> portletIds, long timestamp, Element portletElement) {
1659    
1660                    String portletName = portletElement.elementText("portlet-name");
1661    
1662                    String portletId = portletName;
1663    
1664                    if (Validator.isNotNull(servletContextName)) {
1665                            portletId = portletId.concat(PortletConstants.WAR_SEPARATOR).concat(
1666                                    servletContextName);
1667                    }
1668    
1669                    portletId = PortalUtil.getJsSafePortletId(portletId);
1670    
1671                    if (_log.isDebugEnabled()) {
1672                            _log.debug("Reading portlet " + portletId);
1673                    }
1674    
1675                    portletIds.add(portletId);
1676    
1677                    Portlet portletModel = portletsPool.get(portletId);
1678    
1679                    if (portletModel == null) {
1680                            portletModel = new PortletImpl(CompanyConstants.SYSTEM, portletId);
1681    
1682                            portletsPool.put(portletId, portletModel);
1683                    }
1684    
1685                    portletModel.setTimestamp(timestamp);
1686    
1687                    portletModel.setPluginPackage(pluginPackage);
1688                    portletModel.setPortletApp(portletApp);
1689    
1690                    portletModel.setPortletName(portletName);
1691                    portletModel.setDisplayName(
1692                            GetterUtil.getString(
1693                                    portletElement.elementText("display-name"),
1694                                    portletModel.getDisplayName()));
1695                    portletModel.setPortletClass(
1696                            GetterUtil.getString(portletElement.elementText("portlet-class")));
1697    
1698                    Map<String, String> initParams = portletModel.getInitParams();
1699    
1700                    for (Element initParamElement : portletElement.elements("init-param")) {
1701                            initParams.put(
1702                                    initParamElement.elementText("name"),
1703                                    initParamElement.elementText("value"));
1704                    }
1705    
1706                    Element expirationCacheElement = portletElement.element(
1707                            "expiration-cache");
1708    
1709                    if (expirationCacheElement != null) {
1710                            portletModel.setExpCache(
1711                                    GetterUtil.getInteger(expirationCacheElement.getText()));
1712                    }
1713    
1714                    for (Element supportsElement : portletElement.elements("supports")) {
1715                            Map<String, Set<String>> portletModes =
1716                                    portletModel.getPortletModes();
1717    
1718                            String mimeType = supportsElement.elementText("mime-type");
1719    
1720                            Set<String> mimeTypePortletModes = portletModes.get(mimeType);
1721    
1722                            if (mimeTypePortletModes == null) {
1723                                    mimeTypePortletModes = new HashSet<String>();
1724    
1725                                    portletModes.put(mimeType, mimeTypePortletModes);
1726                            }
1727    
1728                            mimeTypePortletModes.add(PortletMode.VIEW.toString().toLowerCase());
1729    
1730                            for (Element portletModeElement :
1731                                            supportsElement.elements("portlet-mode")) {
1732    
1733                                    mimeTypePortletModes.add(
1734                                            portletModeElement.getTextTrim().toLowerCase());
1735                            }
1736    
1737                            Map<String, Set<String>> windowStates =
1738                                    portletModel.getWindowStates();
1739    
1740                            Set<String> mimeTypeWindowStates = windowStates.get(mimeType);
1741    
1742                            if (mimeTypeWindowStates == null) {
1743                                    mimeTypeWindowStates = new HashSet<String>();
1744    
1745                                    windowStates.put(mimeType, mimeTypeWindowStates);
1746                            }
1747    
1748                            mimeTypeWindowStates.add(
1749                                    WindowState.NORMAL.toString().toLowerCase());
1750    
1751                            List<Element> windowStateElements = supportsElement.elements(
1752                                    "window-state");
1753    
1754                            if (windowStateElements.isEmpty()) {
1755                                    mimeTypeWindowStates.add(
1756                                            WindowState.MAXIMIZED.toString().toLowerCase());
1757                                    mimeTypeWindowStates.add(
1758                                            WindowState.MINIMIZED.toString().toLowerCase());
1759                                    mimeTypeWindowStates.add(
1760                                            LiferayWindowState.EXCLUSIVE.toString().toLowerCase());
1761                                    mimeTypeWindowStates.add(
1762                                            LiferayWindowState.POP_UP.toString().toLowerCase());
1763                            }
1764    
1765                            for (Element windowStateElement : windowStateElements) {
1766                                    mimeTypeWindowStates.add(
1767                                            windowStateElement.getTextTrim().toLowerCase());
1768                            }
1769                    }
1770    
1771                    Set<String> supportedLocales = portletModel.getSupportedLocales();
1772    
1773                    //supportedLocales.add(
1774                    //        LocaleUtil.toLanguageId(LocaleUtil.getDefault()));
1775    
1776                    for (Element supportedLocaleElement : portletElement.elements(
1777                                    "supported-locale")) {
1778    
1779                            String supportedLocale = supportedLocaleElement.getText();
1780    
1781                            supportedLocales.add(supportedLocale);
1782                    }
1783    
1784                    portletModel.setResourceBundle(
1785                            portletElement.elementText("resource-bundle"));
1786    
1787                    Element portletInfoElement = portletElement.element("portlet-info");
1788    
1789                    String portletInfoTitle = null;
1790                    String portletInfoShortTitle = null;
1791                    String portletInfoKeyWords = null;
1792                    String portletInfoDescription = null;
1793    
1794                    if (portletInfoElement != null) {
1795                            portletInfoTitle = portletInfoElement.elementText("title");
1796                            portletInfoShortTitle = portletInfoElement.elementText(
1797                                    "short-title");
1798                            portletInfoKeyWords = portletInfoElement.elementText("keywords");
1799                    }
1800    
1801                    PortletInfo portletInfo = new PortletInfo(
1802                            portletInfoTitle, portletInfoShortTitle, portletInfoKeyWords,
1803                            portletInfoDescription);
1804    
1805                    portletModel.setPortletInfo(portletInfo);
1806    
1807                    Element portletPreferencesElement = portletElement.element(
1808                            "portlet-preferences");
1809    
1810                    String defaultPreferences = null;
1811                    String preferencesValidator = null;
1812    
1813                    if (portletPreferencesElement != null) {
1814                            Element preferencesValidatorElement =
1815                                    portletPreferencesElement.element("preferences-validator");
1816    
1817                            if (preferencesValidatorElement != null) {
1818                                    preferencesValidator = preferencesValidatorElement.getText();
1819    
1820                                    portletPreferencesElement.remove(preferencesValidatorElement);
1821                            }
1822    
1823                            defaultPreferences = portletPreferencesElement.asXML();
1824                    }
1825    
1826                    portletModel.setDefaultPreferences(defaultPreferences);
1827                    portletModel.setPreferencesValidator(preferencesValidator);
1828    
1829                    if (!portletApp.isWARFile() &&
1830                            Validator.isNotNull(preferencesValidator) &&
1831                            PropsValues.PREFERENCE_VALIDATE_ON_STARTUP) {
1832    
1833                            try {
1834                                    PreferencesValidator preferencesValidatorObj =
1835                                            PortalUtil.getPreferencesValidator(portletModel);
1836    
1837                                    preferencesValidatorObj.validate(
1838                                            PortletPreferencesFactoryUtil.fromDefaultXML(
1839                                                    defaultPreferences));
1840                            }
1841                            catch (Exception e) {
1842                                    if (_log.isWarnEnabled()) {
1843                                            _log.warn(
1844                                                    "Portlet with the name " + portletId +
1845                                                            " does not have valid default preferences");
1846                                    }
1847                            }
1848                    }
1849    
1850                    Set<String> unlikedRoles = portletModel.getUnlinkedRoles();
1851    
1852                    for (Element roleElement :
1853                                    portletElement.elements("security-role-ref")) {
1854    
1855                            unlikedRoles.add(roleElement.elementText("role-name"));
1856                    }
1857    
1858                    for (Element supportedProcessingEventElement :
1859                                    portletElement.elements("supported-processing-event")) {
1860    
1861                            Element qNameElement = supportedProcessingEventElement.element(
1862                                    "qname");
1863                            Element nameElement = supportedProcessingEventElement.element(
1864                                    "name");
1865    
1866                            QName qName = PortletQNameUtil.getQName(
1867                                    qNameElement, nameElement, portletApp.getDefaultNamespace());
1868    
1869                            portletModel.addProcessingEvent(qName);
1870                    }
1871    
1872                    for (Element supportedPublishingEventElement :
1873                                    portletElement.elements("supported-publishing-event")) {
1874    
1875                            Element qNameElement = supportedPublishingEventElement.element(
1876                                    "qname");
1877                            Element nameElement = supportedPublishingEventElement.element(
1878                                    "name");
1879    
1880                            QName qName = PortletQNameUtil.getQName(
1881                                    qNameElement, nameElement, portletApp.getDefaultNamespace());
1882    
1883                            portletModel.addPublishingEvent(qName);
1884                    }
1885    
1886                    for (Element supportedPublicRenderParameter :
1887                                    portletElement.elements("supported-public-render-parameter")) {
1888    
1889                            String identifier = supportedPublicRenderParameter.getTextTrim();
1890    
1891                            PublicRenderParameter publicRenderParameter =
1892                                    portletApp.getPublicRenderParameter(identifier);
1893    
1894                            if (publicRenderParameter == null) {
1895                                    _log.error(
1896                                            "Supported public render parameter references " +
1897                                                    "unnknown identifier " + identifier);
1898    
1899                                    continue;
1900                            }
1901    
1902                            portletModel.addPublicRenderParameter(publicRenderParameter);
1903                    }
1904            }
1905    
1906            private Set<String> _readPortletXML(
1907                            String servletContextName, ServletContext servletContext,
1908                            String xml, Map<String, Portlet> portletsPool,
1909                            Set<String> servletURLPatterns, PluginPackage pluginPackage)
1910                    throws Exception {
1911    
1912                    Set<String> portletIds = new HashSet<String>();
1913    
1914                    if (xml == null) {
1915                            return portletIds;
1916                    }
1917    
1918                    Document document = SAXReaderUtil.read(
1919                            xml, PropsValues.PORTLET_XML_VALIDATE);
1920    
1921                    Element rootElement = document.getRootElement();
1922    
1923                    PortletApp portletApp = _getPortletApp(servletContextName);
1924    
1925                    portletApp.addServletURLPatterns(servletURLPatterns);
1926    
1927                    Set<String> userAttributes = portletApp.getUserAttributes();
1928    
1929                    for (Element userAttributeElement :
1930                                    rootElement.elements("user-attribute")) {
1931    
1932                            String name = userAttributeElement.elementText("name");
1933    
1934                            userAttributes.add(name);
1935                    }
1936    
1937                    String defaultNamespace = rootElement.elementText("default-namespace");
1938    
1939                    if (Validator.isNotNull(defaultNamespace)) {
1940                            portletApp.setDefaultNamespace(defaultNamespace);
1941                    }
1942    
1943                    for (Element eventDefinitionElement :
1944                                    rootElement.elements("event-definition")) {
1945    
1946                            Element qNameElement = eventDefinitionElement.element("qname");
1947                            Element nameElement = eventDefinitionElement.element("name");
1948                            String valueType = eventDefinitionElement.elementText("value-type");
1949    
1950                            QName qName = PortletQNameUtil.getQName(
1951                                    qNameElement, nameElement, portletApp.getDefaultNamespace());
1952    
1953                            EventDefinition eventDefinition = new EventDefinitionImpl(
1954                                    qName, valueType, portletApp);
1955    
1956                            portletApp.addEventDefinition(eventDefinition);
1957                    }
1958    
1959                    for (Element publicRenderParameterElement :
1960                                    rootElement.elements("public-render-parameter")) {
1961    
1962                            String identifier = publicRenderParameterElement.elementText(
1963                                    "identifier");
1964                            Element qNameElement = publicRenderParameterElement.element(
1965                                    "qname");
1966                            Element nameElement = publicRenderParameterElement.element("name");
1967    
1968                            QName qName = PortletQNameUtil.getQName(
1969                                    qNameElement, nameElement, portletApp.getDefaultNamespace());
1970    
1971                            PublicRenderParameter publicRenderParameter =
1972                                    new PublicRenderParameterImpl(identifier, qName, portletApp);
1973    
1974                            portletApp.addPublicRenderParameter(publicRenderParameter);
1975                    }
1976    
1977                    for (Element containerRuntimeOptionElement :
1978                                    rootElement.elements("container-runtime-option")) {
1979    
1980                            String name = GetterUtil.getString(
1981                                    containerRuntimeOptionElement.elementText("name"));
1982    
1983                            List<String> values = new ArrayList<String>();
1984    
1985                            for (Element valueElement :
1986                                            containerRuntimeOptionElement.elements("value")) {
1987    
1988                                    values.add(valueElement.getTextTrim());
1989                            }
1990    
1991                            Map<String, String[]> containerRuntimeOptions =
1992                                    portletApp.getContainerRuntimeOptions();
1993    
1994                            containerRuntimeOptions.put(
1995                                    name, values.toArray(new String[values.size()]));
1996    
1997                            if (name.equals(
1998                                            LiferayPortletConfig.RUNTIME_OPTION_PORTAL_CONTEXT) &&
1999                                    !values.isEmpty() && GetterUtil.getBoolean(values.get(0))) {
2000    
2001                                    portletApp.setWARFile(false);
2002                            }
2003                    }
2004    
2005                    long timestamp = ServletContextUtil.getLastModified(servletContext);
2006    
2007                    for (Element portletElement : rootElement.elements("portlet")) {
2008                            _readPortletXML(
2009                                    servletContextName, portletsPool, pluginPackage, portletApp,
2010                                    portletIds, timestamp, portletElement);
2011                    }
2012    
2013                    for (Element filterElement : rootElement.elements("filter")) {
2014                            String filterName = filterElement.elementText("filter-name");
2015                            String filterClass = filterElement.elementText("filter-class");
2016    
2017                            Set<String> lifecycles = new LinkedHashSet<String>();
2018    
2019                            for (Element lifecycleElement :
2020                                            filterElement.elements("lifecycle")) {
2021    
2022                                    lifecycles.add(lifecycleElement.getText());
2023                            }
2024    
2025                            Map<String, String> initParams = new HashMap<String, String>();
2026    
2027                            for (Element initParamElement :
2028                                            filterElement.elements("init-param")) {
2029    
2030                                    initParams.put(
2031                                            initParamElement.elementText("name"),
2032                                            initParamElement.elementText("value"));
2033                            }
2034    
2035                            PortletFilter portletFilter = new PortletFilterImpl(
2036                                    filterName, filterClass, lifecycles, initParams, portletApp);
2037    
2038                            portletApp.addPortletFilter(portletFilter);
2039                    }
2040    
2041                    for (Element filterMappingElement :
2042                                    rootElement.elements("filter-mapping")) {
2043    
2044                            String filterName = filterMappingElement.elementText("filter-name");
2045    
2046                            for (Element portletNameElement :
2047                                            filterMappingElement.elements("portlet-name")) {
2048    
2049                                    String portletName = portletNameElement.getTextTrim();
2050    
2051                                    PortletFilter portletFilter = portletApp.getPortletFilter(
2052                                            filterName);
2053    
2054                                    if (portletFilter == null) {
2055                                            _log.error(
2056                                                    "Filter mapping references unnknown filter name " +
2057                                                            filterName);
2058    
2059                                            continue;
2060                                    }
2061    
2062                                    List<Portlet> portletModels = _getPortletsByPortletName(
2063                                            portletName, servletContextName, portletsPool);
2064    
2065                                    if (portletModels.size() == 0) {
2066                                            _log.error(
2067                                                    "Filter mapping with filter name " + filterName +
2068                                                            " references unnknown portlet name " + portletName);
2069                                    }
2070    
2071                                    for (Portlet portletModel : portletModels) {
2072                                            portletModel.getPortletFilters().put(
2073                                                    filterName, portletFilter);
2074                                    }
2075                            }
2076                    }
2077    
2078                    for (Element listenerElement : rootElement.elements("listener")) {
2079                            String listenerClass = listenerElement.elementText(
2080                                    "listener-class");
2081    
2082                            PortletURLListener portletURLListener = new PortletURLListenerImpl(
2083                                    listenerClass, portletApp);
2084    
2085                            portletApp.addPortletURLListener(portletURLListener);
2086                    }
2087    
2088                    return portletIds;
2089            }
2090    
2091            private Set<String> _readWebXML(String xml) throws Exception {
2092                    Set<String> servletURLPatterns = new LinkedHashSet<String>();
2093    
2094                    if (xml == null) {
2095                            return servletURLPatterns;
2096                    }
2097    
2098                    Document document = SAXReaderUtil.read(xml);
2099    
2100                    Element rootElement = document.getRootElement();
2101    
2102                    for (Element servletMappingElement :
2103                                    rootElement.elements("servlet-mapping")) {
2104    
2105                            String urlPattern = servletMappingElement.elementText(
2106                                    "url-pattern");
2107    
2108                            servletURLPatterns.add(urlPattern);
2109                    }
2110    
2111                    return servletURLPatterns;
2112            }
2113    
2114            private void _setSpriteImages(
2115                            ServletContext servletContext, PortletApp portletApp,
2116                            String resourcePath)
2117                    throws Exception {
2118    
2119                    Set<String> resourcePaths = servletContext.getResourcePaths(
2120                            resourcePath);
2121    
2122                    if (resourcePaths == null) {
2123                            return;
2124                    }
2125    
2126                    List<File> imageFiles = new ArrayList<File>(resourcePaths.size());
2127    
2128                    for (String curResourcePath : resourcePaths) {
2129                            if (curResourcePath.endsWith(StringPool.SLASH)) {
2130                                    _setSpriteImages(servletContext, portletApp, curResourcePath);
2131                            }
2132                            else if (curResourcePath.endsWith(".png")) {
2133                                    String realPath = ServletContextUtil.getRealPath(
2134                                            servletContext, curResourcePath);
2135    
2136                                    if (realPath != null) {
2137                                            File imageFile = new File(realPath);
2138    
2139                                            imageFiles.add(imageFile);
2140                                    }
2141                                    else {
2142                                            if (ServerDetector.isTomcat()) {
2143                                                    if (_log.isInfoEnabled()) {
2144                                                            _log.info(ServletContextUtil.LOG_INFO_SPRITES);
2145                                                    }
2146                                            }
2147                                            else {
2148                                                    _log.error(
2149                                                            "Real path for " + curResourcePath + " is null");
2150                                            }
2151                                    }
2152                            }
2153                    }
2154    
2155                    String spriteFileName = PropsValues.SPRITE_FILE_NAME;
2156                    String spritePropertiesFileName =
2157                            PropsValues.SPRITE_PROPERTIES_FILE_NAME;
2158                    String spritePropertiesRootPath = ServletContextUtil.getRealPath(
2159                            servletContext, StringPool.SLASH);
2160    
2161                    Properties spriteProperties = SpriteProcessorUtil.generate(
2162                            servletContext, imageFiles, spriteFileName,
2163                            spritePropertiesFileName, spritePropertiesRootPath, 16, 16, 10240);
2164    
2165                    if (spriteProperties == null) {
2166                            return;
2167                    }
2168    
2169                    spriteFileName =
2170                            resourcePath.substring(0, resourcePath.length()) + spriteFileName;
2171    
2172                    portletApp.setSpriteImages(spriteFileName, spriteProperties);
2173            }
2174    
2175            private static Log _log = LogFactoryUtil.getLog(
2176                    PortletLocalServiceImpl.class);
2177    
2178            private static Map<Long, Map<String, Portlet>> _companyPortletsPool =
2179                    new ConcurrentHashMap<Long, Map<String, Portlet>>();
2180            private static Map<String, Portlet> _customAttributesDisplayPortlets =
2181                    new ConcurrentHashMap<String, Portlet>();
2182            private static Map<String, Portlet> _friendlyURLMapperPortlets =
2183                    new ConcurrentHashMap<String, Portlet>();
2184            private static Map<String, PortletApp> _portletAppsPool =
2185                    new ConcurrentHashMap<String, PortletApp>();
2186            private static Map<String, String> _portletIdsByStrutsPath =
2187                    new ConcurrentHashMap<String, String>();
2188            private static Map<String, Portlet> _portletsPool =
2189                    new ConcurrentHashMap<String, Portlet>();
2190    
2191    }