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.lheo;
017
018import java.util.ArrayList;
019import java.util.List;
020
021import org.apache.avalon.framework.component.Component;
022import org.apache.cocoon.xml.AttributesImpl;
023import org.apache.cocoon.xml.XMLUtils;
024import org.apache.commons.lang3.StringUtils;
025import org.xml.sax.ContentHandler;
026import org.xml.sax.SAXException;
027
028import org.ametys.cms.repository.Content;
029import org.ametys.runtime.plugin.component.AbstractLogEnabled;
030
031import com.google.common.base.Splitter;
032
033/**
034 * Class utils for LHEO XML export
035 */
036public class LHEOUtils extends AbstractLogEnabled implements Component
037{
038    /** The Avalon role */
039    public static final String ROLE = LHEOUtils.class.getName();
040    
041    /**
042     * Create some LHEO elements for tag >coordonnees<
043     * <br>Contains the following XML tags:
044     * <br>[0,1] &lt;civilite&gt;
045     * <br>[0,1] &lt;nom&gt;
046     * <br>[0,1] &lt;prenom&gt;
047     * <br>[0,3] &lt;ligne&gt;
048     * @param contentHandler the content handler
049     * @param content the saxed content
050     * @param civility the civility. Can be null.
051     * @param lastname the lastname. Can be null.
052     * @param firstname the firstname. Can be null.
053     * @param address the address. Can be null.
054     * @throws SAXException if a saxing exception occurred
055     */
056    public void createCoordinateLHEOElementsPart1(ContentHandler contentHandler, Content content, String civility, String lastname, String firstname, String address) throws SAXException
057    {
058        List<String> lines = StringUtils.isNotBlank(address) ? Splitter.fixedLength(50).splitToList(address) : new ArrayList<>();
059        createCoordinateLHEOElementsPart1(contentHandler, content, civility, lastname, firstname, lines);
060    }
061    
062    /**
063     * Create some LHEO elements for tag &gt;coordonnees&lt;
064     * <br>Contains the following XML tags:
065     * <br>[0,1] &lt;civilite&gt;
066     * <br>[0,1] &lt;nom&gt;
067     * <br>[0,1] &lt;prenom&gt;
068     * <br>[0,3] &lt;ligne&gt;
069     * @param contentHandler the content handler
070     * @param content the saxed content
071     * @param civility the civility. Can be null.
072     * @param lastname the lastname. Can be null.
073     * @param firstname the firstname. Can be null.
074     * @param lines the address line. Can be empty.
075     * @throws SAXException if a saxing exception occurred
076     */
077    public void createCoordinateLHEOElementsPart1(ContentHandler contentHandler, Content content, String civility, String lastname, String firstname, List<String> lines) throws SAXException
078    {
079        // <civilite>
080        createLHEOElement(contentHandler, content, "civilite", civility, 1, 50);
081        
082        // <nom>
083        createLHEOElement(contentHandler, content, "nom", lastname, 1, 50);
084        
085        // <prenom>
086        createLHEOElement(contentHandler, content, "prenom", firstname, 1, 50);
087        
088        // <ligne>
089        int size = lines.size();
090        if (size > 3)
091        {
092            size = 3;
093            getLogger().warn("[" + content.getTitle() + " (" + content.getId() + ")] The value " + StringUtils.join(lines, "") + " can be set in 3 lines. It will be truncated.");
094        }
095        
096        for (int i = 0; i < size; i++)
097        {
098            createLHEOElement(contentHandler, content, "ligne", lines.get(i), 1, 50);
099        }
100    }
101    
102    /**
103     * Create some LHEO elements for tag &gt;coordonnees&lt;
104     * <br>Contains the following XML tags:
105     * <br>[0,1] &lt;telfixe&gt;
106     * <br>[0,1] &lt;portable&gt;
107     * <br>[0,1] &lt;fax&gt;
108     * <br>[0,1] &lt;courriel&gt;
109     * <br>[0,1] &lt;web&gt;
110     * @param contentHandler the content handler
111     * @param content the saxed content
112     * @param telFix the telFix. Can be null.
113     * @param portable the portable. Can be null.
114     * @param fax the fax. Can be null.
115     * @param mail the mail. Can be null.
116     * @param urlWeb the url web. Can be null.
117     * @throws SAXException if a saxing exception occurred
118     */
119    public void createCoordinateLHEOElementsPart2(ContentHandler contentHandler, Content content, String telFix, String portable, String fax, String mail, String urlWeb) throws SAXException
120    {
121        // <telfixe>
122        if (StringUtils.isNotBlank(telFix))
123        {
124            XMLUtils.startElement(contentHandler, "telfixe");
125            createLHEOElement(contentHandler, content, "numtel", telFix, 1, 25);
126            XMLUtils.endElement(contentHandler, "telfixe");
127        }
128        
129        // <portable>
130        if (StringUtils.isNotBlank(portable))
131        {
132            XMLUtils.startElement(contentHandler, "portable");
133            createLHEOElement(contentHandler, content, "numtel", portable, 1, 25);
134            XMLUtils.endElement(contentHandler, "portable");
135        }
136        
137        // <fax>
138        if (StringUtils.isNotBlank(fax))
139        {
140            XMLUtils.startElement(contentHandler, "fax");
141            createLHEOElement(contentHandler, content, "numtel", fax, 1, 25);
142            XMLUtils.endElement(contentHandler, "fax");
143        }
144        
145        // <courriel>
146        createLHEOElement(contentHandler, content, "courriel", mail, 3, 160);
147        
148        // <web>
149        if (StringUtils.isNotBlank(urlWeb))
150        {
151            XMLUtils.startElement(contentHandler, "web");
152            createLHEOElement(contentHandler, content, "urlweb", urlWeb, 3, 400);
153            XMLUtils.endElement(contentHandler, "web");
154        }
155    }
156    
157    /**
158     * Create some LHEO elements for tag &gt;adresse&lt;
159     * <br>Contains the following XML tags:
160     * <br>[0,1] &lt;ligne&gt;
161     * <br>[0,1] &lt;codepostal&gt;
162     * <br>[0,1] &lt;ville&gt;
163     * <br>[0,3] &lt;departement&gt;
164     * <br>[0,1] &lt;code-INSEE-commune&gt;
165     * <br>[0,1] &lt;code-INSEE-canton&gt;
166     * <br>[0,1] &lt;region&gt;
167     * <br>[0,1] &lt;pays&gt;
168     * <br>[0,1] &lt;geolocalisation&gt;
169     * @param contentHandler the content handler
170     * @param content the saxed content
171     * @param address the address. Is mandatory.
172     * @param zipCode the zip code. Is mandatory.
173     * @param town the town. Is mandatory.
174     * @param department the department. Can be null.
175     * @param codeINSEEtown the code INSEE for the town. Can be null.
176     * @param codeINSEEdistrict the code INSEE for the district. Can be null.
177     * @param zone the zone. Can be null.
178     * @param country the country. Can be null.
179     * @param latitude the latitude. Can be null.
180     * @param longitude the longitude. Can be null.
181     * @throws SAXException if a saxing exception occurred
182     */
183    public void createAddressLHEOElements(ContentHandler contentHandler, Content content, String address, String zipCode, String town, String department, String codeINSEEtown, String codeINSEEdistrict, String zone, String country, String latitude, String longitude) throws SAXException
184    {
185        List<String> lines = StringUtils.isNotBlank(address) ? Splitter.fixedLength(50).splitToList(address) : new ArrayList<>();
186        createAddressLHEOElements(contentHandler, content, lines, zipCode, town, department, codeINSEEtown, codeINSEEdistrict, zone, country, latitude, longitude);
187    }
188    
189    /**
190     * Create some LHEO elements for tag &gt;adresse&lt;
191     * <br>Contains the following XML tags:
192     * <br>[0,1] &lt;ligne&gt;
193     * <br>[0,1] &lt;codepostal&gt;
194     * <br>[0,1] &lt;ville&gt;
195     * <br>[0,3] &lt;departement&gt;
196     * <br>[0,1] &lt;code-INSEE-commune&gt;
197     * <br>[0,1] &lt;code-INSEE-canton&gt;
198     * <br>[0,1] &lt;region&gt;
199     * <br>[0,1] &lt;pays&gt;
200     * <br>[0,1] &lt;geolocalisation&gt;
201     * @param contentHandler the content handler
202     * @param content the saxed content
203     * @param lines the address lines. Is mandatory.
204     * @param zipCode the zip code. Is mandatory.
205     * @param town the town. Is mandatory.
206     * @param department the department. Can be null.
207     * @param codeINSEEtown the code INSEE for the town. Can be null.
208     * @param codeINSEEdistrict the code INSEE for the district. Can be null.
209     * @param zone the zone. Can be null.
210     * @param country the country. Can be null.
211     * @param latitude the latitude. Can be null.
212     * @param longitude the longitude. Can be null.
213     * @throws SAXException if a saxing exception occurred
214     */
215    public void createAddressLHEOElements(ContentHandler contentHandler, Content content, List<String> lines, String zipCode, String town, String department, String codeINSEEtown, String codeINSEEdistrict, String zone, String country, String latitude, String longitude) throws SAXException
216    {
217        // <ligne>
218        int size = lines.size();
219        if (size > 4)
220        {
221            size = 4;
222            getLogger().warn("[" + content.getTitle() + " (" + content.getId() + ")] The value " + StringUtils.join(lines, "") + " can be set in 4 lines. It will be truncated.");
223        }
224        
225        if (size != 0)
226        {
227            for (int i = 0; i < size; i++)
228            {
229                createLHEOElement(contentHandler, content, "ligne", lines.get(i), 1, 50);
230            }
231        }
232        else
233        {
234            getLogger().warn("[" + content.getTitle() + " (" + content.getId() + ")] The tag adresse must contain at least one line");
235        }
236        
237        // <codepostal>
238        createMandatoryLHEOElement(contentHandler, content, "codepostal", zipCode, 5, 5);
239        
240        // <ville>
241        createMandatoryLHEOElement(contentHandler, content, "ville", town, 1, 50);
242        
243        // <departement>
244        createLHEOElement(contentHandler, content, "departement", department, 2, 3);
245        
246        // <code-INSEE-commune>
247        createLHEOElement(contentHandler, content, "code-INSEE-commune", codeINSEEtown, 5, 5);
248        
249        // <code-INSEE-canton>
250        createLHEOElement(contentHandler, content, "code-INSEE-canton", codeINSEEdistrict, 4, 5);
251        
252        // <region>
253        createLHEOElement(contentHandler, content, "region", zone, 2, 2);
254        
255        // <pays>
256        createLHEOElement(contentHandler, content, "pays", country, 2, 2);
257        
258        // <geolocalisation>
259        if (StringUtils.isNotBlank(latitude) && StringUtils.isNotBlank(longitude))
260        {
261            XMLUtils.startElement(contentHandler, "geolocalisation");
262            
263            // <latitude>
264            createLHEOElement(contentHandler, content, "latitude", latitude, 0, 30);
265            
266            // <longitude>
267            createLHEOElement(contentHandler, content, "longitude", longitude, 0, 30);
268            
269            XMLUtils.endElement(contentHandler, "geolocalisation");
270        }
271    }
272    
273    /**
274     * Create the mandatory LHEO element
275     * @param contentHandler the content handler
276     * @param content the saxed content
277     * @param elementName the element name
278     * @param value the value to sax
279     * @throws SAXException if a saxing error occurred
280     */
281    public void createMandatoryLHEOElement(ContentHandler contentHandler, Content content, String elementName, String value) throws SAXException
282    {
283        createMandatoryLHEOElement(contentHandler, content, elementName, new AttributesImpl(),  value, 0, 0);
284    }
285    
286    /**
287     * Create the mandatory LHEO element
288     * @param contentHandler the content handler
289     * @param content the saxed content
290     * @param elementName the element name
291     * @param value the value to sax
292     * @param minLength the min length of the value (0 if there is no min length). If the value length is lower than minLength, a warning will be logged
293     * @param maxLength the max length of the value (0 if there is no max length). If the value length is greater than maxLength, a warning will be logged and the value will be troncated
294     * @throws SAXException if a saxing error occurred
295     */
296    public void createMandatoryLHEOElement(ContentHandler contentHandler, Content content, String elementName, String value, int minLength, int maxLength) throws SAXException
297    {
298        createMandatoryLHEOElement(contentHandler, content, elementName, new AttributesImpl(), value, minLength, maxLength);
299    }
300    
301    /**
302     * Create the mandatory LHEO element
303     * @param contentHandler the content handler
304     * @param content the saxed content
305     * @param elementName the element name
306     * @param attrs the attributes
307     * @param value the value to sax
308     * @throws SAXException if a saxing error occurred
309     */
310    public void createMandatoryLHEOElement(ContentHandler contentHandler, Content content, String elementName, AttributesImpl attrs, String value) throws SAXException
311    {
312        if (StringUtils.isBlank(value))
313        {
314            getLogger().warn("[" + content.getTitle() + " (" + content.getId() + ")] The value for tag " + elementName + " is mandatory");
315        }
316        else
317        {
318            createLHEOElement(contentHandler, content, elementName, value, 0, 0);
319        }
320    }
321    
322    /**
323     * Create the mandatory LHEO element
324     * @param contentHandler the content handler
325     * @param content the saxed content
326     * @param elementName the element name
327     * @param attrs the attributes
328     * @param value the value to sax
329     * @param minLength the min length of the value (0 if there is no min length). If the value length is lower than minLength, a warning will be logged
330     * @param maxLength the max length of the value (0 if there is no max length). If the value length is greater than maxLength, a warning will be logged and the value will be troncated
331     * @throws SAXException if a saxing error occurred
332     */
333    public void createMandatoryLHEOElement(ContentHandler contentHandler, Content content, String elementName, AttributesImpl attrs, String value, int minLength, int maxLength) throws SAXException
334    {
335        if (StringUtils.isBlank(value))
336        {
337            getLogger().warn("[" + content.getTitle() + " (" + content.getId() + ")] The value for tag " + elementName + " is mandatory");
338        }
339        else
340        {
341            createLHEOElement(contentHandler, content, elementName, value, minLength, maxLength);
342        }
343    }
344    
345    /**
346     * Create the LHEO element
347     * @param contentHandler the content handler
348     * @param content the saxed content
349     * @param elementName the element name
350     * @param value the value to sax
351     * @throws SAXException if a saxing error occurred
352     */
353    public void createLHEOElement(ContentHandler contentHandler, Content content, String elementName, String value) throws SAXException
354    {
355        createLHEOElement(contentHandler, content, elementName, new AttributesImpl(), value, 0, 0);
356    }
357    
358    /**
359     * Create the LHEO element
360     * @param contentHandler the content handler
361     * @param content the saxed content
362     * @param elementName the element name
363     * @param value the value to sax
364     * @param minLength the min length of the value (0 if there is no min length). If the value length is lower than minLength, a warning will be logged
365     * @param maxLength the max length of the value (0 if there is no max length). If the value length is greater than maxLength, a warning will be logged and the value will be troncated
366     * @throws SAXException if a saxing error occurred
367     */
368    public void createLHEOElement(ContentHandler contentHandler, Content content, String elementName, String value, int minLength, int maxLength) throws SAXException
369    {
370        createLHEOElement(contentHandler, content, elementName, new AttributesImpl(), value, minLength, maxLength);
371    }
372    
373    /**
374     * Create the LHEO element
375     * @param contentHandler the content handler
376     * @param content the saxed content
377     * @param elementName the element name
378     * @param attrs the attributes
379     * @param value the value to sax
380     * @throws SAXException if a saxing error occurred
381     */
382    public void createLHEOElement(ContentHandler contentHandler, Content content, String elementName, AttributesImpl attrs, String value) throws SAXException
383    {
384        if (StringUtils.isNotBlank(value))
385        {
386            XMLUtils.createElement(contentHandler, elementName, attrs, value);
387        }
388    }
389    
390    /**
391     * Create the LHEO element
392     * @param contentHandler the content handler
393     * @param content the saxed content
394     * @param elementName the element name
395     * @param attrs the attributes
396     * @param value the value to sax
397     * @param minLength the min length of the value (0 if there is no min length). If the value length is lower than minLength, a warning will be logged
398     * @param maxLength the max length of the value (0 if there is no max length). If the value length is greater than maxLength, a warning will be logged and the value will be troncated
399     * @throws SAXException if a saxing error occurred
400     */
401    public void createLHEOElement(ContentHandler contentHandler, Content content, String elementName, AttributesImpl attrs, String value, int minLength, int maxLength) throws SAXException
402    {
403        if (StringUtils.isNotBlank(value))
404        {
405            String computedValue = value;
406            int valueLength = computedValue.length();
407            if (minLength != 0 && maxLength != 0 && minLength == maxLength)
408            {
409                if (valueLength < minLength)
410                {
411                    getLogger().warn("[" + content.getTitle() + " (" + content.getId() + ")] The value for element " + elementName + " is supposed to contains exactly " + minLength + " characters.");
412                }
413                else
414                {
415                    getLogger().warn("[" + content.getTitle() + " (" + content.getId() + ")] The value for element " + elementName + " is supposed to contains exactly " + minLength + " characters. It will be troncated.");
416                    computedValue = StringUtils.substring(value, 0, maxLength);
417                }
418            }
419            else
420            {
421                if (maxLength != 0 && valueLength > maxLength)
422                {
423                    getLogger().warn("[" + content.getTitle() + " (" + content.getId() + ")] The value for element " + elementName + " is not supposed to contains more than " + maxLength + " characters. It will be troncated.");
424                    computedValue = StringUtils.substring(value, 0, maxLength);
425                }
426                
427                if (minLength != 0 && valueLength < minLength)
428                {
429                    getLogger().warn("[" + content.getTitle() + " (" + content.getId() + ")] The value for element " + elementName + " is not supposed to contains less than " + minLength + " characters.");
430                }
431            }
432            
433            XMLUtils.createElement(contentHandler, elementName, attrs, computedValue);
434        }
435    }
436}