1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package org.xwiki.extension.repository.internal

File DefaultExtensionSerializer.java

 

Coverage histogram

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

Code metrics

122
299
28
1
807
594
97
0.32
10.68
28
3.46

Classes

Class Line # Actions
DefaultExtensionSerializer 87 299 0% 97 14
0.968819696.9%
 

Contributing tests

This file is covered by 113 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.extension.repository.internal;
21   
22    import java.io.IOException;
23    import java.io.InputStream;
24    import java.io.OutputStream;
25    import java.io.StringReader;
26    import java.io.StringWriter;
27    import java.net.MalformedURLException;
28    import java.net.URL;
29    import java.util.ArrayList;
30    import java.util.Collection;
31    import java.util.Collections;
32    import java.util.Date;
33    import java.util.HashMap;
34    import java.util.LinkedHashMap;
35    import java.util.LinkedList;
36    import java.util.List;
37    import java.util.Map;
38    import java.util.Set;
39   
40    import javax.inject.Inject;
41    import javax.inject.Singleton;
42    import javax.xml.parsers.DocumentBuilder;
43    import javax.xml.parsers.DocumentBuilderFactory;
44    import javax.xml.parsers.ParserConfigurationException;
45    import javax.xml.transform.OutputKeys;
46    import javax.xml.transform.Result;
47    import javax.xml.transform.Transformer;
48    import javax.xml.transform.TransformerException;
49    import javax.xml.transform.TransformerFactory;
50    import javax.xml.transform.dom.DOMSource;
51    import javax.xml.transform.stream.StreamResult;
52   
53    import org.apache.commons.io.IOUtils;
54    import org.w3c.dom.Document;
55    import org.w3c.dom.Element;
56    import org.w3c.dom.Node;
57    import org.w3c.dom.NodeList;
58    import org.xwiki.component.annotation.Component;
59    import org.xwiki.extension.DefaultExtensionScm;
60    import org.xwiki.extension.DefaultExtensionScmConnection;
61    import org.xwiki.extension.Extension;
62    import org.xwiki.extension.ExtensionAuthor;
63    import org.xwiki.extension.ExtensionDependency;
64    import org.xwiki.extension.ExtensionId;
65    import org.xwiki.extension.ExtensionIssueManagement;
66    import org.xwiki.extension.ExtensionLicense;
67    import org.xwiki.extension.ExtensionLicenseManager;
68    import org.xwiki.extension.ExtensionScm;
69    import org.xwiki.extension.ExtensionScmConnection;
70    import org.xwiki.extension.InstalledExtension;
71    import org.xwiki.extension.InvalidExtensionException;
72    import org.xwiki.extension.MutableExtension;
73    import org.xwiki.extension.internal.ExtensionFactory;
74    import org.xwiki.extension.repository.internal.core.DefaultCoreExtension;
75    import org.xwiki.extension.repository.internal.core.DefaultCoreExtensionRepository;
76    import org.xwiki.extension.repository.internal.local.DefaultLocalExtension;
77    import org.xwiki.extension.repository.internal.local.DefaultLocalExtensionRepository;
78   
79    /**
80    * Local repository storage serialization tool.
81    *
82    * @version $Id: a3e7e8e25ae6cc7a332c7559955f3fe7bf1fbfbd $
83    * @since 6.4M1
84    */
85    @Component
86    @Singleton
 
