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