Merge "Adds test for MetamodelToAASXConverter" into development
diff --git a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/aasx/AASXToMetamodelConverter.java b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/aasx/AASXToMetamodelConverter.java
index c97f4a4..8fa5c34 100644
--- a/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/aasx/AASXToMetamodelConverter.java
+++ b/sdks/java/basys.sdk/src/main/java/org/eclipse/basyx/aas/factory/aasx/AASXToMetamodelConverter.java
@@ -75,7 +75,7 @@
 	}
 
 	public AASXToMetamodelConverter(InputStream stream) {
-		aasxInputStream = stream;
+		this.aasxInputStream = stream;
 	}
 
 	@SuppressWarnings("unchecked")
diff --git a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/TestMetamodelToAASXConverter.java b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/TestMetamodelToAASXConverter.java
index c58fa47..5677e4b 100644
--- a/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/TestMetamodelToAASXConverter.java
+++ b/sdks/java/basys.sdk/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/TestMetamodelToAASXConverter.java
@@ -16,14 +16,19 @@
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Set;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipInputStream;
 
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.transform.TransformerException;
 
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.eclipse.basyx.aas.bundle.AASBundle;
+import org.eclipse.basyx.aas.factory.aasx.AASXToMetamodelConverter;
 import org.eclipse.basyx.aas.factory.aasx.InMemoryFile;
 import org.eclipse.basyx.aas.factory.aasx.MetamodelToAASXConverter;
 import org.eclipse.basyx.aas.metamodel.api.IAssetAdministrationShell;
@@ -33,13 +38,17 @@
 import org.eclipse.basyx.aas.metamodel.map.descriptor.ModelUrn;
 import org.eclipse.basyx.aas.metamodel.map.parts.Asset;
 import org.eclipse.basyx.submodel.metamodel.api.ISubmodel;
+import org.eclipse.basyx.submodel.metamodel.api.identifier.IIdentifier;
 import org.eclipse.basyx.submodel.metamodel.api.parts.IConceptDescription;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElementCollection;
+import org.eclipse.basyx.submodel.metamodel.api.submodelelement.dataelement.IFile;
 import org.eclipse.basyx.submodel.metamodel.map.Submodel;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.SubmodelElementCollection;
 import org.eclipse.basyx.submodel.metamodel.map.submodelelement.dataelement.File;
 import org.eclipse.basyx.vab.modelprovider.VABPathTools;
 import org.junit.Before;
 import org.junit.Test;