87    public class DefaultExtensionSerializer implements ExtensionSerializer
88    {
89    private static final String ELEMENT_ID = "id";
90   
91    private static final String ELEMENT_VERSION = "version";
92   
93    private static final String ELEMENT_TYPE = "type";
94   
95    private static final String ELEMENT_LICENSES = "licenses";
96   
97    private static final String ELEMENT_LLICENSE = "license";
98   
99    private static final String ELEMENT_LLNAME = "name";
100   
101    private static final String ELEMENT_LLCONTENT = "content";
102   
103    private static final String ELEMENT_NAME = "name";
104   
105    private static final String ELEMENT_SUMMARY = "summary";
106   
107    private static final String ELEMENT_CATEGORY = "category";
108   
109    private static final String ELEMENT_DESCRIPTION = "description";
110   
111    private static final String ELEMENT_WEBSITE = "website";
112   
113    private static final String ELEMENT_AUTHORS = "authors";
114   
115    private static final String ELEMENT_AAUTHOR = "author";
116   
117    private static final String ELEMENT_AANAME = "name";
118   
119    private static final String ELEMENT_AAURL = "url";
120   
121    private static final String ELEMENT_DEPENDENCIES = "dependencies";
122   
123    private static final String ELEMENT_MANAGEDDEPENDENCIES = "manageddependencies";
124   
125    private static final String ELEMENT_DDEPENDENCY = "dependency";
126   
127    private static final String ELEMENT_EXTENSIONFEATURES = "extensionfeatures";
128   
129    private static final String ELEMENT_EFFEATURE = "feature";
130   
131    private static final String ELEMENT_EFFID = "feature";
132   
133    private static final String ELEMENT_EFFVERSION = "version";
134   
135    private static final String ELEMENT_ALLOWEDNAMESPACES = "allowednamespaces";
136   
137    private static final String ELEMENT_ANNAMESPACE = "namespace";
138   
139    private static final String ELEMENT_SCM = "scm";
140   
141    private static final String ELEMENT_SCONNECTION = "connection";
142   
143    private static final String ELEMENT_SDEVELOPERCONNECTION = "developerconnection";
144   
145    private static final String ELEMENT_SCSYSTEM = "system";
146   
147    private static final String ELEMENT_SCPATH = "path";
148   
149    private static final String ELEMENT_SURL = "url";
150   
151    private static final String ELEMENT_ISSUEMANAGEMENT = "issuemanagement";
152   
153    private static final String ELEMENT_ISYSTEM = "system";
154   
155    private static final String ELEMENT_IURL = "url";
156   
157    private static final String ELEMENT_PROPERTIES = "properties";
158   
159    @Deprecated
160    private static final String ELEMENT_FEATURES = "features";
161   
162    @Deprecated
163    private static final String ELEMENT_FFEATURE = "feature";
164   
165    @Deprecated
166    private static final String ELEMENT_INSTALLED = "installed";
167   
168    @Deprecated
169    private static final String ELEMENT_NAMESPACES = "namespaces";
170   
171    @Deprecated
172    private static final String ELEMENT_NNAMESPACE = "namespace";
173   
174    @Inject
175    private ExtensionLicenseManager licenseManager;
176   
177    @Inject
178    private ExtensionFactory factory;
179   
180    /**
181    * Used to parse XML descriptor file.
182    */
183    private DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
184   
185    protected Map<String, ExtensionPropertySerializer> serializerById;
186   
187    protected Map<Class<?>, ExtensionPropertySerializer> serializerByClass;
188   
 
189  277 toggle {
190    {
191  277 this.serializerById = new HashMap<String, ExtensionPropertySerializer>();
192  277 this.serializerByClass = new LinkedHashMap<Class<?>, ExtensionPropertySerializer>();
193   
194  277 StringExtensionPropertySerializer stringSerializer = new StringExtensionPropertySerializer();
195  277 IntegerExtensionPropertySerializer integerSerializer = new IntegerExtensionPropertySerializer();
196  277 BooleanExtensionPropertySerializer booleanSerializer = new BooleanExtensionPropertySerializer();
197  277 DateExtensionPropertySerializer dateSerializer = new DateExtensionPropertySerializer();
198  277 URLExtensionPropertySerializer urlSerializer = new URLExtensionPropertySerializer();
199  277 CollectionExtensionPropertySerializer collectionSerializer =
200    new CollectionExtensionPropertySerializer(this.serializerById, this.serializerByClass);
201  277 SetExtensionPropertySerializer setSerializer =
202    new SetExtensionPropertySerializer(this.serializerById, this.serializerByClass);
203  277 StringKeyMapExtensionPropertySerializer mapSerializer =
204    new StringKeyMapExtensionPropertySerializer(this.serializerById, this.serializerByClass);
205   
206  277 this.serializerById.put(null, stringSerializer);
207  277 this.serializerById.put("", stringSerializer);
208  277 this.serializerById.put(integerSerializer.getType(), integerSerializer);
209  277 this.serializerById.put(booleanSerializer.getType(), booleanSerializer);
210  277 this.serializerById.put(dateSerializer.getType(), dateSerializer);
211  277 this.serializerById.put(urlSerializer.getType(), urlSerializer);
212  277 this.serializerById.put(collectionSerializer.getType(), collectionSerializer);
213  277 this.serializerById.put(setSerializer.getType(), setSerializer);
214  277 this.serializerById.put(mapSerializer.getType(), mapSerializer);
215   
216  277 this.serializerByClass.put(String.class, stringSerializer);
217  277 this.serializerByClass.put(Integer.class, integerSerializer);
218  277 this.serializerByClass.put(Boolean.class, booleanSerializer);
219  277 this.serializerByClass.put(Date.class, dateSerializer);
220  277 this.serializerByClass.put(URL.class, urlSerializer);
221  277 this.serializerByClass.put(Set.class, setSerializer);
222  277 this.serializerByClass.put(Collection.class, collectionSerializer);
223  277 this.serializerByClass.put(Map.class, mapSerializer);
224    }
225    }
226   
 
227  11778 toggle @Override
228    public DefaultCoreExtension loadCoreExtensionDescriptor(DefaultCoreExtensionRepository repository, URL url,
229    InputStream descriptor) throws InvalidExtensionException
230    {
231  11778 Element extensionElement = getExtensionElement(descriptor);
232   
233  11778 DefaultCoreExtension coreExtension = new DefaultCoreExtension(repository, url, getExtensionId(extensionElement),
234    getExtensionType(extensionElement));
235   
236  11778 loadExtensionDescriptor(coreExtension, extensionElement);
237   
238  11778 coreExtension.setComplete(true);
239   
240  11778 return coreExtension;
241    }
242   
 
243  1535 toggle @Override
244    public DefaultLocalExtension loadLocalExtensionDescriptor(DefaultLocalExtensionRepository repository,
245    InputStream descriptor) throws InvalidExtensionException
246    {
247  1535 Element extensionElement = getExtensionElement(descriptor);
248   
249  1535 DefaultLocalExtension localExtension =
250    new DefaultLocalExtension(repository, getExtensionId(extensionElement), getExtensionType(extensionElement));
251   
252  1535 loadExtensionDescriptor(localExtension, extensionElement);
253   
254  1535 return localExtension;
255    }
256   
 
257  13313 toggle private Element getExtensionElement(InputStream descriptor) throws InvalidExtensionException
258    {
259  13313 DocumentBuilder documentBuilder;
260  13313 try {
261  13313 documentBuilder = this.documentBuilderFactory.newDocumentBuilder();
262    } catch (ParserConfigurationException e) {
263  0 throw new InvalidExtensionException("Failed to create new DocumentBuilder", e);
264    }
265   
266  13313 Document document;
267  13313 try {
268  13313 document = documentBuilder.parse(descriptor);
269    } catch (Exception e) {
270  0 throw new InvalidExtensionException("Failed to parse descriptor", e);
271    }
272   
273  13313 return document.getDocumentElement();
274    }
275   
 
276  13313 toggle private ExtensionId getExtensionId(Element extensionElement)
277    {
278  13313 Node idNode = extensionElement.getElementsByTagName(ELEMENT_ID).item(0);
279  13313 Node versionNode = extensionElement.getElementsByTagName(ELEMENT_VERSION).item(0);
280   
281  13313 return new ExtensionId(idNode.getTextContent(), this.factory.getVersion(versionNode.getTextContent()));
282    }
283   
 
284  13313 toggle private String getExtensionType(Element extensionElement)
285    {
286  13313 Node typeNode = extensionElement.getElementsByTagName(ELEMENT_TYPE).item(0);
287   
288  13313 return typeNode.getTextContent();
289    }
290   
 
291  13313 toggle private void loadExtensionDescriptor(MutableExtension extension, Element extensionElement)
292    throws InvalidExtensionException
293    {
294  13313 Node nameNode = getNode(extensionElement, ELEMENT_NAME);
295  13313 if (nameNode != null) {
296  11512 extension.setName(nameNode.getTextContent());
297    }
298  13313 Node categoryNode = getNode(extensionElement, ELEMENT_CATEGORY);
299  13313 if (categoryNode != null) {
300  1 extension.setCategory(categoryNode.getTextContent());
301    }
302  13313 Node summaryNode = getNode(extensionElement, ELEMENT_SUMMARY);
303  13313 if (summaryNode != null) {
304  10884 extension.setSummary(summaryNode.getTextContent());
305    }
306  13313 Node descriptionNode = getNode(extensionElement, ELEMENT_DESCRIPTION);
307  13313 if (descriptionNode != null) {
308  201 extension.setDescription(descriptionNode.getTextContent());
309    }
310  13313 Node websiteNode = getNode(extensionElement, ELEMENT_WEBSITE);
311  13313 if (websiteNode != null) {
312  11712 extension.setWebsite(websiteNode.getTextContent());
313    }
314   
315    // Licenses
316  13313 Node licensesNode = getNode(extensionElement, ELEMENT_LICENSES);
317  13313 if (licensesNode != null) {
318  11514 NodeList licenseNodeList = licensesNode.getChildNodes();
319  48598 for (int i = 0; i < licenseNodeList.getLength(); ++i) {
320  37084 Node licenseNode = licenseNodeList.item(i);
321   
322  37084 if (licenseNode.getNodeName().equals(ELEMENT_LLICENSE)) {
323  12785 Node licenseNameNode = getNode(licenseNode, ELEMENT_LLNAME);
324  12785 Node licenceContentNode = getNode(licenseNode, ELEMENT_LLCONTENT);
325   
326  12785 String licenseName = licenseNameNode.getTextContent();
327  12785 ExtensionLicense license = this.licenseManager.getLicense(licenseName);
328  12785 if (license == null) {
329  2207 try {
330  2207 license = new ExtensionLicense(licenseName, licenceContentNode != null
331    ? IOUtils.readLines(new StringReader(licenceContentNode.getTextContent())) : null);
332    } catch (IOException e) {
333    // That should never happen
334  0 throw new InvalidExtensionException("Failed to write license content", e);
335    }
336    }
337   
338  12785 extension.addLicense(license);
339    }
340    }
341    }
342   
343    // Authors
344  13313 Node authorsNode = getNode(extensionElement, ELEMENT_AUTHORS);
345  13313 if (authorsNode != null) {
346  9849 NodeList authors = authorsNode.getChildNodes();
347  101146 for (int i = 0; i < authors.getLength(); ++i) {
348  91297 Node authorNode = authors.item(i);
349   
350  91297 if (authorNode.getNodeName().equals(ELEMENT_AAUTHOR)) {
351  40724 Node authorNameNode = getNode(authorNode, ELEMENT_AANAME);
352  40724 Node authorURLNode = getNode(authorNode, ELEMENT_AAURL);
353   
354  40724 String authorName = authorNameNode != null ? authorNameNode.getTextContent() : null;
355  40724 URL authorURL;
356  40724 if (authorURLNode != null) {
357  2306 try {
358  2306 authorURL = new URL(authorURLNode.getTextContent());
359    } catch (MalformedURLException e) {
360    // That should never happen
361  0 throw new InvalidExtensionException(
362    "Malformed URL [" + authorURLNode.getTextContent() + "]", e);
363    }
364    } else {
365  38418 authorURL = null;
366    }
367   
368  40724 extension.addAuthor(this.factory.getExtensionAuthor(authorName, authorURL));
369    }
370    }
371    }
372   
373    // Extension features
374  13313 Node featuresNode = getNode(extensionElement, ELEMENT_EXTENSIONFEATURES);
375  13313 if (featuresNode != null) {
376  436 NodeList extensionFeatures = featuresNode.getChildNodes();
377  1824 for (int i = 0; i < extensionFeatures.getLength(); ++i) {
378  1388 Node featureNode = extensionFeatures.item(i);
379   
380  1388 if (featureNode.getNodeName().equals(ELEMENT_EFFEATURE)) {
381  476 Node idNode = getNode(featureNode, ELEMENT_EFFID);
382  476 Node versionNode = getNode(featureNode, ELEMENT_EFFVERSION);
383   
384  476 String id = idNode != null ? idNode.getTextContent() : null;
385  476 String version = versionNode != null ? versionNode.getTextContent() : null;
386   
387  476 if (version != null) {
388  476 extension.addExtensionFeature(new ExtensionId(id, this.factory.getVersion(version)));
389    } else {
390  0 extension.addExtensionFeature(new ExtensionId(id, extension.getId().getVersion()));
391    }
392    }
393    }
394    }
395  13313 if (featuresNode == null) {
396    // @Deprecated Features
397  12877 List<String> legacyFeatures = parseList(extensionElement, ELEMENT_FEATURES, ELEMENT_FFEATURE);
398  12877 if (legacyFeatures != null) {
399  370 extension.setFeatures(legacyFeatures);
400    }
401    }
402   
403    // Allowed namespaces
404  13313 List<String> allowedNamespaces = parseList(extensionElement, ELEMENT_ALLOWEDNAMESPACES, ELEMENT_ANNAMESPACE);
405  13313 if (allowedNamespaces != null) {
406  6 extension.setAllowedNamespaces(allowedNamespaces);
407    }
408   
409    // Scm
410  13313 extension.setScm(loadlScm(extensionElement));
411   
412    // Issue Management
413  13313 extension.setIssueManagement(loadIssueManagement(extensionElement));
414   
415    // Dependencies
416  13313 extension.setDependencies(loadDependencies(extensionElement, ELEMENT_DEPENDENCIES));
417   
418    // Managed dependencies
419  13313 extension.setManagedDependencies(loadDependencies(extensionElement, ELEMENT_MANAGEDDEPENDENCIES));
420   
421    // Properties
422  13313 Map<String, Object> properties = parseProperties(extensionElement);
423  13313 if (properties != null) {
424  12877 extension.setProperties(properties);
425    }
426   
427    // @Deprecated Install fields
428   
429  13313 Node enabledNode = getNode(extensionElement, ELEMENT_INSTALLED);
430  13313 if (enabledNode != null) {
431  240 extension.putProperty(InstalledExtension.PKEY_INSTALLED, Boolean.valueOf(enabledNode.getTextContent()));
432    }
433   
434    // @Deprecated Namespaces
435  13313 List<String> namespaces = parseList(extensionElement, ELEMENT_NAMESPACES, ELEMENT_NNAMESPACE);
436  13313 if (namespaces != null) {
437  0 extension.putProperty(InstalledExtension.PKEY_NAMESPACES, namespaces);
438    }
439    }
440   
 
441  26626 toggle private Collection<ExtensionDependency> loadDependencies(Element extensionElement, String dependenciesFiel)
442    {
443  26626 Node dependenciesNode = getNode(extensionElement, dependenciesFiel);
444  26626 if (dependenciesNode != null) {
445  15544 NodeList dependenciesNodeList = dependenciesNode.getChildNodes();
446   
447  15544 List<ExtensionDependency> dependencies = new ArrayList<>(dependenciesNodeList.getLength());
448   
449  1213332 for (int i = 0; i < dependenciesNodeList.getLength(); ++i) {
450  1197788 Node dependency = dependenciesNodeList.item(i);
451   
452  1197788 if (dependency.getNodeName().equals(ELEMENT_DDEPENDENCY)) {
453  591122 Node dependencyIdNode = getNode(dependency, ELEMENT_ID);
454  591122 Node dependencyVersionNode = getNode(dependency, ELEMENT_VERSION);
455   
456  591122 dependencies.add(this.factory.getExtensionDependency(dependencyIdNode.getTextContent(),
457  591122 dependencyVersionNode != null
458    ? this.factory.getVersionConstraint(dependencyVersionNode.getTextContent()) : null,
459    parseProperties((Element) dependency)));
460    }
461    }
462   
463  15544 return dependencies;
464    }
465   
466  11082 return Collections.emptyList();
467    }
468   
 
469  13313 toggle private ExtensionScm loadlScm(Element extensionElement)
470    {
471  13313 Node node = getNode(extensionElement, ELEMENT_SCM);
472   
473  13313 if (node != null) {
474  11188 Node connectionNode = getNode(node, ELEMENT_SCONNECTION);
475  11188 Node developerConnectionNode = getNode(node, ELEMENT_SDEVELOPERCONNECTION);
476  11188 Node urlNode = getNode(node, ELEMENT_SURL);
477   
478  11188 return new DefaultExtensionScm(urlNode != null ? urlNode.getTextContent() : null,
479    loadlScmConnection(connectionNode), loadlScmConnection(developerConnectionNode));
480    }
481   
482  2125 return null;
483    }
484   
 
485  22376 toggle private ExtensionScmConnection loadlScmConnection(Node scmConnectionElement)
486    {
487  22376 if (scmConnectionElement != null) {
488  20293 Node system = getNode(scmConnectionElement, ELEMENT_SCSYSTEM);
489  20293 Node path = getNode(scmConnectionElement, ELEMENT_SCPATH);
490   
491  20293 if (system != null) {
492  20293 return new DefaultExtensionScmConnection(system.getTextContent(),
493  20293 path != null ? path.getTextContent() : null);
494    }
495    }
496   
497  2083 return null;
498    }
499   
 
500  13313 toggle private ExtensionIssueManagement loadIssueManagement(Element extensionElement)
501    {
502  13313 Node node = getNode(extensionElement, ELEMENT_ISSUEMANAGEMENT);
503   
504  13313 if (node != null) {
505  8344 Node systemNode = getNode(node, ELEMENT_ISYSTEM);
506  8344 Node urlNode = getNode(node, ELEMENT_IURL);
507   
508  8344 if (systemNode != null) {
509  8032 return this.factory.getExtensionIssueManagement(systemNode.getTextContent(),
510  8032 urlNode != null ? urlNode.getTextContent() : null);
511    }
512    }
513   
514  5281 return null;
515    }
516   
 
517  39503 toggle private List<String> parseList(Element extensionElement, String rootElement, String childElement)
518    {
519  39503 List<String> list;
520   
521  39503 Node featuresNode = getNode(extensionElement, rootElement);
522  39503 if (featuresNode != null) {
523  376 list = new LinkedList<String>();
524   
525  376 NodeList features = featuresNode.getChildNodes();
526  1506 for (int i = 0; i < features.getLength(); ++i) {
527  1130 Node featureNode = features.item(i);
528   
529  1130 if (featureNode.getNodeName() == childElement) {
530  377 list.add(featureNode.getTextContent());
531    }
532    }
533    } else {
534  39127 list = null;
535    }
536   
537  39503 return list;
538    }
539   
 
540  604435 toggle private Map<String, Object> parseProperties(Element parentElement)
541    {
542  604435 Map<String, Object> properties = null;
543   
544  604435 Node propertiesNode = getNode(parentElement, ELEMENT_PROPERTIES);
545  604435 if (propertiesNode != null) {
546  602916 properties = new HashMap<String, Object>();
547  602916 NodeList propertyNodeList = propertiesNode.getChildNodes();
548  2568774 for (int i = 0; i < propertyNodeList.getLength(); ++i) {
549  1965858 Node propertyNode = propertyNodeList.item(i);
550   
551  1965858 if (propertyNode.getNodeType() == Node.ELEMENT_NODE) {
552  681471 Object value =
553    CollectionExtensionPropertySerializer.toValue((Element) propertyNode, this.serializerById);
554   
555  681471 if (value != null) {
556  681471 properties.put(propertyNode.getNodeName(), value);
557    }
558    }
559    }
560    }
561   
562  604435 return properties;
563    }
564   
 
565  2198059 toggle private Node getNode(Node parentNode, String elementName)
566    {
567  2198059 NodeList children = parentNode.getChildNodes();
568  12075104 for (int i = 0; i < children.getLength(); ++i) {
569  11899102 Node node = children.item(i);
570   
571  11899102 if (node.getNodeName().equals(elementName)) {
572  2022057 return node;
573    }
574    }
575   
576  176002 return null;
577    }
578   
 
579  14182 toggle @Override
580    public void saveExtensionDescriptor(Extension extension, OutputStream fos)
581    throws ParserConfigurationException, TransformerException
582    {
583  14182 DocumentBuilder documentBuilder = this.documentBuilderFactory.newDocumentBuilder();
584  14182 Document document = documentBuilder.newDocument();
585   
586  14182 Element extensionElement = document.createElement("extension");
587  14182 document.appendChild(extensionElement);
588   
589  14182 addElement(document, extensionElement, ELEMENT_ID, extension.getId().getId());
590  14182 addElement(document, extensionElement, ELEMENT_VERSION, extension.getId().getVersion().getValue());
591  14182 addElement(document, extensionElement, ELEMENT_TYPE, extension.getType());
592  14182 addElement(document, extensionElement, ELEMENT_NAME, extension.getName());
593  14182 addElement(document, extensionElement, ELEMENT_CATEGORY, extension.getCategory());
594  14182 addElement(document, extensionElement, ELEMENT_SUMMARY, extension.getSummary());
595  14182 addElement(document, extensionElement, ELEMENT_DESCRIPTION, extension.getDescription());
596  14182 addElement(document, extensionElement, ELEMENT_WEBSITE, extension.getWebSite());
597   
598  14182 addExtensionFeatures(document, extensionElement, extension);
599  14182 addLegacyFeatures(document, extensionElement, extension);
600   
601  14182 addAuthors(document, extensionElement, extension);
602   
603  14182 addAllowedNamespaces(document, extensionElement, extension);
604   
605  14182 addLicenses(document, extensionElement, extension);
606   
607  14182 addScm(document, extensionElement, extension);
608   
609  14182 addIssueManagement(document, extensionElement, extension);
610   
611  14182 addDependencies(document, extensionElement, extension);
612  14182 addManagedDependencies(document, extensionElement, extension);
613   
614  14182 addProperties(document, extensionElement, extension.getProperties());
615   
616    // save
617   
618  14182 TransformerFactory transfac = TransformerFactory.newInstance();
619  14182 Transformer trans = transfac.newTransformer();
620  14182 trans.setOutputProperty(OutputKeys.INDENT, "yes");
621   
622  14182 DOMSource source = new DOMSource(document);
623  14182 Result result = new StreamResult(fos);
624  14182 trans.transform(source, result);
625    }
626   
 
627  14182 toggle private void addLicenses(Document document, Element parentElement, Extension extension)
628    {
629  14182 if (extension.getLicenses() != null && !extension.getLicenses().isEmpty()) {
630  13314 Element licensesElement = document.createElement(ELEMENT_LICENSES);
631  13314 parentElement.appendChild(licensesElement);
632   
633  13314 for (ExtensionLicense license : extension.getLicenses()) {
634  14692 Element licenseElement = document.createElement(ELEMENT_LLICENSE);
635  14692 licensesElement.appendChild(licenseElement);
636   
637  14692 addElement(document, licenseElement, ELEMENT_LLNAME, license.getName());
638  14692 if (this.licenseManager.getLicense(license.getName()) == null && license.getContent() != null) {
639    // Only store content if it's a custom license (license content is pretty big generally)
640  1 StringWriter content = new StringWriter();
641  1 try {
642  1 IOUtils.writeLines(license.getContent(), IOUtils.LINE_SEPARATOR_UNIX, content);
643    } catch (IOException e) {
644    // That should never happen
645    }
646  1 addElement(document, licenseElement, ELEMENT_LLCONTENT, content.toString());
647    }
648    }
649    }
650    }
651   
 
652  14182 toggle @Deprecated
653    private void addLegacyFeatures(Document document, Element parentElement, Extension extension)
654    {
655  14182 Collection<String> features = extension.getFeatures();
656  14182 if (!features.isEmpty()) {
657  693 Element featuresElement = document.createElement(ELEMENT_FEATURES);
658  693 parentElement.appendChild(featuresElement);
659   
660  693 for (String feature : features) {
661  762 addElement(document, featuresElement, ELEMENT_FFEATURE, feature);
662    }
663    }
664    }
665   
 
666  14182 toggle private void addAllowedNamespaces(Document document, Element parentElement, Extension extension)
667    {
668  14182 Collection<String> namespaces = extension.getAllowedNamespaces();
669  14182 if (namespaces != null) {
670  7 Element namespacesElement = document.createElement(ELEMENT_ALLOWEDNAMESPACES);
671  7 parentElement.appendChild(namespacesElement);
672   
673  7 for (String namespace : namespaces) {
674  7 addElement(document, namespacesElement, ELEMENT_ANNAMESPACE, namespace);
675    }
676    }
677    }
678   
 
679  14182 toggle private void addExtensionFeatures(Document document, Element parentElement, Extension extension)
680    {
681  14182 Collection<ExtensionId> features = extension.getExtensionFeatures();
682  14182 if (!features.isEmpty()) {
683  693 Element featuresElement = document.createElement(ELEMENT_EXTENSIONFEATURES);
684  693 parentElement.appendChild(featuresElement);
685   
686  693 for (ExtensionId feature : features) {
687  762 Element authorElement = document.createElement(ELEMENT_EFFEATURE);
688  762 featuresElement.appendChild(authorElement);
689   
690  762 addElement(document, authorElement, ELEMENT_EFFID, feature.getId());
691  762 addElement(document, authorElement, ELEMENT_EFFVERSION, feature.getVersion().getValue());
692    }
693    }
694    }
695   
 
696  14182 toggle private void addAuthors(Document document, Element parentElement, Extension extension)
697    {
698  14182 Collection<ExtensionAuthor> authors = extension.getAuthors();
699  14182 if (!authors.isEmpty()) {
700  11336 Element authorsElement = document.createElement(ELEMENT_AUTHORS);
701  11336 parentElement.appendChild(authorsElement);
702   
703  11336 for (ExtensionAuthor author : authors) {
704  47437 Element authorElement = document.createElement(ELEMENT_AAUTHOR);
705  47437 authorsElement.appendChild(authorElement);
706   
707  47437 addElement(document, authorElement, ELEMENT_AANAME, author.getName());
708   
709  47437 URL authorURL = author.getURL();
710  47437 if (authorURL != null) {
711  2489 addElement(document, authorElement, ELEMENT_AAURL, authorURL.toString());
712    }
713    }
714    }
715    }
716   
 
717  14182 toggle private void addScm(Document document, Element extensionElement, Extension extension)
718    {
719  14182 ExtensionScm scm = extension.getScm();
720   
721  14182 if (scm != null) {
722  12979 Element scmElement = document.createElement(ELEMENT_SCM);
723  12979 extensionElement.appendChild(scmElement);
724   
725  12979 addElement(document, scmElement, ELEMENT_SURL, scm.getUrl());
726  12979 addScmConnection(document, scmElement, scm.getConnection(), ELEMENT_SCONNECTION);
727  12979 addScmConnection(document, scmElement, scm.getDeveloperConnection(), ELEMENT_SDEVELOPERCONNECTION);
728    }
729    }
730   
 
731  25958 toggle private void addScmConnection(Document document, Element scmElement, ExtensionScmConnection connection,
732    String elementName)
733    {
734  25958 if (connection != null) {
735  23334 Element connectionElement = document.createElement(elementName);
736  23334 scmElement.appendChild(connectionElement);
737   
738  23334 addElement(document, connectionElement, ELEMENT_SCSYSTEM, connection.getSystem());
739  23334 addElement(document, connectionElement, ELEMENT_SCPATH, connection.getPath());
740    }
741    }
742   
 
743  14182 toggle private void addIssueManagement(Document document, Element extensionElement, Extension extension)
744    {
745  14182 ExtensionIssueManagement issueManagement = extension.getIssueManagement();
746   
747  14182 if (issueManagement != null) {
748  9625 Element issuemanagementElement = document.createElement(ELEMENT_ISSUEMANAGEMENT);
749  9625 extensionElement.appendChild(issuemanagementElement);
750   
751  9625 addElement(document, issuemanagementElement, ELEMENT_ISYSTEM, issueManagement.getSystem());
752  9625 addElement(document, issuemanagementElement, ELEMENT_IURL, issueManagement.getURL());
753    }
754    }
755   
 
756  14182 toggle private void addDependencies(Document document, Element parentElement, Extension extension)
757    {
758  14182 addDependencies(document, parentElement, ELEMENT_DEPENDENCIES, extension.getDependencies());
759    }
760   
 
761  14182 toggle private void addManagedDependencies(Document document, Element parentElement, Extension extension)
762    {
763  14182 addDependencies(document, parentElement, ELEMENT_MANAGEDDEPENDENCIES, extension.getManagedDependencies());
764    }
765   
 
766  28364 toggle private void addDependencies(Document document, Element parentElement, String fieldName,
767    Collection<ExtensionDependency> dependencies)
768    {
769  28364 if (dependencies != null && !dependencies.isEmpty()) {
770  17274 Element dependenciesElement = document.createElement(fieldName);
771  17274 parentElement.appendChild(dependenciesElement);
772   
773  17274 for (ExtensionDependency dependency : dependencies) {
774  691968 Element dependencyElement = document.createElement(ELEMENT_DDEPENDENCY);
775  691968 dependenciesElement.appendChild(dependencyElement);
776   
777  691968 addElement(document, dependencyElement, ELEMENT_ID, dependency.getId());
778  691968 addElement(document, dependencyElement, ELEMENT_VERSION, dependency.getVersionConstraint().getValue());
779  691968 addProperties(document, dependencyElement, dependency.getProperties());
780    }
781    }
782    }
783   
 
784  706150 toggle private void addProperties(Document document, Element parentElement, Map<String, Object> properties)
785    {
786  706150 if (!properties.isEmpty()) {
787  705940 Element propertiesElement = document.createElement(ELEMENT_PROPERTIES);
788  705940 parentElement.appendChild(propertiesElement);
789   
790  705940 for (Map.Entry<String, Object> entry : properties.entrySet()) {
791  2120097 addElement(document, propertiesElement, entry.getKey(), entry.getValue());
792    }
793    }
794    }
795   
796    // Tools
797   
 
798  3763298 toggle private void addElement(Document document, Element parentElement, String elementName, Object elementValue)
799    {
800  3763298 Element element = CollectionExtensionPropertySerializer.toElement(elementValue, document, elementName,
801    this.serializerByClass);
802   
803  3763298 if (element != null) {
804  2408665 parentElement.appendChild(element);
805    }
806    }
807    }