Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
13ee184
upgrade to latest generated java model and adding toString method
sebbader-sap Jun 16, 2023
d868f19
Update dataformat-aasx project
emildinchev Jun 27, 2023
f339157
Update dataformat-core
emildinchev Jun 27, 2023
c62e54d
Update dataformat-core project
emildinchev Jun 29, 2023
ddc62e2
Update dataformat-json project
emildinchev Jun 29, 2023
2bdb3bb
Create dataformat-rdf project
emildinchev Jun 29, 2023
3037e71
Update dataformat-xml project
emildinchev Jun 29, 2023
7e1b1c4
Update model project
emildinchev Jun 29, 2023
61258fa
Update model project
emildinchev Jun 30, 2023
534bbec
Update model project
emildinchev Jun 30, 2023
78c8cc3
Revert the changed files
emildinchev Jul 3, 2023
f44bd1a
Remove dataformat-rdf project
emildinchev Jul 3, 2023
a30a902
fix compile errors
sebbader-sap Jul 3, 2023
93a10e1
Merge branch 'generated-v3-part2' of https://github.com/sap-contribut…
sebbader-sap Jul 3, 2023
651a383
fix compile errors
sebbader-sap Jul 3, 2023
c50a4ac
Adapt the copyright notice
emildinchev Jul 3, 2023
4dcdcda
Adapt the copyright notice
emildinchev Jul 3, 2023
8471132
add next iteration of generated part 1 classes
sebbader-sap Jul 3, 2023
2ca2599
Merge branch 'generated-v3-part2' of https://github.com/sap-contribut…
sebbader-sap Jul 3, 2023
49e6e23
Fix the tests in dataformat-core
emildinchev Jul 4, 2023
3678a6e
Fix the compilation errors in XML-Serializer Project
emildinchev Jul 4, 2023
b1ddf4b
Fix Some XML Serialization Tests
emildinchev Jul 4, 2023
1d8e192
Fix some XML Serialization Tests
emildinchev Jul 4, 2023
30ee673
Fix the dataformat-xml project
emildinchev Jul 5, 2023
18decbf
Fix the dataformat-json project
emildinchev Jul 6, 2023
b0c17e6
Adapt the mixins
emildinchev Jul 7, 2023
6326dae
Revert some changes in the comments
emildinchev Jul 7, 2023
74811fb
Adapt dataformat-core
emildinchev Jul 7, 2023
382fd3d
Adapt dataformat-json project
emildinchev Jul 7, 2023
5c7bff0
Update PropertyMixin.java
emildinchev Jul 7, 2023
32df45a
Merge pull request #1 from sap-contributions/generated-v3-part2
emildinchev Jul 11, 2023
e5184d4
Create ValueOnlyJsonSerializer
emildinchev Jul 13, 2023
30dfca8
Implement the value-only serialization
emildinchev Jul 17, 2023
836e7ca
Add unit tests for value-only serialization.
emildinchev Jul 17, 2023
7d547d9
Add unit tests for value-only serialization
emildinchev Jul 17, 2023
83e867f
Add a copyright header
emildinchev Jul 18, 2023
ca4165b
Add more tests
emildinchev Jul 18, 2023
1e2f37a
Correct the documentation to make it conformable with maven-javadoc-p…
emildinchev Jul 19, 2023
7ee8ca3
Add methods for valueOnly deserialization
emildinchev Jul 19, 2023
27f34cb
Rename the serializer classes to mappers, as they will be used for th…
emildinchev Jul 19, 2023
adb7040
Extract the method createMapper
emildinchev Jul 19, 2023
41609d2
Revert the changes in the JsonSerializer
emildinchev Jul 19, 2023
e06ebe9
Implement the deserialization
emildinchev Jul 20, 2023
ece1a16
Add some more test data
emildinchev Jul 20, 2023
1ae7ca8
Add unit tests for the update
emildinchev Jul 20, 2023
3499b69
Refactor the unit tests
emildinchev Jul 20, 2023
78e63f3
Fix the test
emildinchev Jul 20, 2023
4b9b34d
Remove unused imports
emildinchev Jul 20, 2023
27f96eb
Update the ValueOnlySerializationException
emildinchev Jul 20, 2023
3960a99
Revert JsonSerializer
emildinchev Jul 20, 2023
8eac11b
Make the exception RuntimeException
emildinchev Jul 20, 2023
70fb63b
Hide the constants
emildinchev Jul 20, 2023
120ad8b
Make AnnotatedRelationshipMapper a subclass of RelationshipMapper
emildinchev Jul 20, 2023
b22b990
Correct the Javadoc
emildinchev Jul 20, 2023
f0ee90d
Update value-only test-files
arnoweiss Jul 21, 2023
809b857
Reduce the class visibility
emildinchev Jul 21, 2023
452375a
Change the methods visibility to package-private.
emildinchev Jul 21, 2023
43a1089
Merge pull request #4 from arnoweiss/feat-value-only-serialization
sebbader-sap Jul 24, 2023
497449e
split ValueOnlyMapper into JsonValueOnlySerialiser and JsonValueOnlyD…
sebbader-sap Jul 25, 2023
5d67f72
remove not applicable copyright headers
sebbader-sap Jul 25, 2023
ff6555b
fix code warnings in valueonly
sebbader-sap Jul 25, 2023
49e2e88
activate valueonly tests again
sebbader-sap Jul 25, 2023
3d36b1e
test: adopt unit tests (#6)
tschultebahrenberg-sap Aug 2, 2023
b135ba9
Delete unused interfaces
emildinchev Nov 13, 2023
5176972
Remove unused files
emildinchev Nov 13, 2023
2fa939e
Delete EmbeddedDataSpecificationDeserializer.java
emildinchev Nov 13, 2023
1976284
Delete EmbeddedDataSpecificationSerializer.java
emildinchev Nov 13, 2023
0f1ecfb
Delete unused classes
emildinchev Nov 13, 2023
4a37fe2
Delete unused classes
emildinchev Nov 13, 2023
ccaf4ee
Delete ReflectionAnnotationIntrospector.java
emildinchev Nov 13, 2023
4d57e8a
Delete modeltype package
emildinchev Nov 13, 2023
38349fe
Remove dataformat-rdf project
emildinchev Nov 14, 2023
e95526f
Update JsonDeserializer.java
emildinchev Nov 14, 2023
6999ae9
Fix build
emildinchev Apr 22, 2024
0f3a8ff
Delete pom.xml
emildinchev Apr 22, 2024
aac3d2d
Revert pom.xml
emildinchev Apr 22, 2024
67b97e1
Update pom.xml
emildinchev Apr 22, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
6 changes: 6 additions & 0 deletions dataformat-aasx/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.digitaltwin.aas4j</groupId>
<artifactId>dataformat-json</artifactId>
<version>1.0.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,37 +21,40 @@
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

import org.apache.commons.io.IOUtils;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
import org.apache.poi.openxml4j.opc.PackagingURIHelper;

import org.eclipse.digitaltwin.aas4j.v3.dataformat.DeserializationException;
import org.eclipse.digitaltwin.aas4j.v3.dataformat.aasx.internal.AASXUtils;
import org.eclipse.digitaltwin.aas4j.v3.dataformat.core.DeserializationException;
import org.eclipse.digitaltwin.aas4j.v3.dataformat.core.internal.visitor.AssetAdministrationShellElementWalkerVisitor;
import org.eclipse.digitaltwin.aas4j.v3.dataformat.json.JsonDeserializer;
import org.eclipse.digitaltwin.aas4j.v3.dataformat.xml.XmlDeserializer;
import org.eclipse.digitaltwin.aas4j.v3.model.Environment;
import org.eclipse.digitaltwin.aas4j.v3.model.File;
import org.eclipse.digitaltwin.aas4j.v3.model.Submodel;
import org.eclipse.digitaltwin.aas4j.v3.model.SubmodelElement;
import org.eclipse.digitaltwin.aas4j.v3.model.SubmodelElementCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* The AASX package converter converts a aasx package into a list of aas, a list
* of submodels a list of assets, a list of Concept descriptions
*/
public class AASXDeserializer {
private static Logger logger = LoggerFactory.getLogger(AASXDeserializer.class);

private static final String XML_TYPE = "http://www.admin-shell.io/aasx/relationships/aas-spec";
private static final String AASX_ORIGIN = "/aasx/aasx-origin";
// In an older version of AAS4J/AASX Package Explorer,
// the wrong namespace was used
private static final String AASPEC_RELTYPE_BACKWARDSCOMPATIBLE = "http://www.admin-shell.io/aasx/relationships/aas-spec";
private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;


private final XmlDeserializer deserializer;
private final XmlDeserializer xmlDeserializer;
private final JsonDeserializer jsonDeserializer;

private Environment environment;
private final OPCPackage aasxRoot;
Expand All @@ -65,20 +68,40 @@ public class AASXDeserializer {
*/
public AASXDeserializer(InputStream inputStream) throws InvalidFormatException, IOException {
aasxRoot = OPCPackage.open(inputStream);
this.deserializer = new XmlDeserializer();
this.xmlDeserializer = new XmlDeserializer();
this.jsonDeserializer = new JsonDeserializer();
}

/**
* Constructor for custom XML deserialization
*
* @param deserializer a custom deserializer used for deserializing the aas environment
* Constructor for custom deserialization
*
* @param xmlDeserializer a custom XML deserializer used for deserializing the aas environment
* @param inputStream an input stream to an aasx package that can be read with this instance
* @throws InvalidFormatException if aasx package format is invalid
* @throws IOException if creating input streams for aasx fails
*/
public AASXDeserializer(XmlDeserializer deserializer, InputStream inputStream) throws InvalidFormatException, IOException {
public AASXDeserializer(XmlDeserializer xmlDeserializer,
InputStream inputStream) throws InvalidFormatException, IOException {
aasxRoot = OPCPackage.open(inputStream);
this.deserializer = deserializer;
this.xmlDeserializer = xmlDeserializer;
this.jsonDeserializer = new JsonDeserializer();
}

/**
* Constructor for custom deserialization
*
* @param xmlDeserializer a custom XML deserializer used for deserializing the aas environment
* @param jsonDeserializer a custom JSON deserializer used for deserializing the aas environment
* @param inputStream an input stream to an aasx package that can be read with this instance
* @throws InvalidFormatException if aasx package format is invalid
* @throws IOException if creating input streams for aasx fails
*/
public AASXDeserializer(XmlDeserializer xmlDeserializer,
JsonDeserializer jsonDeserializer,
InputStream inputStream) throws InvalidFormatException, IOException {
aasxRoot = OPCPackage.open(inputStream);
this.xmlDeserializer = xmlDeserializer;
this.jsonDeserializer = jsonDeserializer;
}

/**
Expand All @@ -95,45 +118,141 @@ public Environment read() throws InvalidFormatException, IOException, Deserializ
if (environment != null) {
return environment;
}
environment = deserializer.read(getXMLResourceString(aasxRoot));
if (MetamodelContentType.XML.equals(getContentType())) {
environment = xmlDeserializer.read(getResourceString(aasxRoot));
}
if (MetamodelContentType.JSON.equals(getContentType())) {
environment = jsonDeserializer.read(getResourceString(aasxRoot), Environment.class);
}
return environment;
}

/**
* Currently XML and JSON are supported for deserializing.
* @return The content type of the metafile
* @throws InvalidFormatException if aasx package format is invalid
* @throws IOException if creating input streams for aasx fails
*/
protected MetamodelContentType getContentType() throws InvalidFormatException, IOException {
MetamodelContentType contentType;
PackagePart packagePart = getPackagePart(aasxRoot);
// We also check for the none official content types "test/xml" and "text/json", which are commonly used
switch (packagePart.getContentType()) {
case "text/xml":
case "application/xml":
contentType = MetamodelContentType.XML;
break;
case "text/json":
case "application/json":
contentType = MetamodelContentType.JSON;
break;
default:
throw new RuntimeException("The following content type is not supported: " + packagePart.getContentType());
}
return contentType;
}

/**
* Return the Content of the xml file in the aasx-package as String
*
*
* @deprecated This method will be replaced by the method {@link AASXDeserializer#getResourceString()}.
*
* @throws InvalidFormatException if aasx package format is invalid
* @throws IOException if creating input streams for aasx fails
*/
@Deprecated
public String getXMLResourceString() throws InvalidFormatException, IOException {
return getXMLResourceString(this.aasxRoot);
return getResourceString(this.aasxRoot);
}

private String getXMLResourceString(OPCPackage aasxPackage) throws InvalidFormatException, IOException {
// Get the "/aasx/aasx-origin" Part. It is Relationship source for the
// XML-Document
PackagePart originPart = aasxPackage.getPart(PackagingURIHelper.createPartName(AASX_ORIGIN));

// Get the Relation to the XML Document
PackageRelationshipCollection originRelationships = originPart.getRelationshipsByType(XML_TYPE);
/**
* Return the Content of the xml or json file in the aasx-package as String
*
* @throws InvalidFormatException if aasx package format is invalid
* @throws IOException if creating input streams for aasx fails
*/
public String getResourceString() throws InvalidFormatException, IOException {
return getResourceString(this.aasxRoot);
}

// If there is more than one or no XML-Document that is an error
if (originRelationships.size() > 1) {
throw new RuntimeException("More than one 'aasx-spec' document found in .aasx");
} else if (originRelationships.size() == 0) {
throw new RuntimeException("No 'aasx-spec' document found in .aasx");
/**
* Retrieves a list of related files from the deserialized aasx package
*
* @return the list of file in memory
* @throws InvalidFormatException
* if aasx package format is invalid
* @throws IOException
* if creating input streams for aasx fails
* @throws DeserializationException
* if deserialization of the serialized aas environment fails
*/
public List<InMemoryFile> getRelatedFiles() throws InvalidFormatException, IOException, DeserializationException {
List<String> filePaths = parseReferencedFilePathsFromAASX().stream().filter(AASXUtils::isFilePath).collect(Collectors.toList());
List<InMemoryFile> files = new ArrayList<>();
for (String filePath : filePaths) {
try {
files.add(readFile(aasxRoot, filePath));
} catch (Exception e) {
logger.warn("Loading file {} failed and will not be included.", filePath, e);
}
}
return files;
}

// Get the PackagePart of the XML-Document
PackagePart xmlPart = originPart.getRelatedPart(originRelationships.getRelationship(0));
private PackagePart getPackagePart(OPCPackage aasxPackage) throws InvalidFormatException, IOException {
PackagePart originPart = getOriginPart(aasxPackage);
PackageRelationshipCollection originRelationships = getXMLDocumentRelation(originPart);
return originPart.getRelatedPart(originRelationships.getRelationship(0));
}

private String getResourceString(OPCPackage aasxPackage) throws InvalidFormatException, IOException {
PackagePart xmlPart = getPackagePart(aasxPackage);
return readContentFromPackagePart(xmlPart);
}

// Read the content from the PackagePart
private String readContentFromPackagePart(PackagePart xmlPart) throws IOException {
InputStream stream = xmlPart.getInputStream();
StringWriter writer = new StringWriter();
IOUtils.copy(stream, writer, DEFAULT_CHARSET);
return writer.toString();
}

private PackagePart getOriginPart(OPCPackage aasxPackage) throws InvalidFormatException {
return aasxPackage.getPart(PackagingURIHelper.createPartName(AASXSerializer.ORIGIN_PATH));
}

private PackageRelationshipCollection getXMLDocumentRelation(PackagePart originPart) throws InvalidFormatException {
String xmlPart = getXMLPart(originPart);
PackageRelationshipCollection originRelationships = originPart.getRelationshipsByType(xmlPart);

checkNumberOfRelationsForValidity(originRelationships);

return originRelationships;
}

private String getXMLPart(PackagePart originPart) throws InvalidFormatException {
if (isCompatibilityModeNeeded(originPart)) {
logger.info("AASX contains wrong Relationship namespace. This may be related to the AASX being created with an old version of AASX Package Explorer or an old version of AAS4J. Future compatibility with the wrong namespace may not be guaranteed");
return AASPEC_RELTYPE_BACKWARDSCOMPATIBLE;
} else {
return AASXSerializer.AASSPEC_RELTYPE;
}
}

private boolean isCompatibilityModeNeeded(PackagePart originPart) throws InvalidFormatException {
PackageRelationshipCollection originRelationshipsBackwardsCompatible = originPart.getRelationshipsByType(AASPEC_RELTYPE_BACKWARDSCOMPATIBLE);

return originRelationshipsBackwardsCompatible.size() > 0;
}

private void checkNumberOfRelationsForValidity(PackageRelationshipCollection originRelationships) throws InvalidFormatException {
if (originRelationships.size() > 1) {
throw new InvalidFormatException("More than one 'aasx-spec' document found in .aasx");
} else if (originRelationships.size() == 0) {
throw new InvalidFormatException("No 'aasx-spec' document found in .aasx");
}
}

/**
* Load the referenced filepaths in the submodels such as PDF, PNG files from
* the package
Expand All @@ -148,51 +267,23 @@ private List<String> parseReferencedFilePathsFromAASX() throws IOException, Inva
read();

List<String> paths = new ArrayList<>();
for (Submodel sm : environment.getSubmodels()) {
paths.addAll(parseElements(sm.getSubmodelElements()));
}
return paths;
}

/**
* Gets the file paths from a collection of ISubmodelElement
*
* @param elements the submodel elements to process
* @return the Paths from the File elements
*/
private List<String> parseElements(Collection<SubmodelElement> elements) {
List<String> paths = new ArrayList<>();
for (SubmodelElement element : elements) {
if (element instanceof File) {
File file = (File) element;
paths.add(file.getValue());
} else if (element instanceof SubmodelElementCollection) {
SubmodelElementCollection collection = (SubmodelElementCollection) element;
paths.addAll(parseElements(collection.getValue()));
environment.getAssetAdministrationShells().stream().filter(aas -> aas.getAssetInformation() != null
&& aas.getAssetInformation().getDefaultThumbnail() != null
&& aas.getAssetInformation().getDefaultThumbnail().getPath() != null)
.forEach(aas -> paths.add(aas.getAssetInformation().getDefaultThumbnail().getPath()));
new AssetAdministrationShellElementWalkerVisitor() {
@Override
public void visit(File file) {
if(file != null && file.getValue() != null) {
paths.add(file.getValue());
}
}
}
}.visit(environment);
return paths;
}

/**
* Retrieves a list of related files from the deserialized aasx package
*
* @return the list of file in memory
* @throws InvalidFormatException if aasx package format is invalid
* @throws IOException if creating input streams for aasx fails
* @throws DeserializationException if deserialization of the serialized aas environment fails
*/
public List<InMemoryFile> getRelatedFiles() throws InvalidFormatException, IOException, DeserializationException {
List<String> filePaths = parseReferencedFilePathsFromAASX();
List<InMemoryFile> files = new ArrayList<>();
for (String filePath : filePaths) {
files.add(readFile(aasxRoot, filePath));
}
return files;
}

private InMemoryFile readFile(OPCPackage aasxRoot, String filePath) throws InvalidFormatException, IOException {
PackagePart part = aasxRoot.getPart(PackagingURIHelper.createPartName(AASXUtils.getPathFromURL(filePath)));
PackagePart part = aasxRoot.getPart(PackagingURIHelper.createPartName(AASXUtils.removeFilePartOfURI(filePath)));
InputStream stream = part.getInputStream();
return new InMemoryFile(stream.readAllBytes(), filePath);
}
Expand Down
Loading