+import org.xml.sax.SAXException;
 
 /**
  * Test for the AASXFactory
@@ -52,111 +61,164 @@
 	private static final String XML_PATH = "aasx/xml/content.xml";
 	private static final String ORIGIN_PATH = "aasx/aasx-origin";
 	private static final String EXTERNAL_FILE_URL = "http://localhost:8080/image.png";
-	
-	
+	private static final String INTERNAL_FILE_PATH_1 = "aasx/Document/docu.pdf";
+	private static final String INTERNAL_FILE_PATH_2 = "/aasx/Document/docu2.pdf";
+
+	private static final String FILE_ID_SHORT_1 = "file1";
+	private static final String FILE_ID_SHORT_2 = "file2";
+	private static final String FILE_ID_SHORT_3 = "file3";
+	private static final String COLLECTION_ID_SHORT = "collection";
+
 	private AssetAdministrationShell aas;
 	private Submodel sm1;
 	private Submodel sm2;
-	
+
 	private List<IAssetAdministrationShell> aasList = new ArrayList<>();
 	private List<ISubmodel> submodelList = new ArrayList<>();
 	private List<IAsset> assetList = new ArrayList<>();
 	private List<IConceptDescription> conceptDescriptionList = new ArrayList<>();
 
 	private List<InMemoryFile> fileList = new ArrayList<>();
-	
-	
-	
+
 	@Before
 	public void setup() throws IOException {
 		Asset asset = new Asset("asset-id", new ModelUrn("ASSET_IDENTIFICATION"), AssetKind.TYPE);
 		aas = new AssetAdministrationShell("aas-id", new ModelUrn("AAS_IDENTIFICATION"), asset);
-		
+
 		sm1 = new Submodel("sm1", new ModelUrn("SM1_ID"));
 		sm2 = new Submodel("sm2", new ModelUrn("SM2_ID"));
-		
-        File file1 = new File(EXTERNAL_FILE_URL, "image/png");
-		file1.setIdShort("file1");
-		File file2 = new File("aasx/Document/docu.pdf", "application/pdf");
-		file2.setIdShort("file2");
-		File file3 = new File("/aasx/Document/docu2.pdf", "application/pdf");
-		file3.setIdShort("file3");
-		
-		
-		
-		SubmodelElementCollection collection = new SubmodelElementCollection("collection");
+
+		File file1 = new File(EXTERNAL_FILE_URL, "image/png");
+		file1.setIdShort(FILE_ID_SHORT_1);
+		File file2 = new File(INTERNAL_FILE_PATH_1, "application/pdf");
+		file2.setIdShort(FILE_ID_SHORT_2);
+		File file3 = new File(INTERNAL_FILE_PATH_2, "application/pdf");
+		file3.setIdShort(FILE_ID_SHORT_3);
+
+		SubmodelElementCollection collection = new SubmodelElementCollection(COLLECTION_ID_SHORT);
 		collection.addSubmodelElement(file2);
-		
+
 		sm1.addSubmodelElement(file1);
 		sm1.addSubmodelElement(collection);
 		sm2.addSubmodelElement(file3);
-		
+
 		aas.addSubmodel(sm1);
 		aas.addSubmodel(sm2);
-		
+
 		aasList.add(aas);
 		submodelList.add(sm1);
 		submodelList.add(sm2);
 		assetList.add(asset);
-		
-		
-		byte[] content1 = {5,6,7,8,9};
+
+		byte[] content1 = { 5, 6, 7, 8, 9 };
 		InMemoryFile file = new InMemoryFile(content1, "/aasx/Document/docu.pdf");
 		fileList.add(file);
-		
-		byte[] content2 = {10,11,12,13,14};
+
+		byte[] content2 = { 10, 11, 12, 13, 14 };
 		file = new InMemoryFile(content2, "aasx/Document/docu2.pdf");
 		fileList.add(file);
 	}
-	
-	
+
 	@Test
-	public void testBuildAASX() throws IOException, TransformerException, ParserConfigurationException {
-		
-		// This stream can be used to write the .aasx directly to a file
-		// FileOutputStream out = new FileOutputStream("path/to/test.aasx");
-		
-		// This stream keeps the output of the AASXFactory only in memory
+	public void testBuildAASX() throws IOException, TransformerException, ParserConfigurationException,
+			InvalidFormatException, SAXException {
+
 		ByteArrayOutputStream out = new ByteArrayOutputStream();
-		
 		MetamodelToAASXConverter.buildAASX(aasList, assetList, conceptDescriptionList, submodelList, fileList, out);
-		
 		validateAASX(out);
-		
 	}
-	
-	
+
+	@Test
+	public void testFilePathsAreCorrectlyChanged() throws IOException, TransformerException,
+			ParserConfigurationException, InvalidFormatException, SAXException {
+
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		MetamodelToAASXConverter.buildAASX(aasList, assetList, conceptDescriptionList, submodelList, fileList, out);
+
+		Set<AASBundle> aasBundle = deserializeAASX(out);
+		assertFilepathsAreCorrect(aasBundle);
+	}
+
 	private void validateAASX(ByteArrayOutputStream byteStream) throws IOException {
 		ZipInputStream in = new ZipInputStream(new ByteArrayInputStream(byteStream.toByteArray()));
 		ZipEntry zipEntry = null;
 
 		ArrayList<String> filePaths = new ArrayList<>();
-		
-		while((zipEntry = in.getNextEntry()) != null) {
-			if(zipEntry.getName().equals(XML_PATH)) {
-				
-				// Read the first 5 bytes of the XML file to make sure it is in fact XML file
-				// No further test of XML file necessary as XML-Converter is tested separately
-				byte[] buf = new byte[5];
-				in.read(buf);
-				assertEquals("<?xml", new String(buf));
-				
+
+		while ((zipEntry = in.getNextEntry()) != null) {
+			if (isExpectedXMLPath(zipEntry)) {
+				assertIsXML(in);
 			}
-			
-			// Write the paths of all files contained in the .aasx into filePaths
 			filePaths.add(zipEntry.getName());
 		}
-		
+
 		assertTrue(filePaths.contains(XML_PATH));
 		assertTrue(filePaths.contains(ORIGIN_PATH));
-		
-		// Check if all expected files are present
-		// Needs to strip the first slash of the paths, as ZipEntry gives paths without it
-		for(InMemoryFile file: fileList) {
-			assertTrue(filePaths.contains(VABPathTools.stripSlashes(file.getPath())));
-		}
-		
-		assertFalse(filePaths.contains(VABPathTools.stripSlashes(EXTERNAL_FILE_URL)));	
+		assertExpectedFileElementsArePresent(filePaths);
 	}
-	
+
+	private void assertExpectedFileElementsArePresent(List<String> filePaths) {
+		fileList.stream().forEach(file -> assertFilePathsContainFile(filePaths, file));
+		assertFilePathsDoNotContainExternalFileURL(filePaths);
+	}
+
+	private void assertFilePathsDoNotContainExternalFileURL(List<String> filePaths) {
+		String strippedExternalFileURL = VABPathTools.stripSlashes(EXTERNAL_FILE_URL);
+		assertFalse(filePaths.contains(strippedExternalFileURL));
+	}
+
+	private void assertFilePathsContainFile(List<String> filePaths, InMemoryFile file) {
+		String strippedPath = VABPathTools.stripSlashes(file.getPath());
+		assertTrue(filePaths.contains(strippedPath));
+	}
+
+	private boolean isExpectedXMLPath(ZipEntry zipEntry) {
+		return zipEntry.getName().equals(XML_PATH);
+	}
+
+	private void assertIsXML(ZipInputStream in) throws IOException {
+		byte[] buf = new byte[5];
+		in.read(buf);
+		assertEquals("<?xml", new String(buf));
+	}
+
+	private Set<AASBundle> deserializeAASX(ByteArrayOutputStream byteStream)
+			throws IOException, InvalidFormatException, ParserConfigurationException, SAXException {
+		InputStream in = new ByteArrayInputStream(byteStream.toByteArray());
+
+		AASXToMetamodelConverter aasxDeserializer = new AASXToMetamodelConverter(in);
+		return aasxDeserializer.retrieveAASBundles();
+	}
+
+	private void assertFilepathsAreCorrect(Set<AASBundle> aasBundles) {
+		AASBundle aasBundle = extractedAASBundleFromAASBundleSet(aasBundles, aas.getIdentification());
+		Set<ISubmodel> deserializedSubmodels = aasBundle.getSubmodels();
+
+		ISubmodel deserializedSm1 = extractSubmodelFromSubmodelSet(deserializedSubmodels, sm1.getIdentification());
+		ISubmodel deserializedSm2 = extractSubmodelFromSubmodelSet(deserializedSubmodels, sm2.getIdentification());
+
+		ISubmodelElementCollection deserializedCollection = (ISubmodelElementCollection) deserializedSm1
+				.getSubmodelElement(COLLECTION_ID_SHORT);
+
+		IFile deserializedFile1 = (IFile) deserializedSm1.getSubmodelElement(FILE_ID_SHORT_1);
+		IFile deserializedFile2 = (IFile) deserializedCollection.getSubmodelElement(FILE_ID_SHORT_2);
+		IFile deserializedFile3 = (IFile) deserializedSm2.getSubmodelElement(FILE_ID_SHORT_3);
+
+		assertEquals(EXTERNAL_FILE_URL, deserializedFile1.getValue());
+		assertEquals(harmonizePrefixSlash(INTERNAL_FILE_PATH_1), deserializedFile2.getValue());
+		assertEquals(harmonizePrefixSlash(INTERNAL_FILE_PATH_2), deserializedFile3.getValue());
+	}
+
+	private AASBundle extractedAASBundleFromAASBundleSet(Set<AASBundle> aasBundles, IIdentifier identifier) {
+		return aasBundles.stream().filter(aasB -> aasB.getAAS().getIdentification().equals(identifier)).findAny().get();
+	}
+
+	private Object harmonizePrefixSlash(String path) {
+		return path.startsWith("/") ? path : "/" + path;
+	}
+
+	private ISubmodel extractSubmodelFromSubmodelSet(Set<ISubmodel> submodelSet, IIdentifier identifier) {
+		return submodelSet.stream().filter(sm -> sm.getIdentification().equals(identifier)).findAny().get();
+	}
+
 }