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            XMLUtils.startElement(contentHandler, "geolocalisation");
267            
268            // <latitude>
269            createLHEOElement(contentHandler, content, "latitude", latitude, 0, 30);
270            
271            // <longitude>
272            createLHEOElement(contentHandler, content, "longitude", longitude, 0, 30);
273            
274            XMLUtils.endElement(contentHandler, "geolocalisation");
275        }
276    }
277    
278    /**
279     * Create the mandatory LHEO element
280     * @param contentHandler the content handler
281     * @param content the saxed content
282     * @param elementName the element name
283     * @param value the value to sax
284     * @throws SAXException if a saxing error occurred
285     */
286    public static void createMandatoryLHEOElement(ContentHandler contentHandler, Content content, String elementName, String value) throws SAXException
287    {
288        createMandatoryLHEOElement(contentHandler, content, elementName, new AttributesImpl(),  value, 0, 0);
289    }
290    
291    /**
292     * Create the mandatory LHEO element
293     * @param contentHandler the content handler
294     * @param content the saxed content
295     * @param elementName the element name
296     * @param value the value to sax
297     * @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
298     * @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
299     * @throws SAXException if a saxing error occurred
300     */
301    public static void createMandatoryLHEOElement(ContentHandler contentHandler, Content content, String elementName, String value, int minLength, int maxLength) throws SAXException
302    {
303        createMandatoryLHEOElement(contentHandler, content, elementName, new AttributesImpl(), value, minLength, maxLength);
304    }
305    
306    /**
307     * Create the mandatory LHEO element
308     * @param contentHandler the content handler
309     * @param content the saxed content
310     * @param elementName the element name
311     * @param attrs the attributes
312     * @param value the value to sax
313     * @throws SAXException if a saxing error occurred
314     */
315    public static void createMandatoryLHEOElement(ContentHandler contentHandler, Content content, String elementName, AttributesImpl attrs, String value) throws SAXException
316    {
317        if (StringUtils.isBlank(value))
318        {
319            __logger.warn("[" + content.getTitle() + " (" + content.getId() + ")] The value for tag " + elementName + " is mandatory");
320        }
321        else
322        {
323            createLHEOElement(contentHandler, content, elementName, value, 0, 0);
324        }
325    }
326    
327    /**
328     * Create the mandatory LHEO element
329     * @param contentHandler the content handler
330     * @param content the saxed content
331     * @param elementName the element name
332     * @param attrs the attributes
333     * @param value the value to sax
334     * @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
335     * @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
336     * @throws SAXException if a saxing error occurred
337     */
338    public static void createMandatoryLHEOElement(ContentHandler contentHandler, Content content, String elementName, AttributesImpl attrs, String value, int minLength, int maxLength) throws SAXException
339    {
340        if (StringUtils.isBlank(value))
341        {
342            __logger.warn("[" + content.getTitle() + " (" + content.getId() + ")] The value for tag " + elementName + " is mandatory");
343        }
344        else
345        {
346            createLHEOElement(contentHandler, content, elementName, value, minLength, maxLength);
347        }
348    }
349    
350    /**
351     * Create the LHEO element
352     * @param contentHandler the content handler
353     * @param content the saxed content
354     * @param elementName the element name
355     * @param value the value to sax
356     * @throws SAXException if a saxing error occurred
357     */
358    public static void createLHEOElement(ContentHandler contentHandler, Content content, String elementName, String value) throws SAXException
359    {
360        createLHEOElement(contentHandler, content, elementName, new AttributesImpl(), value, 0, 0);
361    }
362    
363    /**
364     * Create the LHEO element
365     * @param contentHandler the content handler
366     * @param content the saxed content
367     * @param elementName the element name
368     * @param value the value to sax
369     * @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
370     * @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
371     * @throws SAXException if a saxing error occurred
372     */
373    public static void createLHEOElement(ContentHandler contentHandler, Content content, String elementName, String value, int minLength, int maxLength) throws SAXException
374    {
375        createLHEOElement(contentHandler, content, elementName, new AttributesImpl(), value, minLength, maxLength);
376    }
377    
378    /**
379     * Create the LHEO element
380     * @param contentHandler the content handler
381     * @param content the saxed content
382     * @param elementName the element name
383     * @param attrs the attributes
384     * @param value the value to sax
385     * @throws SAXException if a saxing error occurred
386     */
387    public static void createLHEOElement(ContentHandler contentHandler, Content content, String elementName, AttributesImpl attrs, String value) throws SAXException
388    {
389        if (StringUtils.isNotBlank(value))
390        {
391            XMLUtils.createElement(contentHandler, elementName, attrs, value);
392        }
393    }
394    
395    /**
396     * Create the LHEO element
397     * @param contentHandler the content handler
398     * @param content the saxed content
399     * @param elementName the element name
400     * @param attrs the attributes
401     * @param value the value to sax
402     * @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
403     * @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
404     * @throws SAXException if a saxing error occurred
405     */
406    public static void createLHEOElement(ContentHandler contentHandler, Content content, String elementName, AttributesImpl attrs, String value, int minLength, int maxLength) throws SAXException
407    {
408        if (StringUtils.isNotBlank(value))
409        {
410            String computedValue = value;
411            int valueLength = computedValue.length();
412            if (minLength != 0 && maxLength != 0 && minLength == maxLength)
413            {
414                if (valueLength < minLength)
415                {
416                    __logger.warn("[" + content.getTitle() + " (" + content.getId() + ")] The value for element " + elementName + " is supposed to contains exactly " + minLength + " characters.");
417                }
418                else
419                {
420                    __logger.warn("[" + content.getTitle() + " (" + content.getId() + ")] The value for element " + elementName + " is supposed to contains exactly " + minLength + " characters. It will be troncated.");
421                    computedValue = StringUtils.substring(value, 0, maxLength);
422                }
423            }
424            else
425            {
426                if (maxLength != 0 && valueLength > maxLength)
427                {
428                    __logger.warn("[" + content.getTitle() + " (" + content.getId() + ")] The value for element " + elementName + " is not supposed to contains more than " + maxLength + " characters. It will be troncated.");
429                    computedValue = StringUtils.substring(value, 0, maxLength);
430                }
431                
432                if (minLength != 0 && valueLength < minLength)
433                {
434                    __logger.warn("[" + content.getTitle() + " (" + content.getId() + ")] The value for element " + elementName + " is not supposed to contains less than " + minLength + " characters.");
435                }
436            }
437            
438            XMLUtils.createElement(contentHandler, elementName, attrs, computedValue);
439        }
440    }
441}