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