001/*
002 *  Copyright 2016 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.ametys.odf.rights;
017
018import java.util.Collections;
019import java.util.Map;
020import java.util.Set;
021
022import org.apache.avalon.framework.service.ServiceException;
023import org.apache.avalon.framework.service.ServiceManager;
024import org.apache.commons.lang3.StringUtils;
025
026import org.ametys.cms.content.ContentHelper;
027import org.ametys.cms.repository.Content;
028import org.ametys.core.right.AccessController;
029import org.ametys.core.right.RightsException;
030import org.ametys.odf.ODFHelper;
031import org.ametys.odf.ProgramItem;
032import org.ametys.odf.coursepart.CoursePart;
033import org.ametys.odf.orgunit.OrgUnit;
034import org.ametys.odf.person.Person;
035import org.ametys.odf.rights.ODFRightHelper.PermissionContext;
036import org.ametys.odf.tree.ODFContentsTreeHelper;
037import org.ametys.plugins.core.impl.right.AbstractHierarchicalWithPermissionContextAccessController;
038import org.ametys.plugins.repository.AmetysObject;
039import org.ametys.plugins.repository.AmetysObjectResolver;
040import org.ametys.plugins.repository.collection.AmetysObjectCollection;
041import org.ametys.runtime.i18n.I18nizableText;
042import org.ametys.runtime.i18n.I18nizableTextParameter;
043
044/**
045 * {@link AccessController} for a ODF {@link Content}
046 */
047public class ODFContentHierarchicalAccessController extends AbstractHierarchicalWithPermissionContextAccessController<AmetysObject, ODFRightHelper.PermissionContext>
048{
049    /** the odf context category */
050    public static final I18nizableText ODF_CONTEXT_CATEGORY = new I18nizableText("plugin.odf", "PLUGINS_ODF_RIGHT_ASSIGNMENT_CONTEXT_CONTENTS_LABEL");
051    /** The helper for root content */
052    protected ODFHelper _odfHelper;
053    /** The helper for contents */
054    protected ContentHelper _contentHelper;
055    /** Ametys Object Resolver */
056    protected AmetysObjectResolver _resolver;
057    /** The right helper for ODF contents */
058    protected ODFRightHelper _odfRightHelper;
059    /** The ODF contents tree helper */
060    protected ODFContentsTreeHelper _odfContentTreeHelper;
061    
062    @Override
063    public void service(ServiceManager manager) throws ServiceException
064    {
065        super.service(manager);
066        _odfContentTreeHelper = (ODFContentsTreeHelper) manager.lookup(ODFContentsTreeHelper.ROLE);
067        _odfHelper = (ODFHelper) manager.lookup(ODFHelper.ROLE);
068        _odfRightHelper = (ODFRightHelper) manager.lookup(ODFRightHelper.ROLE);
069        _contentHelper = (ContentHelper) manager.lookup(ContentHelper.ROLE);
070        _resolver = (AmetysObjectResolver) manager.lookup(AmetysObjectResolver.ROLE);
071    }
072    
073    @Override
074    public boolean isSupported(Object object)
075    {
076        return object instanceof ProgramItem || object instanceof OrgUnit || object instanceof Person || object instanceof CoursePart || object.equals(_odfHelper.getRootContent());
077    }
078    
079    @Override
080    protected Set<AmetysObject> _getParents(AmetysObject object, PermissionContext permissionCtx)
081    {
082        if (!(object instanceof Content))
083        {
084            return null;
085        }
086        
087        return _odfRightHelper.getParents((Content) object, permissionCtx);
088    }
089    
090    @Override
091    protected PermissionContext _getPermissionContext(AmetysObject initialObject)
092    {
093        return new PermissionContext((Content) initialObject);
094    }
095    
096    @Override
097    protected Set< ? extends Object> _convertWorkspaceToRootRightContexts(Set<Object> workspacesContexts)
098    {
099        if (workspacesContexts.contains("/cms"))
100        {
101            return Collections.singleton(_odfHelper.getRootContent());
102        }
103        return null;
104    }
105    
106    @Override
107    protected I18nizableText getObjectLabelForExplanation(Object object) throws RightsException
108    {
109        if (object instanceof Content)
110        {
111            Map<String, I18nizableTextParameter> params = Map.of("title", getObjectLabel(object));
112            if (object instanceof ProgramItem)
113            {
114                return new I18nizableText("plugin.odf", "PLUGINS_ODF_ODF_CONTENT_ACCESS_CONTROLLER_PROGRAM_ITEM_CONTEXT_LABEL", params);
115            }
116            else if (object instanceof CoursePart)
117            {
118                return new I18nizableText("plugin.odf", "PLUGINS_ODF_ODF_CONTENT_ACCESS_CONTROLLER_COURSE_PART_CONTEXT_LABEL", params);
119            }
120            else if (object instanceof OrgUnit)
121            {
122                return new I18nizableText("plugin.odf", "PLUGINS_ODF_ODF_CONTENT_ACCESS_CONTROLLER_ORGUNIT_CONTEXT_LABEL", params);
123            }
124            else if (object instanceof Person)
125            {
126                return new I18nizableText("plugin.odf", "PLUGINS_ODF_ODF_CONTENT_ACCESS_CONTROLLER_PERSON_CONTEXT_LABEL", params);
127            }
128        }
129        else if (object.equals(_odfHelper.getRootContent()))
130        {
131            return new I18nizableText("plugin.odf", "PLUGINS_ODF_ODF_CONTENT_ACCESS_CONTROLLER_ROOT_CONTEXT_EXPLANATION_LABEL");
132        }
133        
134        throw new RightsException("Unsupported object " + object.toString());
135    }
136    
137    public I18nizableText getObjectLabel(Object object)
138    {
139        if (object instanceof Content content)
140        {
141            return getContentObjectLabel(content, _odfContentTreeHelper);
142        }
143        else if (object.equals(_odfHelper.getRootContent()))
144        {
145            return new I18nizableText("plugin.odf", "PLUGINS_ODF_ODF_CONTENT_ACCESS_CONTROLLER_ROOT_CONTEXT_LABEL");
146        }
147        throw new RightsException("Unsupported context: " + object.toString());
148    }
149    
150    public I18nizableText getObjectCategory(Object object)
151    {
152        return ODF_CONTEXT_CATEGORY;
153    }
154    
155    public int getObjectPriority(Object object)
156    {
157        if (object instanceof AmetysObjectCollection)
158        {
159            return 10;
160        }
161        return super.getObjectPriority(object);
162    }
163
164    /**
165     * Get a standardized object label for an ODF content
166     * @param content the content
167     * @param helper  the ODF content tree helper
168     * @return the label
169     */
170    public static I18nizableText getContentObjectLabel(Content content, ODFContentsTreeHelper helper)
171    {
172        String code = null;
173        if (content instanceof ProgramItem)
174        {
175            code = helper.getProgramItemDisplayCode((ProgramItem & Content) content);
176        }
177        
178        if (StringUtils.isNotEmpty(code))
179        {
180            return new I18nizableText(content.getTitle() + " [" + code + "]");
181        }
182        else
183        {
184            return new I18nizableText(content.getTitle());
185        }
186    }
187}