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.program;
017
018import java.util.Arrays;
019import java.util.Collections;
020import java.util.List;
021import java.util.Optional;
022import java.util.stream.Collectors;
023
024import javax.jcr.Node;
025
026import org.apache.commons.lang3.ArrayUtils;
027
028import org.ametys.cms.data.ContentDataHelper;
029import org.ametys.cms.data.ContentValue;
030import org.ametys.cms.data.RichText;
031import org.ametys.odf.courselist.CourseList;
032import org.ametys.odf.courselist.CourseListContainer;
033import org.ametys.plugins.repository.AmetysRepositoryException;
034import org.ametys.runtime.model.exception.UndefinedItemPathException;
035
036/**
037 * Container java object
038 */
039public class Container extends AbstractTraversableProgramPart<ContainerFactory> implements CourseListContainer
040{
041
042    /** Constants for ects attribute */
043    public static final String ECTS = "ects";
044
045    /** Constants for description attribute */
046    public static final String DESCRIPTION = "description";
047
048    /** Constants for period attribute */
049    public static final String PERIOD = "period";
050
051    /** Constants for nature attribute* */
052    public static final String NATURE = "nature";
053    
054    /** Constants for orgunit attribute */
055    public static final String ORG_UNIT = "orgUnit";
056
057    /**
058     * Constructor
059     * @param node The JCR node
060     * @param parentPath The parent path
061     * @param factory the ametys object factory
062     */
063    public Container(Node node, String parentPath, ContainerFactory factory)
064    {
065        super(node, parentPath, factory);
066    }
067    
068    // --------------------------------------------------------------------------------------//
069    // GETTERS AND SETTERS
070    // --------------------------------------------------------------------------------------//
071    /**
072     * Get the ECTS credits
073     * @return the ECTS credits 
074     * @throws AmetysRepositoryException if an error occurred
075     */
076    public double getEcts() throws AmetysRepositoryException
077    {
078        return getValue(ECTS, false, 0D);
079    }
080
081    /**
082     * Get the description
083     * @return the description or null if not set
084     */
085    public RichText getDescription()
086    {
087        return getValue(DESCRIPTION);
088    }
089    
090    /**
091     * Get the period
092     * @return the period
093     * @throws AmetysRepositoryException if an error occurs
094     */
095    public String getPeriod() throws AmetysRepositoryException
096    {
097        return ContentDataHelper.getContentIdFromContentData(this, PERIOD);
098    }
099
100    /**
101     * Get the nature
102     * @return the nature
103     * @throws AmetysRepositoryException if an error occurs
104     */
105    public String getNature() throws AmetysRepositoryException
106    {
107        return ContentDataHelper.getContentIdFromContentData(this, NATURE);
108    }
109    
110    // --------------------------------------------------------------------------------------//
111    // Methods of CourseListContainer
112    // --------------------------------------------------------------------------------------//
113    @Override
114    public List<CourseList> getCourseLists()
115    {
116        return Arrays.stream(getValue(CHILD_PROGRAM_PARTS, false, new ContentValue[0]))
117                .map(ContentValue::getContentIfExists)
118                .filter(Optional::isPresent)
119                .map(Optional::get)
120                // This cast is not checked because an exception must be thrown if the retrieved content is not a program part 
121                // TODO: change this behavior to throw our own exception and not a CassCastException
122                .map(ProgramPart.class::cast)
123                // Program parts that are not course lists are simply ignored
124                .filter(CourseList.class::isInstance)
125                .map(CourseList.class::cast)
126                .collect(Collectors.toList());
127    }
128
129    @Override
130    public boolean containsCourseList(String clId)
131    {
132        return ArrayUtils.contains(ContentDataHelper.getContentIdsArrayFromMultipleContentData(this, CHILD_PROGRAM_PARTS), clId);
133    }
134
135    @Override
136    public boolean hasCourseLists()
137    {
138        return !getCourseLists().isEmpty();
139    }
140    
141    // --------------------------------------------------------------------------------------//
142    // CDMfr
143    // --------------------------------------------------------------------------------------//
144    @Override
145    protected String getCDMType()
146    {
147        return "PR";
148    }
149    
150    // --------------------------------------------------------------------------------------//
151    // ORGUNITS
152    // --------------------------------------------------------------------------------------//
153    /**
154     * Return the list of orgunit content id binded to this container, or empty list if there is not.
155     * @return the list of orgunit content id binded to this container, or empty list if there is not.
156     */
157    public List<String> getOrgUnits()
158    {
159        try
160        {
161            return ContentDataHelper.getContentIdsListFromMultipleContentData(this, ORG_UNIT);
162        }
163        catch (UndefinedItemPathException e)
164        {
165            return Collections.EMPTY_LIST; // this attribute is not part of model
166        }
167    }
168}