Skip to content

Commit defe852

Browse files
committed
Sort packages, files, and relationship arrays
Fixes #83
1 parent c2182bd commit defe852

File tree

3 files changed

+305
-2
lines changed

3 files changed

+305
-2
lines changed

src/main/java/org/spdx/jacksonstore/JacksonSerializer.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
import java.util.Objects;
2929
import java.util.Optional;
3030
import java.util.Set;
31+
import java.util.stream.Collectors;
32+
import java.util.stream.StreamSupport;
3133

3234
import org.slf4j.Logger;
3335
import org.slf4j.LoggerFactory;
@@ -268,14 +270,17 @@ public ObjectNode docToJsonNode(String documentUri) throws InvalidSPDXAnalysisEx
268270
doc.put(SpdxConstantsCompatV2.PROP_DOCUMENT_NAMESPACE.getName(), documentUri);
269271
ArrayNode packages = getDocElements(documentUri, SpdxConstantsCompatV2.CLASS_SPDX_PACKAGE, relationships);
270272
if (!packages.isEmpty()) {
273+
sortArrayNode(packages);
271274
doc.set(SpdxConstantsCompatV2.PROP_DOCUMENT_PACKAGES.getName(), packages);
272275
}
273276
ArrayNode files = getDocElements(documentUri, SpdxConstantsCompatV2.CLASS_SPDX_FILE, relationships);
274277
if (!files.isEmpty()) {
278+
sortArrayNode(files);
275279
doc.set(SpdxConstantsCompatV2.PROP_DOCUMENT_FILES.getName(), files);
276280
}
277281
ArrayNode snippets = getDocElements(documentUri, SpdxConstantsCompatV2.CLASS_SPDX_SNIPPET, relationships);
278282
if (!snippets.isEmpty()) {
283+
sortArrayNode(snippets);
279284
doc.set(SpdxConstantsCompatV2.PROP_DOCUMENT_SNIPPETS.getName(), snippets);
280285
}
281286
//Remove duplicate relationships
@@ -302,7 +307,7 @@ public ObjectNode docToJsonNode(String documentUri) throws InvalidSPDXAnalysisEx
302307
relatedIds.add(relatedID);
303308
}
304309
}
305-
310+
sortArrayNode(deDupedRelationships);
306311

307312
doc.set(SpdxConstantsCompatV2.PROP_DOCUMENT_RELATIONSHIPS.getName(), deDupedRelationships);
308313
ObjectNode output;
@@ -326,6 +331,16 @@ public ObjectNode docToJsonNode(String documentUri) throws InvalidSPDXAnalysisEx
326331
}
327332
}
328333

334+
/**
335+
* Sorts the elements of an ArrayNode in place
336+
* @param an ArrayNode to sort
337+
*/
338+
private void sortArrayNode(ArrayNode an) {
339+
List<JsonNode> arrayElements = StreamSupport.stream(an.spliterator(), false).sorted(NODE_COMPARATOR).collect(Collectors.toList());
340+
an.removeAll();
341+
an.addAll(arrayElements);
342+
}
343+
329344
/**
330345
* Convert a typed value into an ObjectNode adding all stored properties
331346
* @param documentUri Document namespace or Uri

src/test/java/org/spdx/jacksonstore/MultiFormatStoreTest.java

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@ public class MultiFormatStoreTest extends TestCase {
9292
static final String JSON_NO_HAS_FILES_FILE_PATH = "testResources" + File.separator + "noHasFilesDescribes.json";
9393
static final String XML_1REL_FILE_PATH = "testResources" + File.separator + "SPDXXML-SingleRel-v2.3.spdx.xml";
9494
static final String JSON_SCHEMA_V2_3 = "testResources" + File.separator + "spdx-schema.json";
95-
95+
static final String UNSORTED_JSON = "testResources" + File.separator + "SPDXJSONUnsortedIds.json";
96+
9697
/* (non-Javadoc)
9798
* @see junit.framework.TestCase#setUp()
9899
*/
@@ -720,4 +721,41 @@ private List<String> getDocUris(ISerializableModelStore resultStore) throws Inva
720721
.map(tv -> tv.getObjectUri().substring(0, tv.getObjectUri().indexOf('#')))
721722
.collect(Collectors.toList());
722723
}
724+
725+
public void testSortOrder() throws InvalidSPDXAnalysisException, IOException, SpdxCompareException, ProcessingException {
726+
File jsonFile = new File(UNSORTED_JSON);
727+
MultiFormatStore inputStore = new MultiFormatStore(new InMemSpdxStore(), Format.JSON_PRETTY);
728+
try (InputStream input = new FileInputStream(jsonFile)) {
729+
inputStore.deSerialize(input, false);
730+
}
731+
Path tempDirPath = Files.createTempDirectory("mfsTestunsorted");
732+
File serFile = tempDirPath.resolve("testspdx.json").toFile();
733+
assertTrue(serFile.createNewFile());
734+
try {
735+
try (OutputStream stream = new FileOutputStream(serFile)) {
736+
inputStore.serialize(stream);
737+
}
738+
ISerializableModelStore resultStore = new MultiFormatStore(new InMemSpdxStore(), MultiFormatStore.Format.JSON);
739+
try (InputStream inStream = new FileInputStream(serFile)) {
740+
JsonNode root = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT).readTree(inStream);
741+
String previousId = "SPDXRef-Package-0";
742+
for (JsonNode pkgNode : root.get("packages")) {
743+
String spdxId = pkgNode.get("SPDXID").asText();
744+
assertTrue(previousId.compareTo(spdxId) < 0);
745+
previousId = spdxId;
746+
}
747+
previousId = "SPDXRef-File-0";
748+
for (JsonNode pkgNode : root.get("files")) {
749+
String spdxId = pkgNode.get("SPDXID").asText();
750+
assertTrue(previousId.compareTo(spdxId) < 0);
751+
previousId = spdxId;
752+
}
753+
}
754+
} finally {
755+
if (serFile.exists()) {
756+
serFile.delete();
757+
}
758+
tempDirPath.toFile().delete();
759+
}
760+
}
723761
}

0 commit comments

Comments
 (0)