diff --git a/pom.xml b/pom.xml index 1f246e8..37d9805 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ org.spdx spdx-jackson-store - 1.1.10-SNAPSHOT + 2.0.0-SNAPSHOT jar spdx-jackson-store @@ -141,7 +141,7 @@ This store supports serializing and deserializing files in JSON, YAML and XML fo org.spdx java-spdx-library - 1.1.11 + 2.0.0-Alpha com.google.code.gson diff --git a/src/main/java/org/spdx/jacksonstore/JacksonDeSerializer.java b/src/main/java/org/spdx/jacksonstore/JacksonDeSerializer.java index 975354b..94918bf 100644 --- a/src/main/java/org/spdx/jacksonstore/JacksonDeSerializer.java +++ b/src/main/java/org/spdx/jacksonstore/JacksonDeSerializer.java @@ -31,25 +31,26 @@ import javax.annotation.Nullable; +import org.spdx.core.IndividualUriValue; +import org.spdx.core.InvalidSPDXAnalysisException; +import org.spdx.core.ModelObjectHelper; +import org.spdx.core.SimpleUriValue; +import org.spdx.core.TypedValue; import org.spdx.jacksonstore.MultiFormatStore.Format; -import org.spdx.library.InvalidSPDXAnalysisException; -import org.spdx.library.SpdxConstants; -import org.spdx.library.model.ExternalSpdxElement; -import org.spdx.library.model.IndividualUriValue; -import org.spdx.library.model.ModelStorageClassConverter; -import org.spdx.library.model.ReferenceType; -import org.spdx.library.model.SimpleUriValue; -import org.spdx.library.model.SpdxDocument; -import org.spdx.library.model.SpdxElement; -import org.spdx.library.model.SpdxModelFactory; -import org.spdx.library.model.TypedValue; -import org.spdx.library.model.enumerations.RelationshipType; -import org.spdx.library.model.license.AnyLicenseInfo; -import org.spdx.library.model.license.LicenseInfoFactory; +import org.spdx.library.LicenseInfoFactory; +import org.spdx.library.model.v2.ExternalSpdxElement; +import org.spdx.library.model.v2.ReferenceType; +import org.spdx.library.model.v2.SpdxConstantsCompatV2; +import org.spdx.library.model.v2.SpdxDocument; +import org.spdx.library.model.v2.SpdxElement; +import org.spdx.library.model.v2.SpdxModelFactoryCompatV2; +import org.spdx.library.model.v2.enumerations.RelationshipType; +import org.spdx.library.model.v2.license.AnyLicenseInfo; import org.spdx.library.referencetype.ListedReferenceTypes; import org.spdx.storage.IModelStore; import org.spdx.storage.IModelStore.IModelStoreLock; import org.spdx.storage.IModelStore.IdType; +import org.spdx.storage.compatv2.CompatibleModelStoreWrapper; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; @@ -64,15 +65,18 @@ public class JacksonDeSerializer { /** - * Properties that should not be restored as part of the deserialization + * Property names that should not be restored as part of the deserialization */ static final Set SKIPPED_PROPERTIES = Collections.unmodifiableSet(new HashSet(Arrays.asList(new String[] { - SpdxConstants.PROP_DOCUMENT_PACKAGES, SpdxConstants.PROP_DOCUMENT_FILES, - SpdxConstants.PROP_DOCUMENT_SNIPPETS, SpdxConstants.SPDX_IDENTIFIER, SpdxConstants.PROP_DOCUMENT_RELATIONSHIPS, - SpdxConstants.PROP_DOCUMENT_NAMESPACE + SpdxConstantsCompatV2.PROP_DOCUMENT_PACKAGES.getName(), + SpdxConstantsCompatV2.PROP_DOCUMENT_FILES.getName(), + SpdxConstantsCompatV2.PROP_DOCUMENT_SNIPPETS.getName(), + SpdxConstantsCompatV2.SPDX_IDENTIFIER, + SpdxConstantsCompatV2.PROP_DOCUMENT_RELATIONSHIPS.getName(), + SpdxConstantsCompatV2.PROP_DOCUMENT_NAMESPACE.getName() }))); - private IModelStore store; + private CompatibleModelStoreWrapper store; @SuppressWarnings("unused") private Format format; private Map>> addedRelationships = new HashMap<>(); @@ -83,7 +87,7 @@ public class JacksonDeSerializer { public JacksonDeSerializer(IModelStore store, Format format) { Objects.requireNonNull(store, "Model store can not be null"); Objects.requireNonNull(format, "Format can not be null"); - this.store = store; + this.store = new CompatibleModelStoreWrapper(store); this.format = format; } @@ -100,18 +104,19 @@ public void storeDocument(String documentNamespace, JsonNode doc) throws Invalid IModelStoreLock lock = store.enterCriticalSection(documentNamespace, false); try { Map spdxIdProperties = new HashMap<>(); // properties which contain an SPDX id which needs to be replaced - store.create(documentNamespace, SpdxConstants.SPDX_DOCUMENT_ID, SpdxConstants.CLASS_SPDX_DOCUMENT); - restoreObjectPropertyValues(documentNamespace, SpdxConstants.SPDX_DOCUMENT_ID, doc, spdxIdProperties); + store.create(documentNamespace, SpdxConstantsCompatV2.SPDX_DOCUMENT_ID, SpdxConstantsCompatV2.CLASS_SPDX_DOCUMENT); + restoreObjectPropertyValues(documentNamespace, SpdxConstantsCompatV2.SPDX_DOCUMENT_ID, doc, spdxIdProperties); // restore the packages Map addedElements = new HashMap<>(); - addedElements.put(SpdxConstants.SPDX_DOCUMENT_ID, new TypedValue(SpdxConstants.SPDX_DOCUMENT_ID, SpdxConstants.CLASS_SPDX_DOCUMENT)); - restoreElements(documentNamespace, SpdxConstants.CLASS_SPDX_PACKAGE, - doc.get(SpdxConstants.PROP_DOCUMENT_PACKAGES), addedElements, spdxIdProperties); - restoreElements(documentNamespace, SpdxConstants.CLASS_SPDX_FILE, - doc.get(SpdxConstants.PROP_DOCUMENT_FILES), addedElements, spdxIdProperties); - restoreElements(documentNamespace, SpdxConstants.CLASS_SPDX_SNIPPET, - doc.get(SpdxConstants.PROP_DOCUMENT_SNIPPETS), addedElements, spdxIdProperties); - restoreRelationships(documentNamespace, doc.get(SpdxConstants.PROP_DOCUMENT_RELATIONSHIPS), + addedElements.put(SpdxConstantsCompatV2.SPDX_DOCUMENT_ID, + CompatibleModelStoreWrapper.typedValueFromDocUri(documentNamespace, SpdxConstantsCompatV2.SPDX_DOCUMENT_ID, false, SpdxConstantsCompatV2.CLASS_SPDX_DOCUMENT)); + restoreElements(documentNamespace, SpdxConstantsCompatV2.CLASS_SPDX_PACKAGE, + doc.get(SpdxConstantsCompatV2.PROP_DOCUMENT_PACKAGES.getName()), addedElements, spdxIdProperties); + restoreElements(documentNamespace, SpdxConstantsCompatV2.CLASS_SPDX_FILE, + doc.get(SpdxConstantsCompatV2.PROP_DOCUMENT_FILES.getName()), addedElements, spdxIdProperties); + restoreElements(documentNamespace, SpdxConstantsCompatV2.CLASS_SPDX_SNIPPET, + doc.get(SpdxConstantsCompatV2.PROP_DOCUMENT_SNIPPETS.getName()), addedElements, spdxIdProperties); + restoreRelationships(documentNamespace, doc.get(SpdxConstantsCompatV2.PROP_DOCUMENT_RELATIONSHIPS.getName()), addedElements); // fix up the ID's for (Entry propertyToFix:spdxIdProperties.entrySet()) { @@ -163,7 +168,7 @@ private void restoreElement(String documentUri, String type, @Nullable JsonNode if (!jsonNode.isObject()) { throw new InvalidSPDXAnalysisException("Invalid JSON node type for SPDX element"); } - JsonNode idNode = jsonNode.get(SpdxConstants.SPDX_IDENTIFIER); + JsonNode idNode = jsonNode.get(SpdxConstantsCompatV2.SPDX_IDENTIFIER); if (Objects.isNull(idNode) || !idNode.isTextual()) { throw new InvalidSPDXAnalysisException("Missing SPDX ID for type "+type); } @@ -181,7 +186,7 @@ private void restoreElement(String documentUri, String type, @Nullable JsonNode // Add more information to the error message throw new InvalidSPDXAnalysisException("Error parsing JSON field for ID "+id+": "+ex.getMessage(), ex); } - addedElements.put(id, new TypedValue(id, type)); + addedElements.put(id, CompatibleModelStoreWrapper.typedValueFromDocUri(documentUri, id, store, type)); } /** @@ -242,7 +247,7 @@ private void restoreRelationships(String documentNamespace, JsonNode jsonNode, */ private void restoreRelationship(String documentNamespace, JsonNode relationship, Map addedElements) throws InvalidSPDXAnalysisException { - JsonNode elementIdNode = relationship.get(SpdxConstants.PROP_SPDX_ELEMENTID); + JsonNode elementIdNode = relationship.get(SpdxConstantsCompatV2.PROP_SPDX_ELEMENTID.getName()); if (Objects.isNull(elementIdNode) || !elementIdNode.isTextual()) { throw new InvalidSPDXAnalysisException("Missing SPDX element ID"); } @@ -250,7 +255,7 @@ private void restoreRelationship(String documentNamespace, JsonNode relationship if (Objects.isNull(element)) { throw new InvalidSPDXAnalysisException("Missing SPDX element for ID "+elementIdNode.asText()); } - JsonNode relationshipTypeNode = relationship.get(SpdxConstants.PROP_RELATIONSHIP_TYPE); + JsonNode relationshipTypeNode = relationship.get(SpdxConstantsCompatV2.PROP_RELATIONSHIP_TYPE.getName()); if (Objects.isNull(relationshipTypeNode) || !relationshipTypeNode.isTextual()) { throw new InvalidSPDXAnalysisException("Missing required relationship type"); } @@ -261,19 +266,20 @@ private void restoreRelationship(String documentNamespace, JsonNode relationship throw new InvalidSPDXAnalysisException("Unknown relationship type: "+relationshipTypeNode.asText()); } SimpleUriValue relationshipType = new SimpleUriValue(relationshipTypeUri); - JsonNode relatedElementNode = relationship.get(SpdxConstants.PROP_RELATED_SPDX_ELEMENT); + JsonNode relatedElementNode = relationship.get(SpdxConstantsCompatV2.PROP_RELATED_SPDX_ELEMENT.getName()); if (Objects.isNull(relatedElementNode) || !relatedElementNode.isTextual()) { throw new InvalidSPDXAnalysisException("Missing required related element"); } Object relatedElement = idToObjectValue(documentNamespace, relatedElementNode.asText(), addedElements); - JsonNode commentNode = relationship.get(SpdxConstants.RDFS_PROP_COMMENT); + JsonNode commentNode = relationship.get(SpdxConstantsCompatV2.RDFS_PROP_COMMENT.getName()); Optional relationshipComment; if (Objects.isNull(commentNode) || !commentNode.isTextual()) { relationshipComment = Optional.empty(); } else { relationshipComment = Optional.of(commentNode.asText()); } - addRelationship(documentNamespace, element.getId(), relationshipType, relatedElement, relationshipComment); + addRelationship(documentNamespace, CompatibleModelStoreWrapper.objectUriToId(store, element.getObjectUri(), documentNamespace), + relationshipType, relatedElement, relationshipComment); } /** @@ -289,7 +295,7 @@ private void restoreRelationship(String documentNamespace, JsonNode relationship private String addRelationship(String documentNamespace, String elementId, SimpleUriValue relationshipType, Object relatedElement, Optional relationshipComment) throws InvalidSPDXAnalysisException { String relatedElementId; if (relatedElement instanceof TypedValue) { - relatedElementId = ((TypedValue)relatedElement).getId(); + relatedElementId = CompatibleModelStoreWrapper.objectUriToId(store, ((TypedValue)relatedElement).getObjectUri(), documentNamespace); } else if (relatedElement instanceof String) { relatedElementId = (String)relatedElement; } else if (relatedElement instanceof IndividualUriValue) { @@ -318,13 +324,13 @@ private String addRelationship(String documentNamespace, String elementId, Simpl addedRelationships.put(elementId, elementRelationships); } String relationshipId = store.getNextId(IdType.Anonymous, documentNamespace); - store.create(documentNamespace, relationshipId, SpdxConstants.CLASS_RELATIONSHIP); - store.setValue(documentNamespace, relationshipId, SpdxConstants.PROP_RELATIONSHIP_TYPE, relationshipType); - store.setValue(documentNamespace, relationshipId, SpdxConstants.PROP_RELATED_SPDX_ELEMENT, relatedElement); - store.addValueToCollection(documentNamespace, elementId, SpdxConstants.PROP_RELATIONSHIP, - new TypedValue(relationshipId, SpdxConstants.CLASS_RELATIONSHIP)); + store.create(documentNamespace, relationshipId, SpdxConstantsCompatV2.CLASS_RELATIONSHIP); + store.setValue(documentNamespace, relationshipId, SpdxConstantsCompatV2.PROP_RELATIONSHIP_TYPE, relationshipType); + store.setValue(documentNamespace, relationshipId, SpdxConstantsCompatV2.PROP_RELATED_SPDX_ELEMENT, relatedElement); + store.addValueToCollection(documentNamespace, elementId, SpdxConstantsCompatV2.PROP_RELATIONSHIP, + CompatibleModelStoreWrapper.typedValueFromDocUri(documentNamespace, relationshipId, store, SpdxConstantsCompatV2.CLASS_RELATIONSHIP)); if (relationshipComment.isPresent()) { - store.setValue(documentNamespace, relationshipId, SpdxConstants.RDFS_PROP_COMMENT, relationshipComment.get()); + store.setValue(documentNamespace, relationshipId, SpdxConstantsCompatV2.RDFS_PROP_COMMENT, relationshipComment.get()); } relatedElementRelationships.put(relationshipType, relationshipId); return relationshipId; @@ -345,11 +351,11 @@ private void restoreObjectPropertyValues(String documentUri, String id, JsonNode Entry field = fieldIterator.next(); if (SKIPPED_PROPERTIES.contains(field.getKey())) { continue; - } else if (SpdxConstants.PROP_DOCUMENT_DESCRIBES.equals(field.getKey())) { + } else if (SpdxConstantsCompatV2.PROP_DOCUMENT_DESCRIBES.getName().equals(field.getKey())) { // These needs to be converted to a DocumentDescribes relationship convertFieldToRelationship(documentUri, id, field.getValue(), RelationshipType.DESCRIBES, spdxIdProperties); - } else if (SpdxConstants.PROP_PACKAGE_FILE.equals( + } else if (SpdxConstantsCompatV2.PROP_PACKAGE_FILE.getName().equals( MultiFormatStore.collectionPropertyNameToPropertyName(field.getKey()))) { // These needs to be converted to a CONTAINSS relationship convertFieldToRelationship(documentUri, id, field.getValue(), @@ -378,13 +384,13 @@ private void convertFieldToRelationship(String documentUri, String id, JsonNode String relationshipId = addRelationship(documentUri, id, new SimpleUriValue(relationshipType.getIndividualURI()), spdxidNode.asText(), Optional.empty()); - spdxIdProperties.put(relationshipId, SpdxConstants.PROP_RELATED_SPDX_ELEMENT); // Add the SPDX ID to the list to be translated back to elements later + spdxIdProperties.put(relationshipId, SpdxConstantsCompatV2.PROP_RELATED_SPDX_ELEMENT.getName()); // Add the SPDX ID to the list to be translated back to elements later } } else { String relationshipId = addRelationship(documentUri, id, new SimpleUriValue(relationshipType.getIndividualURI()), spdxIdField.asText(), Optional.empty()); - spdxIdProperties.put(relationshipId, SpdxConstants.PROP_RELATED_SPDX_ELEMENT); // Add the SPDX ID to the list to be translated back to elements later + spdxIdProperties.put(relationshipId, SpdxConstantsCompatV2.PROP_RELATED_SPDX_ELEMENT.getName()); // Add the SPDX ID to the list to be translated back to elements later } } @@ -477,13 +483,13 @@ private Object toStoredObject(String documentUri, String id, String property, Js if (!propertyType.isPresent()) { throw new InvalidSPDXAnalysisException("Unknown type for property " + property); } - if (SpdxConstants.CLASS_SINGLE_POINTER.equals(propertyType.get())) { + if (SpdxConstantsCompatV2.CLASS_SINGLE_POINTER.equals(propertyType.get())) { // need to determine whether a byte or line pointer type // A bit of Duck Typing is in order - if (Objects.nonNull(value.get(SpdxConstants.PROP_POINTER_OFFSET))) { - propertyType = Optional.of(SpdxConstants.CLASS_POINTER_BYTE_OFFSET_POINTER); - } else if (Objects.nonNull(value.get(SpdxConstants.PROP_POINTER_LINE_NUMBER))) { - propertyType = Optional.of(SpdxConstants.CLASS_POINTER_LINE_CHAR_POINTER); + if (Objects.nonNull(value.get(SpdxConstantsCompatV2.PROP_POINTER_OFFSET.getName()))) { + propertyType = Optional.of(SpdxConstantsCompatV2.CLASS_POINTER_BYTE_OFFSET_POINTER); + } else if (Objects.nonNull(value.get(SpdxConstantsCompatV2.PROP_POINTER_LINE_NUMBER.getName()))) { + propertyType = Optional.of(SpdxConstantsCompatV2.CLASS_POINTER_LINE_CHAR_POINTER); } else { throw new InvalidSPDXAnalysisException("Can not determine type for snippet pointer"); } @@ -491,7 +497,7 @@ private Object toStoredObject(String documentUri, String id, String property, Js String objectId = findObjectIdInJsonObject(documentUri, value); store.create(documentUri, objectId, propertyType.get()); restoreObjectPropertyValues(documentUri, objectId, value, spdxIdProperties); - return new TypedValue(objectId, propertyType.get()); + return CompatibleModelStoreWrapper.typedValueFromDocUri(documentUri, objectId, store, propertyType.get()); } case STRING: return getStringPropertyValueForJsonNode(documentUri, id, property, value, @@ -524,7 +530,7 @@ private Object getStringPropertyValueForJsonNode(String documentUri, String id, Class clazz = null; if (propertyType.isPresent()) { // check for SPDX model types - clazz = SpdxModelFactory.SPDX_TYPE_TO_CLASS.get(propertyType.get()); + clazz = SpdxModelFactoryCompatV2.SPDX_TYPE_TO_CLASS_V2.get(propertyType.get()); if (Objects.isNull(clazz)) { // check for primitive types clazz = SpdxJsonLDContext.XMLSCHEMA_TYPE_TO_JAVA_CLASS.get(propertyType.get()); @@ -537,8 +543,8 @@ private Object getStringPropertyValueForJsonNode(String documentUri, String id, // check for SPDX model classes if (AnyLicenseInfo.class.isAssignableFrom(clazz)) { // convert license expressions to their model object form - AnyLicenseInfo parsedLicense = LicenseInfoFactory.parseSPDXLicenseString(value.asText(), store, documentUri, null); - return ModelStorageClassConverter.modelObjectToStoredObject(parsedLicense, documentUri, store, null); + AnyLicenseInfo parsedLicense = LicenseInfoFactory.parseSPDXLicenseStringCompatV2(value.asText(), store, documentUri, null); + return ModelObjectHelper.modelObjectToStoredObject(parsedLicense, store, null, null); } else if (SpdxDocument.class.isAssignableFrom(clazz)) { // Convert any IndividualUriValue values final String uriValue = value.asText(); @@ -616,15 +622,15 @@ public String getIndividualURI() { * @throws InvalidSPDXAnalysisException */ private String findObjectIdInJsonObject(String documentUri, JsonNode jsonObject) throws InvalidSPDXAnalysisException { - JsonNode retval = jsonObject.get(SpdxConstants.SPDX_IDENTIFIER); + JsonNode retval = jsonObject.get(SpdxConstantsCompatV2.SPDX_IDENTIFIER); if (Objects.isNull(retval) || !retval.isTextual()) { - retval = jsonObject.get(SpdxConstants.PROP_LICENSE_ID); + retval = jsonObject.get(SpdxConstantsCompatV2.PROP_LICENSE_ID.getName()); } if (Objects.isNull(retval) || !retval.isTextual()) { - retval = jsonObject.get(SpdxConstants.PROP_LICENSE_EXCEPTION_ID); + retval = jsonObject.get(SpdxConstantsCompatV2.PROP_LICENSE_EXCEPTION_ID.getName()); } if (Objects.isNull(retval) || !retval.isTextual()) { - retval = jsonObject.get(SpdxConstants.EXTERNAL_DOCUMENT_REF_IDENTIFIER); + retval = jsonObject.get(SpdxConstantsCompatV2.EXTERNAL_DOCUMENT_REF_IDENTIFIER); } if (Objects.isNull(retval) || !retval.isTextual()) { return store.getNextId(IdType.Anonymous, documentUri); @@ -645,21 +651,21 @@ private String findObjectIdInJsonObject(String documentUri, JsonNode jsonObject) private Object idToObjectValue(String documentNamespace, String spdxId, Map addedElements) throws InvalidSPDXAnalysisException { TypedValue fixedValue = addedElements.get(spdxId); if (Objects.isNull(fixedValue)) { - if (spdxId.equals(SpdxConstants.NONE_VALUE)) { + if (spdxId.equals(SpdxConstantsCompatV2.NONE_VALUE)) { return new IndividualUriValue() { @Override public String getIndividualURI() { - return SpdxConstants.URI_VALUE_NONE; + return SpdxConstantsCompatV2.URI_VALUE_NONE; } }; - } else if (spdxId.equals(SpdxConstants.NOASSERTION_VALUE)) { + } else if (spdxId.equals(SpdxConstantsCompatV2.NOASSERTION_VALUE)) { return new IndividualUriValue() { @Override public String getIndividualURI() { - return SpdxConstants.URI_VALUE_NOASSERTION; + return SpdxConstantsCompatV2.URI_VALUE_NOASSERTION; } }; diff --git a/src/main/java/org/spdx/jacksonstore/JacksonSerializer.java b/src/main/java/org/spdx/jacksonstore/JacksonSerializer.java index 6996def..832dadf 100644 --- a/src/main/java/org/spdx/jacksonstore/JacksonSerializer.java +++ b/src/main/java/org/spdx/jacksonstore/JacksonSerializer.java @@ -31,25 +31,28 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.spdx.core.CoreModelObject; +import org.spdx.core.IndividualUriValue; +import org.spdx.core.InvalidSPDXAnalysisException; +import org.spdx.core.ModelRegistry; +import org.spdx.core.SpdxInvalidTypeException; +import org.spdx.core.TypedValue; import org.spdx.jacksonstore.MultiFormatStore.Format; import org.spdx.jacksonstore.MultiFormatStore.Verbose; -import org.spdx.library.InvalidSPDXAnalysisException; -import org.spdx.library.SpdxConstants; -import org.spdx.library.model.ExternalDocumentRef; -import org.spdx.library.model.ExternalSpdxElement; -import org.spdx.library.model.IndividualUriValue; -import org.spdx.library.model.SpdxElement; -import org.spdx.library.model.SpdxInvalidTypeException; -import org.spdx.library.model.SpdxModelFactory; -import org.spdx.library.model.TypedValue; -import org.spdx.library.model.enumerations.Purpose; -import org.spdx.library.model.enumerations.RelationshipType; -import org.spdx.library.model.enumerations.SpdxEnumFactory; -import org.spdx.library.model.license.AnyLicenseInfo; -import org.spdx.library.model.license.SimpleLicensingInfo; +import org.spdx.library.model.v2.ExternalDocumentRef; +import org.spdx.library.model.v2.ExternalSpdxElement; +import org.spdx.library.model.v2.SpdxConstantsCompatV2; +import org.spdx.library.model.v2.SpdxElement; +import org.spdx.library.model.v2.SpdxModelFactoryCompatV2; +import org.spdx.library.model.v2.enumerations.Purpose; +import org.spdx.library.model.v2.enumerations.RelationshipType; +import org.spdx.library.model.v2.enumerations.SpdxEnumFactoryCompatV2; +import org.spdx.library.model.v2.license.AnyLicenseInfo; +import org.spdx.library.model.v2.license.SimpleLicensingInfo; import org.spdx.storage.IModelStore; import org.spdx.storage.IModelStore.IModelStoreLock; import org.spdx.storage.IModelStore.IdType; +import org.spdx.storage.compatv2.CompatibleModelStoreWrapper; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; @@ -60,7 +63,7 @@ /** * Serializer for a model store to convert the document model object into a JsonNode * - * the method docToJsonNode(String documentUri) will generate the JSON node + * the method docToJsonNode(String documentUri) will generate the JSON node for a document * @author Gary O'Neall * */ @@ -131,25 +134,25 @@ private int compareObject(JsonNode arg0, JsonNode arg1) { if (!arg1.isObject()) { return 1; } - JsonNode spdxid0 = arg0.get(SpdxConstants.SPDX_IDENTIFIER); + JsonNode spdxid0 = arg0.get(SpdxConstantsCompatV2.SPDX_IDENTIFIER); if (Objects.nonNull(spdxid0) && spdxid0.isTextual()) { - JsonNode spdxid1 = arg1.get(SpdxConstants.SPDX_IDENTIFIER); + JsonNode spdxid1 = arg1.get(SpdxConstantsCompatV2.SPDX_IDENTIFIER); return Objects.nonNull(spdxid1) && spdxid1.isTextual() ? spdxid0.asText().compareTo(spdxid1.asText()) : 1; } // look for special cases where we don't want to sort in the order of properties - JsonNode licenseId0 = arg0.get(SpdxConstants.PROP_LICENSE_ID); + JsonNode licenseId0 = arg0.get(SpdxConstantsCompatV2.PROP_LICENSE_ID.getName()); if (Objects.nonNull(licenseId0) && licenseId0.isTextual()) { return compareExtractedLicense(licenseId0.asText(), arg1); } - JsonNode spdxDocument0 = arg0.get(SpdxConstants.PROP_EXTERNAL_SPDX_DOCUMENT); - JsonNode externalDocId0 = arg0.get(SpdxConstants.PROP_EXTERNAL_DOCUMENT_ID); + JsonNode spdxDocument0 = arg0.get(SpdxConstantsCompatV2.PROP_EXTERNAL_SPDX_DOCUMENT.getName()); + JsonNode externalDocId0 = arg0.get(SpdxConstantsCompatV2.PROP_EXTERNAL_DOCUMENT_ID.getName()); if (Objects.nonNull(spdxDocument0) && Objects.nonNull(externalDocId0) && spdxDocument0.isTextual() && externalDocId0.isTextual()) { return compareExternalDocumentRef(spdxDocument0.asText(), externalDocId0.asText(), arg1); } - JsonNode refCategory0 = arg0.get(SpdxConstants.PROP_REFERENCE_CATEGORY); - JsonNode refType0 = arg0.get(SpdxConstants.PROP_REFERENCE_TYPE); - JsonNode refLocator0 = arg0.get(SpdxConstants.PROP_REFERENCE_LOCATOR); + JsonNode refCategory0 = arg0.get(SpdxConstantsCompatV2.PROP_REFERENCE_CATEGORY.getName()); + JsonNode refType0 = arg0.get(SpdxConstantsCompatV2.PROP_REFERENCE_TYPE.getName()); + JsonNode refLocator0 = arg0.get(SpdxConstantsCompatV2.PROP_REFERENCE_LOCATOR.getName()); if (Objects.nonNull(refCategory0) && Objects.nonNull(refType0) && Objects.nonNull(refLocator0) && refCategory0.isTextual() && refType0.isTextual() && refLocator0.isTextual()) { return compareExternalRef(refCategory0.asText(), refType0.asText(), refLocator0.asText(), arg1); @@ -171,9 +174,9 @@ private int compareObject(JsonNode arg0, JsonNode arg1) { private int compareExternalRef(String refCategory, String refType, String refLocator, JsonNode compare) { - JsonNode compRefCategory = compare.get(SpdxConstants.PROP_REFERENCE_CATEGORY); - JsonNode compRefType = compare.get(SpdxConstants.PROP_REFERENCE_TYPE); - JsonNode compRefLocator = compare.get(SpdxConstants.PROP_REFERENCE_LOCATOR); + JsonNode compRefCategory = compare.get(SpdxConstantsCompatV2.PROP_REFERENCE_CATEGORY.getName()); + JsonNode compRefType = compare.get(SpdxConstantsCompatV2.PROP_REFERENCE_TYPE.getName()); + JsonNode compRefLocator = compare.get(SpdxConstantsCompatV2.PROP_REFERENCE_LOCATOR.getName()); if (Objects.isNull(compRefCategory) || Objects.isNull(compRefType) || Objects.isNull(compRefLocator) || !compRefCategory.isTextual() || !compRefType.isTextual() || !compRefLocator.isTextual()) { return 1; @@ -191,8 +194,8 @@ private int compareExternalRef(String refCategory, String refType, private int compareExternalDocumentRef(String document, String externalDocId, JsonNode compare) { - JsonNode compDocument = compare.get(SpdxConstants.PROP_EXTERNAL_SPDX_DOCUMENT); - JsonNode compExternalDocId = compare.get(SpdxConstants.PROP_EXTERNAL_DOCUMENT_ID); + JsonNode compDocument = compare.get(SpdxConstantsCompatV2.PROP_EXTERNAL_SPDX_DOCUMENT.getName()); + JsonNode compExternalDocId = compare.get(SpdxConstantsCompatV2.PROP_EXTERNAL_DOCUMENT_ID.getName()); if (Objects.isNull(compDocument) || Objects.isNull(compExternalDocId) || !compDocument.isTextual() || !compExternalDocId.isTextual()) { return 1; @@ -205,7 +208,7 @@ private int compareExternalDocumentRef(String document, String externalDocId, } private int compareExtractedLicense(String licenseId, JsonNode compare) { - JsonNode compLicenseId = compare.get(SpdxConstants.PROP_LICENSE_ID); + JsonNode compLicenseId = compare.get(SpdxConstantsCompatV2.PROP_LICENSE_ID.getName()); if (Objects.isNull(compLicenseId) || !compLicenseId.isTextual()) { return 1; } else { @@ -216,7 +219,7 @@ private int compareExtractedLicense(String licenseId, JsonNode compare) { }; private ObjectMapper mapper; - private IModelStore store; + private CompatibleModelStoreWrapper store; private Format format; private Verbose verbose; @@ -226,15 +229,28 @@ private int compareExtractedLicense(String licenseId, JsonNode compare) { * @param store Model store containing the documents */ public JacksonSerializer(ObjectMapper mapper, Format format, Verbose verbose, IModelStore store) { - Objects.requireNonNull(mapper, "Null required Jackson mapper"); - Objects.requireNonNull(format, "Null required format"); - Objects.requireNonNull(verbose, "Null required verbose"); - Objects.requireNonNull(store, "Null required store"); + Objects.requireNonNull(mapper, "Non-null required Jackson mapper"); + Objects.requireNonNull(format, "Non-null required format"); + Objects.requireNonNull(verbose, "Non-null required verbose"); + Objects.requireNonNull(store, "Non-null required store"); this.mapper = mapper; - this.store = store; + this.store = new CompatibleModelStoreWrapper(store); this.format = format; this.verbose = verbose; } + + /** + * @param documentUris list of document uris + * @return JSON array of all documents which have the document Uris + * @throws InvalidSPDXAnalysisException + */ + public ArrayNode docsToJsonNode(List documentUris) throws InvalidSPDXAnalysisException { + ArrayNode retval = mapper.createArrayNode(); + for (String documentUri:documentUris) { + retval.add(docToJsonNode(documentUri)); + } + return retval; + } /** * @param documentUri URI for the document to be converted @@ -245,21 +261,22 @@ public ObjectNode docToJsonNode(String documentUri) throws InvalidSPDXAnalysisEx Objects.requireNonNull(documentUri,"Null Document URI"); IModelStoreLock lock = store.enterCriticalSection(documentUri, false); //TODO: True value causes deadlock due to false value in ExternalDocumentRef line 58 try { - TypedValue document = new TypedValue(SpdxConstants.SPDX_DOCUMENT_ID, SpdxConstants.CLASS_SPDX_DOCUMENT); + TypedValue document = CompatibleModelStoreWrapper.typedValueFromDocUri(documentUri, + SpdxConstantsCompatV2.SPDX_DOCUMENT_ID, false, SpdxConstantsCompatV2.CLASS_SPDX_DOCUMENT); ArrayNode relationships = mapper.createArrayNode(); ObjectNode doc = typedValueToObjectNode(documentUri, document, relationships); - doc.put(SpdxConstants.PROP_DOCUMENT_NAMESPACE, documentUri); - ArrayNode packages = getDocElements(documentUri, SpdxConstants.CLASS_SPDX_PACKAGE, relationships); + doc.put(SpdxConstantsCompatV2.PROP_DOCUMENT_NAMESPACE.getName(), documentUri); + ArrayNode packages = getDocElements(documentUri, SpdxConstantsCompatV2.CLASS_SPDX_PACKAGE, relationships); if (packages.size() > 0) { - doc.set(SpdxConstants.PROP_DOCUMENT_PACKAGES, packages); + doc.set(SpdxConstantsCompatV2.PROP_DOCUMENT_PACKAGES.getName(), packages); } - ArrayNode files = getDocElements(documentUri, SpdxConstants.CLASS_SPDX_FILE, relationships); + ArrayNode files = getDocElements(documentUri, SpdxConstantsCompatV2.CLASS_SPDX_FILE, relationships); if (files.size() > 0) { - doc.set(SpdxConstants.PROP_DOCUMENT_FILES, files); + doc.set(SpdxConstantsCompatV2.PROP_DOCUMENT_FILES.getName(), files); } - ArrayNode snippets = getDocElements(documentUri, SpdxConstants.CLASS_SPDX_SNIPPET, relationships); + ArrayNode snippets = getDocElements(documentUri, SpdxConstantsCompatV2.CLASS_SPDX_SNIPPET, relationships); if (snippets.size() > 0) { - doc.set(SpdxConstants.PROP_DOCUMENT_SNIPPETS, snippets); + doc.set(SpdxConstantsCompatV2.PROP_DOCUMENT_SNIPPETS.getName(), snippets); } //Remove duplicate relationships Map>> iDRelTypeRelatediDMap = new HashMap<>(); @@ -267,9 +284,9 @@ public ObjectNode docToJsonNode(String documentUri) throws InvalidSPDXAnalysisEx ArrayNode deDupedRelationships = new ArrayNode(JsonNodeFactory.instance); while (relIter.hasNext()) { JsonNode relationship = relIter.next(); - String id = relationship.get(SpdxConstants.PROP_SPDX_ELEMENTID).asText(); - String relType = relationship.get(SpdxConstants.PROP_RELATIONSHIP_TYPE).asText(); - String relatedID = relationship.get(SpdxConstants.PROP_RELATED_SPDX_ELEMENT).asText(); + String id = relationship.get(SpdxConstantsCompatV2.PROP_SPDX_ELEMENTID.getName()).asText(); + String relType = relationship.get(SpdxConstantsCompatV2.PROP_RELATIONSHIP_TYPE.getName()).asText(); + String relatedID = relationship.get(SpdxConstantsCompatV2.PROP_RELATED_SPDX_ELEMENT.getName()).asText(); Map> relTypeRelatedIdMap = iDRelTypeRelatediDMap.get(id); if (Objects.isNull(relTypeRelatedIdMap)) { relTypeRelatedIdMap = new HashMap<>(); @@ -287,7 +304,7 @@ public ObjectNode docToJsonNode(String documentUri) throws InvalidSPDXAnalysisEx } - doc.set(SpdxConstants.PROP_DOCUMENT_RELATIONSHIPS, deDupedRelationships); + doc.set(SpdxConstantsCompatV2.PROP_DOCUMENT_RELATIONSHIPS.getName(), deDupedRelationships); ObjectNode output; switch (format) { case YAML: { @@ -328,38 +345,40 @@ private ObjectNode typedValueToObjectNode(String documentUri, TypedValue storedI ObjectNode retval = mapper.createObjectNode(); Set hasFileIds = new HashSet<>(); // keep track of any hasFile properties added to avoid duplicates Set documentDescribesIds = new HashSet<>(); // keep track of any documentDescribes properties added to avoid duplicates - List docPropNames = new ArrayList(store.getPropertyValueNames(documentUri, storedItem.getId())); + List docPropNames = new ArrayList(store.getPropertyValueNames(storedItem.getObjectUri())); docPropNames.sort(new PropertyComparator(storedItem.getType())); - Class clazz = SpdxModelFactory.SPDX_TYPE_TO_CLASS.get(storedItem.getType()); - IdType idType = store.getIdType(storedItem.getId()); + Class clazz = SpdxModelFactoryCompatV2.SPDX_TYPE_TO_CLASS_V2.get(storedItem.getType()); + IdType idType = store.getIdType(storedItem.getObjectUri()); + String id = CompatibleModelStoreWrapper.objectUriToId(store, storedItem.getObjectUri(), documentUri); if (SpdxElement.class.isAssignableFrom(clazz)) { if (IdType.SpdxId.equals(idType)) { - retval.put(SpdxConstants.SPDX_IDENTIFIER, storedItem.getId()); + retval.put(SpdxConstantsCompatV2.SPDX_IDENTIFIER, CompatibleModelStoreWrapper.objectUriToId(store, storedItem.getObjectUri(), documentUri)); } else if (!IdType.Anonymous.equals(idType)) { - logger.error("Invalid ID "+storedItem.getId()+". Must be an SPDX Identifier or Anonymous"); - throw new InvalidSPDXAnalysisException("Invalid ID "+storedItem.getId()+". Must be an SPDX Identifier or Anonymous"); + logger.error("Invalid ID "+storedItem.getObjectUri()+". Must be an SPDX Identifier or Anonymous"); + throw new InvalidSPDXAnalysisException("Invalid ID "+storedItem.getObjectUri()+". Must be an SPDX Identifier or Anonymous"); } } else if (ExternalDocumentRef.class.isAssignableFrom(clazz)) { - retval.put(SpdxConstants.EXTERNAL_DOCUMENT_REF_IDENTIFIER, storedItem.getId()); + retval.put(SpdxConstantsCompatV2.EXTERNAL_DOCUMENT_REF_IDENTIFIER, CompatibleModelStoreWrapper.objectUriToId(store, storedItem.getObjectUri(), documentUri)); } else if (SimpleLicensingInfo.class.isAssignableFrom(clazz)) { - retval.put(SpdxConstants.PROP_LICENSE_ID, storedItem.getId()); + retval.put(SpdxConstantsCompatV2.PROP_LICENSE_ID.getName(), id); } for (String propertyName:docPropNames) { - if (SpdxConstants.PROP_RELATIONSHIP.equals(propertyName)) { + if (SpdxConstantsCompatV2.PROP_RELATIONSHIP.getName().equals(propertyName)) { addJsonRelationships(documentUri, storedItem, retval, relationships, hasFileIds, documentDescribesIds); - } else if (SpdxConstants.PROP_SPDX_EXTRACTED_LICENSES.equals(propertyName)) { + } else if (SpdxConstantsCompatV2.PROP_SPDX_EXTRACTED_LICENSES.getName().equals(propertyName)) { retval.set(MultiFormatStore.propertyNameToCollectionPropertyName(propertyName), - toExtractedLicensesArrayNode(documentUri, storedItem.getId(), propertyName, relationships)); - } else if (store.isCollectionProperty(documentUri, storedItem.getId(), propertyName)) { - Iterator propertyValues = store.listValues(documentUri, storedItem.getId(), propertyName); + toExtractedLicensesArrayNode(documentUri, id, propertyName, relationships)); + } else if (store.isCollectionProperty(documentUri, id, propertyName)) { + Iterator propertyValues = store.listValues(documentUri, id, propertyName); ArrayNode valuesArray; - if (SpdxConstants.PROP_PACKAGE_FILE.equals(propertyName) && hasFileIds.size() > 0) { + if (SpdxConstantsCompatV2.PROP_PACKAGE_FILE.getName().equals(propertyName) && hasFileIds.size() > 0) { // Need to filter out existing hasFileIds List hasFilesToAdd = new ArrayList<>(); while (propertyValues.hasNext()) { Object fileToAdd = propertyValues.next(); if (fileToAdd instanceof TypedValue) { - String fileToAddId = ((TypedValue)fileToAdd).getId(); + String fileToAddId = CompatibleModelStoreWrapper.objectUriToId(store, + ((TypedValue)fileToAdd).getObjectUri(), documentUri); if (!hasFileIds.contains(fileToAddId)) { hasFilesToAdd.add(fileToAdd); hasFileIds.add(fileToAddId); @@ -371,13 +390,14 @@ private ObjectNode typedValueToObjectNode(String documentUri, TypedValue storedI valuesArray = toArrayNode(documentUri, hasFilesToAdd.iterator(), relationships); - } else if (SpdxConstants.PROP_DOCUMENT_DESCRIBES.equals(propertyName) && documentDescribesIds.size() > 0) { + } else if (SpdxConstantsCompatV2.PROP_DOCUMENT_DESCRIBES.getName().equals(propertyName) && documentDescribesIds.size() > 0) { // Need to filter out existing documentDescribes List describesToAdd = new ArrayList<>(); while (propertyValues.hasNext()) { Object describedElementToAdd = propertyValues.next(); if (describedElementToAdd instanceof TypedValue) { - String describedElementToAddId = ((TypedValue)describedElementToAdd).getId(); + String describedElementToAddId = CompatibleModelStoreWrapper.objectUriToId(store, + ((TypedValue)describedElementToAdd).getObjectUri(), documentUri); if (!hasFileIds.contains(describedElementToAddId)) { describesToAdd.add(describedElementToAdd); hasFileIds.add(describedElementToAddId); @@ -395,7 +415,7 @@ private ObjectNode typedValueToObjectNode(String documentUri, TypedValue storedI retval.set(MultiFormatStore.propertyNameToCollectionPropertyName(propertyName), valuesArray); } else { - Optional value = store.getValue(documentUri, storedItem.getId(), propertyName); + Optional value = store.getValue(documentUri, id, propertyName); if (value.isPresent()) { setValueField(retval, propertyName, documentUri, value.get(), relationships); } @@ -439,8 +459,8 @@ private ArrayNode toExtractedLicensesArrayNode(String documentUri, String id, St while (extractedLicenses.hasNext()) { Object extractedLicense = extractedLicenses.next(); if (!(extractedLicense instanceof TypedValue) || - (!SpdxConstants.CLASS_SPDX_EXTRACTED_LICENSING_INFO.equals(((TypedValue)extractedLicense).getType()))) { - throw new SpdxInvalidTypeException("Extracted License Infos not of type "+SpdxConstants.CLASS_SPDX_EXTRACTED_LICENSING_INFO); + (!SpdxConstantsCompatV2.CLASS_SPDX_EXTRACTED_LICENSING_INFO.equals(((TypedValue)extractedLicense).getType()))) { + throw new SpdxInvalidTypeException("Extracted License Infos not of type "+SpdxConstantsCompatV2.CLASS_SPDX_EXTRACTED_LICENSING_INFO); } retval.add(typedValueToObjectNode(documentUri, (TypedValue)extractedLicense, relationships)); } @@ -461,36 +481,37 @@ private ArrayNode toExtractedLicensesArrayNode(String documentUri, String id, St */ private void addJsonRelationships(String documentUri, TypedValue element, ObjectNode elementNode, ArrayNode relationships, Set hasFileIds, Set documentDescribesIds) throws InvalidSPDXAnalysisException { - Iterator valueList = store.listValues(documentUri, element.getId(), - SpdxConstants.PROP_RELATIONSHIP); + Iterator valueList = store.listValues(documentUri, CompatibleModelStoreWrapper.objectUriToId(store, + element.getObjectUri(), documentUri), + SpdxConstantsCompatV2.PROP_RELATIONSHIP); while (valueList.hasNext()) { Object value = valueList.next(); if (!(value instanceof TypedValue)) { throw new SpdxInvalidTypeException("Expected relationship type, value list element was of type "+value.getClass().toString()); } TypedValue tvValue = (TypedValue)value; - if (!SpdxConstants.CLASS_RELATIONSHIP.equals(tvValue.getType())) { + String tvId = CompatibleModelStoreWrapper.objectUriToId(store, tvValue.getObjectUri(), documentUri); + if (!SpdxConstantsCompatV2.CLASS_RELATIONSHIP.equals(tvValue.getType())) { throw new SpdxInvalidTypeException("Expected relationship type, value list element was of type "+tvValue.getType()); } - Optional relatedSpdxElement = store.getValue(documentUri, tvValue.getId(), SpdxConstants.PROP_RELATED_SPDX_ELEMENT); + Optional relatedSpdxElement = store.getValue(documentUri, tvId, SpdxConstantsCompatV2.PROP_RELATED_SPDX_ELEMENT); if (!relatedSpdxElement.isPresent()) { - logger.warn("Missing related SPDX element for a relationship for "+element.getId()+". Skipping the serialization of this relationship."); + logger.warn("Missing related SPDX element for a relationship for "+element.getObjectUri()+". Skipping the serialization of this relationship."); continue; } - Optional relationshipComment = store.getValue(documentUri, tvValue.getId(), SpdxConstants.RDFS_PROP_COMMENT); + Optional relationshipComment = store.getValue(documentUri, tvId, SpdxConstantsCompatV2.RDFS_PROP_COMMENT); String relatedElementId; if (relatedSpdxElement.get() instanceof TypedValue) { - relatedElementId = ((TypedValue)relatedSpdxElement.get()).getId(); + relatedElementId = CompatibleModelStoreWrapper.objectUriToId(store, ((TypedValue)relatedSpdxElement.get()).getObjectUri(), documentUri); } else if (relatedSpdxElement.get() instanceof IndividualUriValue) { String externalUri = ((IndividualUriValue)relatedSpdxElement.get()).getIndividualURI(); - if (SpdxConstants.URI_VALUE_NONE.equals(externalUri)) { - relatedElementId = SpdxConstants.NONE_VALUE; - } else if (SpdxConstants.URI_VALUE_NOASSERTION.equals(externalUri)) { - relatedElementId = SpdxConstants.NOASSERTION_VALUE; - } else if (SpdxConstants.EXTERNAL_SPDX_ELEMENT_URI_PATTERN.matcher(externalUri).matches()) { + if (SpdxConstantsCompatV2.URI_VALUE_NONE.equals(externalUri)) { + relatedElementId = SpdxConstantsCompatV2.NONE_VALUE; + } else if (SpdxConstantsCompatV2.URI_VALUE_NOASSERTION.equals(externalUri)) { + relatedElementId = SpdxConstantsCompatV2.NOASSERTION_VALUE; + } else if (SpdxConstantsCompatV2.EXTERNAL_SPDX_ELEMENT_URI_PATTERN.matcher(externalUri).matches()) { // external SPDX element - ExternalSpdxElement externalElement = ExternalSpdxElement.uriToExternalSpdxElement(externalUri, store, documentUri, null); - relatedElementId = externalElement.getExternalDocumentId() + ":" + externalElement.getExternalElementId(); + relatedElementId = ExternalSpdxElement.uriToExternalSpdxElementReference(externalUri, store, documentUri, null, CompatibleModelStoreWrapper.LATEST_SPDX_2X_VERSION); } else { throw new SpdxInvalidTypeException("SPDX element must be of SpdxElement, SpdxNoneElement, SpdxNoAssertionElement or external SPDX element type. URI does not match pattern for external element: "+externalUri); } @@ -498,9 +519,9 @@ private void addJsonRelationships(String documentUri, TypedValue element, Object throw new SpdxInvalidTypeException("SPDX element must be of SpdxElement or external SPDX element type. Found type "+relatedSpdxElement.get().getClass().toString()); } - Optional relationshipType = store.getValue(documentUri, tvValue.getId(), SpdxConstants.PROP_RELATIONSHIP_TYPE); + Optional relationshipType = store.getValue(documentUri, tvId, SpdxConstantsCompatV2.PROP_RELATIONSHIP_TYPE); if (!relationshipType.isPresent()) { - logger.warn("Missing type for a relationship for "+element.getId()+". Skipping the serialization of this relationship."); + logger.warn("Missing type for a relationship for "+element.getObjectUri()+". Skipping the serialization of this relationship."); continue; } if (!(relationshipType.get() instanceof IndividualUriValue)) { @@ -508,11 +529,12 @@ private void addJsonRelationships(String documentUri, TypedValue element, Object } String relationshipTypeStr = individualUriToString(documentUri, ((IndividualUriValue)relationshipType.get()).getIndividualURI()); ObjectNode relationship = mapper.createObjectNode(); - relationship.put(SpdxConstants.PROP_SPDX_ELEMENTID, element.getId()); - relationship.put(SpdxConstants.PROP_RELATIONSHIP_TYPE, relationshipTypeStr); - relationship.put(SpdxConstants.PROP_RELATED_SPDX_ELEMENT, relatedElementId); + relationship.put(SpdxConstantsCompatV2.PROP_SPDX_ELEMENTID.getName(), CompatibleModelStoreWrapper.objectUriToId(store, + element.getObjectUri(), documentUri)); + relationship.put(SpdxConstantsCompatV2.PROP_RELATIONSHIP_TYPE.getName(), relationshipTypeStr); + relationship.put(SpdxConstantsCompatV2.PROP_RELATED_SPDX_ELEMENT.getName(), relatedElementId); if (relationshipComment.isPresent()) { - relationship.put(SpdxConstants.RDFS_PROP_COMMENT, (String)relationshipComment.get()); + relationship.put(SpdxConstantsCompatV2.RDFS_PROP_COMMENT.getName(), (String)relationshipComment.get()); } relationships.add(relationship); } @@ -575,16 +597,17 @@ private Object toSerializable(String documentUri, Object value, ArrayNode relati return individualUriToString(documentUri, ((IndividualUriValue)value).getIndividualURI()); } else if (value instanceof TypedValue) { TypedValue tvStoredValue = (TypedValue)value; - Class clazz = SpdxModelFactory.SPDX_TYPE_TO_CLASS.get(tvStoredValue.getType()); + String tvId = CompatibleModelStoreWrapper.objectUriToId(store, tvStoredValue.getObjectUri(), documentUri); + Class clazz = SpdxModelFactoryCompatV2.SPDX_TYPE_TO_CLASS_V2.get(tvStoredValue.getType()); if (AnyLicenseInfo.class.isAssignableFrom(clazz) && (Verbose.STANDARD.equals(verbose) || Verbose.COMPACT.equals(verbose))) { - AnyLicenseInfo ali = (AnyLicenseInfo)SpdxModelFactory.createModelObject(store, documentUri, - tvStoredValue.getId(), tvStoredValue.getType(), null); - return ali.toString(); + CoreModelObject inflated = ModelRegistry.getModelRegistry().inflateModelObject(store, tvStoredValue.getObjectUri(), tvStoredValue.getType(), + null, tvStoredValue.getSpecVersion(), false, documentUri + "#"); + return inflated.toString(); } else if (SpdxElement.class.isAssignableFrom(clazz) && Verbose.COMPACT.equals(verbose) && - !IModelStore.IdType.Anonymous.equals(store.getIdType(tvStoredValue.getId()))) { - return tvStoredValue.getId(); + !IModelStore.IdType.Anonymous.equals(store.getIdType(tvId))) { + return tvId; } else { return typedValueToObjectNode(documentUri, (TypedValue)value, relationships); } @@ -601,22 +624,22 @@ private Object toSerializable(String documentUri, Object value, ArrayNode relati * @throws InvalidSPDXAnalysisException */ private String individualUriToString(String documentUri, String uri) throws InvalidSPDXAnalysisException { - Object enumval = SpdxEnumFactory.uriToEnum.get(uri); + Object enumval = SpdxEnumFactoryCompatV2.uriToEnum.get(uri); if (Objects.nonNull(enumval)) { if (enumval instanceof RelationshipType || enumval instanceof Purpose) { return enumval.toString(); } else { return enumval.toString().replaceAll("_", "-"); } - } else if (SpdxConstants.EXTERNAL_SPDX_ELEMENT_URI_PATTERN.matcher(uri).matches()) { - ExternalSpdxElement externalElement = ExternalSpdxElement.uriToExternalSpdxElement(uri, store, documentUri, null); - return externalElement.getExternalDocumentId() + ":" + externalElement.getExternalElementId(); - } else if (SpdxConstants.URI_VALUE_NONE.equals(uri)) { - return SpdxConstants.NONE_VALUE; - } else if (SpdxConstants.URI_VALUE_NOASSERTION.equals(uri)) { - return SpdxConstants.NOASSERTION_VALUE; - } else if (uri.startsWith(SpdxConstants.SPDX_LISTED_REFERENCE_TYPES_PREFIX)) { - return uri.substring(SpdxConstants.SPDX_LISTED_REFERENCE_TYPES_PREFIX.length()); + } else if (SpdxConstantsCompatV2.EXTERNAL_SPDX_ELEMENT_URI_PATTERN.matcher(uri).matches()) { + return ExternalSpdxElement.uriToExternalSpdxElementReference(uri, store, documentUri, null, + CompatibleModelStoreWrapper.LATEST_SPDX_2X_VERSION); + } else if (SpdxConstantsCompatV2.URI_VALUE_NONE.equals(uri)) { + return SpdxConstantsCompatV2.NONE_VALUE; + } else if (SpdxConstantsCompatV2.URI_VALUE_NOASSERTION.equals(uri)) { + return SpdxConstantsCompatV2.NOASSERTION_VALUE; + } else if (uri.startsWith(SpdxConstantsCompatV2.SPDX_LISTED_REFERENCE_TYPES_PREFIX)) { + return uri.substring(SpdxConstantsCompatV2.SPDX_LISTED_REFERENCE_TYPES_PREFIX.length()); } else { return uri; } diff --git a/src/main/java/org/spdx/jacksonstore/MultiFormatStore.java b/src/main/java/org/spdx/jacksonstore/MultiFormatStore.java index 9311243..c4607a0 100644 --- a/src/main/java/org/spdx/jacksonstore/MultiFormatStore.java +++ b/src/main/java/org/spdx/jacksonstore/MultiFormatStore.java @@ -21,14 +21,26 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; + +import javax.annotation.Nullable; import org.json.JSONObject; import org.json.XML; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.spdx.library.InvalidSPDXAnalysisException; -import org.spdx.library.SpdxConstants; +import org.spdx.core.CoreModelObject; +import org.spdx.core.InvalidSPDXAnalysisException; +import org.spdx.core.TypedValue; +import org.spdx.library.ModelCopyManager; +import org.spdx.library.SpdxModelFactory; +import org.spdx.library.model.v2.SpdxConstantsCompatV2; +import org.spdx.library.model.v2.SpdxDocument; import org.spdx.storage.IModelStore; import org.spdx.storage.ISerializableModelStore; import org.spdx.storage.simple.ExtendedSpdxStore; @@ -37,7 +49,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; -import com.fasterxml.jackson.databind.node.ObjectNode; +import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.dataformat.xml.XmlFactory; import com.fasterxml.jackson.dataformat.xml.XmlMapper; import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator; @@ -155,15 +167,27 @@ public synchronized void setVerbose(Verbose verbose) { setMapper(); } - + @Override + public synchronized void serialize(OutputStream stream) throws InvalidSPDXAnalysisException, IOException { + serialize(stream, null); + } /* (non-Javadoc) * @see org.spdx.storage.ISerializableModelStore#serialize(java.lang.String, java.io.OutputStream) */ @Override - public synchronized void serialize(String documentUri, OutputStream stream) throws InvalidSPDXAnalysisException, IOException { + public synchronized void serialize(OutputStream stream, @Nullable CoreModelObject modelObject) throws InvalidSPDXAnalysisException, IOException { JacksonSerializer serializer = new JacksonSerializer(outputMapper, format, verbose, this); - ObjectNode output = serializer.docToJsonNode(documentUri); + JsonNode output; + if (Objects.nonNull(modelObject)) { + output = serializer.docToJsonNode(modelObject.getObjectUri().substring(0, modelObject.getObjectUri().indexOf('#'))); + } else { + List allDocuments = getAllItems(null, SpdxConstantsCompatV2.CLASS_SPDX_DOCUMENT) + .map(tv -> tv.getObjectUri().substring(0, tv.getObjectUri().indexOf('#'))) + .collect(Collectors.toList()); + output = allDocuments.size() == 1 ? serializer.docToJsonNode(allDocuments.get(0)) : + serializer.docsToJsonNode(allDocuments); + } JsonGenerator jgen = null; try { switch (format) { @@ -200,7 +224,7 @@ public synchronized void serialize(String documentUri, OutputStream stream) thro public static String propertyNameToCollectionPropertyName(String propertyName) { if (propertyName.endsWith("y")) { return propertyName.substring(0, propertyName.length()-1) + "ies"; - } else if (SpdxConstants.PROP_PACKAGE_LICENSE_INFO_FROM_FILES.equals(propertyName)) { + } else if (SpdxConstantsCompatV2.PROP_PACKAGE_LICENSE_INFO_FROM_FILES.getName().equals(propertyName)) { return propertyName; } else { return propertyName + "s"; @@ -210,7 +234,7 @@ public static String propertyNameToCollectionPropertyName(String propertyName) { public static String collectionPropertyNameToPropertyName(String collectionPropertyName) { if (collectionPropertyName.endsWith("ies")) { return collectionPropertyName.substring(0, collectionPropertyName.length()-3) + "y"; - } else if (SpdxConstants.PROP_PACKAGE_LICENSE_INFO_FROM_FILES.equals(collectionPropertyName)) { + } else if (SpdxConstantsCompatV2.PROP_PACKAGE_LICENSE_INFO_FROM_FILES.getName().equals(collectionPropertyName)) { return collectionPropertyName; } else { return collectionPropertyName.substring(0, collectionPropertyName.length()-1); @@ -221,44 +245,109 @@ public static String collectionPropertyNameToPropertyName(String collectionPrope * @see org.spdx.storage.ISerializableModelStore#deSerialize(java.io.InputStream, boolean) */ @Override - public synchronized String deSerialize(InputStream stream, boolean overwrite) throws InvalidSPDXAnalysisException, IOException { + public synchronized SpdxDocument deSerialize(InputStream stream, boolean overwrite) throws InvalidSPDXAnalysisException, IOException { Objects.requireNonNull(stream, "Input stream must not be null"); if (this.verbose != Verbose.COMPACT) { throw new InvalidSPDXAnalysisException("Only COMPACT verbose option is supported for deserialization"); } - JsonNode doc; + JsonNode root; if (Format.XML.equals(format)) { // Jackson XML mapper does not support deserializing collections or arrays. Use Json-In-Java to convert to JSON JSONObject jo = XML.toJSONObject(new InputStreamReader(stream, "UTF-8")); - doc = inputMapper.readTree(jo.toString()).get("Document"); + root = inputMapper.readTree(jo.toString()).get("Document"); } else { - doc = inputMapper.readTree(stream); + root = inputMapper.readTree(stream); } - if (Objects.isNull(doc)) { + if (Objects.isNull(root)) { throw new InvalidSPDXAnalysisException("Missing SPDX Document"); } - JsonNode namespaceNode = doc.get(SpdxConstants.PROP_DOCUMENT_NAMESPACE); - if (Objects.isNull(namespaceNode)) { - throw new InvalidSPDXAnalysisException("Missing document namespace"); + List documentNamespaces = new ArrayList<>(); + if (root instanceof ArrayNode) { + for (JsonNode docNode:(ArrayNode)root) { + documentNamespaces.add(getNamespaceFromDoc(docNode)); + } + } else { + documentNamespaces.add(getNamespaceFromDoc(root)); } - String documentNamespace = namespaceNode.asText(); - if (Objects.isNull(documentNamespace) || documentNamespace.isEmpty()) { - throw new InvalidSPDXAnalysisException("Empty document namespace"); + + Set existingDocNamespaces = this.getDocumentUris(); + boolean existing = false; + for (String docNamespace:documentNamespaces) { + if (existingDocNamespaces.contains(docNamespace)) { + existing = true; + break; + } } - if (this.getDocumentUris().contains(documentNamespace)) { - IModelStoreLock lock = this.enterCriticalSection(documentNamespace, false); + if (existing) { + IModelStoreLock lock = this.enterCriticalSection(false); try { if (!overwrite) { - throw new InvalidSPDXAnalysisException("Document namespace "+documentNamespace+" already exists."); + throw new InvalidSPDXAnalysisException("Document namespace(s) already exists."); + } + for (String docNamespace:documentNamespaces) { + if (existingDocNamespaces.contains(docNamespace)) { + this.clear(docNamespace); + } } - this.clear(documentNamespace); } finally { this.leaveCriticalSection(lock); } } JacksonDeSerializer deSerializer = new JacksonDeSerializer(this, format); - deSerializer.storeDocument(documentNamespace, doc); + String docNamespace; + if (root instanceof ArrayNode) { + for (JsonNode doc:(ArrayNode)root) { + deSerializer.storeDocument(getNamespaceFromDoc(doc), doc); + } + docNamespace = getNamespaceFromDoc((ArrayNode)root.get(0)); + } else { + deSerializer.storeDocument(getNamespaceFromDoc(root), root); + docNamespace = getNamespaceFromDoc(root); + } + return (SpdxDocument)SpdxModelFactory.inflateModelObject(this, docNamespace + "#" + SpdxConstantsCompatV2.SPDX_DOCUMENT_ID, + SpdxConstantsCompatV2.CLASS_SPDX_DOCUMENT, new ModelCopyManager(), + SpdxConstantsCompatV2.SPEC_TWO_POINT_THREE_VERSION, false, docNamespace); + } + + /** + * Get the document namespace from the JSON node representing the SPDX document + * @param docNode root of the SPDX document + * @throws InvalidSPDXAnalysisException on missing document namespace + */ + private String getNamespaceFromDoc(JsonNode docNode) throws InvalidSPDXAnalysisException { + JsonNode namespaceNode = docNode.get(SpdxConstantsCompatV2.PROP_DOCUMENT_NAMESPACE.getName()); + if (Objects.isNull(namespaceNode)) { + throw new InvalidSPDXAnalysisException("Missing document namespace"); + } + String documentNamespace = namespaceNode.asText(); + if (Objects.isNull(documentNamespace) || documentNamespace.isEmpty()) { + throw new InvalidSPDXAnalysisException("Empty document namespace"); + } return documentNamespace; + } + /** + * @param documentNamespace + * @throws InvalidSPDXAnalysisException + */ + public void clear(String documentNamespace) throws InvalidSPDXAnalysisException { + List valuesToDelete = this.getAllItems(documentNamespace, null).collect(Collectors.toList()); + for (TypedValue valueToDelete:valuesToDelete) { + this.delete(valueToDelete.getObjectUri()); + } + } + + /** + * @return list of SPDX V2 document URI's in this model store + * @throws InvalidSPDXAnalysisException + */ + public Set getDocumentUris() throws InvalidSPDXAnalysisException { + Set retval = new HashSet<>(); + this.getAllItems(null, null).forEach(tv -> { + if (tv.getObjectUri().contains("#")) { + retval.add(tv.getObjectUri().substring(0, tv.getObjectUri().indexOf('#'))); + } + }); + return retval; } } \ No newline at end of file diff --git a/src/main/java/org/spdx/jacksonstore/PropertyComparator.java b/src/main/java/org/spdx/jacksonstore/PropertyComparator.java index e9b6514..6e3ab1c 100644 --- a/src/main/java/org/spdx/jacksonstore/PropertyComparator.java +++ b/src/main/java/org/spdx/jacksonstore/PropertyComparator.java @@ -26,7 +26,7 @@ import java.util.Map; import java.util.Objects; -import org.spdx.library.SpdxConstants; +import org.spdx.library.model.v2.SpdxConstantsCompatV2; /** * Comparator for property names for different SPDX class types @@ -40,25 +40,25 @@ public class PropertyComparator implements Comparator { static final List DOCUMENT_PROPERTY_ORDER = Arrays.asList(new String[] { - SpdxConstants.PROP_DOCUMENT_NAMESPACE, - SpdxConstants.PROP_SPDX_SPEC_VERSION, - SpdxConstants.PROP_SPDX_CREATION_INFO, - SpdxConstants.PROP_NAME, - SpdxConstants.PROP_SPDX_DATA_LICENSE, - SpdxConstants.RDFS_PROP_COMMENT, - SpdxConstants.PROP_SPDX_EXTERNAL_DOC_REF, - SpdxConstants.PROP_DOCUMENT_DESCRIBES, - SpdxConstants.PROP_DOCUMENT_PACKAGES, - SpdxConstants.PROP_DOCUMENT_FILES, - SpdxConstants.PROP_DOCUMENT_SNIPPETS, - SpdxConstants.PROP_SPDX_EXTRACTED_LICENSES, - SpdxConstants.PROP_ANNOTATION, - SpdxConstants.PROP_DOCUMENT_RELATIONSHIPS + SpdxConstantsCompatV2.PROP_DOCUMENT_NAMESPACE.getName(), + SpdxConstantsCompatV2.PROP_SPDX_SPEC_VERSION.getName(), + SpdxConstantsCompatV2.PROP_SPDX_CREATION_INFO.getName(), + SpdxConstantsCompatV2.PROP_NAME.getName(), + SpdxConstantsCompatV2.PROP_SPDX_DATA_LICENSE.getName(), + SpdxConstantsCompatV2.RDFS_PROP_COMMENT.getName(), + SpdxConstantsCompatV2.PROP_SPDX_EXTERNAL_DOC_REF.getName(), + SpdxConstantsCompatV2.PROP_DOCUMENT_DESCRIBES.getName(), + SpdxConstantsCompatV2.PROP_DOCUMENT_PACKAGES.getName(), + SpdxConstantsCompatV2.PROP_DOCUMENT_FILES.getName(), + SpdxConstantsCompatV2.PROP_DOCUMENT_SNIPPETS.getName(), + SpdxConstantsCompatV2.PROP_SPDX_EXTRACTED_LICENSES.getName(), + SpdxConstantsCompatV2.PROP_ANNOTATION.getName(), + SpdxConstantsCompatV2.PROP_DOCUMENT_RELATIONSHIPS.getName() }); static final Map> propertyOrderMap; static { HashMap> hm = new HashMap<>(); - hm.put(SpdxConstants.CLASS_SPDX_DOCUMENT, DOCUMENT_PROPERTY_ORDER); + hm.put(SpdxConstantsCompatV2.CLASS_SPDX_DOCUMENT, DOCUMENT_PROPERTY_ORDER); propertyOrderMap = Collections.unmodifiableMap(hm); } private List propertyOrder; diff --git a/src/main/java/org/spdx/jacksonstore/SpdxJsonLDContext.java b/src/main/java/org/spdx/jacksonstore/SpdxJsonLDContext.java index 89df7da..8f6096d 100644 --- a/src/main/java/org/spdx/jacksonstore/SpdxJsonLDContext.java +++ b/src/main/java/org/spdx/jacksonstore/SpdxJsonLDContext.java @@ -28,7 +28,7 @@ import java.util.Optional; import java.util.Set; -import org.spdx.library.InvalidSPDXAnalysisException; +import org.spdx.core.InvalidSPDXAnalysisException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; diff --git a/src/test/java/org/spdx/jacksonstore/MultiFormatStoreTest.java b/src/test/java/org/spdx/jacksonstore/MultiFormatStoreTest.java index 8378d0d..d9b3335 100644 --- a/src/test/java/org/spdx/jacksonstore/MultiFormatStoreTest.java +++ b/src/test/java/org/spdx/jacksonstore/MultiFormatStoreTest.java @@ -35,26 +35,31 @@ import java.util.List; import java.util.Objects; import java.util.Optional; +import java.util.stream.Collectors; +import org.spdx.core.DefaultModelStore; +import org.spdx.core.InvalidSPDXAnalysisException; +import org.spdx.core.ModelRegistry; import org.spdx.jacksonstore.MultiFormatStore.Format; import org.spdx.jacksonstore.MultiFormatStore.Verbose; -import org.spdx.library.InvalidSPDXAnalysisException; +import org.spdx.library.LicenseInfoFactory; import org.spdx.library.ModelCopyManager; -import org.spdx.library.SpdxConstants; -import org.spdx.library.Version; -import org.spdx.library.model.Checksum; -import org.spdx.library.model.Relationship; -import org.spdx.library.model.SpdxDocument; -import org.spdx.library.model.SpdxElement; -import org.spdx.library.model.SpdxFile; -import org.spdx.library.model.SpdxModelFactory; -import org.spdx.library.model.SpdxPackage; -import org.spdx.library.model.enumerations.ChecksumAlgorithm; -import org.spdx.library.model.enumerations.Purpose; -import org.spdx.library.model.enumerations.RelationshipType; -import org.spdx.library.model.license.AnyLicenseInfo; -import org.spdx.library.model.license.LicenseInfoFactory; -import org.spdx.library.model.license.SpdxNoAssertionLicense; +import org.spdx.library.model.v2.Checksum; +import org.spdx.library.model.v2.Relationship; +import org.spdx.library.model.v2.SpdxConstantsCompatV2; +import org.spdx.library.model.v2.SpdxDocument; +import org.spdx.library.model.v2.SpdxElement; +import org.spdx.library.model.v2.SpdxFile; +import org.spdx.library.model.v2.SpdxModelFactoryCompatV2; +import org.spdx.library.model.v2.SpdxModelInfoV2_X; +import org.spdx.library.model.v2.SpdxPackage; +import org.spdx.library.model.v2.Version; +import org.spdx.library.model.v2.enumerations.ChecksumAlgorithm; +import org.spdx.library.model.v2.enumerations.Purpose; +import org.spdx.library.model.v2.enumerations.RelationshipType; +import org.spdx.library.model.v2.license.AnyLicenseInfo; +import org.spdx.library.model.v2.license.SpdxNoAssertionLicense; +import org.spdx.library.model.v3_0_1.SpdxModelInfoV3_0; import org.spdx.storage.IModelStore; import org.spdx.storage.ISerializableModelStore; import org.spdx.storage.simple.InMemSpdxStore; @@ -93,6 +98,9 @@ public class MultiFormatStoreTest extends TestCase { */ protected void setUp() throws Exception { super.setUp(); + ModelRegistry.getModelRegistry().registerModel(new SpdxModelInfoV2_X()); + ModelRegistry.getModelRegistry().registerModel(new SpdxModelInfoV3_0()); + DefaultModelStore.initialize(new InMemSpdxStore(), "http://test/doc", new ModelCopyManager()); } /* (non-Javadoc) @@ -111,11 +119,12 @@ protected void tearDown() throws Exception { public void testDeSerializeSerializeJson() throws InvalidSPDXAnalysisException, IOException, SpdxCompareException { File jsonFile = new File(JSON_FILE_PATH); MultiFormatStore inputStore = new MultiFormatStore(new InMemSpdxStore(), Format.JSON_PRETTY); + SpdxDocument inputDocument; try (InputStream input = new FileInputStream(jsonFile)) { - inputStore.deSerialize(input, false); + inputDocument = inputStore.deSerialize(input, false); } - String documentUri = inputStore.getDocumentUris().get(0); - SpdxDocument inputDocument = new SpdxDocument(inputStore, documentUri, null, false); + String documentUri = inputStore.getDocumentUris().toArray(new String[inputStore.getDocumentUris().size()])[0]; + assertEquals(documentUri, inputDocument.getDocumentUri()); List verify = inputDocument.verify(); assertEquals(0, verify.size()); // test Overwrite @@ -129,7 +138,7 @@ public void testDeSerializeSerializeJson() throws InvalidSPDXAnalysisException, } // Deserialize ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - inputStore.serialize(documentUri, outputStream); + inputStore.serialize(outputStream); ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray()); MultiFormatStore outputStore = new MultiFormatStore(new InMemSpdxStore(), Format.JSON_PRETTY); outputStore.deSerialize(inputStream, false); @@ -153,7 +162,7 @@ public void testDeserialize2point3Fields() throws InvalidSPDXAnalysisException, try (InputStream input = new FileInputStream(jsonFile)) { inputStore.deSerialize(input, false); } - String documentUri = inputStore.getDocumentUris().get(0); + String documentUri = inputStore.getDocumentUris().toArray(new String[inputStore.getDocumentUris().size()])[0]; SpdxDocument inputDocument = new SpdxDocument(inputStore, documentUri, null, false); List verify = inputDocument.verify(); assertEquals(0, verify.size()); @@ -212,7 +221,7 @@ public void testDeSerializeSerializeYaml() throws InvalidSPDXAnalysisException, try (InputStream input = new FileInputStream(jsonFile)) { inputStore.deSerialize(input, false); } - String documentUri = inputStore.getDocumentUris().get(0); + String documentUri = inputStore.getDocumentUris().toArray(new String[inputStore.getDocumentUris().size()])[0]; SpdxDocument inputDocument = new SpdxDocument(inputStore, documentUri, null, false); List verify = inputDocument.verify(); assertEquals(0, verify.size()); @@ -220,7 +229,7 @@ public void testDeSerializeSerializeYaml() throws InvalidSPDXAnalysisException, // Deserialize ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); inputStore.setFormat(Format.YAML); - inputStore.serialize(documentUri, outputStream); + inputStore.serialize(outputStream); ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray()); MultiFormatStore outputStore = new MultiFormatStore(new InMemSpdxStore(), Format.YAML); outputStore.deSerialize(inputStream, false); @@ -244,7 +253,7 @@ public void testDeSerializeSerializeXml() throws InvalidSPDXAnalysisException, I try (InputStream input = new FileInputStream(jsonFile)) { inputStore.deSerialize(input, false); } - String documentUri = inputStore.getDocumentUris().get(0); + String documentUri = inputStore.getDocumentUris().toArray(new String[inputStore.getDocumentUris().size()])[0]; SpdxDocument inputDocument = new SpdxDocument(inputStore, documentUri, null, false); List verify = inputDocument.verify(); assertEquals(0, verify.size()); @@ -252,7 +261,7 @@ public void testDeSerializeSerializeXml() throws InvalidSPDXAnalysisException, I // Deserialize ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); inputStore.setFormat(Format.XML); - inputStore.serialize(documentUri, outputStream); + inputStore.serialize(outputStream); @SuppressWarnings("unused") String temp = new String(outputStream.toByteArray()); ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray()); @@ -291,7 +300,7 @@ public void testDuplicates() throws FileNotFoundException, IOException, InvalidS try (InputStream input = new FileInputStream(jsonFile)) { inputStore.deSerialize(input, false); } - String documentUri = inputStore.getDocumentUris().get(0); + String documentUri = inputStore.getDocumentUris().toArray(new String[inputStore.getDocumentUris().size()])[0]; SpdxDocument inputDocument = new SpdxDocument(inputStore, documentUri, null, false); List verify = inputDocument.verify(); assertEquals(0, verify.size()); @@ -320,7 +329,7 @@ public void testNoHasFiles() throws FileNotFoundException, IOException, InvalidS try (InputStream input = new FileInputStream(jsonFile)) { inputStore.deSerialize(input, false); } - String documentUri = inputStore.getDocumentUris().get(0); + String documentUri = inputStore.getDocumentUris().toArray(new String[inputStore.getDocumentUris().size()])[0]; SpdxDocument inputDocument = new SpdxDocument(inputStore, documentUri, null, false); List verify = inputDocument.verify(); assertEquals(0, verify.size()); @@ -352,11 +361,11 @@ public void testRelationshipComment() throws InvalidSPDXAnalysisException, IOExc String documentUri = "https://someuri"; ModelCopyManager copyManager = new ModelCopyManager(); ISerializableModelStore modelStore = new MultiFormatStore(new InMemSpdxStore(), MultiFormatStore.Format.JSON_PRETTY); - SpdxDocument document = SpdxModelFactory.createSpdxDocument(modelStore, documentUri, copyManager); + SpdxDocument document = SpdxModelFactoryCompatV2.createSpdxDocumentV2(modelStore, documentUri, copyManager); document.setSpecVersion(Version.TWO_POINT_THREE_VERSION); document.setName("SPDX-tool-test"); Checksum sha1Checksum = Checksum.create(modelStore, documentUri, ChecksumAlgorithm.SHA1, "d6a770ba38583ed4bb4525bd96e50461655d2758"); - AnyLicenseInfo concludedLicense = LicenseInfoFactory.parseSPDXLicenseString("LGPL-2.0-only OR LicenseRef-2"); + AnyLicenseInfo concludedLicense = LicenseInfoFactory.parseSPDXLicenseStringCompatV2("LGPL-2.0-only OR LicenseRef-2"); SpdxFile fileA = document.createSpdxFile("SPDXRef-fileA", "./package/fileA.c", concludedLicense, Arrays.asList(new AnyLicenseInfo[0]), "Copyright 2008-2010 John Smith", sha1Checksum) .build(); @@ -380,13 +389,16 @@ public void testRelationshipComment() throws InvalidSPDXAnalysisException, IOExc assertTrue(serFile.createNewFile()); try { try (OutputStream stream = new FileOutputStream(serFile)) { - modelStore.serialize(documentUri, stream); + modelStore.serialize(stream); } ISerializableModelStore resultStore = new MultiFormatStore(new InMemSpdxStore(), MultiFormatStore.Format.JSON); try (InputStream inStream = new FileInputStream(serFile)) { - assertEquals(documentUri, resultStore.deSerialize(inStream, false)); + resultStore.deSerialize(inStream, false); + List restoredDocUris = getDocUris(resultStore); + assertEquals(1, restoredDocUris.size()); + assertEquals(documentUri, restoredDocUris.get(0)); } - document = SpdxModelFactory.createSpdxDocument(resultStore, documentUri, copyManager); + document = SpdxModelFactoryCompatV2.createSpdxDocumentV2(resultStore, documentUri, copyManager); docrels = document.getRelationships(); assertEquals(1, docrels.size()); for (Relationship rel:docrels) { @@ -416,7 +428,7 @@ public void testRelationshipComment() throws InvalidSPDXAnalysisException, IOExc assertEquals("SPDXRef-DOCUMENT", relationshipNode.get("spdxElementId").asText()); assertEquals(fileA.getId(), relationshipNode.get("relatedSpdxElement").asText()); assertEquals(RelationshipType.CONTAINS.toString(), relationshipNode.get("relationshipType").asText()); - assertEquals(relationshipComment, relationshipNode.get(SpdxConstants.RDFS_PROP_COMMENT).asText()); + assertEquals(relationshipComment, relationshipNode.get(SpdxConstantsCompatV2.RDFS_PROP_COMMENT.getName()).asText()); } assertEquals(1, count); @@ -439,11 +451,11 @@ public void testDocumentDescribes() throws InvalidSPDXAnalysisException, IOExcep String documentUri = "https://someuri"; ModelCopyManager copyManager = new ModelCopyManager(); ISerializableModelStore modelStore = new MultiFormatStore(new InMemSpdxStore(), MultiFormatStore.Format.JSON_PRETTY); - SpdxDocument document = SpdxModelFactory.createSpdxDocument(modelStore, documentUri, copyManager); + SpdxDocument document = SpdxModelFactoryCompatV2.createSpdxDocumentV2(modelStore, documentUri, copyManager); document.setSpecVersion(Version.TWO_POINT_THREE_VERSION); document.setName("SPDX-tool-test"); Checksum sha1Checksum = Checksum.create(modelStore, documentUri, ChecksumAlgorithm.SHA1, "d6a770ba38583ed4bb4525bd96e50461655d2758"); - AnyLicenseInfo concludedLicense = LicenseInfoFactory.parseSPDXLicenseString("LGPL-2.0-only OR LicenseRef-2"); + AnyLicenseInfo concludedLicense = LicenseInfoFactory.parseSPDXLicenseStringCompatV2("LGPL-2.0-only OR LicenseRef-2"); SpdxFile fileA = document.createSpdxFile("SPDXRef-fileA", "./package/fileA.c", concludedLicense, Arrays.asList(new AnyLicenseInfo[0]), "Copyright 2008-2010 John Smith", sha1Checksum) .build(); @@ -477,13 +489,16 @@ public void testDocumentDescribes() throws InvalidSPDXAnalysisException, IOExcep assertTrue(serFile.createNewFile()); try { try (OutputStream stream = new FileOutputStream(serFile)) { - modelStore.serialize(documentUri, stream); + modelStore.serialize(stream); } ISerializableModelStore resultStore = new MultiFormatStore(new InMemSpdxStore(), MultiFormatStore.Format.JSON); try (InputStream inStream = new FileInputStream(serFile)) { - assertEquals(documentUri, resultStore.deSerialize(inStream, false)); + resultStore.deSerialize(inStream, false); + List restoredDocUris = getDocUris(resultStore); + assertEquals(1, restoredDocUris.size()); + assertEquals(documentUri, restoredDocUris.get(0)); } - document = SpdxModelFactory.createSpdxDocument(resultStore, documentUri, copyManager); + document = SpdxModelFactoryCompatV2.createSpdxDocumentV2(resultStore, documentUri, copyManager); assertEquals(2, document.getDocumentDescribes().size()); assertTrue(document.getDocumentDescribes().contains(fileA)); assertTrue(document.getDocumentDescribes().contains(fileB)); @@ -530,11 +545,11 @@ public void testhasFiles() throws InvalidSPDXAnalysisException, IOException { String documentUri = "https://someuri"; ModelCopyManager copyManager = new ModelCopyManager(); ISerializableModelStore modelStore = new MultiFormatStore(new InMemSpdxStore(), MultiFormatStore.Format.JSON_PRETTY); - SpdxDocument document = SpdxModelFactory.createSpdxDocument(modelStore, documentUri, copyManager); + SpdxDocument document = SpdxModelFactoryCompatV2.createSpdxDocumentV2(modelStore, documentUri, copyManager); document.setSpecVersion(Version.TWO_POINT_THREE_VERSION); document.setName("SPDX-tool-test"); Checksum sha1Checksum = Checksum.create(modelStore, documentUri, ChecksumAlgorithm.SHA1, "d6a770ba38583ed4bb4525bd96e50461655d2758"); - AnyLicenseInfo concludedLicense = LicenseInfoFactory.parseSPDXLicenseString("LGPL-2.0-only OR LicenseRef-2"); + AnyLicenseInfo concludedLicense = LicenseInfoFactory.parseSPDXLicenseStringCompatV2("LGPL-2.0-only OR LicenseRef-2"); SpdxFile fileA = document.createSpdxFile("SPDXRef-fileA", "./package/fileA.c", concludedLicense, Arrays.asList(new AnyLicenseInfo[0]), "Copyright 2008-2010 John Smith", sha1Checksum) .build(); @@ -574,13 +589,16 @@ public void testhasFiles() throws InvalidSPDXAnalysisException, IOException { assertTrue(serFile.createNewFile()); try { try (OutputStream stream = new FileOutputStream(serFile)) { - modelStore.serialize(documentUri, stream); + modelStore.serialize(stream); } ISerializableModelStore resultStore = new MultiFormatStore(new InMemSpdxStore(), MultiFormatStore.Format.JSON); try (InputStream inStream = new FileInputStream(serFile)) { - assertEquals(documentUri, resultStore.deSerialize(inStream, false)); + resultStore.deSerialize(inStream, false); + List restoredDocUris = getDocUris(resultStore); + assertEquals(1, restoredDocUris.size()); + assertEquals(documentUri, restoredDocUris.get(0)); } - document = SpdxModelFactory.createSpdxDocument(resultStore, documentUri, copyManager); + document = SpdxModelFactoryCompatV2.createSpdxDocumentV2(resultStore, documentUri, copyManager); pkg = (SpdxPackage)document.getDocumentDescribes().toArray(new SpdxElement[1])[0]; assertEquals(2, pkg.getFiles().size()); @@ -628,7 +646,7 @@ public void testDeSerializeXml_singleRelationship() throws InvalidSPDXAnalysisEx try (InputStream in = new BufferedInputStream(Files.newInputStream(xmlFile.toPath()))) { inputStore.deSerialize(in, false); } - String documentUri = inputStore.getDocumentUris().get(0); + String documentUri = inputStore.getDocumentUris().toArray(new String[inputStore.getDocumentUris().size()])[0]; SpdxDocument inputDocument = new SpdxDocument(inputStore, documentUri, null, false); List verify = inputDocument.verify(); assertEquals(0, verify.size()); @@ -647,10 +665,10 @@ public void testSerializeJson() throws InvalidSPDXAnalysisException, IOException try (InputStream input = new FileInputStream(jsonFile)) { inputStore.deSerialize(input, false); } - String documentUri = inputStore.getDocumentUris().get(0); + String documentUri = inputStore.getDocumentUris().toArray(new String[inputStore.getDocumentUris().size()])[0]; SpdxDocument inputDocument = new SpdxDocument(inputStore, documentUri, null, false); // Add a purpose of operating system to make sure the underscore is preserved - SpdxPackage pkg = inputDocument.createPackage(SpdxConstants.SPDX_ELEMENT_REF_PRENUM + "-purpose", + SpdxPackage pkg = inputDocument.createPackage(SpdxConstantsCompatV2.SPDX_ELEMENT_REF_PRENUM + "-purpose", "Package with a Purpose", new SpdxNoAssertionLicense(), "NoAssertion", new SpdxNoAssertionLicense()) .setPrimaryPurpose(Purpose.OPERATING_SYSTEM) @@ -666,13 +684,16 @@ public void testSerializeJson() throws InvalidSPDXAnalysisException, IOException assertTrue(serFile.createNewFile()); try { try (OutputStream stream = new FileOutputStream(serFile)) { - inputStore.serialize(documentUri, stream); + inputStore.serialize(stream); } ISerializableModelStore resultStore = new MultiFormatStore(new InMemSpdxStore(), MultiFormatStore.Format.JSON); try (InputStream inStream = new FileInputStream(serFile)) { - assertEquals(documentUri, resultStore.deSerialize(inStream, false)); + resultStore.deSerialize(inStream, false); + List restoredDocUris = getDocUris(resultStore); + assertEquals(1, restoredDocUris.size()); + assertEquals(documentUri, restoredDocUris.get(0)); } - SpdxDocument resultDoc = SpdxModelFactory.createSpdxDocument(resultStore, documentUri, new ModelCopyManager()); + SpdxDocument resultDoc = SpdxModelFactoryCompatV2.createSpdxDocumentV2(resultStore, documentUri, new ModelCopyManager()); verify = resultDoc.verify(); assertEquals(0, verify.size()); // validate schema file @@ -688,4 +709,15 @@ public void testSerializeJson() throws InvalidSPDXAnalysisException, IOException tempDirPath.toFile().delete(); } } + + /** + * @param resultStore + * @return + * @throws InvalidSPDXAnalysisException + */ + private List getDocUris(ISerializableModelStore resultStore) throws InvalidSPDXAnalysisException { + return resultStore.getAllItems(null, SpdxConstantsCompatV2.CLASS_SPDX_DOCUMENT) + .map(tv -> tv.getObjectUri().substring(0, tv.getObjectUri().indexOf('#'))) + .collect(Collectors.toList()); + } }