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.odf.courselist;
017
018import java.util.ArrayList;
019import java.util.List;
020import java.util.Set;
021
022import javax.jcr.Node;
023
024import org.apache.commons.lang3.ArrayUtils;
025
026import org.ametys.odf.course.Course;
027import org.ametys.odf.course.CourseContainer;
028import org.ametys.odf.program.AbstractProgramPart;
029import org.ametys.odf.program.Program;
030import org.ametys.plugins.repository.UnknownAmetysObjectException;
031import org.ametys.plugins.repository.metadata.UnknownMetadataException;
032
033/**
034 * Class representing a list of {@link Course}
035 */
036public class CourseList extends AbstractProgramPart<CourseListFactory> implements CourseContainer
037{
038    /** Constants for choice type metadata */
039    public static final String METADATA_CHOICE_TYPE = "choiceType";
040    /** Constants for minimum number of courses. This metadata is valued only if type is {@link ChoiceType}.CHOICE */
041    public static final String METADATA_MIN_COURSES = "min";
042    /** Constants for maximum number of courses. This metadata is valued only if type is {@link ChoiceType}.CHOICE */
043    public static final String METADATA_MAX_COURSES = "max";
044    /** Constants for child courses metadata */
045    public static final String METADATA_CHILD_COURSES = "courses";
046    /** Name of the metadata holding the direct parent courses */
047    public static final String METADATA_PARENT_COURSES = "parentCourses";
048    
049    /**
050     * The type of the {@link CourseList}
051     */
052    public enum ChoiceType
053    {
054        /** mandatory type */
055        MANDATORY,
056        /** optional type */
057        OPTIONAL,
058        /** choice type */
059        CHOICE
060    }
061
062    /**
063     * Constructor
064     * @param node The JCR node
065     * @param parentPath The parent path
066     * @param factory the factory
067     */
068    public CourseList(Node node, String parentPath, CourseListFactory factory)
069    {
070        super(node, parentPath, factory);
071    }
072
073    @Override
074    public List<Course> getCourses()
075    {
076        List<Course> courses = new ArrayList<>();
077        
078        String[] courseIds = getMetadataHolder().getStringArray(METADATA_CHILD_COURSES, new String[0]);
079        for (String id : courseIds)
080        {
081            try
082            {
083                Course course = _getFactory()._getResolver().resolveById(id);
084                courses.add(course);
085            }
086            catch (UnknownAmetysObjectException e)
087            {
088                // Nothing
089            }
090        }
091        
092        return courses;
093    }
094
095    @Override
096    public boolean containsCourse(String courseId)
097    {
098        try
099        {
100            String[] courseIds = getMetadataHolder().getStringArray(METADATA_CHILD_COURSES, new String[0]);
101            return ArrayUtils.contains(courseIds, courseId);
102        }
103        catch (UnknownMetadataException e)
104        {
105            return false;
106        }
107    }
108    
109    @Override
110    public boolean hasCourses()
111    {
112        return getMetadataHolder().getStringArray(METADATA_CHILD_COURSES, new String[0]).length > 0;
113    }
114    
115    // --------------------------------------------------------------------------------------//
116    // GETTERS AND SETTERS
117    // --------------------------------------------------------------------------------------//
118    /**
119     * If this set of teaching unit element is a type of choice this method
120     * return the minimum number of teaching unit elements that the student must
121     * choose else -1.
122     * 
123     * @return the minimum number of teaching unit element that the student must choose. 0 if not set
124     */
125    public long getMinNumberOfCourses()
126    {
127        return getMetadataHolder().getLong(CourseList.METADATA_MIN_COURSES, 0);
128    }
129
130    /**
131     * If this set of teaching unit element is a type of choice this method
132     * return the maximum number of teaching unit element that this set of
133     * teaching unit element must contains else -1.
134     * 
135     * @return the maximum number of teaching unit element that this set of
136     *         teaching unit element must contains.
137     */
138    public long getMaxNumberOfCourses()
139    {
140        return getMetadataHolder().getLong(CourseList.METADATA_MAX_COURSES, 0);
141    }
142    
143    /**
144     * Indicates whether the teaching unit elements contained are mandatory,
145     * optional or a choice.
146     * 
147     * @return the type of the teaching unit elements contained.
148     */
149    public ChoiceType getType()
150    {
151        try
152        {
153            return ChoiceType.valueOf(getMetadataHolder().getString(CourseList.METADATA_CHOICE_TYPE));
154        }
155        catch (IllegalArgumentException e)
156        {
157            // No corresponding choice
158            return null;
159        }
160        catch (UnknownMetadataException e)
161        {
162            return null;
163        }
164    }
165
166    /**
167     * Get the ids of parent courses
168     * @return the ids of parent courses
169     */
170    public List<Course> getParentCourses()
171    {
172        List<Course> parentCourses = new ArrayList<>();
173        
174        String[] parentId = getMetadataHolder().getStringArray(METADATA_PARENT_COURSES, new String[0]);
175        for (String id : parentId)
176        {
177            try
178            {
179                Course course = _getFactory()._getResolver().resolveById(id);
180                parentCourses.add(course);
181            }
182            catch (UnknownAmetysObjectException e)
183            {
184                // Nothing
185            }
186        }
187        
188        return parentCourses;
189    }
190        
191    @Override
192    public Set<Program> getRootPrograms()
193    {
194        Set<Program> rootPrograms = super.getRootPrograms();
195        for (Course course : getParentCourses())
196        {
197            rootPrograms.addAll(course.getRootPrograms());
198        }
199        return rootPrograms;
200    }
201    
202    // --------------------------------------------------------------------------------------//
203    // CDM-fr
204    // --------------------------------------------------------------------------------------//
205    @Override
206    protected String getCDMType()
207    {
208        return "CL";
209    }
210}