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