Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/**
* Copyright (c) 2020 Source Auditor Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.spdx.jacksonstore;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.SpdxEnumFactory;
import org.spdx.library.model.license.AnyLicenseInfo;
import org.spdx.storage.IModelStore;
import org.spdx.storage.IModelStore.IModelStoreLock;
import org.spdx.storage.IModelStore.IdType;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
/**
* Serializer for a model store to convert the document model object into a JsonNode
*
* the method docToJsonNode(String documentUri) will generate the JSON node
* @author Gary O'Neall
*
*/
public class JacksonSerializer {
static final Logger logger = LoggerFactory.getLogger(JacksonSerializer.class);
/**
* Class to for the name of the XML element to Document
*
*/
class Document extends ObjectNode {
public Document(JsonNodeFactory nc) {
super(nc);
}
}
private ObjectMapper mapper;
private IModelStore store;
private Format format;
private Verbose verbose;
/**
* @param mapper Jackson Object Mapper to use for creating JSON objects
* @param format Format to use
* @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");
this.mapper = mapper;
this.store = store;
this.format = format;
this.verbose = verbose;
}
/**
* @param documentUri URI for the document to be converted
* @return ObjectNode for an SPDX document in Jackson JSON tree format
* @throws InvalidSPDXAnalysisException
*/
public ObjectNode docToJsonNode(String documentUri) throws InvalidSPDXAnalysisException {
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);
ArrayNode relationships = mapper.createArrayNode();
ObjectNode doc = typedValueToObjectNode(documentUri, document, relationships);
doc.put(SpdxConstants.PROP_DOCUMENT_NAMESPACE, documentUri);
ArrayNode documentDescribes = getDocumentDescribes(relationships);
doc.set(SpdxConstants.PROP_DOCUMENT_DESCRIBES, documentDescribes);
ArrayNode packages = getDocElements(documentUri, SpdxConstants.CLASS_SPDX_PACKAGE, relationships);
if (packages.size() > 0) {
doc.set(SpdxConstants.PROP_DOCUMENT_PACKAGES, packages);
}
ArrayNode files = getDocElements(documentUri, SpdxConstants.CLASS_SPDX_FILE, relationships);
if (files.size() > 0) {
doc.set(SpdxConstants.PROP_DOCUMENT_FILES, files);
}
ArrayNode snippets = getDocElements(documentUri, SpdxConstants.CLASS_SPDX_SNIPPET, relationships);
if (snippets.size() > 0) {
doc.set(SpdxConstants.PROP_DOCUMENT_SNIPPETS, snippets);
}
//TODO: Remove duplicate relationships
doc.set(SpdxConstants.PROP_DOCUMENT_RELATIONSHIPS, relationships);
ObjectNode output;
switch (format) {
case YAML: {
output = doc;
break;
}
case XML: {
output = new Document(JsonNodeFactory.instance);
output.setAll(doc);
break;
}
case JSON: {
output = doc;
break;
}
case JSON_PRETTY:
default: {
output = doc;
break;
}
}
return output;
} finally {
store.leaveCriticalSection(lock);
}
}
/**
* Convert a typed value into an ObjectNode adding all stored properties
* @param documentUri Document namespace or Uri
* @param storedItem stored value to convert to a JSON serializable form
* @param relationships ArrayNode of relationships to add any found relationships
* @return ObjectNode with all fields added from the stored typedValue
* @throws InvalidSPDXAnalysisException
*/
private ObjectNode typedValueToObjectNode(String documentUri, TypedValue storedItem, ArrayNode relationships) throws InvalidSPDXAnalysisException {
ObjectNode retval = mapper.createObjectNode();
List docPropNames = new ArrayList(store.getPropertyValueNames(documentUri, storedItem.getId()));
docPropNames.sort(new PropertyComparator(storedItem.getType()));
//TODO - do we sort for all types or just for the document level?
Class> clazz = SpdxModelFactory.SPDX_TYPE_TO_CLASS.get(storedItem.getType());
if (SpdxElement.class.isAssignableFrom(clazz) &&
IdType.SpdxId.equals(store.getIdType(storedItem.getId()))) {
retval.put(SpdxConstants.SPDX_IDENTIFIER, storedItem.getId());
}
if (ExternalDocumentRef.class.isAssignableFrom(clazz)) {
retval.put(SpdxConstants.EXTERNAL_DOCUMENT_REF_IDENTIFIER, storedItem.getId());
}
for (String propertyName:docPropNames) {
if (SpdxConstants.PROP_RELATIONSHIP.equals(propertyName)) {
for (ObjectNode relationship:toJsonRelationships(documentUri, storedItem.getId(), store.listValues(documentUri, storedItem.getId(), SpdxConstants.PROP_RELATIONSHIP))) {
relationships.add(relationship);
}
} else if (SpdxConstants.PROP_SPDX_EXTRACTED_LICENSES.equals(propertyName)) {
retval.set(MultiFormatStore.propertyNameToCollectionPropertyName(propertyName),
toExtractedLicensesArrayNode(documentUri, storedItem.getId(), propertyName, relationships));
} else if (store.isCollectionProperty(documentUri, storedItem.getId(), propertyName)) {
ArrayNode valuesArray = toArrayNode(documentUri, store.listValues(documentUri, storedItem.getId(), propertyName),
relationships);
retval.set(MultiFormatStore.propertyNameToCollectionPropertyName(propertyName),
valuesArray);
} else {
Optional