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