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