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