14
14
import static org .lfenergy .compas .scl .data .exception .CompasSclDataServiceErrorCode .HEADER_NOT_FOUND_ERROR_CODE ;
15
15
import static org .w3c .dom .Node .ELEMENT_NODE ;
16
16
17
+ /**
18
+ * Support class to work with the SCL XML in a generic way as W3C Element/Node class.
19
+ * This way multiple versions of the SCL XSD can easily be supported.
20
+ */
17
21
public class SclElementProcessor {
22
+ /**
23
+ * Make sure that the SCL XSD Namespace will be the default namespace used on the passed
24
+ * Node and all it's child nodes. Attributes aren't fixed, because these use the "null" namespace
25
+ * as they are marked as "unqualified" in the XSD (attributeFormDefault="unqualified").
26
+ *
27
+ * @param root The root node from which to start, will mostly be the SCL XML Element.
28
+ */
18
29
public void fixDefaultPrefix (Node root ) {
19
30
var oldNamespacePrefixes = new HashSet <String >();
31
+ // Use a stack to walk through all child nodes.
20
32
var nodes = new Stack <Node >();
33
+ // Start with the root node.
21
34
nodes .push (root );
22
35
23
36
while (!nodes .isEmpty ()) {
24
37
var node = nodes .pop ();
25
- if (node . getNodeType () == ELEMENT_NODE && SCL_NS_URI .equals (node .getNamespaceURI ())
38
+ if (SCL_NS_URI .equals (node .getNamespaceURI ())
26
39
&& node .getPrefix () != null && !node .getPrefix ().isBlank ()) {
40
+ // The namespace is the SCL XSD Namespace, but with a prefix, so we will fix that.
27
41
oldNamespacePrefixes .add (node .getPrefix ());
28
42
node .setPrefix ("" );
29
43
}
30
44
31
- // For child nodes of this node
45
+ // Push all the Child Nodes (Type Element) on the Stack and continue with these.
32
46
NodeList childNodes = node .getChildNodes ();
33
47
if (childNodes != null ) {
34
48
for (int i = 0 , count = childNodes .getLength (); i < count ; ++i ) {
35
- nodes .push (childNodes .item (i ));
49
+ var childNode = childNodes .item (i );
50
+ if (childNode .getNodeType () == ELEMENT_NODE ) {
51
+ nodes .push (childNode );
52
+ }
36
53
}
37
54
}
38
55
}
@@ -42,25 +59,50 @@ public void fixDefaultPrefix(Node root) {
42
59
);
43
60
}
44
61
62
+ /**
63
+ * Search for the SCL Header in the SCL Root Element and return that.
64
+ *
65
+ * @param scl The SCL Root Element
66
+ * @return The Header Element if found or empty() if not.
67
+ */
45
68
public Optional <Element > getSclHeader (Element scl ) {
46
69
return getChildNodesByName (scl , SCL_HEADER_ELEMENT_NAME ).stream ()
47
70
.findFirst ();
48
71
}
49
72
73
+ /**
74
+ * Add the SCL Header ot the SCL Root Element, because that element is important for the SCL Data Service
75
+ * we want to make sure it's there.
76
+ *
77
+ * @param scl The SCL Root Element
78
+ * @return The new created Header Element.
79
+ */
50
80
public Element addSclHeader (Element scl ) {
51
81
var header = scl .getOwnerDocument ().createElementNS (SCL_NS_URI , SCL_HEADER_ELEMENT_NAME );
52
82
header .setPrefix (SCL_NS_PREFIX );
53
83
scl .insertBefore (header , scl .getFirstChild ());
54
84
return header ;
55
85
}
56
86
87
+ /**
88
+ * Search for the private element with type "#Constants.COMPAS_SCL_EXTENSION_TYPE" on the SCL Root Element.
89
+ *
90
+ * @param scl The SCL Root Element
91
+ * @return The Private Element with the correct type if found or empty() if not.
92
+ */
57
93
public Optional <Element > getCompasPrivate (Element scl ) {
58
94
return getChildNodesByName (scl , SCL_PRIVATE_ELEMENT_NAME ).stream ()
59
95
.filter (element -> element .hasAttribute (SCL_PRIVATE_TYPE_ATTR ))
60
96
.filter (element -> element .getAttribute (SCL_PRIVATE_TYPE_ATTR ).equals (COMPAS_SCL_EXTENSION_TYPE ))
61
97
.findFirst ();
62
98
}
63
99
100
+ /**
101
+ * Create a Private Element with type "#COMPAS_SCL_EXTENSION_TYPE" on the SCL Root Element.
102
+ *
103
+ * @param scl The SCL Root Element
104
+ * @return The new created Private Element with the correct type.
105
+ */
64
106
public Element addCompasPrivate (Element scl ) {
65
107
scl .setAttribute ("xmlns:" + COMPAS_EXTENSION_NS_PREFIX , COMPAS_EXTENSION_NS_URI );
66
108
@@ -74,7 +116,14 @@ public Element addCompasPrivate(Element scl) {
74
116
return tPrivate ;
75
117
}
76
118
77
-
119
+ /**
120
+ * Add a new element with namespace "#COMPAS_EXTENSION_NS_URI" to the Private element of CoMPAS.
121
+ *
122
+ * @param compasPrivate The Private Element on which to add the new Element.
123
+ * @param localName The name of the Element to create.
124
+ * @param value The value set on the new Element.
125
+ * @return The new created Element.
126
+ */
78
127
public Element addCompasElement (Element compasPrivate , String localName , String value ) {
79
128
Element element = compasPrivate .getOwnerDocument ().createElementNS (COMPAS_EXTENSION_NS_URI , localName );
80
129
element .setPrefix (COMPAS_EXTENSION_NS_PREFIX );
@@ -83,17 +132,38 @@ public Element addCompasElement(Element compasPrivate, String localName, String
83
132
return element ;
84
133
}
85
134
135
+ /**
136
+ * Returns the value of a specific attribute from the passed Element.
137
+ *
138
+ * @param element The Element to search for the attribute.
139
+ * @param attributeName The name of the Attribute to search for.
140
+ * @return The value if found or empty() if not.
141
+ */
86
142
public Optional <String > getAttributeValue (Element element , String attributeName ) {
87
143
var value = element .getAttribute (attributeName );
88
144
return (value != null && !value .isBlank ()) ? Optional .of (value ) : Optional .empty ();
89
145
}
90
146
147
+ /**
148
+ * Search for a Child Node on the passed Element.
149
+ *
150
+ * @param root The element on which to search for a child Node.
151
+ * @param localName The name of the Child Node.
152
+ * @return The Child Node if found or empty() if not.
153
+ */
91
154
public Optional <Element > getChildNodeByName (Element root , String localName ) {
92
155
return getChildNodesByName (root , localName )
93
156
.stream ()
94
157
.findFirst ();
95
158
}
96
159
160
+ /**
161
+ * Search for all Child Node on the passed Element.
162
+ *
163
+ * @param root The element on which to search for all child Node.
164
+ * @param localName The name of the Child Node.
165
+ * @return The list of Child Nodes found.
166
+ */
97
167
public List <Element > getChildNodesByName (Element root , String localName ) {
98
168
var foundElements = new ArrayList <Element >();
99
169
var childNodes = root .getChildNodes ();
0 commit comments