001/*
002 *  Copyright 2018 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.odfpilotage.report.impl;
017
018import java.io.File;
019import java.io.FileOutputStream;
020import java.io.IOException;
021import java.time.LocalDate;
022import java.util.Set;
023
024import javax.xml.transform.Result;
025import javax.xml.transform.TransformerFactory;
026import javax.xml.transform.sax.SAXTransformerFactory;
027import javax.xml.transform.sax.TransformerHandler;
028import javax.xml.transform.stream.StreamResult;
029
030import org.apache.avalon.framework.service.ServiceException;
031import org.apache.avalon.framework.service.ServiceManager;
032import org.apache.cocoon.xml.AttributesImpl;
033import org.apache.cocoon.xml.XMLUtils;
034import org.apache.commons.io.FileUtils;
035import org.apache.commons.lang3.StringUtils;
036import org.xml.sax.SAXException;
037
038import org.ametys.cms.FilterNameHelper;
039import org.ametys.core.util.DateUtils;
040import org.ametys.odf.program.Program;
041import org.ametys.odf.program.SubProgram;
042import org.ametys.plugins.odfpilotage.helper.PilotageStatusHelper;
043
044/**
045 * Class to generate "règlement des études" extract as DOC.
046 */
047public class ReglementEtudesExtract extends AbstractExtract
048{
049    /** The pilotage status helper */
050    protected PilotageStatusHelper _pilotageStatusHelper;
051    
052    @Override
053    public void service(ServiceManager manager) throws ServiceException
054    {
055        super.service(manager);
056        _pilotageStatusHelper = (PilotageStatusHelper) manager.lookup(PilotageStatusHelper.ROLE);
057    }
058    
059    @Override
060    protected String getType()
061    {
062        return "reglementetudes";
063    }
064    
065    @Override
066    protected void _saxProgram(Program program)
067    {
068        Set<SubProgram> subPrograms = _odfHelper.getChildSubPrograms(program);
069        _saxProgramsTree(subPrograms, program);
070    }
071
072    /**
073     * Get the report filename for a given program
074     * @param program The program
075     * @return the file name
076     */
077    private String _getReportFileName(Program program)
078    {
079        StringBuilder sb = new StringBuilder();
080
081        sb.append("reglement-etudes-");
082        
083        // Catalog
084        sb.append(program.getCatalog());
085        sb.append("-");
086        
087        // Lang
088        sb.append(program.getLanguage());
089        sb.append("-");
090
091        sb.append(program.getTitle());
092        
093        // Code Ametys
094        String code = program.getCode();
095        if (StringUtils.isNotBlank(code))
096        {
097            sb.append("-");
098            sb.append(code);
099        }
100        
101        // Date
102        sb.append("-");
103        sb.append(_currentFormattedDate);
104        
105        return FilterNameHelper.filterName(sb.toString());
106    }
107    
108    private void _saxProgramsTree(Set<SubProgram> subPrograms, Program program)
109    {
110        SAXTransformerFactory factory = (SAXTransformerFactory) TransformerFactory.newInstance();
111        String fileName = _getReportFileName(program);
112        
113        // Delete old files
114        File xmlFile = new File(_tmpFolder, fileName + ".xml");
115        FileUtils.deleteQuietly(xmlFile);
116
117        // Write XML file
118        try (FileOutputStream fos = new FileOutputStream(xmlFile))
119        {
120            TransformerHandler handler = factory.newTransformerHandler();
121
122            // Prepare the transformation
123            Result result = new StreamResult(fos);
124            handler.setResult(result);
125            
126            handler.startDocument();
127            
128            AttributesImpl attrs = new AttributesImpl();
129            attrs.addCDATAAttribute("type", getType());
130            attrs.addCDATAAttribute("date", _reportHelper.getReadableCurrentDate());
131            XMLUtils.startElement(handler, "report", attrs);
132            
133            _saxReport(handler, program, subPrograms);
134            
135            XMLUtils.endElement(handler, "report");
136            handler.endDocument();
137
138            // Convert the report to configured output format
139            convertReport(_tmpFolder, fileName, xmlFile);
140        }
141        catch (Exception e)
142        {
143            getLogger().error("An error occured while generating 'Règlements des études' extract for program '{}' ({})", program.getTitle(), program.getCode(), e);
144        }
145        finally
146        {
147            FileUtils.deleteQuietly(xmlFile);
148        }
149    }
150    
151    private void _saxReport(TransformerHandler handler, Program program, Set<SubProgram> subPrograms) throws SAXException
152    {
153        _saxProgram(handler, program);
154        
155        for (SubProgram subProgram : subPrograms)
156        {
157            _saxSubProgram(handler, subProgram);
158        }
159    }
160    
161    private void _saxProgram(TransformerHandler handler, Program program) throws SAXException
162    {
163        AttributesImpl attr = new AttributesImpl();
164        attr.addCDATAAttribute("title", program.getTitle());
165        
166        LocalDate date = _pilotageStatusHelper.getCFVUMCCValidationDate(program);
167        if (date != null)
168        {
169            attr.addCDATAAttribute("CFVUDate", DateUtils.localDateToString(date));
170        }
171        
172        XMLUtils.startElement(handler, "program", attr);
173        
174        // Catalog
175        XMLUtils.createElement(handler, "catalog", program.getCatalog());
176        
177        // Degree
178        String degreeId = program.getDegree();
179        if (StringUtils.isNotEmpty(degreeId))
180        {
181            XMLUtils.createElement(handler, "degree", _refTableHelper.getItemLabel(degreeId, program.getLanguage()));
182        }
183
184        // Mention
185        String mentionId = program.getMention();
186        if (StringUtils.isNotEmpty(mentionId))
187        {
188            XMLUtils.createElement(handler, "mention", _refTableHelper.getItemLabel(mentionId, program.getLanguage()));
189        }
190        
191        // Domain
192        String[] domains = program.getDomain();
193        for (String domain : domains)
194        {
195            AttributesImpl attrs = new AttributesImpl();
196            attrs.addCDATAAttribute("code", _refTableHelper.getItemCode(domain));
197            XMLUtils.createElement(handler, "domain", attrs, _refTableHelper.getItemLabel(domain, program.getLanguage()));
198        }
199        
200        // Règlement des études
201        try
202        {
203            program.dataToSAX(handler, "reglementEtudes");
204        }
205        catch (IOException e)
206        {
207            getLogger().error("Unable to SAX rich-text metadata 'reglementEtudes'.", e);
208        }
209        
210        XMLUtils.endElement(handler, "program");
211    }
212    
213    private void _saxSubProgram(TransformerHandler handler, SubProgram subprogram) throws SAXException
214    {
215        AttributesImpl attr = new AttributesImpl();
216        attr.addCDATAAttribute("title", subprogram.getTitle());
217        XMLUtils.startElement(handler, "subprogram", attr);
218        
219        try
220        {
221            subprogram.dataToSAX(handler, "reglementEtudes");
222        }
223        catch (IOException e)
224        {
225            getLogger().error("Unable to SAX rich-text metadata 'reglementEtudes'.", e);
226        }
227        
228        XMLUtils.endElement(handler, "subprogram");
229    }
230}