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