001/*
002 *  Copyright 2010 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.plugins.odfweb.repository;
017
018import java.util.Map;
019
020import org.apache.avalon.framework.service.ServiceException;
021import org.apache.avalon.framework.service.ServiceManager;
022import org.apache.avalon.framework.service.Serviceable;
023import org.apache.commons.lang3.StringUtils;
024
025import org.ametys.odf.course.Course;
026import org.ametys.odf.program.Program;
027import org.ametys.plugins.repository.AmetysObjectFactory;
028import org.ametys.plugins.repository.AmetysObjectResolver;
029import org.ametys.plugins.repository.AmetysRepositoryException;
030import org.ametys.plugins.repository.UnknownAmetysObjectException;
031import org.ametys.web.repository.page.Page;
032
033import com.google.common.base.Splitter;
034
035/**
036 * {@link AmetysObjectFactory} handling {@link ProgramPage}.
037 */
038public class CoursePageFactory implements AmetysObjectFactory<CoursePage>, Serviceable
039{
040    AmetysObjectResolver _resolver;
041    OdfPageHandler _odfPageHandler;
042    
043    @Override
044    public void service(ServiceManager manager) throws ServiceException
045    {
046        _resolver = (AmetysObjectResolver) manager.lookup(AmetysObjectResolver.ROLE);
047        _odfPageHandler = (OdfPageHandler) manager.lookup(OdfPageHandler.ROLE);
048    }
049    
050    @Override
051    public CoursePage getAmetysObjectById(String id) throws AmetysRepositoryException
052    {
053        // Id is like // E.g: course://path/from/program?rootId=xxx&courseId=xxx&programId=xxxx
054        String path = StringUtils.substringBetween(id, "://", "?");
055        String queryString = StringUtils.substringAfter(id, "?");
056        Map<String, String> ids = Splitter.on("&").withKeyValueSeparator("=").split(queryString);
057        
058        String rootId = ids.get("rootId");
059        String courseId = ids.get("courseId");
060        String programId = ids.get("programId");
061        
062        try
063        {
064            Page root = _resolver.resolveById(rootId);
065            Course course = _resolver.resolveById(courseId);
066            Program program = _resolver.resolveById(programId);
067            
068            // Check that parent ProgramPage exists
069            String levelPath = _computeLevelsPath(root, program);
070            root.getChild(levelPath + "/" + path);
071            
072            return new CoursePage(_resolver, _odfPageHandler, root, course, program, path, null);
073        }
074        catch (UnknownAmetysObjectException e)
075        {
076            throw new UnknownAmetysObjectException("There's no object for id " + id, e);
077        }
078    }
079    
080    /**
081     * Compute the path from the root odf page, representing the first and second level pages.
082     * @param root The odf root page
083     * @param program The program to compute
084     * @return the path
085     */
086    String _computeLevelsPath(Page root, Program program)
087    {
088        String level1 = _odfPageHandler.getProgramLevel1Value(root, program);
089        String level2 = _odfPageHandler.getProgramLevel2Value(root, program);
090        
091        // The path is no more valid, re-calculate the real path
092        String secondLevelPageId = "odfLevel2://" + level1 + "/" + level2 + "?rootId=" + root.getId();
093        Page secondLevelPage = _resolver.resolveById(secondLevelPageId);
094        
095        return secondLevelPage.getParent().getName() + "/" + secondLevelPage.getName();
096    }
097
098    @Override
099    public String getScheme()
100    {
101        return "course";
102    }
103
104    @Override
105    public boolean hasAmetysObjectForId(String id) throws AmetysRepositoryException
106    {
107        String path = StringUtils.substringBetween(id, "://", "?");
108        String queryString = StringUtils.substringAfter(id, "?");
109        Map<String, String> ids = Splitter.on("&").withKeyValueSeparator("=").split(queryString);
110        
111        String rootId = ids.get("rootId");
112        String courseId = ids.get("courseId");
113        String programId = ids.get("programId");
114        
115        try
116        {
117            Page root = _resolver.resolveById(rootId);
118            
119            Program program = _resolver.resolveById(programId);
120            
121            // Check that parent ProgramPage exists
122            String levelPath = _computeLevelsPath(root, program);
123            root.getChild(levelPath + "/" + path);
124            
125            return _resolver.hasAmetysObjectForId(courseId);
126        }
127        catch (UnknownAmetysObjectException e)
128        {
129            return false;
130        }
131    }
132}