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