Skip to content

Commit fb5d58b

Browse files
Added system property to ensure the prerelease functionality is not he default behavior. Added unit test. Minor formatting cleanup. #121
1 parent 90c6954 commit fb5d58b

File tree

3 files changed

+92
-50
lines changed

3 files changed

+92
-50
lines changed

src/main/java/org/cyclonedx/util/PropertyDeserializer.java

Lines changed: 33 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,7 @@
1313
import java.util.ArrayList;
1414
import java.util.Arrays;
1515
import java.util.List;
16-
1716
import org.cyclonedx.model.Property;
18-
1917
import com.fasterxml.jackson.core.JsonParser;
2018
import com.fasterxml.jackson.databind.DeserializationContext;
2119
import com.fasterxml.jackson.databind.JsonNode;
@@ -29,15 +27,13 @@
2927
* @author wrgoff
3028
* @since 28 May 2021
3129
*/
32-
public class PropertyDeserializer extends StdDeserializer<List<Property>>
33-
{
30+
public class PropertyDeserializer extends StdDeserializer<List<Property>> {
3431
private static final long serialVersionUID = 3080840606644733407L;
3532

3633
/**
3734
* Default Constructor.
3835
*/
39-
public PropertyDeserializer()
40-
{
36+
public PropertyDeserializer() {
4137
this(null);
4238
}
4339

@@ -46,8 +42,7 @@ public PropertyDeserializer()
4642
*
4743
* @param vc Class for which the deserializer is for.
4844
*/
49-
public PropertyDeserializer(final Class<?> vc)
50-
{
45+
public PropertyDeserializer(final Class<?> vc) {
5146
super(vc);
5247
}
5348

@@ -60,34 +55,26 @@ public PropertyDeserializer(final Class<?> vc)
6055
*/
6156
@Override
6257
public List<Property> deserialize(final JsonParser parser,
63-
final DeserializationContext context) throws IOException
64-
{
58+
final DeserializationContext context) throws IOException {
6559
List<Property> properties = new ArrayList<>();
6660

67-
if (parser instanceof FromXmlParser)
68-
{
61+
if (parser instanceof FromXmlParser) {
6962
JsonNode node = parser.getCodec().readTree(parser);
70-
if (node.has("properties"))
71-
{
63+
if (node.has("properties")) {
7264
JsonNode propertiesNode = node.get("properties");
73-
if(propertiesNode.isArray())
74-
{
65+
if(propertiesNode.isArray()) {
7566
ArrayNode arrayNode = (ArrayNode) node;
76-
for (int i = 0; i < arrayNode.size(); i++)
77-
{
67+
for (int i = 0; i < arrayNode.size(); i++) {
7868
node = node.get("property");
7969
properties.addAll(parsePropertyNode(node, new ArrayList<Property>()));
8070
}
8171
}
8272
}
83-
else if (node.has("property"))
84-
{
73+
else if (node.has("property")) {
8574
node = node.get("property");
8675
properties.addAll(parsePropertyNode(node, new ArrayList<Property>()));
8776
}
88-
}
89-
else
90-
{
77+
} else {
9178
Property[] props = parser.readValueAs(Property[].class);
9279
properties = Arrays.asList(props.clone());
9380
}
@@ -100,29 +87,26 @@ else if (node.has("property"))
10087
* @param node JsonNode to process the property form.
10188
* @return Property processed from the JsonNode passed in.
10289
*/
103-
private Property parseProperty(JsonNode node)
104-
{
105-
String name = "";
106-
String value = "";
90+
private Property parseProperty(JsonNode node) {
91+
String name = null;
92+
String value = null;
10793

10894
JsonNode nameNode = node.get("name");
109-
if (nameNode != null)
95+
if (nameNode != null) {
11096
name = nameNode.asText();
111-
97+
}
11298
JsonNode valueNode = node.get("");
113-
if (valueNode != null)
99+
if (valueNode != null) {
114100
value = valueNode.asText();
115-
else
116-
{
101+
} else if (isPreleaseDeserializationEnabled()) {
117102
valueNode = node.get("value");
118-
if (valueNode != null)
103+
if (valueNode != null) {
119104
value = valueNode.asText();
105+
}
120106
}
121-
122107
Property prop = new Property();
123108
prop.setName(name);
124109
prop.setValue(value);
125-
126110
return prop;
127111
}
128112

@@ -133,18 +117,15 @@ private Property parseProperty(JsonNode node)
133117
* @param props List of properties to append to.
134118
* @return List of properties processed.
135119
*/
136-
private List<Property> parseArrayNode(ArrayNode arrayNode, List<Property> props)
137-
{
120+
private List<Property> parseArrayNode(ArrayNode arrayNode, List<Property> props) {
138121
JsonNode node;
139-
for (int i = 0; i < arrayNode.size(); i++)
140-
{
122+
for (int i = 0; i < arrayNode.size(); i++) {
141123
node = arrayNode.get(i);
142-
if (node instanceof ArrayNode)
143-
{
124+
if (node instanceof ArrayNode) {
144125
parseArrayNode(((ArrayNode) node), props);
145-
}
146-
else
126+
} else {
147127
props.add(parseProperty(node));
128+
}
148129
}
149130
return props;
150131
}
@@ -156,16 +137,18 @@ private List<Property> parseArrayNode(ArrayNode arrayNode, List<Property> props)
156137
* @param properties List of properties to append to.
157138
* @return List of properties.
158139
*/
159-
private List<Property> parsePropertyNode(JsonNode node, List<Property> properties)
160-
{
161-
if (node.isArray())
162-
{
140+
private List<Property> parsePropertyNode(JsonNode node, List<Property> properties) {
141+
if (node.isArray()) {
163142
ArrayNode arrayNode = (ArrayNode) node;
164143
properties.addAll(parseArrayNode(arrayNode, new ArrayList<Property>()));
165-
}
166-
else
144+
} else {
167145
properties.add(parseProperty(node));
168-
146+
}
169147
return properties;
170148
}
149+
150+
private boolean isPreleaseDeserializationEnabled() {
151+
final String s = System.getProperty("cyclonedx.prerelease.13.properties");
152+
return Boolean.parseBoolean(s);
153+
}
171154
}

src/test/java/org/cyclonedx/parsers/XmlParserTest.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,4 +426,24 @@ public void testParsedObjects13Bom() throws Exception {
426426
assertEquals("pkg:maven/org.acme/[email protected]", d11.getRef());
427427
assertNull(d11.getDependencies());
428428
}
429+
430+
@Test
431+
public void test13PrereleasePropertyBom() throws Exception {
432+
final File file = new File(this.getClass().getResource("/1.3/valid-properties-1.3-prerelease.xml").getFile());
433+
final XmlParser parser = new XmlParser();
434+
final boolean valid = parser.isValid(file, CycloneDxSchema.Version.VERSION_12);
435+
assertFalse(valid);
436+
final Bom bom1 = parser.parse(file);
437+
Component c1 = bom1.getComponents().get(0);
438+
assertEquals(2, c1.getProperties().size());
439+
assertEquals("Foo", c1.getProperties().get(0).getName());
440+
assertNull(c1.getProperties().get(0).getValue());
441+
442+
System.setProperty("cyclonedx.prerelease.13.properties", "true");
443+
final Bom bom2 = parser.parse(file);
444+
Component c2 = bom2.getComponents().get(0);
445+
assertEquals(2, c2.getProperties().size());
446+
assertEquals("Foo", c2.getProperties().get(0).getName());
447+
assertEquals("Bar", c2.getProperties().get(0).getValue());
448+
}
429449
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?xml version="1.0"?>
2+
<bom serialNumber="urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" version="1" xmlns="http://cyclonedx.org/schema/bom/1.3">
3+
<!-- This is NOT a valid CycloneDX v1.3 SBOM. However Lockheed Martin adopted this when v1.3 was in development
4+
and the spec had changed since release. The prerelease version had used attributes for the value. The released
5+
version uses the element value itself so that CDATA could be used. To trigger the prerelease behavior the
6+
`cyclonedx.prerelease.13.properties` system property must be present and set to true.
7+
-->
8+
<metadata>
9+
<properties>
10+
<property name="Foo" value="Bar"/>
11+
<property name="Foo" value="You"/>
12+
<property name="Foo" value="Two"/>
13+
<property name="Bar" value="Foo"/>
14+
</properties>
15+
</metadata>
16+
<components>
17+
<component type="library">
18+
<name>acme-library</name>
19+
<version>1.0.0</version>
20+
<properties>
21+
<property name="Foo" value="Bar"/>
22+
<property name="Bar" value="Foo"/>
23+
</properties>
24+
</component>
25+
</components>
26+
<services>
27+
<service bom-ref="b2a46a4b-8367-4bae-9820-95557cfe03a8">
28+
<group>org.partner</group>
29+
<name>Stock ticker service</name>
30+
<endpoints>
31+
<endpoint>https://partner.org/api/v1/stock</endpoint>
32+
</endpoints>
33+
<properties>
34+
<property name="Foo" value="Bar"/>
35+
<property name="Bar" value="Foo"/>
36+
</properties>
37+
</service>
38+
</services>
39+
</bom>

0 commit comments

Comments
 (0)