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.HashSet;
020import java.util.List;
021import java.util.Set;
022
023import org.apache.avalon.framework.context.Context;
024import org.apache.avalon.framework.context.ContextException;
025import org.apache.avalon.framework.context.Contextualizable;
026import org.apache.avalon.framework.service.ServiceException;
027import org.apache.avalon.framework.service.ServiceManager;
028import org.apache.cocoon.components.ContextHelper;
029import org.apache.cocoon.environment.Request;
030
031import org.ametys.cms.content.ContentHelper;
032import org.ametys.cms.content.archive.ArchiveConstants;
033import org.ametys.cms.repository.Content;
034import org.ametys.core.right.AccessController;
035import org.ametys.odf.ODFHelper;
036import org.ametys.odf.ProgramItem;
037import org.ametys.odf.course.Course;
038import org.ametys.odf.courselist.CourseList;
039import org.ametys.odf.orgunit.OrgUnit;
040import org.ametys.odf.person.Person;
041import org.ametys.plugins.core.impl.right.AbstractHierarchicalAccessController;
042import org.ametys.plugins.repository.AmetysObject;
043import org.ametys.plugins.repository.AmetysObjectResolver;
044import org.ametys.plugins.repository.RepositoryConstants;
045import org.ametys.plugins.repository.collection.AmetysObjectCollection;
046import org.ametys.plugins.repository.provider.RequestAttributeWorkspaceSelector;
047
048/**
049 * {@link AccessController} for a ODF {@link Content}
050 */
051public class ODFContentHierarchicalAccessController extends AbstractHierarchicalAccessController<AmetysObject> implements Contextualizable
052{
053    /** The helper for root content */
054    protected ODFHelper _odfHelper;
055    /** The helper for contents */
056    protected ContentHelper _contentHelper;
057    /** The avalon context */
058    protected Context _context;
059    /** Ametys Object Resolver */
060    protected AmetysObjectResolver _resolver;
061
062
063    public void contextualize(Context context) throws ContextException
064    {
065        _context = context;
066    }
067    
068    @Override
069    public void service(ServiceManager manager) throws ServiceException
070    {
071        super.service(manager);
072        _odfHelper = (ODFHelper) manager.lookup(ODFHelper.ROLE);
073        _contentHelper = (ContentHelper) manager.lookup(ContentHelper.ROLE);
074        _resolver = (AmetysObjectResolver) manager.lookup(AmetysObjectResolver.ROLE);
075    }
076    
077    @Override
078    public boolean isSupported(Object object)
079    {
080        return object instanceof ProgramItem || object instanceof OrgUnit || object instanceof Person;
081    }
082    
083    /**
084     * Determines if the object is a orphan program item (without parent)
085     * @param object the object
086     * @return true if the object is a orphan program item 
087     */
088    protected boolean _isOrphanProgramItem(Object object)
089    {
090        if (object instanceof ProgramItem)
091        {
092            List<ProgramItem> parentProgramItems = _odfHelper.getParentProgramItems((ProgramItem) object);
093            return parentProgramItems.isEmpty();
094        }
095        
096        return false;
097    }
098    
099    @Override
100    protected Set<AmetysObject> _getParents(AmetysObject object)
101    {
102        if (object instanceof Content)
103        {
104            Set<AmetysObject> parents = new HashSet<>();
105            
106            if (object instanceof ProgramItem)
107            {
108                List<ProgramItem> parentProgramItems = _odfHelper.getParentProgramItems((ProgramItem) object);
109                if (parentProgramItems.size() > 0)
110                {
111                    parents.addAll(parentProgramItems);
112                }
113            }
114            else if (object instanceof Course)
115            {
116                List<CourseList> parentCls = ((Course) object).getParentCourseLists();
117                if (parentCls.size() > 0)
118                {
119                    parents.addAll(parentCls);
120                }
121            }
122            else if (object instanceof OrgUnit)
123            {
124                OrgUnit parentOrgUnit = ((OrgUnit) object).getParentOrgUnit();
125                if (parentOrgUnit != null)
126                {
127                    parents.add(parentOrgUnit);
128                }
129            }
130            
131            // default
132            AmetysObject parent = object.getParent();
133            boolean parentAdded = false;
134            if (parent instanceof AmetysObjectCollection && (RepositoryConstants.NAMESPACE_PREFIX + ":contents").equals(((AmetysObjectCollection) parent).getName()))
135            {
136                Request request = ContextHelper.getRequest(_context);
137                String originalWorkspace = RequestAttributeWorkspaceSelector.getForcedWorkspace(request);
138                if (ArchiveConstants.ARCHIVE_WORKSPACE.equals(originalWorkspace))
139                {
140                    try
141                    {
142                        RequestAttributeWorkspaceSelector.setForcedWorkspace(request, RepositoryConstants.DEFAULT_WORKSPACE);
143                        AmetysObject parentFromDefault = _resolver.resolveByPath(parent.getPath());
144                        parents.add(parentFromDefault);
145                        parentAdded = true;
146                    }
147                    finally
148                    {
149                        RequestAttributeWorkspaceSelector.setForcedWorkspace(request, originalWorkspace);
150                    }
151                }
152            }
153            if (!parentAdded)
154            {
155                parents.add(parent);
156            }
157            
158            return parents;
159        }
160        else
161        {
162            return null;
163        }
164    }
165    
166    @Override
167    protected Set< ? extends Object> _convertWorkspaceToRootRightContexts(Set<Object> workspacesContexts)
168    {
169        if (workspacesContexts.contains("/cms"))
170        {
171            return Collections.singleton(_odfHelper.getRootContent());
172        }
173        return null;
174    }
175}