001    /**
002     * Copyright (c) 2000-2012 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.security.permission;
016    
017    import com.liferay.portal.NoSuchResourceActionException;
018    import com.liferay.portal.kernel.bean.BeanReference;
019    import com.liferay.portal.kernel.exception.SystemException;
020    import com.liferay.portal.kernel.language.LanguageUtil;
021    import com.liferay.portal.kernel.log.Log;
022    import com.liferay.portal.kernel.log.LogFactoryUtil;
023    import com.liferay.portal.kernel.util.ContentTypes;
024    import com.liferay.portal.kernel.util.GetterUtil;
025    import com.liferay.portal.kernel.util.ListUtil;
026    import com.liferay.portal.kernel.util.StringPool;
027    import com.liferay.portal.kernel.util.StringUtil;
028    import com.liferay.portal.kernel.util.UnmodifiableList;
029    import com.liferay.portal.kernel.util.Validator;
030    import com.liferay.portal.kernel.xml.Document;
031    import com.liferay.portal.kernel.xml.DocumentType;
032    import com.liferay.portal.kernel.xml.Element;
033    import com.liferay.portal.kernel.xml.SAXReaderUtil;
034    import com.liferay.portal.model.Group;
035    import com.liferay.portal.model.LayoutPrototype;
036    import com.liferay.portal.model.LayoutSetPrototype;
037    import com.liferay.portal.model.Organization;
038    import com.liferay.portal.model.PasswordPolicy;
039    import com.liferay.portal.model.Permission;
040    import com.liferay.portal.model.Portlet;
041    import com.liferay.portal.model.PortletConstants;
042    import com.liferay.portal.model.ResourceAction;
043    import com.liferay.portal.model.Role;
044    import com.liferay.portal.model.RoleConstants;
045    import com.liferay.portal.model.User;
046    import com.liferay.portal.model.UserGroup;
047    import com.liferay.portal.service.GroupServiceUtil;
048    import com.liferay.portal.service.PortletLocalService;
049    import com.liferay.portal.service.ResourceActionLocalService;
050    import com.liferay.portal.service.RoleLocalService;
051    import com.liferay.portal.util.Portal;
052    import com.liferay.portal.util.PortletKeys;
053    import com.liferay.portal.util.PropsValues;
054    import com.liferay.portlet.PortletResourceBundles;
055    import com.liferay.portlet.expando.model.ExpandoColumn;
056    import com.liferay.portlet.mobiledevicerules.model.MDRRuleGroup;
057    import com.liferay.util.UniqueList;
058    
059    import java.io.InputStream;
060    
061    import java.util.ArrayList;
062    import java.util.Collections;
063    import java.util.HashMap;
064    import java.util.HashSet;
065    import java.util.Iterator;
066    import java.util.List;
067    import java.util.Locale;
068    import java.util.Map;
069    import java.util.Set;
070    
071    import javax.servlet.jsp.PageContext;
072    
073    /**
074     * @author Brian Wing Shun Chan
075     * @author Daeyoung Song
076     * @author Raymond Augé
077     */
078    public class ResourceActionsImpl implements ResourceActions {
079    
080            public void afterPropertiesSet() {
081                    _organizationModelResources = new HashSet<String>();
082    
083                    for (String resource : getOrganizationModelResources()) {
084                            _organizationModelResources.add(resource);
085                    }
086    
087                    _portalModelResources = new HashSet<String>();
088    
089                    for (String resource : getPortalModelResources()) {
090                            _portalModelResources.add(resource);
091                    }
092    
093                    _portletModelResources = new HashMap<String, Set<String>>();
094                    _portletResourceActions = new HashMap<String, List<String>>();
095                    _portletResourceGroupDefaultActions =
096                            new HashMap<String, List<String>>();
097                    _portletResourceGuestDefaultActions =
098                            new HashMap<String, List<String>>();
099                    _portletResourceGuestUnsupportedActions =
100                            new HashMap<String, List<String>>();
101                    _portletResourceLayoutManagerActions =
102                            new HashMap<String, List<String>>();
103                    _modelPortletResources = new HashMap<String, Set<String>>();
104                    _modelResourceActions = new HashMap<String, List<String>>();
105                    _modelResourceGroupDefaultActions = new HashMap<String, List<String>>();
106                    _modelResourceGuestDefaultActions = new HashMap<String, List<String>>();
107                    _modelResourceGuestUnsupportedActions =
108                            new HashMap<String, List<String>>();
109                    _modelResourceOwnerDefaultActions = new HashMap<String, List<String>>();
110    
111                    try {
112                            ClassLoader classLoader = getClass().getClassLoader();
113    
114                            for (String config : PropsValues.RESOURCE_ACTIONS_CONFIGS) {
115                                    read(null, classLoader, config);
116                            }
117                    }
118                    catch (Exception e) {
119                            _log.error(e, e);
120                    }
121            }
122    
123            public void checkAction(String name, String actionId)
124                    throws NoSuchResourceActionException {
125    
126                    List<String> resourceActions = getResourceActions(name);
127    
128                    if (!resourceActions.contains(actionId)) {
129                            throw new NoSuchResourceActionException(
130                                    name.concat(StringPool.POUND).concat(actionId));
131                    }
132            }
133    
134            public String getAction(Locale locale, String action) {
135                    String key = getActionNamePrefix() + action;
136    
137                    String value = LanguageUtil.get(locale, key, null);
138    
139                    if ((value == null) || (value.equals(key))) {
140                            value = PortletResourceBundles.getString(locale, key);
141                    }
142    
143                    if (value == null) {
144                            value = key;
145                    }
146    
147                    return value;
148            }
149    
150            public String getAction(PageContext pageContext, String action) {
151                    String key = getActionNamePrefix() + action;
152    
153                    String value = LanguageUtil.get(pageContext, key, null);
154    
155                    if ((value == null) || (value.equals(key))) {
156                            value = PortletResourceBundles.getString(pageContext, key);
157                    }
158    
159                    if (value == null) {
160                            value = key;
161                    }
162    
163                    return value;
164            }
165    
166            public String getActionNamePrefix() {
167                    return _ACTION_NAME_PREFIX;
168            }
169    
170            public List<String> getActions(List<Permission> permissions) {
171                    List<String> actions = new UniqueList<String>();
172    
173                    for (Permission permission : permissions) {
174                            actions.add(permission.getActionId());
175                    }
176    
177                    return actions;
178            }
179    
180            public List<String> getActionsNames(
181                    PageContext pageContext, List<String> actions) {
182    
183                    List<String> actionNames = new UniqueList<String>();
184    
185                    for (String action : actions) {
186                            actionNames.add(getAction(pageContext, action));
187                    }
188    
189                    return actionNames;
190            }
191    
192            public List<String> getActionsNames(
193                    PageContext pageContext, String name, long actionIds) {
194    
195                    try {
196                            List<ResourceAction> resourceActions =
197                                    resourceActionLocalService.getResourceActions(name);
198    
199                            List<String> actions = new ArrayList<String>();
200    
201                            for (ResourceAction resourceAction : resourceActions) {
202                                    long bitwiseValue = resourceAction.getBitwiseValue();
203    
204                                    if ((actionIds & bitwiseValue) == bitwiseValue) {
205                                            actions.add(resourceAction.getActionId());
206                                    }
207                            }
208    
209                            return getActionsNames(pageContext, actions);
210                    }
211                    catch (Exception e) {
212                            _log.error(e, e);
213    
214                            return Collections.emptyList();
215                    }
216            }
217    
218            public List<String> getModelNames() {
219                    return ListUtil.fromMapKeys(_modelPortletResources);
220            }
221    
222            public List<String> getModelPortletResources(String name) {
223                    Set<String> resources = _modelPortletResources.get(name);
224    
225                    if (resources == null) {
226                            return new UniqueList<String>();
227                    }
228                    else {
229                            return Collections.list(Collections.enumeration(resources));
230                    }
231            }
232    
233            public String getModelResource(Locale locale, String name) {
234                    String key = getModelResourceNamePrefix() + name;
235    
236                    String value = LanguageUtil.get(locale, key, null);
237    
238                    if ((value == null) || (value.equals(key))) {
239                            value = PortletResourceBundles.getString(locale, key);
240                    }
241    
242                    if (value == null) {
243                            value = key;
244                    }
245    
246                    return value;
247            }
248    
249            public String getModelResource(PageContext pageContext, String name) {
250                    String key = getModelResourceNamePrefix() + name;
251    
252                    String value = LanguageUtil.get(pageContext, key, null);
253    
254                    if ((value == null) || (value.equals(key))) {
255                            value = PortletResourceBundles.getString(pageContext, key);
256                    }
257    
258                    if (value == null) {
259                            value = key;
260                    }
261    
262                    return value;
263            }
264    
265            public List<String> getModelResourceActions(String name) {
266                    return getActions(_modelResourceActions, name);
267            }
268    
269            public List<String> getModelResourceGroupDefaultActions(String name) {
270                    return getActions(_modelResourceGroupDefaultActions, name);
271            }
272    
273            public List<String> getModelResourceGuestDefaultActions(String name) {
274                    return getActions(_modelResourceGuestDefaultActions, name);
275            }
276    
277            public List<String> getModelResourceGuestUnsupportedActions(String name) {
278                    return getActions(_modelResourceGuestUnsupportedActions, name);
279            }
280    
281            public String getModelResourceNamePrefix() {
282                    return _MODEL_RESOURCE_NAME_PREFIX;
283            }
284    
285            public List<String> getModelResourceOwnerDefaultActions(String name) {
286                    return getActions(_modelResourceOwnerDefaultActions, name);
287            }
288    
289            public String[] getOrganizationModelResources() {
290                    return _ORGANIZATION_MODEL_RESOURCES;
291            }
292    
293            public String[] getPortalModelResources() {
294                    return _PORTAL_MODEL_RESOURCES;
295            }
296    
297            public String getPortletBaseResource(String portletName) {
298                    List<String> modelNames = getPortletModelResources(portletName);
299    
300                    for (String modelName : modelNames) {
301                            if (!modelName.contains(".model.")) {
302                                    return modelName;
303                            }
304                    }
305    
306                    return null;
307            }
308    
309            public List<String> getPortletModelResources(String portletName) {
310                    portletName = PortletConstants.getRootPortletId(portletName);
311    
312                    Set<String> resources = _portletModelResources.get(portletName);
313    
314                    if (resources == null) {
315                            return new UniqueList<String>();
316                    }
317                    else {
318                            return Collections.list(Collections.enumeration(resources));
319                    }
320            }
321    
322            public List<String> getPortletNames() {
323                    return ListUtil.fromMapKeys(_portletModelResources);
324            }
325    
326            public List<String> getPortletResourceActions(Portlet portlet) {
327                    List<String> actions = ListUtil.copy(
328                            getPortletResourceActions(portlet.getPortletId()));
329    
330                    synchronized (this) {
331                            checkPortletActions(portlet, actions);
332    
333                            setActions(
334                                    _portletResourceActions, portlet.getPortletId(), actions);
335                    }
336    
337                    return actions;
338            }
339    
340            public List<String> getPortletResourceActions(String name) {
341                    name = PortletConstants.getRootPortletId(name);
342    
343                    List<String> actions = getActions(_portletResourceActions, name);
344    
345                    if (!actions.isEmpty()) {
346                            return actions;
347                    }
348    
349                    synchronized (this) {
350                            actions = getPortletMimeTypeActions(name);
351    
352                            if (!name.equals(PortletKeys.PORTAL)) {
353                                    checkPortletActions(name, actions);
354                            }
355    
356                            List<String> groupDefaultActions =
357                                    _portletResourceGroupDefaultActions.get(name);
358    
359                            if (groupDefaultActions == null) {
360                                    groupDefaultActions = new UniqueList<String>();
361    
362                                    checkPortletGroupDefaultActions(groupDefaultActions);
363    
364                                    _portletResourceGroupDefaultActions.put(
365                                            name, new UnmodifiableList<String>(groupDefaultActions));
366                            }
367    
368                            List<String> guestDefaultActions =
369                                    _portletResourceGuestDefaultActions.get(name);
370    
371                            if (guestDefaultActions == null) {
372                                    guestDefaultActions = new UniqueList<String>();
373    
374                                    checkPortletGuestDefaultActions(guestDefaultActions);
375    
376                                    _portletResourceGuestDefaultActions.put(
377                                            name, new UnmodifiableList<String>(guestDefaultActions));
378                            }
379    
380                            List<String> layoutManagerActions =
381                                    _portletResourceLayoutManagerActions.get(name);
382    
383                            if (layoutManagerActions == null) {
384                                    layoutManagerActions = new UniqueList<String>();
385    
386                                    checkPortletLayoutManagerActions(layoutManagerActions);
387    
388                                    _portletResourceLayoutManagerActions.put(
389                                            name, new UnmodifiableList<String>(layoutManagerActions));
390                            }
391    
392                            actions = setActions(_portletResourceActions, name, actions);
393                    }
394    
395                    return actions;
396            }
397    
398            public List<String> getPortletResourceGroupDefaultActions(String name) {
399    
400                    // This method should always be called only after
401                    // _getPortletResourceActions has been called at least once to
402                    // populate the default group actions. Check to make sure this is the
403                    // case. However, if it is not, that means the methods
404                    // getPortletResourceGuestDefaultActions and
405                    // getPortletResourceGuestDefaultActions may not work either.
406    
407                    name = PortletConstants.getRootPortletId(name);
408    
409                    return getActions(_portletResourceGroupDefaultActions, name);
410            }
411    
412            public List<String> getPortletResourceGuestDefaultActions(String name) {
413                    name = PortletConstants.getRootPortletId(name);
414    
415                    return getActions(_portletResourceGuestDefaultActions, name);
416            }
417    
418            public List<String> getPortletResourceGuestUnsupportedActions(String name) {
419                    name = PortletConstants.getRootPortletId(name);
420    
421                    List<String> actions = getActions(
422                            _portletResourceGuestUnsupportedActions, name);
423    
424                    if (actions.contains(ActionKeys.CONFIGURATION) &&
425                            actions.contains(ActionKeys.PERMISSIONS)) {
426    
427                            return actions;
428                    }
429    
430                    actions = new UniqueList<String>(actions);
431    
432                    actions.add(ActionKeys.CONFIGURATION);
433                    actions.add(ActionKeys.PERMISSIONS);
434    
435                    setActions(_portletResourceGuestUnsupportedActions, name, actions);
436    
437                    return actions;
438            }
439    
440            public List<String> getPortletResourceLayoutManagerActions(String name) {
441                    name = PortletConstants.getRootPortletId(name);
442    
443                    List<String> actions = getActions(
444                            _portletResourceLayoutManagerActions, name);
445    
446                    // This check can never return an empty list. If the list is empty, it
447                    // means that the portlet does not have an explicit resource-actions
448                    // configuration file and should therefore be handled as if it has
449                    // defaults of CONFIGURATION, PREFERENCES, and VIEW.
450    
451                    if (actions.isEmpty()) {
452                            actions = new UniqueList<String>();
453    
454                            actions.add(ActionKeys.CONFIGURATION);
455                            actions.add(ActionKeys.PREFERENCES);
456                            actions.add(ActionKeys.VIEW);
457    
458                            setActions(_portletResourceLayoutManagerActions, name, actions);
459                    }
460    
461                    return actions;
462            }
463    
464            public List<String> getResourceActions(String name) {
465                    if (name.contains(StringPool.PERIOD)) {
466                            return getModelResourceActions(name);
467                    }
468                    else {
469                            return getPortletResourceActions(name);
470                    }
471            }
472    
473            public List<String> getResourceActions(
474                    String portletResource, String modelResource) {
475    
476                    List<String> actions = null;
477    
478                    if (Validator.isNull(modelResource)) {
479                            actions = getPortletResourceActions(portletResource);
480                    }
481                    else {
482                            actions = getModelResourceActions(modelResource);
483                    }
484    
485                    return actions;
486            }
487    
488            public List<String> getResourceGroupDefaultActions(String name) {
489                    if (name.contains(StringPool.PERIOD)) {
490                            return getModelResourceGroupDefaultActions(name);
491                    }
492                    else {
493                            return getPortletResourceGroupDefaultActions(name);
494                    }
495            }
496    
497            public List<String> getResourceGuestUnsupportedActions(
498                    String portletResource, String modelResource) {
499    
500                    List<String> actions = null;
501    
502                    if (Validator.isNull(modelResource)) {
503                            actions = getPortletResourceGuestUnsupportedActions(
504                                    portletResource);
505                    }
506                    else {
507                            actions = getModelResourceGuestUnsupportedActions(modelResource);
508                    }
509    
510                    return actions;
511            }
512    
513            /**
514             * @deprecated {@link #getRoles(long, Group, String, int[])}
515             */
516            public List<Role> getRoles(
517                            long companyId, Group group, String modelResource)
518                            throws SystemException {
519    
520                    return getRoles(companyId, group, modelResource, null);
521            }
522    
523            public List<Role> getRoles(
524                            long companyId, Group group, String modelResource, int[] roleTypes)
525                    throws SystemException {
526    
527                    List<Role> allRoles = roleLocalService.getRoles(companyId);
528    
529                    if (roleTypes == null) {
530                            roleTypes = getRoleTypes(companyId, group, modelResource);
531                    }
532    
533                    List<Role> roles = new ArrayList<Role>();
534    
535                    for (int roleType : roleTypes) {
536                            for (Role role : allRoles) {
537                                    if (role.getType() == roleType) {
538                                            roles.add(role);
539                                    }
540                            }
541                    }
542    
543                    return roles;
544            }
545    
546            public boolean hasModelResourceActions(String name) {
547                    List<String> actions = _modelResourceActions.get(name);
548    
549                    if ((actions != null) && !actions.isEmpty()) {
550                            return true;
551                    }
552                    else {
553                            return false;
554                    }
555            }
556    
557            public boolean isOrganizationModelResource(String modelResource) {
558                    if (_organizationModelResources.contains(modelResource)) {
559                            return true;
560                    }
561                    else {
562                            return false;
563                    }
564            }
565    
566            public boolean isPortalModelResource(String modelResource) {
567                    if (_portalModelResources.contains(modelResource)) {
568                            return true;
569                    }
570                    else {
571                            return false;
572                    }
573            }
574    
575            public void read(
576                            String servletContextName, ClassLoader classLoader, String source)
577                    throws Exception {
578    
579                    InputStream inputStream = classLoader.getResourceAsStream(source);
580    
581                    if (inputStream == null) {
582                            if (_log.isWarnEnabled() && !source.endsWith("-ext.xml")) {
583                                    _log.warn("Cannot load " + source);
584                            }
585    
586                            return;
587                    }
588    
589                    if (_log.isDebugEnabled()) {
590                            _log.debug("Loading " + source);
591                    }
592    
593                    Document document = SAXReaderUtil.read(inputStream, true);
594    
595                    DocumentType documentType = document.getDocumentType();
596    
597                    String publicId = GetterUtil.getString(documentType.getPublicId());
598    
599                    if (publicId.equals(
600                                    "-//Liferay//DTD Resource Action Mapping 6.0.0//EN")) {
601    
602                            if (_log.isWarnEnabled()) {
603                                    _log.warn(
604                                            "Please update " + source + " to use the 6.1.0 format");
605                            }
606                    }
607    
608                    Element rootElement = document.getRootElement();
609    
610                    for (Element resourceElement : rootElement.elements("resource")) {
611                            String file = resourceElement.attributeValue("file").trim();
612    
613                            read(servletContextName, classLoader, file);
614    
615                            String extFile = StringUtil.replace(file, ".xml", "-ext.xml");
616    
617                            read(servletContextName, classLoader, extFile);
618                    }
619    
620                    read(servletContextName, document);
621            }
622    
623            public void read(String servletContextName, InputStream inputStream)
624                    throws Exception {
625    
626                    Document document = SAXReaderUtil.read(inputStream, true);
627    
628                    read(servletContextName, document);
629            }
630    
631            public void setPortal(Portal portal) {
632                    this.portal = portal;
633            }
634    
635            protected void checkGuestUnsupportedActions(
636                    List<String> guestUnsupportedActions,
637                    List<String> guestDefaultActions) {
638    
639                    // Guest default actions cannot reference guest unsupported actions
640    
641                    Iterator<String> itr = guestDefaultActions.iterator();
642    
643                    while (itr.hasNext()) {
644                            String actionId = itr.next();
645    
646                            if (guestUnsupportedActions.contains(actionId)) {
647                                    itr.remove();
648                            }
649                    }
650            }
651    
652            protected void checkModelActions(List<String> actions) {
653                    if (!actions.contains(ActionKeys.PERMISSIONS)) {
654                            actions.add(ActionKeys.PERMISSIONS);
655                    }
656            }
657    
658            protected void checkPortletActions(Portlet portlet, List<String> actions) {
659                    if (!actions.contains(ActionKeys.ACCESS_IN_CONTROL_PANEL) &&
660                            !actions.contains(ActionKeys.ADD_TO_PAGE)) {
661    
662                            actions.add(ActionKeys.ADD_TO_PAGE);
663                    }
664    
665                    if ((portlet != null) &&
666                            (portlet.getControlPanelEntryCategory() != null) &&
667                            !actions.contains(ActionKeys.ACCESS_IN_CONTROL_PANEL)) {
668    
669                            actions.add(ActionKeys.ACCESS_IN_CONTROL_PANEL);
670                    }
671    
672                    if (!actions.contains(ActionKeys.CONFIGURATION)) {
673                            actions.add(ActionKeys.CONFIGURATION);
674                    }
675    
676                    if (!actions.contains(ActionKeys.PERMISSIONS)) {
677                            actions.add(ActionKeys.PERMISSIONS);
678                    }
679    
680                    if (!actions.contains(ActionKeys.VIEW)) {
681                            actions.add(ActionKeys.VIEW);
682                    }
683            }
684    
685            protected void checkPortletActions(String name, List<String> actions) {
686                    Portlet portlet = portletLocalService.getPortletById(name);
687    
688                    checkPortletActions(portlet, actions);
689            }
690    
691            protected void checkPortletGroupDefaultActions(List<String> actions) {
692                    if (actions.isEmpty()) {
693                            actions.add(ActionKeys.VIEW);
694                    }
695            }
696    
697            protected void checkPortletGuestDefaultActions(List<String> actions) {
698                    if (actions.isEmpty()) {
699                            actions.add(ActionKeys.VIEW);
700                    }
701            }
702    
703            protected void checkPortletLayoutManagerActions(List<String> actions) {
704                    if (!actions.contains(ActionKeys.CONFIGURATION)) {
705                            actions.add(ActionKeys.CONFIGURATION);
706                    }
707    
708                    if (!actions.contains(ActionKeys.PERMISSIONS)) {
709                            actions.add(ActionKeys.PERMISSIONS);
710                    }
711    
712                    if (!actions.contains(ActionKeys.PREFERENCES)) {
713                            actions.add(ActionKeys.PREFERENCES);
714                    }
715    
716                    if (!actions.contains(ActionKeys.VIEW)) {
717                            actions.add(ActionKeys.VIEW);
718                    }
719            }
720    
721            protected List<String> getActions(
722                    Map<String, List<String>> actionsMap, String name) {
723    
724                    List<String> actions = actionsMap.get(name);
725    
726                    if (actions == null) {
727                            actions = new UniqueList<String>();
728    
729                            actionsMap.put(name, actions);
730                    }
731    
732                    return actions;
733            }
734    
735            protected Element getPermissionsChildElement(
736                    Element parentElement, String childElementName) {
737    
738                    Element permissionsElement = parentElement.element("permissions");
739    
740                    if (permissionsElement != null) {
741                            return permissionsElement.element(childElementName);
742                    }
743                    else {
744                            return parentElement.element(childElementName);
745                    }
746            }
747    
748            protected List<String> getPortletMimeTypeActions(String name) {
749                    List<String> actions = new UniqueList<String>();
750    
751                    Portlet portlet = portletLocalService.getPortletById(name);
752    
753                    if (portlet != null) {
754                            Map<String, Set<String>> portletModes = portlet.getPortletModes();
755    
756                            Set<String> mimeTypePortletModes = portletModes.get(
757                                    ContentTypes.TEXT_HTML);
758    
759                            if (mimeTypePortletModes != null) {
760                                    for (String actionId : mimeTypePortletModes) {
761                                            if (actionId.equalsIgnoreCase("edit")) {
762                                                    actions.add(ActionKeys.PREFERENCES);
763                                            }
764                                            else if (actionId.equalsIgnoreCase("edit_guest")) {
765                                                    actions.add(ActionKeys.GUEST_PREFERENCES);
766                                            }
767                                            else {
768                                                    actions.add(actionId.toUpperCase());
769                                            }
770                                    }
771                            }
772                    }
773                    else {
774                            if (_log.isDebugEnabled()) {
775                                    _log.debug(
776                                            "Unable to obtain resource actions for unknown portlet " +
777                                                    name);
778                            }
779                    }
780    
781                    return actions;
782            }
783    
784            protected int[] getRoleTypes(
785                    long companyId, Group group, String modelResource) {
786    
787                    int[] types = {
788                            RoleConstants.TYPE_REGULAR, RoleConstants.TYPE_SITE
789                    };
790    
791                    if (isPortalModelResource(modelResource)) {
792                            if (modelResource.equals(Organization.class.getName()) ||
793                                    modelResource.equals(User.class.getName())) {
794    
795                                    types = new int[] {
796                                            RoleConstants.TYPE_REGULAR, RoleConstants.TYPE_ORGANIZATION
797                                    };
798                            }
799                            else {
800                                    types = new int[] {RoleConstants.TYPE_REGULAR};
801                            }
802                    }
803                    else {
804                            if (group != null) {
805                                    if (group.isLayout()) {
806                                            try {
807                                                    group = GroupServiceUtil.getGroup(
808                                                            group.getParentGroupId());
809                                            }
810                                            catch (Exception e) {
811                                            }
812                                    }
813    
814                                    if (group.isOrganization()) {
815                                            types = new int[] {
816                                                    RoleConstants.TYPE_REGULAR,
817                                                    RoleConstants.TYPE_ORGANIZATION, RoleConstants.TYPE_SITE
818                                            };
819                                    }
820                                    else if (group.isUser()) {
821                                            types = new int[] {RoleConstants.TYPE_REGULAR};
822                                    }
823                            }
824                    }
825    
826                    return types;
827            }
828    
829            protected void read(String servletContextName, Document document)
830                    throws Exception {
831    
832                    Element rootElement = document.getRootElement();
833    
834                    if (PropsValues.RESOURCE_ACTIONS_READ_PORTLET_RESOURCES) {
835                            for (Element portletResourceElement :
836                                            rootElement.elements("portlet-resource")) {
837    
838                                    readPortletResource(servletContextName, portletResourceElement);
839                            }
840                    }
841    
842                    for (Element modelResourceElement :
843                                    rootElement.elements("model-resource")) {
844    
845                            readModelResource(servletContextName, modelResourceElement);
846                    }
847            }
848    
849            protected List<String> readActionKeys(Element parentElement) {
850                    List<String> actions = new ArrayList<String>();
851    
852                    for (Element actionKeyElement : parentElement.elements("action-key")) {
853                            String actionKey = actionKeyElement.getTextTrim();
854    
855                            if (Validator.isNull(actionKey)) {
856                                    continue;
857                            }
858    
859                            actions.add(actionKey);
860                    }
861    
862                    return actions;
863            }
864    
865            protected void readGroupDefaultActions(
866                    Element parentElement, Map<String, List<String>> actionsMap,
867                    String name) {
868    
869                    List<String> groupDefaultActions = new UniqueList<String>(
870                            getActions(actionsMap, name));
871    
872                    Element groupDefaultsElement = getPermissionsChildElement(
873                            parentElement, "site-member-defaults");
874    
875                    if (groupDefaultsElement == null) {
876                            groupDefaultsElement = getPermissionsChildElement(
877                                    parentElement, "community-defaults");
878    
879                            if (_log.isWarnEnabled() && (groupDefaultsElement != null)) {
880                                    _log.warn(
881                                            "The community-defaults element is deprecated. Use the " +
882                                                    "site-member-defaults element instead.");
883                            }
884                    }
885    
886                    groupDefaultActions.addAll(readActionKeys(groupDefaultsElement));
887    
888                    setActions(actionsMap, name, groupDefaultActions);
889            }
890    
891            protected List<String> readGuestDefaultActions(
892                    Element parentElement, Map<String, List<String>> actionsMap,
893                    String name) {
894    
895                    List<String> guestDefaultActions = new UniqueList<String>(
896                            getActions(actionsMap, name));
897    
898                    Element guestDefaultsElement = getPermissionsChildElement(
899                            parentElement, "guest-defaults");
900    
901                    guestDefaultActions.addAll(readActionKeys(guestDefaultsElement));
902    
903                    return guestDefaultActions;
904            }
905    
906            protected void readGuestUnsupportedActions(
907                    Element parentElement, Map<String, List<String>> actionsMap,
908                    String name, List<String> guestDefaultActions) {
909    
910                    List<String> guestUnsupportedActions = new UniqueList<String>(
911                            getActions(actionsMap, name));
912    
913                    Element guestUnsupportedElement = getPermissionsChildElement(
914                            parentElement, "guest-unsupported");
915    
916                    guestUnsupportedActions.addAll(readActionKeys(guestUnsupportedElement));
917    
918                    checkGuestUnsupportedActions(
919                            guestUnsupportedActions, guestDefaultActions);
920    
921                    setActions(actionsMap, name, guestUnsupportedActions);
922            }
923    
924            protected void readLayoutManagerActions(
925                    Element parentElement, Map<String, List<String>> actionsMap,
926                    String name, List<String> supportsActions) {
927    
928                    List<String> layoutManagerActions = new UniqueList<String>(
929                            getActions(actionsMap, name));
930    
931                    Element layoutManagerElement = getPermissionsChildElement(
932                            parentElement, "layout-manager");
933    
934                    if (layoutManagerElement != null) {
935                            layoutManagerActions.addAll(readActionKeys(layoutManagerElement));
936                    }
937                    else {
938                            layoutManagerActions.addAll(supportsActions);
939                    }
940    
941                    setActions(actionsMap, name, layoutManagerActions);
942            }
943    
944            protected void readModelResource(
945                    String servletContextName, Element modelResourceElement) {
946    
947                    String name = modelResourceElement.elementTextTrim("model-name");
948    
949                    Element portletRefElement = modelResourceElement.element("portlet-ref");
950    
951                    for (Element portletNameElement :
952                                    portletRefElement.elements("portlet-name")) {
953    
954                            String portletName = portletNameElement.getTextTrim();
955    
956                            if (servletContextName != null) {
957                                    portletName = portletName.concat(
958                                            PortletConstants.WAR_SEPARATOR).concat(servletContextName);
959                            }
960    
961                            portletName = portal.getJsSafePortletId(portletName);
962    
963                            // Reference for a portlet to child models
964    
965                            Set<String> modelResources = _portletModelResources.get(
966                                    portletName);
967    
968                            if (modelResources == null) {
969                                    modelResources = new HashSet<String>();
970    
971                                    _portletModelResources.put(portletName, modelResources);
972                            }
973    
974                            modelResources.add(name);
975    
976                            // Reference for a model to parent portlets
977    
978                            Set<String> portletResources = _modelPortletResources.get(name);
979    
980                            if (portletResources == null) {
981                                    portletResources = new HashSet<String>();
982    
983                                    _modelPortletResources.put(name, portletResources);
984                            }
985    
986                            portletResources.add(portletName);
987                    }
988    
989                    List<String> supportsActions = readSupportsActions(
990                            modelResourceElement, _modelResourceActions, name);
991    
992                    checkModelActions(supportsActions);
993    
994                    setActions(_modelResourceActions, name, supportsActions);
995    
996                    readGroupDefaultActions(
997                            modelResourceElement, _modelResourceGroupDefaultActions, name);
998    
999                    List<String> guestDefaultActions = readGuestDefaultActions(
1000                            modelResourceElement, _modelResourceGuestDefaultActions, name);
1001    
1002                    readGuestUnsupportedActions(
1003                            modelResourceElement, _modelResourceGuestUnsupportedActions, name,
1004                            guestDefaultActions);
1005    
1006                    setActions(
1007                            _modelResourceGuestDefaultActions, name, guestDefaultActions);
1008    
1009                    readOwnerDefaultActions(
1010                            modelResourceElement, _modelResourceOwnerDefaultActions, name);
1011            }
1012    
1013            protected void readOwnerDefaultActions(
1014                    Element parentElement, Map<String, List<String>> actionsMap,
1015                    String name) {
1016    
1017                    List<String> ownerDefaultActions = new UniqueList<String>(
1018                            getActions(actionsMap, name));
1019    
1020                    Element ownerDefaultsElement = getPermissionsChildElement(
1021                            parentElement, "owner-defaults");
1022    
1023                    if (ownerDefaultsElement == null) {
1024                            return;
1025                    }
1026    
1027                    ownerDefaultActions.addAll(readActionKeys(ownerDefaultsElement));
1028    
1029                    setActions(actionsMap, name, ownerDefaultActions);
1030            }
1031    
1032            protected void readPortletResource(
1033                    String servletContextName, Element portletResourceElement) {
1034    
1035                    String name = portletResourceElement.elementTextTrim("portlet-name");
1036    
1037                    if (servletContextName != null) {
1038                            name = name.concat(PortletConstants.WAR_SEPARATOR).concat(
1039                                    servletContextName);
1040                    }
1041    
1042                    name = portal.getJsSafePortletId(name);
1043    
1044                    List<String> supportsActions = readSupportsActions(
1045                            portletResourceElement, _portletResourceActions, name);
1046    
1047                    supportsActions.addAll(getPortletMimeTypeActions(name));
1048    
1049                    if (!name.equals(PortletKeys.PORTAL)) {
1050                            checkPortletActions(name, supportsActions);
1051                    }
1052    
1053                    supportsActions = setActions(
1054                            _portletResourceActions, name, supportsActions);
1055    
1056                    readGroupDefaultActions(
1057                            portletResourceElement, _portletResourceGroupDefaultActions, name);
1058    
1059                    List<String> guestDefaultActions = readGuestDefaultActions(
1060                            portletResourceElement, _portletResourceGuestDefaultActions, name);
1061    
1062                    readGuestUnsupportedActions(
1063                            portletResourceElement, _portletResourceGuestUnsupportedActions,
1064                            name, guestDefaultActions);
1065    
1066                    setActions(
1067                            _portletResourceGuestDefaultActions, name, guestDefaultActions);
1068    
1069                    readLayoutManagerActions(
1070                            portletResourceElement, _portletResourceLayoutManagerActions, name,
1071                            supportsActions);
1072            }
1073    
1074            protected List<String> readSupportsActions(
1075                    Element parentElement, Map<String, List<String>> actionsMap,
1076                    String name) {
1077    
1078                    List<String> supportsActions = new UniqueList<String>(
1079                            getActions(actionsMap, name));
1080    
1081                    Element supportsElement = getPermissionsChildElement(
1082                            parentElement, "supports");
1083    
1084                    supportsActions.addAll(readActionKeys(supportsElement));
1085    
1086                    return supportsActions;
1087            }
1088    
1089            protected List<String> setActions(
1090                    Map<String, List<String>> actionsMap, String name,
1091                    List<String> actions) {
1092    
1093                    actions = new UnmodifiableList<String>(actions);
1094    
1095                    actionsMap.put(name, actions);
1096    
1097                    return actions;
1098            }
1099    
1100            protected Portal portal;
1101            @BeanReference(type = PortletLocalService.class)
1102            protected PortletLocalService portletLocalService;
1103            @BeanReference(type = ResourceActionLocalService.class)
1104            protected ResourceActionLocalService resourceActionLocalService;
1105            @BeanReference(type = RoleLocalService.class)
1106            protected RoleLocalService roleLocalService;
1107    
1108            private static final String _ACTION_NAME_PREFIX = "action.";
1109    
1110            private static final String _MODEL_RESOURCE_NAME_PREFIX = "model.resource.";
1111    
1112            private static final String[] _ORGANIZATION_MODEL_RESOURCES = {
1113                    Organization.class.getName(), PasswordPolicy.class.getName(),
1114                    User.class.getName()
1115            };
1116    
1117            private static final String[] _PORTAL_MODEL_RESOURCES = {
1118                    ExpandoColumn.class.getName(), LayoutPrototype.class.getName(),
1119                    LayoutSetPrototype.class.getName(), MDRRuleGroup.class.getName(),
1120                    Organization.class.getName(), PasswordPolicy.class.getName(),
1121                    Role.class.getName(), User.class.getName(), UserGroup.class.getName()
1122            };
1123    
1124            private static Log _log = LogFactoryUtil.getLog(ResourceActionsImpl.class);
1125    
1126            private Map<String, Set<String>> _modelPortletResources;
1127            private Map<String, List<String>> _modelResourceActions;
1128            private Map<String, List<String>> _modelResourceGroupDefaultActions;
1129            private Map<String, List<String>> _modelResourceGuestDefaultActions;
1130            private Map<String, List<String>> _modelResourceGuestUnsupportedActions;
1131            private Map<String, List<String>> _modelResourceOwnerDefaultActions;
1132            private Set<String> _organizationModelResources;
1133            private Set<String> _portalModelResources;
1134            private Map<String, Set<String>> _portletModelResources;
1135            private Map<String, List<String>> _portletResourceActions;
1136            private Map<String, List<String>> _portletResourceGroupDefaultActions;
1137            private Map<String, List<String>> _portletResourceGuestDefaultActions;
1138            private Map<String, List<String>> _portletResourceGuestUnsupportedActions;
1139            private Map<String, List<String>> _portletResourceLayoutManagerActions;
1140    
1141    }