1. Project Clover database Sat Feb 2 2019 06:45:20 CET
  2. Package org.xwiki.xar

File XarPackage.java

 

Coverage histogram

../../../img/srcFileCovDistChart10.png
0% of files have more coverage

Code metrics

58
193
50
1
788
452
91
0.47
3.86
50
1.82

Classes

Class Line # Actions
XarPackage 68 193 0% 91 24
0.920265892%
 

Contributing tests

This file is covered by 36 tests. .

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20    package org.xwiki.xar;
21   
22    import java.io.File;
23    import java.io.FileInputStream;
24    import java.io.IOException;
25    import java.io.InputStream;
26    import java.io.OutputStream;
27    import java.util.Collection;
28    import java.util.Enumeration;
29    import java.util.LinkedHashMap;
30    import java.util.Map;
31    import java.util.Objects;
32   
33    import javax.xml.parsers.DocumentBuilder;
34    import javax.xml.parsers.DocumentBuilderFactory;
35    import javax.xml.parsers.ParserConfigurationException;
36    import javax.xml.stream.XMLOutputFactory;
37    import javax.xml.stream.XMLStreamException;
38    import javax.xml.stream.XMLStreamWriter;
39   
40    import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
41    import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
42    import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
43    import org.apache.commons.compress.archivers.zip.ZipFile;
44    import org.apache.commons.io.input.CloseShieldInputStream;
45    import org.apache.commons.lang3.LocaleUtils;
46    import org.apache.commons.lang3.StringUtils;
47    import org.w3c.dom.Attr;
48    import org.w3c.dom.Document;
49    import org.w3c.dom.Element;
50    import org.w3c.dom.Node;
51    import org.w3c.dom.NodeList;
52    import org.xml.sax.SAXException;
53    import org.xwiki.model.EntityType;
54    import org.xwiki.model.internal.reference.DefaultSymbolScheme;
55    import org.xwiki.model.internal.reference.LocalStringEntityReferenceSerializer;
56    import org.xwiki.model.reference.LocalDocumentReference;
57    import org.xwiki.xar.internal.XarUtils;
58    import org.xwiki.xar.internal.model.XarModel;
59   
60    import javanet.staxutils.IndentingXMLStreamWriter;
61   
62    /**
63    * Manipulate package.xml XAR package file.
64    *
65    * @version $Id: 340915084c6f004a3c72e753cc807654f4c2a010 $
66    * @since 5.4RC1
67    */
 
