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