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