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.Arrays;
019import java.util.List;
020import java.util.Optional;
021import java.util.stream.Collectors;
022
023import javax.jcr.Node;
024
025import org.ametys.cms.data.ContentDataHelper;
026import org.ametys.cms.data.ContentValue;
027import org.ametys.odf.course.Course;
028import org.ametys.odf.course.CourseContainer;
029import org.ametys.odf.program.AbstractProgramPart;
030
031/**
032 * Class representing a list of {@link Course}
033 */
034public class CourseList extends AbstractProgramPart<CourseListFactory> implements CourseContainer
035{
036    /** Constants for choice type attribute */
037    public static final String CHOICE_TYPE = "choiceType";
038    /** Constants for minimum number of courses. This attribute is valued only if type is {@link ChoiceType}.CHOICE */
039    public static final String MIN_COURSES = "min";
040    /** Constants for maximum number of courses. This attribute is valued only if type is {@link ChoiceType}.CHOICE */
041    public static final String MAX_COURSES = "max";
042    /** Constants for child courses attribute */
043    public static final String CHILD_COURSES = "courses";
044    /** Name of the attribute holding the direct parent courses */
045    public static final String PARENT_COURSES = "parentCourses";
046    
047    /**
048     * The type of the {@link CourseList}
049     */
050    public enum ChoiceType
051    {
052        /** mandatory type */
053        MANDATORY,
054        /** optional type */
055        OPTIONAL,
056        /** choice type */
057        CHOICE
058    }
059
060    /**
061     * Constructor
062     * @param node The JCR node
063     * @param parentPath The parent path
064     * @param factory the factory
065     */
066    public CourseList(Node node, String parentPath, CourseListFactory factory)
067    {
068        super(node, parentPath, factory);
069    }
070
071    @Override
072    public List<Course> getCourses()
073    {
074        return Arrays.stream(getValue(CHILD_COURSES, false, new ContentValue[0]))
075                .map(ContentValue::getContentIfExists)
076                .filter(Optional::isPresent)
077                .map(Optional::get)
078                .map(Course.class::cast)
079                .collect(Collectors.toList());
080    }
081
082    @Override
083    public boolean containsCourse(String courseId)
084    {
085        List<String> courseIds = ContentDataHelper.getContentIdsListFromMultipleContentData(this, CHILD_COURSES);
086        return courseIds.contains(courseId);
087    }
088    
089    @Override
090    public boolean hasCourses()
091    {
092        return !ContentDataHelper.isMultipleContentDataEmpty(this, CHILD_COURSES);
093    }
094    
095    // --------------------------------------------------------------------------------------//
096    // GETTERS AND SETTERS
097    // --------------------------------------------------------------------------------------//
098    /**
099     * If this set of teaching unit element is a type of choice this method
100     * return the minimum number of teaching unit elements that the student must
101     * choose else -1.
102     * 
103     * @return the minimum number of teaching unit element that the student must choose. 0 if not set
104     */
105    public long getMinNumberOfCourses()
106    {
107        return getValue(CourseList.MIN_COURSES, false, 0L);
108    }
109
110    /**
111     * If this set of teaching unit element is a type of choice this method
112     * return the maximum number of teaching unit element that this set of
113     * teaching unit element must contains else -1.
114     * 
115     * @return the maximum number of teaching unit element that this set of
116     *         teaching unit element must contains.
117     */
118    public long getMaxNumberOfCourses()
119    {
120        return getValue(CourseList.MAX_COURSES, false, 0L);
121    }
122    
123    /**
124     * Indicates whether the teaching unit elements contained are mandatory,
125     * optional or a choice.
126     * 
127     * @return the type of the teaching unit elements contained.
128     */
129    public ChoiceType getType()
130    {
131        try
132        {
133            String choiceType = getValue(CHOICE_TYPE);
134            return Optional.ofNullable(choiceType).map(ChoiceType::valueOf).orElse(null);
135        }
136        catch (IllegalArgumentException e)
137        {
138            // No corresponding choice
139            return null;
140        }
141    }
142
143    /**
144     * Get the ids of parent courses
145     * @return the ids of parent courses
146     */
147    public List<Course> getParentCourses()
148    {
149        return Arrays.stream(getValue(PARENT_COURSES, false, new ContentValue[0]))
150                .map(ContentValue::getContentIfExists)
151                .filter(Optional::isPresent)
152                .map(Optional::get)
153                .map(Course.class::cast)
154                .collect(Collectors.toList());
155    }
156        
157    // --------------------------------------------------------------------------------------//
158    // CDM-fr
159    // --------------------------------------------------------------------------------------//
160    @Override
161    protected String getCDMType()
162    {
163        return "CL";
164    }
165}