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