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