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