• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

vidal-community / atom-jaxb / #346

12 Jan 2026 08:32PM UTC coverage: 76.438% (+0.04%) from 76.394%
#346

push

github

jcgay
Generate dependency-reduced-pom.xml in target directory

It will be ignored by git...

412 of 539 relevant lines covered (76.44%)

0.76 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

87.88
/atom-jaxb/src/main/java/fr/vidal/oss/jaxb/atom/core/ExtensionElementAdapter.java
1
package fr.vidal.oss.jaxb.atom.core;
2

3
import static java.lang.String.format;
4

5
import java.util.Arrays;
6
import java.util.Collection;
7
import java.util.stream.Collectors;
8
import java.util.stream.IntStream;
9
import jakarta.xml.bind.JAXBContext;
10
import jakarta.xml.bind.JAXBElement;
11
import jakarta.xml.bind.JAXBException;
12
import jakarta.xml.bind.annotation.adapters.XmlAdapter;
13
import javax.xml.parsers.DocumentBuilder;
14
import javax.xml.parsers.DocumentBuilderFactory;
15
import javax.xml.parsers.ParserConfigurationException;
16
import org.w3c.dom.Attr;
17
import org.w3c.dom.Document;
18
import org.w3c.dom.Element;
19
import org.w3c.dom.NamedNodeMap;
20
import org.w3c.dom.Node;
21
import org.w3c.dom.NodeList;
22
import org.w3c.dom.Text;
23

24
public class ExtensionElementAdapter extends XmlAdapter<Element, ExtensionElement> {
1✔
25

26
    private static final Class[] ADAPTED_TYPES = {StructuredElement.class, SimpleElement.class};
1✔
27
    private static final JAXBContext context;
28
    private static final ThreadLocal<DocumentBuilder> getDocumentBuilder = ThreadLocal.withInitial(() -> {
1✔
29
        try {
30
           return DocumentBuilderFactory.newInstance().newDocumentBuilder();
1✔
31
        } catch (ParserConfigurationException e) {
×
32
            throw new AtomExtensionException("Cannot instantiate DocumentBuilder.", e);
×
33
        }
34
    });
35

36
    static {
37
       try {
38
          context = JAXBContext.newInstance(ADAPTED_TYPES);
1✔
39
       } catch (JAXBException e) {
×
40
           throw new AtomExtensionException("Cannot instantiate JAXBContext for classes : " + Arrays.toString(ADAPTED_TYPES), e);
×
41
       }
1✔
42
    }
1✔
43

44
    @Override
45
    public Element marshal(ExtensionElement extensionElement) throws Exception {
46
        if (extensionElement == null) {
1✔
47
            return null;
×
48
        }
49

50
        JAXBElement jaxbElement = extensionElement.toJAXBElement();
1✔
51

52
        DocumentBuilder documentBuilder = getDocumentBuilder.get();
1✔
53
        documentBuilder.reset();
1✔
54
        Document document = documentBuilder.newDocument();
1✔
55
        context.createMarshaller().marshal(jaxbElement, document);
1✔
56
        Element element = document.getDocumentElement();
1✔
57

58
        addAttributes(element, extensionElement);
1✔
59
        return element;
1✔
60
    }
61

62
    private void addAttributes(Element element, ExtensionElement extensionElement) {
63
        for (Attribute attribute : extensionElement.attributes()) {
1✔
64
            addAttribute(element, attribute);
1✔
65
        }
1✔
66
    }
1✔
67

68
    private void addAttribute(Element element, Attribute attribute) {
69
        Namespace namespace = attribute.getNamespace();
1✔
70
        String attributeName = attribute.getName();
1✔
71
        String attributeValue = attribute.getValue();
1✔
72

73
        if (namespace == null) {
1✔
74
            element.setAttribute(attributeName, attributeValue);
×
75
            return;
×
76
        }
77

78
        element.setAttributeNS(
1✔
79
            namespace.uri(),
1✔
80
            format("%s:%s", namespace.prefix(), attributeName),
1✔
81
            attributeValue
82
        );
83
    }
1✔
84

85
    @Override
86
    public ExtensionElement unmarshal(Element element) {
87
        if (element == null) {
1✔
88
            return null;
×
89
        }
90
        return extensionElement(element);
1✔
91
    }
92

93
    private ExtensionElement extensionElement(Node node) {
94

95
        ExtensionElement.Builder elementBuilder;
96
        if (isSimpleElementNode(node)) {
1✔
97
            elementBuilder = ExtensionElements.simpleElement(node.getLocalName(), node.getTextContent());
1✔
98
        } else {
99
            elementBuilder = ExtensionElements.structuredElement(node.getLocalName(), children(node));
1✔
100
        }
101

102
        return elementBuilder
1✔
103
            .withNamespace(namespace(node))
1✔
104
            .addAttributes(attributes(node))
1✔
105
            .build();
1✔
106
    }
107

108
    private boolean isSimpleElementNode(Node node) {
109
        return node.getChildNodes().getLength() == 1
1✔
110
            && isTextualNode(node.getFirstChild());
1✔
111
    }
112

113
    private boolean isTextualNode(Node node) {
114
        return Text.class.isAssignableFrom(node.getClass());
1✔
115
    }
116

117
    private Collection<ExtensionElement> children(Node node) {
118
        return toElements(node.getChildNodes());
1✔
119
    }
120

121
    private Collection<ExtensionElement> toElements(NodeList nodes) {
122
        return IntStream.range(0, nodes.getLength())
1✔
123
            .mapToObj(nodes::item)
1✔
124
            .filter(n -> !isTextualNode(n))
1✔
125
            .map(this::extensionElement)
1✔
126
            .collect(Collectors.toList());
1✔
127
    }
128

129
    private Collection<Attribute> attributes(Node node) {
130
        NamedNodeMap attributes = node.getAttributes();
1✔
131

132
        return IntStream.range(0, attributes.getLength())
1✔
133
            .mapToObj(attributes::item)
1✔
134
            .map(Attr.class::cast)
1✔
135
            .map(ExtensionElementAdapter::attribute)
1✔
136
            .collect(Collectors.toList());
1✔
137
    }
138

139
    private static Attribute attribute(Attr attribute) {
140
        Attribute.Builder builder = Attribute.builder(attribute.getLocalName(), attribute.getTextContent());
1✔
141
        if (hasProperNamespace(attribute)) {
1✔
142
            builder.withNamespace(namespace(attribute));
1✔
143
        }
144
        return builder.build();
1✔
145
    }
146

147
    private static boolean hasProperNamespace(Attr attribute) {
148
        return attribute.getNamespaceURI() != null;
1✔
149
    }
150

151
    private static Namespace namespace(Node item) {
152
        return Namespace.builder(item.getNamespaceURI()).withPrefix(item.getPrefix()).build();
1✔
153
    }
154
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc