diff --git a/src/main/java/org/eclipse/basyx/aas/factory/aasx/AASXToMetamodelConverter.java b/src/main/java/org/eclipse/basyx/aas/factory/aasx/AASXToMetamodelConverter.java index 9326f39c..cd3759f9 100644 --- a/src/main/java/org/eclipse/basyx/aas/factory/aasx/AASXToMetamodelConverter.java +++ b/src/main/java/org/eclipse/basyx/aas/factory/aasx/AASXToMetamodelConverter.java @@ -297,6 +297,15 @@ public void unzipRelatedFiles() throws IOException, ParserConfigurationException unzipRelatedFiles(getTemporaryDirPath()); } + /** + * Unzips all files referenced by the aasx file according to its relationships + * and a relative child path + */ + public void unzipRelatedFilesToChildPath(String childPath) throws IOException, ParserConfigurationException, SAXException, URISyntaxException, InvalidFormatException { + Path tempPath = getTemporaryDirPath().resolve(childPath); + unzipRelatedFiles(tempPath); + } + /** * Unzips all files referenced by the aasx file to a specified directory * diff --git a/src/main/java/org/eclipse/basyx/aas/factory/aasx/SubmodelFileEndpointLoader.java b/src/main/java/org/eclipse/basyx/aas/factory/aasx/SubmodelFileEndpointLoader.java index ae21277c..fa8ab873 100644 --- a/src/main/java/org/eclipse/basyx/aas/factory/aasx/SubmodelFileEndpointLoader.java +++ b/src/main/java/org/eclipse/basyx/aas/factory/aasx/SubmodelFileEndpointLoader.java @@ -34,6 +34,7 @@ import org.eclipse.basyx.submodel.metamodel.api.submodelelement.ISubmodelElementCollection; 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; /** * A utility class for configuring file endpoints in submodels @@ -55,7 +56,8 @@ public class SubmodelFileEndpointLoader { * path at which the files are hosted on the host (e.g. "/files") */ public static void setRelativeFileEndpoints(ISubmodel submodel, String host, int port, String path) { - String fileRoot = "http://" + host + ":" + port + path; + String basePath = "http://" + host + ":" + port; + String fileRoot = VABPathTools.append(basePath, path); setRelativeFileEndpoints(submodel, fileRoot); } @@ -108,7 +110,7 @@ private static void setFileEndpoint(File file, String fileRoot) { } catch (MalformedURLException e1) { // assume that the file value is already a relative path } - String newEndpoint = fileRoot + relativePath; + String newEndpoint = VABPathTools.append(fileRoot, relativePath); file.setValue(newEndpoint); } } diff --git a/src/main/java/org/eclipse/basyx/vab/modelprovider/VABPathTools.java b/src/main/java/org/eclipse/basyx/vab/modelprovider/VABPathTools.java index 16cd1409..183e98b2 100644 --- a/src/main/java/org/eclipse/basyx/vab/modelprovider/VABPathTools.java +++ b/src/main/java/org/eclipse/basyx/vab/modelprovider/VABPathTools.java @@ -218,8 +218,17 @@ public static String append(String path, String element) { if (path == null || element == null) { return null; } - - if (path.lastIndexOf(SEPERATOR) == path.length() - 1) { + if (element.length() == 0) { + return path; + } + boolean lastPathCharIsSeperator = path.lastIndexOf(SEPERATOR) == path.length() - 1; + boolean firstElementCharIsSeparator = SEPERATOR.charAt(0) == element.charAt(0); + boolean atLeastOneSeparatorInTheMiddle = lastPathCharIsSeperator || firstElementCharIsSeparator; + boolean twoSeperatorsInTheMiddle = lastPathCharIsSeperator && firstElementCharIsSeparator; + + if (twoSeperatorsInTheMiddle) { + return path + element.substring(1); + } else if (atLeastOneSeparatorInTheMiddle) { return path + element; } else { return path + SEPERATOR + element; diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/TestAASXToMetamodelConverterFromBaSyx.java b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/TestAASXToMetamodelConverterFromBaSyx.java index 0310e285..6f41d8b3 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/TestAASXToMetamodelConverterFromBaSyx.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/aas/factory/aasx/TestAASXToMetamodelConverterFromBaSyx.java @@ -42,8 +42,10 @@ 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.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; @@ -112,9 +114,9 @@ public class TestAASXToMetamodelConverterFromBaSyx { private static final String PDF_PATH = "/aasx/Document/docu.pdf"; private static final String PDF_MIMETYPE = "application/pdf"; private static final String PDF_IDSHORT = "pdf"; - private static final String TARGET_PATH = "/basyx-temp/files"; // gets set by BaSyx - private static final String[] EXPECTED_UNZIPPED_FILES = { TARGET_PATH + PDF_PATH, TARGET_PATH + IMAGE_PATH }; - private static final String[] EXPECTED_UNZIPPED_FILES_IN_TEMP_DIR = { PDF_PATH, IMAGE_PATH }; + private static final String BASYX_PATH = "/basyx-temp"; // gets set by BaSyx + private static final String FILES_PATH = "/files"; + private static final String[] EXPECTED_UNZIPPED_FILES = { PDF_PATH, IMAGE_PATH }; private static final String REL_PATH = "_rels/.rels"; private static final String ORIGIN_REL_PATH = "aasx/_rels/aasx-origin.rels"; @@ -127,7 +129,7 @@ public class TestAASXToMetamodelConverterFromBaSyx { private static final String TARGET_PATH_REGEX_START = "Target=.*"; private static final String TARGET_PATH_REGEX_FULL = "Target=\"/.*"; private static final String DOCPROPS_PATH_REGEX = "Target=\"docProps.*"; - + private static final byte[] THUMBNAIL = { 22, 23, 24, 25, 26 }; private int bundleSize; @@ -142,12 +144,12 @@ public void setup() throws IOException, TransformerException, ParserConfiguratio packageManager = new AASXToMetamodelConverter(CREATED_AASX_FILE_PATH); } - + @After public void close() { packageManager.close(); } - + @Test public void thumbnailInPackage() throws InvalidFormatException, IOException, ParserConfigurationException, SAXException { assertTrue(IOUtils.contentEquals(new ByteArrayInputStream(THUMBNAIL), packageManager.retrieveThumbnail())); @@ -224,7 +226,7 @@ public void testQualifierValue() throws Exception { ISubmodelElement operationWithQualifer = submodelElements.get(OPERATION_WITH_QUALIFIER_IDSHORT); IConstraint[] constraints = operationWithQualifer.getQualifiers().toArray(new IConstraint[] {}); - Qualifier qualifier = (Qualifier)constraints[0]; + Qualifier qualifier = (Qualifier) constraints[0]; assertEquals(QUALIFIER_VALUE, qualifier.getValue()); } @@ -241,12 +243,29 @@ public void testQualifierValue() throws Exception { public void testFilesOfGeneratedAASX() throws InvalidFormatException, IOException, ParserConfigurationException, SAXException, URISyntaxException { // Unzip files from the .aasx packageManager.unzipRelatedFiles(); - + String tempDirectory = FileUtils.getTempDirectory().getAbsolutePath(); // Check if all expected files are present - for (String path : EXPECTED_UNZIPPED_FILES) { - assertTrue(new java.io.File(tempDirectory + path).exists()); + for (String path : EXPECTED_UNZIPPED_FILES) { + String fullFilePath = tempDirectory + BASYX_PATH + FILES_PATH + path; + assertTrue(new java.io.File(fullFilePath).exists()); + } + } + + /** + * Tests the connected files of the parsed AASX file for subdirs + */ + @Test + public void testFilesOfGeneratedAASXChildPaths() throws InvalidFormatException, IOException, ParserConfigurationException, SAXException, URISyntaxException { + String childPath = "testChildPath"; + packageManager.unzipRelatedFilesToChildPath(childPath); + + String tempDirectory = FileUtils.getTempDirectory().getAbsolutePath(); + + for (String path : EXPECTED_UNZIPPED_FILES) { + String fullFilePath = tempDirectory + BASYX_PATH + "/" + childPath + FILES_PATH + path; + assertTrue(new java.io.File(fullFilePath).exists()); } } @@ -261,13 +280,13 @@ public void testFilesOfGeneratedAASX() throws InvalidFormatException, IOExceptio */ @Test public void testFilesUnzippedToSpecifiedDirectory() throws InvalidFormatException, IOException, ParserConfigurationException, SAXException, URISyntaxException { - Path pathToTempDir = Files.createTempDirectory("aasx"); - packageManager.unzipRelatedFiles(pathToTempDir); + Path pathToTempDir = Files.createTempDirectory("aasx"); + packageManager.unzipRelatedFiles(pathToTempDir); - for (String p : EXPECTED_UNZIPPED_FILES_IN_TEMP_DIR) { - Path path = Path.of(pathToTempDir.toString() + "/files" + p); - assertTrue(new java.io.File(path.toString()).exists()); - } + for (String p : EXPECTED_UNZIPPED_FILES) { + Path path = Path.of(pathToTempDir.toString() + "/files" + p); + assertTrue(new java.io.File(path.toString()).exists()); + } } /** @@ -483,9 +502,9 @@ private void createAASXFile(String filePath) throws IOException, TransformerExce fileList.add(createInMemoryFile(IMAGE_PATH)); fileList.add(createInMemoryFile(PDF_PATH)); submodelElementsSize = 8; - - Thumbnail thumbnail = new Thumbnail(ThumbnailExtension.PNG, new ByteArrayInputStream(THUMBNAIL)); - + + Thumbnail thumbnail = new Thumbnail(ThumbnailExtension.PNG, new ByteArrayInputStream(THUMBNAIL)); + try (FileOutputStream out = new FileOutputStream(filePath)) { MetamodelToAASXConverter.buildAASX(aasList, assetList, conceptDescriptionList, submodelList, fileList, thumbnail, out); } diff --git a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/VABPathToolsTest.java b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/VABPathToolsTest.java index 79653173..119434bc 100644 --- a/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/VABPathToolsTest.java +++ b/src/test/java/org/eclipse/basyx/testsuite/regression/vab/modelprovider/VABPathToolsTest.java @@ -185,8 +185,12 @@ public void testBuildPath() { public void testAppend() { assertEquals("/parent/child", VABPathTools.append("/parent", "child")); assertEquals("/parent/child", VABPathTools.append("/parent/", "child")); + assertEquals("/parent/child", VABPathTools.append("/parent", "/child")); + assertEquals("/parent/child", VABPathTools.append("/parent/", "/child")); assertEquals("/parent/x/child", VABPathTools.append("/parent/x", "child")); assertEquals("/parent/x/child", VABPathTools.append("/parent/x/", "child")); + assertEquals("/parent", VABPathTools.append("/parent", "")); + assertEquals("child", VABPathTools.append("", "child")); assertNull(VABPathTools.append(null, "")); assertNull(VABPathTools.append("", null)); }