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    public boolean supports(Object object)
074    {
075        return object instanceof ProgramItem || object instanceof OrgUnit || object instanceof Person || object instanceof CoursePart || object.equals(_odfHelper.getRootContent());
076    }
077    
078    @Override
079    protected Set<AmetysObject> _getParents(AmetysObject object, PermissionContext permissionCtx)
080    {
081        if (!(object instanceof Content))
082        {
083            return null;
084        }
085        
086        return _odfRightHelper.getParents((Content) object, permissionCtx);
087    }
088    
089    @Override
090    protected PermissionContext _getPermissionContext(AmetysObject initialObject)
091    {
092        return new PermissionContext((Content) initialObject);
093    }
094    
095    @Override
096    protected Set< ? extends Object> _convertWorkspaceToRootRightContexts(Set<Object> workspacesContexts)
097    {
098        if (workspacesContexts.contains("/cms"))
099        {
100            return Collections.singleton(_odfHelper.getRootContent());
101        }
102        return null;
103    }
104    
105    @Override
106    protected I18nizableText getObjectLabelForExplanation(Object object) throws RightsException
107    {
108        if (object instanceof Content)
109        {
110            Map<String, I18nizableTextParameter> params = Map.of("title", getObjectLabel(object));
111            if (object instanceof ProgramItem)
112            {
113                return new I18nizableText("plugin.odf", "PLUGINS_ODF_ODF_CONTENT_ACCESS_CONTROLLER_PROGRAM_ITEM_CONTEXT_LABEL", params);
114            }
115            else if (object instanceof CoursePart)
116            {
117                return new I18nizableText("plugin.odf", "PLUGINS_ODF_ODF_CONTENT_ACCESS_CONTROLLER_COURSE_PART_CONTEXT_LABEL", params);
118            }
119            else if (object instanceof OrgUnit)
120            {
121                return new I18nizableText("plugin.odf", "PLUGINS_ODF_ODF_CONTENT_ACCESS_CONTROLLER_ORGUNIT_CONTEXT_LABEL", params);
122            }
123            else if (object instanceof Person)
124            {
125                return new I18nizableText("plugin.odf", "PLUGINS_ODF_ODF_CONTENT_ACCESS_CONTROLLER_PERSON_CONTEXT_LABEL", params);
126            }
127        }
128        else if (object.equals(_odfHelper.getRootContent()))
129        {
130            return new I18nizableText("plugin.odf", "PLUGINS_ODF_ODF_CONTENT_ACCESS_CONTROLLER_ROOT_CONTEXT_EXPLANATION_LABEL");
131        }
132        
133        throw new RightsException("Unsupported object " + object.toString());
134    }
135    
136    public I18nizableText getObjectLabel(Object object)
137    {
138        if (object instanceof Content content)
139        {
140            return getContentObjectLabel(content, _odfContentTreeHelper);
141        }
142        else if (object.equals(_odfHelper.getRootContent()))
143        {
144            return new I18nizableText("plugin.odf", "PLUGINS_ODF_ODF_CONTENT_ACCESS_CONTROLLER_ROOT_CONTEXT_LABEL");
145        }
146        throw new RightsException("Unsupported context: " + object.toString());
147    }
148    
149    public I18nizableText getObjectCategory(Object object)
150    {
151        return ODF_CONTEXT_CATEGORY;
152    }
153    
154    public int getObjectPriority(Object object)
155    {
156        if (object instanceof AmetysObjectCollection)
157        {
158            return 10;
159        }
160        return super.getObjectPriority(object);
161    }
162
163    /**
164     * Get a standardized object label for an ODF content
165     * @param content the content
166     * @param helper  the ODF content tree helper
167     * @return the label
168     */
169    public static I18nizableText getContentObjectLabel(Content content, ODFContentsTreeHelper helper)
170    {
171        String code = null;
172        if (content instanceof ProgramItem)
173        {
174            code = helper.getProgramItemDisplayCode((ProgramItem & Content) content);
175        }
176        
177        if (StringUtils.isNotEmpty(code))
178        {
179            return new I18nizableText(content.getTitle() + " [" + code + "]");
180        }
181        else
182        {
183            return new I18nizableText(content.getTitle());
184        }
185    }
186}