001/*
002 *  Copyright 2019 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.odfsync.apogee.ws.structure;
017
018import java.rmi.RemoteException;
019import java.util.ArrayList;
020import java.util.Collections;
021import java.util.List;
022
023import org.apache.commons.lang3.StringUtils;
024
025import org.ametys.cms.repository.Content;
026import org.ametys.odf.courselist.CourseList;
027import org.ametys.odf.program.Container;
028import org.ametys.odf.program.Program;
029import org.ametys.odf.program.ProgramPart;
030import org.ametys.odf.program.SubProgram;
031import org.ametys.plugins.odfsync.apogee.ws.ApogeeExportReport;
032import org.ametys.plugins.odfsync.apogee.ws.ApogeeExportReport.ExportStatus;
033
034import gouv.education.apogee.commun.client.ws.creationse.CreationSEMetierServiceInterface;
035
036/**
037 * The structure to export in Apogee the following program
038 * <br>Program / SubProgram / Container (year) / Container (semester) / UE / ELP / ...
039 * <br>into DIP / VDI / ETP-VET / ELP / LSE / ELP / ...
040 */
041public class ApogeeFullStructure extends AbstractApogeeStructure
042{
043    @Override
044    public void checkProgram(Program program, ApogeeExportReport report)
045    {
046        // Check mandatory data for program
047        checkMandatoryDataForContent(program, getDIPMandatoryData(program), report);
048        
049        // Check the program structure
050        List<ProgramPart> programPartChildren = program.getProgramPartChildren();
051        for (ProgramPart programPart : programPartChildren)
052        {
053            if (programPart instanceof SubProgram)
054            {
055                checkSubProgram((SubProgram) programPart, report);
056            }
057            else
058            {
059                // The structure is not handled by this export
060                report.setExportStatus(ExportStatus.CONTENT_STRUCTURE_INVALID);
061                break;
062            }
063        }
064        
065        if (programPartChildren.isEmpty())
066        {
067            // The structure is not handled by this export
068            report.setExportStatus(ExportStatus.CONTENT_STRUCTURE_INVALID);
069        }
070    }
071    
072    @Override
073    public void checkSubProgram(SubProgram subProgram, ApogeeExportReport report)
074    {
075        // Check mandatory data for subProgram
076        checkMandatoryDataForContent(subProgram, getVDIMandatoryData(subProgram), report);
077        
078        // Check mandatory data for subProgram orgUnits
079        checkMandatoryDataForOrgunits(subProgram, subProgram.getOrgUnits(), getOrgUnitMandatoryDataForDIP(), report);
080        
081        // Check the subProgram structure
082        List<ProgramPart> programPartChildren = subProgram.getProgramPartChildren();
083        for (ProgramPart childProgramPart : programPartChildren)
084        {
085            if (childProgramPart instanceof Container)
086            {
087                checkContainerAsYear((Container) childProgramPart, report);
088            }
089            else
090            {
091                // The structure is not handled by this export
092                report.setExportStatus(ExportStatus.CONTENT_STRUCTURE_INVALID);
093                break;
094            }
095        }
096        
097        if (programPartChildren.isEmpty())
098        {
099            // The structure is not handled by this export
100            report.setExportStatus(ExportStatus.CONTENT_STRUCTURE_INVALID);
101        }
102    }
103    
104    @Override
105    public void checkContainerAsYear(Container container, ApogeeExportReport report)
106    {
107        if (isYearContainer(container, report))
108        {
109            // The container is a semester so check the data as a semester (ELP in Apogee)
110            checkMandatoryDataForContent(container, getETPMandatoryData(container), report);
111            checkMandatoryDataForContent(container, getVETMandatoryData(container), report);
112            
113            List<String> orgUnits = StringUtils.isNotBlank(container.getOrgUnit()) ? new ArrayList<>(Collections.singleton(container.getOrgUnit())) : new ArrayList<>();
114            checkMandatoryDataForOrgunits(container, orgUnits, getOrgUnitMandatoryDataForETP(), report);
115            
116            // Check the container structure
117            List<ProgramPart> programPartChildren = container.getProgramPartChildren();
118            for (ProgramPart childProgramPart : programPartChildren)
119            {
120                if (childProgramPart instanceof Container)
121                {
122                    checkContainerAsSemester((Container) childProgramPart, report);
123                }
124                else
125                {
126                    report.setExportStatus(ExportStatus.CONTENT_STRUCTURE_INVALID);
127                    break;
128                }
129            }
130            
131            if (programPartChildren.isEmpty())
132            {
133                // The structure is not handled by this export
134                report.setExportStatus(ExportStatus.CONTENT_STRUCTURE_INVALID);
135            }
136        }
137        else
138        {
139            // The structure is not handled by this export
140            report.setExportStatus(ExportStatus.CONTENT_STRUCTURE_INVALID);
141        }
142    }
143    
144    @Override
145    public void checkContainerAsSemester(Container container, ApogeeExportReport report)
146    {
147        if (isSemesterContainer(container, report))
148        {
149            // The container is a semester so check the data as a semester (ELP in Apogee)
150            checkMandatoryDataForContent(container, getELPMandatoryData(container), report);
151            
152            // Check the container structure
153            for (ProgramPart childProgramPart : container.getProgramPartChildren())
154            {
155                if (childProgramPart instanceof CourseList)
156                {
157                    checkCourseList((CourseList) childProgramPart, report);
158                }
159                else
160                {
161                    report.setExportStatus(ExportStatus.CONTENT_STRUCTURE_INVALID);
162                    break;
163                }
164            }
165        }
166        else
167        {
168            // The structure is not handled by this export
169            report.setExportStatus(ExportStatus.CONTENT_STRUCTURE_INVALID);
170        }
171    }
172    
173    @Override
174    public void createProgram(Program program, ApogeeExportReport report)
175    {
176        try
177        {
178            CreationSEMetierServiceInterface creationService = _apogeeWS.getCreationService();
179            String codDIP = getCodeApogee(program);
180            _apogeeWS.createDIP(program, null, codDIP, creationService);
181            for (ProgramPart pp : program.getProgramPartChildren())
182            {
183                _createSubProgram((SubProgram) pp, program, creationService, report);
184            }
185        }
186        catch (Exception e)
187        {
188            report.setExportStatus(ExportStatus.ERROR);
189            getLogger().error("An error occurred exporting the program '{}' ({}) in Apogee", program.getTitle(), program.getId(), e);
190        }
191    }
192    
193    /**
194     * Create a subProgram in Apogee
195     * @param subProgram the subProgram to create
196     * @param programParent the program parent in Apogee
197     * @param creationService the service to create element in Apogee
198     * @param report the Apogee export report
199     * @throws RemoteException if an export error occurred
200     */
201    protected void _createSubProgram(SubProgram subProgram, Content programParent, CreationSEMetierServiceInterface creationService, ApogeeExportReport report) throws RemoteException
202    {
203        String codDip = getCodeApogee(programParent);
204        Long versionDIP = getVersionApogee(subProgram);
205        
206        _apogeeWS.createVDI(subProgram, programParent.getTitle() + " - " + subProgram.getTitle(), codDip, versionDIP, creationService);
207        
208        for (ProgramPart pp : subProgram.getProgramPartChildren())
209        {
210            _createContainerAsETPVET((Container) pp, programParent, subProgram, creationService, report);
211        }
212    }
213    
214    /**
215     * Create a container as ETP/VET in Apogee
216     * @param container the container to create
217     * @param programParent the program parent in Apogee
218     * @param parentSubProgram the parent subProgram
219     * @param creationService the service to create element in Apogee
220     * @param report the Apogee export report
221     * @throws RemoteException if an export error occurred
222     */
223    protected void _createContainerAsETPVET(Container container, Content programParent, Content parentSubProgram, CreationSEMetierServiceInterface creationService, ApogeeExportReport report) throws RemoteException
224    {
225        String codDIP = getCodeApogee(programParent);
226        Long versionDIP = getVersionApogee(parentSubProgram);
227        String codETP = getCodeApogee(container);
228        Long versionETP = getVersionApogee(container);
229        
230        // Create the ETP / VET from the container
231        _apogeeWS.createETP(container, null, codETP, creationService);
232        _apogeeWS.createVET(container, null, codETP, versionETP, creationService);
233        
234        // Link to the DIP / VDI (Program / SubProgram)
235        _apogeeWS.createLinkDIPETP(codDIP, versionDIP, codETP, versionETP, creationService);
236        
237        for (ProgramPart pp : container.getProgramPartChildren())
238        {
239            _createContainerAsELP((Container) pp, programParent, container, creationService, report);
240        }
241    }
242    
243    /**
244     * Create a container in Apogee
245     * @param container the container to create
246     * @param programParent the program parent in Apogee
247     * @param parentYearContainer the parent year container
248     * @param creationService the service to create element in Apogee
249     * @param report the Apogee export report
250     * @throws RemoteException if an export error occurred
251     */
252    protected void _createContainerAsELP(Container container, Content programParent, Content parentYearContainer, CreationSEMetierServiceInterface creationService, ApogeeExportReport report) throws RemoteException
253    {
254        String codETP = getCodeApogee(parentYearContainer);
255        Long versionETP = getVersionApogee(parentYearContainer);
256        String codELP = getCodeApogee(container);
257        
258        // Create the ELP from the container
259        _apogeeWS.createELP(container, null, codELP, creationService);
260        
261        // Create a mandatory LSE with random code
262        String codLSE = org.ametys.core.util.StringUtils.generateKey();
263        _apogeeWS.createMandatoryLSE("LSE - " + parentYearContainer.getTitle(), codLSE, codELP, creationService);
264        
265        // Create the link between ETP and LSE (year container and semester container)
266        _apogeeWS.createLinkETPELPLSE(codETP, versionETP, codLSE, null, null, null, null, creationService);
267        
268        for (ProgramPart pp : container.getProgramPartChildren())
269        {
270            _createCourseList((CourseList) pp, container, creationService, report);
271        }
272    }
273}