68    public class XarPackage
69    {
70    private static final LocalStringEntityReferenceSerializer TOSTRING_SERIALIZER =
71    new LocalStringEntityReferenceSerializer(new DefaultSymbolScheme());
72   
73    /**
74    * Get all entries found in a XAR file.
75    *
76    * @param file the XAR file
77    * @return the entries of the passed XAR file
78    * @throws XarException when failing to parse the XAR package
79    * @throws IOException when failing to read the file
80    */
 
81  248 toggle public static Collection<XarEntry> getEntries(File file) throws XarException, IOException
82    {
83  248 XarPackage xarPackage = new XarPackage(file);
84   
85  248 return xarPackage.getEntries();
86    }
87   
88    /**
89    * @see #getPackageExtensionId()
90    */
91    private String packageExtensionId;
92   
93    /**
94    * @see #isPackagePreserveVersion()
95    */
96    private boolean packagePreserveVersion = true;
97   
98    /**
99    * @see #getPackageName()
100    */
101    private String packageName;
102   
103    /**
104    * @see #getPackageDescription()
105    */
106    private String packageDescription;
107   
108    /**
109    * @see #getPackageLicense()
110    */
111    private String packageLicense;
112   
113    /**
114    * @see #getPackageAuthor()
115    */
116    private String packageAuthor;
117   
118    /**
119    * @see #getPackageVersion()
120    */
121    private String packageVersion;
122   
123    /**
124    * @see #isPackageBackupPack()
125    */
126    private boolean packageBackupPack;
127   
128    private final Map<LocalDocumentReference, XarEntry> packageFiles = new LinkedHashMap<>();
129   
130    private final Map<LocalDocumentReference, XarEntry> entries = new LinkedHashMap<>();
131   
132    /**
133    * Default constructor.
134    */
 
135  24 toggle public XarPackage()
136    {
137   
138    }
139   
140    /**
141    * @param zipFile the XAR file as a {@link ZipFile}
142    * @throws XarException when failing to parse the XAR package
143    * @throws IOException when failing to read the file
144    */
 
145  1 toggle public XarPackage(ZipFile zipFile) throws XarException, IOException
146    {
147  1 read(zipFile);
148    }
149   
150    /**
151    * @param file the XAR file
152    * @throws IOException when failing to read the file
153    * @throws XarException when failing to parse the XAR package
154    */
 
155  1565 toggle public XarPackage(File file) throws IOException, XarException
156    {
157  1565 if (file.isDirectory()) {
158  7 read(file);
159    } else {
160  1558 try (ZipFile zipFile = new ZipFile(file)) {
161  1556 read(zipFile);
162    }
163    }
164    }
165   
166    /**
167    * @param xarStream an input stream the the XAR file
168    * @throws IOException when failing to read the file
169    * @throws XarException when failing to parse the XAR package
170    */
 
171  4 toggle public XarPackage(InputStream xarStream) throws IOException, XarException
172    {
173  4 read(xarStream);
174    }
175   
176    /**
177    * @param entries the entries in the XAR file
178    */
 
179  0 toggle public XarPackage(Collection<XarEntry> entries)
180    {
181  0 for (XarEntry entry : entries) {
182  0 this.entries.put(entry, entry);
183    }
184    }
185   
186    /**
187    * Find and add the entries located in the passed XAR file.
188    *
189    * @param xarStream an input stream to a XAR file
190    * @throws IOException when failing to read the file
191    * @throws XarException when failing to parse the XAR package
192    */
 
193  4 toggle public void read(InputStream xarStream) throws IOException, XarException
194    {
195  4 ZipArchiveInputStream zis = new ZipArchiveInputStream(xarStream, "UTF-8", false);
196   
197  4 try {
198  15 for (ZipArchiveEntry entry = zis.getNextZipEntry(); entry != null; entry = zis.getNextZipEntry()) {
199  11 if (!entry.isDirectory() && zis.canReadEntryData(entry)) {
200  8 readEntry(zis, entry.getName());
201    }
202    }
203    } finally {
204  4 zis.close();
205    }
206    }
207   
208    /**
209    * Find and add the entries located in the passed XAR file.
210    *
211    * @param zipFile the XAR file
212    * @throws IOException when failing to read the file
213    * @throws XarException when failing to parse the XAR package
214    */
 
215  1557 toggle public void read(ZipFile zipFile) throws IOException, XarException
216    {
217  1557 Enumeration<ZipArchiveEntry> zipEntries = zipFile.getEntries();
218   
219  25059 while (zipEntries.hasMoreElements()) {
220  23502 ZipArchiveEntry entry = zipEntries.nextElement();
221   
222  23502 if (!entry.isDirectory()) {
223  23502 InputStream stream = zipFile.getInputStream(entry);
224   
225  23502 try {
226  23502 readEntry(stream, entry.getName());
227    } finally {
228  23502 stream.close();
229    }
230    }
231    }
232    }
233   
234    /**
235    * Find and add the entries located in the passed XAR directory.
236    *
237    * @param directory the expended XAR file
238    * @throws IOException when failing to read the file
239    * @throws XarException when failing to parse the XAR package
240    * @since 9.5RC1
241    */
 
242  7 toggle public void read(File directory) throws IOException, XarException
243    {
244  7 String directoryName = directory.getPath();
245  7 directoryName += File.separator;
246   
247  7 read(directory, directoryName);
248    }
249   
 
250  525 toggle private void read(File directory, String rootDirectory) throws IOException, XarException
251    {
252  525 for (File file : directory.listFiles()) {
253  6958 if (file.isDirectory()) {
254  518 read(file, rootDirectory);
255    } else {
256  6440 try (FileInputStream stream = new FileInputStream(file)) {
257  6440 String entryName = file.getPath();
258  6440 entryName = entryName.substring(rootDirectory.length(), entryName.length());
259  6440 readEntry(stream, entryName);
260    }
261    }
262    }
263    }
264   
 
265  29950 toggle private void readEntry(InputStream stream, String entryName) throws XarException, IOException
266    {
267  29950 if (entryName.equals(XarModel.PATH_PACKAGE)) {
268  1568 readDescriptor(stream);
269    } else {
270  28382 LocalDocumentReference reference = XarUtils.getReference(stream);
271   
272    // Get current action associated to the document
273  28382 int defaultAction = getDefaultAction(reference);
274    // Get current type associated to the document
275  28382 String entryType = getEntryType(reference);
276   
277    // Create entry
278  28382 XarEntry xarEntry = new XarEntry(reference, entryName, defaultAction, entryType);
279   
280    // Register entry
281  28382 putEntry(xarEntry);
282    }
283    }
284   
285    /**
286    * @return the identifier of the extension stored in the XAR package
287    */
 
288  34 toggle public String getPackageExtensionId()
289    {
290  34 return this.packageExtensionId;
291    }
292   
293    /**
294    * @param packageExtensionId the identifier of the extension stored in the XAR package
295    */
 
296  4 toggle public void setPackageExtensionId(String packageExtensionId)
297    {
298  4 this.packageExtensionId = packageExtensionId;
299    }
300   
301    /**
302    * @return true if the history should be preserved by default
303    */
 
304  4 toggle public boolean isPackagePreserveVersion()
305    {
306  4 return this.packagePreserveVersion;
307    }
308   
309    /**
310    * @param preserveVersion true if the history should be preserved by default
311    * @deprecated since 7.2M1, use {@link #setPackagePreserveVersion(boolean)} instead
312    */
 
313  0 toggle @Deprecated
314    public void setPreserveVersion(boolean preserveVersion)
315    {
316  0 this.packagePreserveVersion = preserveVersion;
317    }
318   
319    /**
320    * @param packagePreserveVersion true if the history should be preserved by default
321    */
 
322  4 toggle public void setPackagePreserveVersion(boolean packagePreserveVersion)
323    {
324  4 this.packagePreserveVersion = packagePreserveVersion;
325    }
326   
327    /**
328    * @return the name of the package
329    */
 
330  9 toggle public String getPackageName()
331    {
332  9 return this.packageName;
333    }
334   
335    /**
336    * @param packageName the name of the package
337    */
 
338  4 toggle public void setPackageName(String packageName)
339    {
340  4 this.packageName = packageName;
341    }
342   
343    /**
344    * @return the description of package
345    */
 
346  9 toggle public String getPackageDescription()
347    {
348  9 return this.packageDescription;
349    }
350   
351    /**
352    * @param packageDescription the description of package
353    */
 
354  4 toggle public void setPackageDescription(String packageDescription)
355    {
356  4 this.packageDescription = packageDescription;
357    }
358   
359    /**
360    * @return the license of the package
361    */
 
362  9 toggle public String getPackageLicense()
363    {
364  9 return this.packageLicense;
365    }
366   
367    /**
368    * @param packageLicense the license of the package
369    */
 
370  4 toggle public void setPackageLicense(String packageLicense)
371    {
372  4 this.packageLicense = packageLicense;
373    }
374   
375    /**
376    * @return the author of the package
377    */
 
378  9 toggle public String getPackageAuthor()
379    {
380  9 return this.packageAuthor;
381    }
382   
383    /**
384    * @param packageAuthor the author of the package
385    */
 
386  4 toggle public void setPackageAuthor(String packageAuthor)
387    {
388  4 this.packageAuthor = packageAuthor;
389    }
390   
391    /**
392    * @return the version of the package
393    */
 
394  19 toggle public String getPackageVersion()
395    {
396  19 return this.packageVersion;
397    }
398   
399    /**
400    * @param packageVersion the version of the package
401    */
 
402  4 toggle public void setPackageVersion(String packageVersion)
403    {
404  4 this.packageVersion = packageVersion;
405    }
406   
407    /**
408    * @return true of the package is a backup
409    */
 
410  8 toggle public boolean isPackageBackupPack()
411    {
412  8 return this.packageBackupPack;
413    }
414   
415    /**
416    * @param packageBackupPack true of the package is a backup
417    */
 
418  4 toggle public void setPackageBackupPack(boolean packageBackupPack)
419    {
420  4 this.packageBackupPack = packageBackupPack;
421    }
422   
423    /**
424    * @return the entries listed in the package descriptor
425    * @since 7.2M1
426    */
 
427  2 toggle public Collection<XarEntry> getPackageFiles()
428    {
429  2 return this.packageFiles.values();
430    }
431   
432    /**
433    * Add a new entry to the package.
434    *
435    * @param reference the entry reference since 7.2M1
436    * @param action the default action associated to this XAR (not used at the moment)
437    */
 
438  0 toggle public void addPackageFile(LocalDocumentReference reference, int action)
439    {
440  0 this.packageFiles.put(reference, new XarEntry(reference, null, action));
441    }
442   
443    /**
444    * Add a new entry to the package.
445    *
446    * @param reference the entry reference
447    * @deprecated since 7.2M1, use {@link #addPackageFile(LocalDocumentReference, int)} instead
448    */
 
449  0 toggle @Deprecated
450    public void addEntry(LocalDocumentReference reference)
451    {
452  0 addEntry(reference, null);
453    }
454   
455    /**
456    * Add a new entry to the package.
457    *
458    * @param reference the entry reference
459    * @param entryName the name of the entry (ZIP style)
460    * @since 7.2M1
461    */
 
462  194 toggle public void addEntry(LocalDocumentReference reference, String entryName)
463    {
464  194 addEntry(reference, entryName, XarModel.ACTION_OVERWRITE);
465    }
466   
467    /**
468    * Add a new entry to the package.
469    *
470    * @param reference the entry reference
471    * @param entryName the name of the entry (ZIP style)
472    * @param action the default action associated to this XAR (not used at the moment)
473    * @since 7.2M1
474    */
 
475  194 toggle public void addEntry(LocalDocumentReference reference, String entryName, int action)
476    {
477  194 XarEntry entry = new XarEntry(reference, entryName, action);
478   
479  194 putEntry(entry);
480    }
481   
 
482  28576 toggle private void putEntry(XarEntry entry)
483    {
484  28576 this.entries.put(entry, entry);
485  28576 this.packageFiles.put(entry, entry);
486    }
487   
488    /**
489    * @return the entries of the package
490    */
 
491  1824 toggle public Collection<XarEntry> getEntries()
492    {
493  1824 return this.entries.values();
494    }
495   
496    /**
497    * @param reference the reference of the document
498    * @return the entry associated to the passage reference
499    */
 
500  34384 toggle public XarEntry getEntry(LocalDocumentReference reference)
501    {
502  34384 return this.entries.get(reference);
503    }
504   
505    /**
506    * Read a XML descriptor of a XAR package (usually names package.xml).
507    *
508    * @param stream the input stream to the XML file to parse
509    * @throws XarException when failing to parse the descriptor
510    * @throws IOException when failing to read the file
511    */
 
512  1584 toggle public void readDescriptor(InputStream stream) throws XarException, IOException
513    {
514  1584 DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
515   
516  1584 DocumentBuilder dBuilder;
517  1584 try {
518  1584 dBuilder = dbFactory.newDocumentBuilder();
519    } catch (ParserConfigurationException e) {
520  0 throw new XarException("Failed to create a new Document builder", e);
521    }
522   
523  1584 Document doc;
524  1584 try {
525    // DocumentBuilder#parse close the passed stream which is not what we want
526  1584 doc = dBuilder.parse(new CloseShieldInputStream(stream));
527    } catch (SAXException e) {
528  0 throw new XarException("Failed to parse XML document", e);
529    }
530   
531    // Normalize the document
532  1584 doc.getDocumentElement().normalize();
533   
534    // Read the document
535  1584 NodeList children = doc.getChildNodes();
536  1584 for (int i = 0; i < children.getLength(); ++i) {
537  1584 Node node = children.item(i);
538  1584 if (node.getNodeType() == Node.ELEMENT_NODE) {
539  1584 Element element = (Element) node;
540  1584 if (element.getTagName().equals(XarModel.ELEMENT_PACKAGE)) {
541  1584 readDescriptorPackage(element);
542  1584 break;
543    }
544    }
545    }
546    }
547   
 
548  1584 toggle private void readDescriptorPackage(Element packageElement)
549    {
550  1584 NodeList children = packageElement.getChildNodes();
551  11418 for (int i = 0; i < children.getLength(); ++i) {
552  9834 Node node = children.item(i);
553  9834 if (node.getNodeType() == Node.ELEMENT_NODE) {
554  4246 Element element = (Element) node;
555  4246 if (element.getTagName().equals(XarModel.ELEMENT_INFOS)) {
556  1584 readDescriptorInfos(element);
557  2662 } else if (element.getTagName().equals(XarModel.ELEMENT_FILES)) {
558  1584 readDescriptorFiles(element);
559    }
560    }
561    }
562    }
563   
 
564  1584 toggle private void readDescriptorInfos(Element infos)
565    {
566  1584 this.packageExtensionId = getElementText(infos, XarModel.ELEMENT_INFOS_EXTENSIONID, true);
567  1584 this.packageVersion = getElementText(infos, XarModel.ELEMENT_INFOS_VERSION, false);
568  1584 this.packageName = getElementText(infos, XarModel.ELEMENT_INFOS_NAME, false);
569  1584 this.packageDescription = getElementText(infos, XarModel.ELEMENT_INFOS_DESCRIPTION, false);
570  1584 this.packageLicense = getElementText(infos, XarModel.ELEMENT_INFOS_LICENSE, false);
571  1584 this.packageAuthor = getElementText(infos, XarModel.ELEMENT_INFOS_AUTHOR, false);
572  1584 this.packageBackupPack =
573    Boolean.parseBoolean(getElementText(infos, XarModel.ELEMENT_INFOS_ISBACKUPPACK, false));
574  1584 this.packagePreserveVersion =
575    Boolean.parseBoolean(getElementText(infos, XarModel.ELEMENT_INFOS_ISPRESERVEVERSION, false));
576    }
577   
 
578  1584 toggle private void readDescriptorFiles(Element files)
579    {
580  1584 NodeList children = files.getChildNodes();
581  58965 for (int i = 0; i < children.getLength(); ++i) {
582  57381 Node node = children.item(i);
583  57381 if (node.getNodeType() == Node.ELEMENT_NODE) {
584  27968 Element element = (Element) node;
585  27968 if (element.getTagName().equals(XarModel.ELEMENT_FILES_FILE)) {
586  27968 String localeString = element.getAttribute(XarModel.ATTRIBUTE_LOCALE);
587  27968 String defaultActionString = getAttribute(element, XarModel.ATTRIBUTE_DEFAULTACTION);
588  27968 String entryType = getAttribute(element, XarModel.ATTRIBUTE_TYPE);
589  27968 String referenceString = element.getTextContent();
590   
591    // Parse reference
592  27968 LocalDocumentReference reference =
593    new LocalDocumentReference(XarUtils.RESOLVER.resolve(referenceString, EntityType.DOCUMENT),
594    LocaleUtils.toLocale(localeString));
595   
596    // Parse default action
597  27968 int defaultAction =
598  27968 defaultActionString != null ? Integer.parseInt(defaultActionString) : XarModel.ACTION_OVERWRITE;
599   
600    // Get entry name associated to the document
601  27968 String entryName = getEntryName(reference);
602   
603    // Create entry
604  27968 XarEntry packageFile = new XarEntry(reference, entryName, defaultAction, entryType);
605   
606    // Register package file entry
607  27968 this.packageFiles.put(packageFile, packageFile);
608   
609    // Update existing entry default action
610  27968 updateEntry(packageFile);
611    }
612    }
613    }
614    }
615   
 
616  55936 toggle private String getAttribute(Element element, String attributeName)
617    {
618  55936 Attr attrribute = element.getAttributeNode(attributeName);
619   
620  55936 return attrribute != null ? attrribute.getValue() : null;
621    }
622   
 
623  27968 toggle private String getEntryName(LocalDocumentReference reference)
624    {
625  27968 String entryName = null;
626   
627  27968 XarEntry entry = this.entries.get(reference);
628  27968 if (entry != null) {
629  15303 entryName = entry.getEntryName();
630    }
631   
632  27968 return entryName;
633    }
634   
 
635  28382 toggle private int getDefaultAction(LocalDocumentReference reference)
636    {
637  28382 int defaultAction = XarModel.ACTION_SKIP;
638   
639  28382 XarEntry packageFile = this.packageFiles.get(reference);
640  28382 if (packageFile != null) {
641  12573 defaultAction = packageFile.getDefaultAction();
642    }
643   
644  28382 return defaultAction;
645    }
646   
 
647  28382 toggle private String getEntryType(LocalDocumentReference reference)
648    {
649  28382 String entryType = null;
650   
651  28382 XarEntry packageFile = this.packageFiles.get(reference);
652  28382 if (packageFile != null) {
653  12573 entryType = packageFile.getEntryType();
654    }
655   
656  28382 return entryType;
657    }
658   
 
659  27968 toggle private void updateEntry(XarEntry packageFile)
660    {
661  27968 if (this.entries.containsKey(packageFile)) {
662  15303 this.entries.put(packageFile, packageFile);
663    }
664    }
665   
 
666  12672 toggle private String getElementText(Element element, String tagName, boolean ignoreEmpty)
667    {
668  12672 NodeList nList = element.getElementsByTagName(tagName);
669   
670  12672 String value = nList.getLength() > 0 ? nList.item(0).getTextContent() : null;
671   
672  12672 if (value != null && ignoreEmpty && StringUtils.isEmpty(value)) {
673  1 value = null;
674    }
675   
676  12672 return value;
677    }
678   
679    /**
680    * Write and add the package descriptor to the passed ZIP stream.
681    *
682    * @param zipStream the ZIP stream in which to write
683    * @param encoding the encoding to use to write the descriptor
684    * @throws XarException when failing to parse the descriptor
685    * @throws IOException when failing to read the file
686    */
 
687  4 toggle public void write(ZipArchiveOutputStream zipStream, String encoding) throws XarException, IOException
688    {
689  4 ZipArchiveEntry zipentry = new ZipArchiveEntry(XarModel.PATH_PACKAGE);
690  4 zipStream.putArchiveEntry(zipentry);
691   
692  4 try {
693  4 write((OutputStream) zipStream, encoding);
694    } finally {
695  4 zipStream.closeArchiveEntry();
696    }
697    }
698   
699    /**
700    * Write the package descriptor to the passed stream as XML.
701    *
702    * @param stream the stream to the resulting XML file
703    * @param encoding the encoding to use to write the descriptor
704    * @throws XarException when failing to parse the descriptor
705    */
 
706  4 toggle public void write(OutputStream stream, String encoding) throws XarException
707    {
708  4 XMLStreamWriter writer;
709  4 try {
710  4 writer = XMLOutputFactory.newInstance().createXMLStreamWriter(stream, encoding);
711    } catch (Exception e) {
712  0 throw new XarException("Failed to create an instance of XML stream writer", e);
713    }
714   
715  4 writer = new IndentingXMLStreamWriter(writer);
716   
717  4 try {
718  4 writer.writeStartDocument(encoding, "1.0");
719  4 write(writer);
720  4 writer.writeEndDocument();
721   
722  4 writer.flush();
723    } catch (Exception e) {
724  0 throw new XarException("Failed to write XML", e);
725    } finally {
726  4 try {
727  4 writer.close();
728    } catch (XMLStreamException e) {
729  0 throw new XarException("Failed to close XML writer", e);
730    }
731    }
732    }
733   
734    /**
735    * Write the package descriptor to the passed XML stream.
736    *
737    * @param writer the XML stream where to write
738    * @throws XMLStreamException when failing to write the file
739    */
 
740  4 toggle public void write(XMLStreamWriter writer) throws XMLStreamException
741    {
742  4 writer.writeStartElement(XarModel.ELEMENT_PACKAGE);
743   
744  4 writer.writeStartElement(XarModel.ELEMENT_INFOS);
745  4 writeElement(writer, XarModel.ELEMENT_INFOS_NAME, getPackageName(), true);
746  4 writeElement(writer, XarModel.ELEMENT_INFOS_DESCRIPTION, getPackageDescription(), true);
747  4 writeElement(writer, XarModel.ELEMENT_INFOS_LICENSE, getPackageLicense(), true);
748  4 writeElement(writer, XarModel.ELEMENT_INFOS_AUTHOR, getPackageAuthor(), true);
749  4 writeElement(writer, XarModel.ELEMENT_INFOS_VERSION, getPackageVersion(), true);
750  4 writeElement(writer, XarModel.ELEMENT_INFOS_ISBACKUPPACK, String.valueOf(isPackageBackupPack()), true);
751  4 writeElement(writer, XarModel.ELEMENT_INFOS_ISPRESERVEVERSION, String.valueOf(isPackagePreserveVersion()),
752    true);
753  4 writeElement(writer, XarModel.ELEMENT_INFOS_EXTENSIONID, getPackageExtensionId(), false);
754  4 writer.writeEndElement();
755   
756  4 writer.writeStartElement(XarModel.ELEMENT_FILES);
757  4 for (XarEntry entry : this.entries.values()) {
758  194 writer.writeStartElement(XarModel.ELEMENT_FILES_FILE);
759   
760  194 writer.writeAttribute(XarModel.ATTRIBUTE_DEFAULTACTION, String.valueOf(entry.getDefaultAction()));
761  194 writer.writeAttribute(XarModel.ATTRIBUTE_LOCALE, Objects.toString(entry.getLocale(), ""));
762  194 if (entry.getEntryType() != null) {
763  0 writer.writeAttribute(XarModel.ATTRIBUTE_TYPE, entry.getEntryType());
764    }
765   
766  194 writer.writeCharacters(TOSTRING_SERIALIZER.serialize(entry));
767   
768  194 writer.writeEndElement();
769    }
770  4 writer.writeEndElement();
771    }
772   
 
773  32 toggle private void writeElement(XMLStreamWriter streamWriter, String localName, String value, boolean emptyIfNull)
774    throws XMLStreamException
775    {
776  32 if (value != null) {
777  17 if (value.isEmpty()) {
778  0 streamWriter.writeEmptyElement(localName);
779    } else {
780  17 streamWriter.writeStartElement(localName);
781  17 streamWriter.writeCharacters(value);
782  17 streamWriter.writeEndElement();
783    }
784  15 } else if (emptyIfNull) {
785  12 streamWriter.writeEmptyElement(localName);
786    }
787    }
788    }