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                .flatMap(Optional::stream)
077                .map(Course.class::cast)
078                .collect(Collectors.toList());
079    }
080
081    @Override
082    public boolean containsCourse(String courseId)
083    {
084        List<String> courseIds = ContentDataHelper.getContentIdsListFromMultipleContentData(this, CHILD_COURSES);
085        return courseIds.contains(courseId);
086    }
087    
088    @Override
089    public boolean hasCourses()
090    {
091        return !ContentDataHelper.isMultipleContentDataEmpty(this, CHILD_COURSES);
092    }
093    
094    // --------------------------------------------------------------------------------------//
095    // GETTERS AND SETTERS
096    // --------------------------------------------------------------------------------------//
097    /**
098     * If this set of teaching unit element is a type of choice this method
099     * return the minimum number of teaching unit elements that the student must
100     * choose else -1.
101     * 
102     * @return the minimum number of teaching unit element that the student must choose. 0 if not set
103     */
104    public long getMinNumberOfCourses()
105    {
106        return getValue(CourseList.MIN_COURSES, false, 0L);
107    }
108
109    /**
110     * If this set of teaching unit element is a type of choice this method
111     * return the maximum number of teaching unit element that this set of
112     * teaching unit element must contains else -1.
113     * 
114     * @return the maximum number of teaching unit element that this set of
115     *         teaching unit element must contains.
116     */
117    public long getMaxNumberOfCourses()
118    {
119        return getValue(CourseList.MAX_COURSES, false, 0L);
120    }
121    
122    /**
123     * Indicates whether the teaching unit elements contained are mandatory,
124     * optional or a choice.
125     * 
126     * @return the type of the teaching unit elements contained.
127     */
128    public ChoiceType getType()
129    {
130        try
131        {
132            String choiceType = getValue(CHOICE_TYPE);
133            return Optional.ofNullable(choiceType).map(ChoiceType::valueOf).orElse(null);
134        }
135        catch (IllegalArgumentException e)
136        {
137            // No corresponding choice
138            return null;
139        }
140    }
141
142    /**
143     * Get the ids of parent courses
144     * @return the ids of parent courses
145     */
146    public List<Course> getParentCourses()
147    {
148        return Arrays.stream(getValue(PARENT_COURSES, false, new ContentValue[0]))
149                .map(ContentValue::getContentIfExists)
150                .flatMap(Optional::stream)
151                .map(Course.class::cast)
152                .collect(Collectors.toList());
153    }
154        
155    // --------------------------------------------------------------------------------------//
156    // CDM-fr
157    // --------------------------------------------------------------------------------------//
158    @Override
159    protected String getCDMType()
160    {
161        return "CL";
162    }
163}