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.odf.ose.export.impl;
017
018import java.util.ArrayList;
019import java.util.HashSet;
020import java.util.List;
021import java.util.Set;
022import java.util.stream.Collectors;
023
024import org.apache.avalon.framework.service.ServiceException;
025import org.apache.avalon.framework.service.ServiceManager;
026import org.apache.avalon.framework.service.Serviceable;
027
028import org.ametys.odf.ODFHelper;
029import org.ametys.odf.ProgramItem;
030import org.ametys.odf.course.Course;
031import org.ametys.odf.ose.db.ParameterizableQuery;
032import org.ametys.odf.ose.export.AbstractOSEExport;
033import org.ametys.odf.ose.export.OSEConstants;
034import org.ametys.odf.ose.export.impl.odf.CourseExporter;
035import org.ametys.odf.ose.export.impl.odf.HierarchyExporter;
036import org.ametys.odf.ose.export.impl.odf.ProgramPartExporter;
037import org.ametys.odf.ose.export.impl.odf.StepExporter;
038import org.ametys.odf.ose.export.impl.odf.db.CheminPedagogiqueHelper;
039import org.ametys.odf.ose.export.impl.odf.db.EffectifsHelper;
040import org.ametys.odf.ose.export.impl.odf.db.ElementPedagogiqueHelper;
041import org.ametys.odf.ose.export.impl.odf.db.EtapeHelper;
042import org.ametys.odf.ose.export.impl.odf.db.LienHelper;
043import org.ametys.odf.ose.export.impl.odf.db.NoeudHelper;
044import org.ametys.odf.ose.export.impl.odf.db.ScenarioHelper;
045import org.ametys.odf.ose.export.impl.odf.db.ScenarioLienHelper;
046import org.ametys.odf.ose.export.impl.odf.db.ScenarioNoeudHelper;
047import org.ametys.odf.ose.export.impl.odf.db.TypeInterventionEPHelper;
048import org.ametys.odf.ose.export.impl.odf.db.VolumeHoraireEnsHelper;
049import org.ametys.odf.program.AbstractProgramPart;
050import org.ametys.odf.program.Container;
051import org.ametys.odf.program.Program;
052import org.ametys.odf.program.ProgramFactory;
053import org.ametys.plugins.odfpilotage.cost.CostComputationComponent;
054import org.ametys.plugins.odfpilotage.cost.entity.CostComputationData;
055import org.ametys.runtime.config.Config;
056
057/**
058 * This exports ODF values to the OSE database by SRC_* views.
059 */
060public class ODFExport extends AbstractOSEExport implements Serviceable
061{
062    /** The exporter of steps */
063    protected StepExporter _stepExporter;
064    /** The exporter of courses */
065    protected CourseExporter _courseExporter;
066    /** The exporter of program elements */
067    protected ProgramPartExporter _programElementExporter;
068    /** The exporter of hierarchy */
069    protected HierarchyExporter _hierarchyExporter;
070    /** The ODF helper */
071    protected ODFHelper _odfHelper;
072    /** The cost computation component */
073    protected CostComputationComponent _costComputationComponent;
074    
075    @Override
076    public void service(ServiceManager manager) throws ServiceException
077    {
078        _stepExporter = (StepExporter) manager.lookup(StepExporter.ROLE);
079        _courseExporter = (CourseExporter) manager.lookup(CourseExporter.ROLE);
080        _programElementExporter = (ProgramPartExporter) manager.lookup(ProgramPartExporter.ROLE);
081        _hierarchyExporter = (HierarchyExporter) manager.lookup(HierarchyExporter.ROLE);
082        _odfHelper = (ODFHelper) manager.lookup(ODFHelper.ROLE);
083        _costComputationComponent = (CostComputationComponent) manager.lookup(CostComputationComponent.ROLE);
084    }
085    
086    @Override
087    public List<ParameterizableQuery> initializeDb()
088    {
089        List<ParameterizableQuery> queries = new ArrayList<>();
090        queries.addAll(EtapeHelper.initialize());
091        queries.addAll(ElementPedagogiqueHelper.initialize());
092        queries.addAll(EffectifsHelper.initialize());
093        queries.addAll(VolumeHoraireEnsHelper.initialize());
094        queries.addAll(CheminPedagogiqueHelper.initialize());
095        queries.addAll(TypeInterventionEPHelper.initialize());
096        queries.addAll(NoeudHelper.initialize());
097        queries.addAll(LienHelper.initialize());
098        queries.addAll(ScenarioHelper.initialize());
099        queries.addAll(ScenarioNoeudHelper.initialize());
100        queries.addAll(ScenarioLienHelper.initialize());
101        return queries;
102    }
103    
104    @Override
105    protected List<ParameterizableQuery> _populate(String ametysCatalog, Long oseCatalog)
106    {
107        List<ParameterizableQuery> queries = new ArrayList<>();
108        queries.addAll(_deleteOldData());
109        queries.addAll(new Populator(oseCatalog).exportSteps(ametysCatalog));
110        return queries;
111    }
112    
113    private List<ParameterizableQuery> _deleteOldData()
114    {
115        List<ParameterizableQuery> queries = new ArrayList<>();
116        queries.add(ScenarioLienHelper.deleteFrom());
117        queries.add(ScenarioNoeudHelper.deleteFrom());
118        queries.add(LienHelper.deleteFrom());
119        queries.add(NoeudHelper.deleteFrom());
120        queries.add(TypeInterventionEPHelper.deleteFrom());
121        queries.add(CheminPedagogiqueHelper.deleteFrom());
122        queries.add(VolumeHoraireEnsHelper.deleteFrom());
123        queries.add(EffectifsHelper.deleteFrom());
124        queries.add(ElementPedagogiqueHelper.deleteFrom());
125        queries.add(EtapeHelper.deleteFrom());
126        return queries;
127    }
128    
129    private class Populator
130    {
131        private Set<String> _exportedObjectIds = new HashSet<>();
132        private Long _oseCatalog;
133        
134        Populator(Long oseCatalog)
135        {
136            this._oseCatalog = oseCatalog;
137        }
138        
139        List<ParameterizableQuery> exportSteps(String ametysCatalog)
140        {
141            CostComputationData costData = _getCostComputationData(ametysCatalog);
142            
143            List<ParameterizableQuery> queries = new ArrayList<>();
144            for (Container step : _stepExporter.getStepsToExport(ametysCatalog))
145            {
146                if (_exportedObjectIds.add(step.getId()))
147                {
148                    queries.addAll(_stepExporter.getQueries(step, _oseCatalog));
149                    queries.addAll(_exportChildren(step, costData));
150                }
151            }
152            return queries;
153        }
154        
155        private CostComputationData _getCostComputationData(String ametysCatalog)
156        {
157            String lang = Config.getInstance().getValue("odf.programs.lang");
158            List<Program> programs = _odfHelper.getProgramItems(ProgramFactory.PROGRAM_CONTENT_TYPE, null, ametysCatalog, lang)
159                    .stream()
160                    .filter(Program.class::isInstance)
161                    .map(Program.class::cast)
162                    .collect(Collectors.toList());
163            return _costComputationComponent.computeCostsOnPrograms(programs);
164        }
165        
166        private List<ParameterizableQuery> _exportChildren(ProgramItem programItem, CostComputationData costData)
167        {
168            List<ParameterizableQuery> queries = new ArrayList<>();
169            for (ProgramItem child : _odfHelper.getChildProgramItems(programItem))
170            {
171                if (_exportedObjectIds.add(child.getId()))
172                {
173                    if (child instanceof Course)
174                    {
175                        queries.addAll(_exportCourse((Course) child, costData));
176                    }
177                    else
178                    {
179                        // SubProgram, Container or CourseList
180                        queries.addAll(_exportProgramPart((AbstractProgramPart) child, costData));
181                    }
182                    queries.addAll(_hierarchyExporter.getQueries(programItem, child, _oseCatalog));
183                }
184            }
185            return queries;
186        }
187    
188        private List<ParameterizableQuery> _exportProgramPart(AbstractProgramPart programPart, CostComputationData costData)
189        {
190            List<ParameterizableQuery> queries = new ArrayList<>();
191            if (!programPart.hasDefinition(OSEConstants.NO_OSE_EXPORT_ATTRIBUTE_NAME) || !programPart.getValue(OSEConstants.NO_OSE_EXPORT_ATTRIBUTE_NAME, true, false))
192            {
193                queries.addAll(_programElementExporter.getQueries(programPart, _oseCatalog, costData));
194                queries.addAll(_exportChildren(programPart, costData));
195            }
196            return queries;
197        }
198        
199        private List<ParameterizableQuery> _exportCourse(Course course, CostComputationData costData)
200        {
201            List<ParameterizableQuery> queries = new ArrayList<>();
202            if (!course.getValue(OSEConstants.NO_OSE_EXPORT_ATTRIBUTE_NAME, true, false))
203            {
204                queries.addAll(_courseExporter.getQueries(course, _oseCatalog, costData));
205                queries.addAll(_exportChildren(course, costData));
206            }
207            return queries;
208        }
209    }
210}
211