From e08e0cf5766b10f0f2d59f6d01a11241acfe7464 Mon Sep 17 00:00:00 2001 From: Yauhenikapl Date: Tue, 9 Jul 2024 18:45:16 +0300 Subject: [PATCH 01/20] Add New Search Command --- .../org/eclipse/esmf/AspectSearchCommand.java | 108 ++++++++++++++++++ .../main/java/org/eclipse/esmf/SammCli.java | 1 + 2 files changed, 109 insertions(+) create mode 100644 tools/samm-cli/src/main/java/org/eclipse/esmf/AspectSearchCommand.java diff --git a/tools/samm-cli/src/main/java/org/eclipse/esmf/AspectSearchCommand.java b/tools/samm-cli/src/main/java/org/eclipse/esmf/AspectSearchCommand.java new file mode 100644 index 000000000..0bd227c40 --- /dev/null +++ b/tools/samm-cli/src/main/java/org/eclipse/esmf/AspectSearchCommand.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2024 Robert Bosch Manufacturing Solutions GmbH + * + * See the AUTHORS file(s) distributed with this work for additional + * information regarding authorship. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * SPDX-License-Identifier: MPL-2.0 + */ + +package org.eclipse.esmf; + +import java.io.File; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +import org.eclipse.esmf.aspectmodel.AspectModelFile; +import org.eclipse.esmf.aspectmodel.loader.AspectModelLoader; +import org.eclipse.esmf.aspectmodel.urn.AspectModelUrn; +import org.eclipse.esmf.metamodel.AspectModel; +import org.eclipse.esmf.metamodel.ModelElement; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import picocli.CommandLine; + +@CommandLine.Command( name = AspectSearchCommand.COMMAND_NAME, + description = "Search separate Properties files used by Aspect Model", + headerHeading = "@|bold Usage|@:%n%n", + descriptionHeading = "%n@|bold Description|@:%n%n", + parameterListHeading = "%n@|bold Parameters|@:%n", + optionListHeading = "%n@|bold Options|@:%n", + mixinStandardHelpOptions = true +) +public class AspectSearchCommand extends AbstractCommand { + public static final String COMMAND_NAME = "search"; + + private static final Logger LOG = LoggerFactory.getLogger( AspectSearchCommand.class ); + + @CommandLine.Mixin + private LoggingMixin loggingMixin; + + @CommandLine.Mixin + private ExternalResolverMixin customResolver; + + @CommandLine.Parameters( paramLabel = "INPUT", description = "Input file name of the Aspect Model .ttl file", arity = "1", index = "0" ) + private String input; + + @CommandLine.Option( names = { "--models-path", "-msp" }, description = "Path to Models, where have to search" ) + private String pathToModels = "-"; + + public String getInput() { + return input; + } + + @Override + public void run() { + final AspectModel aspectModel = loadAspectModelOrFail( input, customResolver ); + + final Path directory = Paths.get( pathToModels ); + final List files = Arrays.stream( Optional.ofNullable( directory.toFile().listFiles() ).orElse( new File[] {} ) ) + .filter( file -> file.isFile() && file.getName().endsWith( ".ttl" ) && !file.getName() + .equals( Paths.get( input ).getFileName().toString() ) ) + .sorted() + .toList(); + + if ( files.isEmpty() ) { + LOG.info( "No .ttl files found in the directory '{}'", directory ); + return; + } + + final List modelUrns = aspectModel.elements().stream().map( ModelElement::urn ).toList(); + + String header = String.format( "| %-60s | %-100s | %-50s | %-60s |", + "URN of the element", "File location", "Model source", "Target element that it is referring to" ); + String separator = new String( new char[header.length()] ).replace( "\0", "-" ); + + // Print Table header + System.out.println( separator ); + System.out.println( header ); + System.out.println( separator ); + + final AspectModelLoader aspectModelLoader = new AspectModelLoader(); + + for ( final File file : files ) { + processFile( file, modelUrns, aspectModelLoader ); + } + } + + private void processFile( File file, List modelUrns, AspectModelLoader aspectModelLoader ) { + final AspectModel aspectModel = loadAspectModelOrFail( file.getPath(), customResolver ); + + for ( final AspectModelUrn modelUrn : modelUrns ) { + final List modelFiles = aspectModel.files(); + for ( final AspectModelFile modelFile : modelFiles ) { + if ( aspectModelLoader.containsDefinition( modelFile, modelUrn ) ) { + System.out.printf( "| %-60s | %-100s | %-50s | %-60s |%n", modelUrn, file.getPath(), file.getName(), "" ); + } + } + } + } +} diff --git a/tools/samm-cli/src/main/java/org/eclipse/esmf/SammCli.java b/tools/samm-cli/src/main/java/org/eclipse/esmf/SammCli.java index ae16fce4d..9a2b816b9 100644 --- a/tools/samm-cli/src/main/java/org/eclipse/esmf/SammCli.java +++ b/tools/samm-cli/src/main/java/org/eclipse/esmf/SammCli.java @@ -44,6 +44,7 @@ public SammCli() { final CommandLine initialCommandLine = new CommandLine( this ) .addSubcommand( new AspectCommand() ) .addSubcommand( new AasCommand() ) + .addSubcommand( new AspectSearchCommand() ) .setCaseInsensitiveEnumValuesAllowed( true ) .setExecutionStrategy( LoggingMixin::executionStrategy ); final CommandLine.IExecutionExceptionHandler defaultExecutionExceptionHandler = initialCommandLine.getExecutionExceptionHandler(); From 724f0ca64abfd50d74439d51e84c72169632b2a7 Mon Sep 17 00:00:00 2001 From: Yauhenikapl Date: Tue, 9 Jul 2024 18:47:26 +0300 Subject: [PATCH 02/20] Rollback BlankNodeInstantiationTest --- .../esmf/aspectmodel/loader/BlankNodeInstantiationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/esmf-aspect-meta-model-java/src/test/java/org/eclipse/esmf/aspectmodel/loader/BlankNodeInstantiationTest.java b/core/esmf-aspect-meta-model-java/src/test/java/org/eclipse/esmf/aspectmodel/loader/BlankNodeInstantiationTest.java index 22dafbfce..96939131f 100644 --- a/core/esmf-aspect-meta-model-java/src/test/java/org/eclipse/esmf/aspectmodel/loader/BlankNodeInstantiationTest.java +++ b/core/esmf-aspect-meta-model-java/src/test/java/org/eclipse/esmf/aspectmodel/loader/BlankNodeInstantiationTest.java @@ -30,6 +30,6 @@ void testBlankNodeInstantiation() { final List list = (List) aspect.getProperties().get( 0 ).getCharacteristic().get(); final Characteristic characteristic = list.getElementCharacteristic().get(); assertThat( characteristic.isAnonymous() ).isTrue(); - assertThat( characteristic.getName() ).isEqualTo( "NumberListTrait" ); + assertThat( characteristic.getName() ).startsWith( "x" ); } } From b4fe8562942d67327faac853aabb38007c9cde99 Mon Sep 17 00:00:00 2001 From: Yauhenikapl Date: Mon, 15 Jul 2024 16:44:40 +0300 Subject: [PATCH 03/20] Specify model namespace definition --- .../aspectmodel/loader/AspectModelLoader.java | 37 ++++++++++++++++ .../esmf/metamodel/impl/DefaultNamespace.java | 2 +- .../loader/AspectModelLoaderTest.java | 40 ++++++++++++++---- .../src/test/resources/namespaces.zip | Bin 0 -> 4783 bytes 4 files changed, 69 insertions(+), 10 deletions(-) create mode 100644 core/esmf-aspect-meta-model-java/src/test/resources/namespaces.zip diff --git a/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoader.java b/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoader.java index 2d47de721..745cf1661 100644 --- a/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoader.java +++ b/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoader.java @@ -16,12 +16,15 @@ import static java.util.stream.Collectors.toSet; import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; import java.io.InputStream; import java.nio.file.Path; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collection; import java.util.Deque; +import java.util.Enumeration; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -30,6 +33,8 @@ import java.util.function.Function; import java.util.function.Supplier; import java.util.stream.Stream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; import org.eclipse.esmf.aspectmodel.AspectModelFile; import org.eclipse.esmf.aspectmodel.resolver.AspectModelFileLoader; @@ -173,6 +178,38 @@ public AspectModel load( final InputStream inputStream ) { return buildAspectModel( loaderContext.loadedFiles() ); } + public AspectModel loadFromArchive( final String pathToArchive ) { + File zipFile = new File( pathToArchive ); + + if (!zipFile.exists() || !zipFile.isFile()) { + throw new RuntimeException(new FileNotFoundException("The specified file does not exist or is not a file.")); + } + + List aspectModelFiles = new ArrayList<>(); + + try ( ZipFile zip = new ZipFile( zipFile ) ) { + Enumeration entries = zip.entries(); + + while ( entries.hasMoreElements() ) { + ZipEntry entry = entries.nextElement(); + System.out.println( entry.getName() ); // Consider removing or modifying this debug statement in production. + + if ( entry.getName().endsWith( ".ttl" ) ) { + try ( InputStream inputStream = zip.getInputStream( entry ) ) { + AspectModelFile aspectModelFile = AspectModelFileLoader.load( inputStream ); + aspectModelFiles.add( aspectModelFile ); + } catch ( IOException e ) { + System.err.println( "Error reading entry: " + entry.getName() + " - " + e.getMessage() ); + } + } + } + } catch ( IOException e ) { + System.err.println( "Error reading the ZIP file: " + e.getMessage() ); + } + + return buildAspectModel( aspectModelFiles ); + } + private AspectModelFile migrate( final AspectModelFile file ) { return MetaModelVersionMigrator.INSTANCE.apply( file ); } diff --git a/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/metamodel/impl/DefaultNamespace.java b/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/metamodel/impl/DefaultNamespace.java index 38018b6d6..63389bff2 100644 --- a/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/metamodel/impl/DefaultNamespace.java +++ b/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/metamodel/impl/DefaultNamespace.java @@ -44,7 +44,7 @@ public DefaultNamespace( final String packagePart, final VersionNumber versionNu * @param elements the list of elements in the namspace */ public DefaultNamespace( final String uri, final List elements, final Optional source ) { - this( uri.split( ":" )[2], VersionNumber.parse( uri.split( ":" )[3] ), elements, source ); + this( uri.split( ":" )[2], VersionNumber.parse( uri.split( ":" )[3].replace( "#", "" ) ), elements, source ); } // /** diff --git a/core/esmf-aspect-meta-model-java/src/test/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoaderTest.java b/core/esmf-aspect-meta-model-java/src/test/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoaderTest.java index 5ebe7306e..c68a2eda2 100644 --- a/core/esmf-aspect-meta-model-java/src/test/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoaderTest.java +++ b/core/esmf-aspect-meta-model-java/src/test/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoaderTest.java @@ -15,12 +15,17 @@ import static org.assertj.core.api.Assertions.assertThat; +import java.net.URISyntaxException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; import java.util.Map; import java.util.Optional; import java.util.function.Function; import java.util.stream.Collectors; import org.eclipse.esmf.metamodel.AbstractEntity; +import org.eclipse.esmf.metamodel.AspectModel; import org.eclipse.esmf.metamodel.ComplexType; import org.eclipse.esmf.test.TestAspect; import org.eclipse.esmf.test.TestResources; @@ -30,17 +35,34 @@ class AspectModelLoaderTest { @Test public void testOfAbstractEntityCyclomaticCreation() { - final Map entities = - TestResources.load( TestAspect.ASPECT_WITH_MULTIPLE_ENTITIES_SAME_EXTEND ).elements().stream() - .filter( ComplexType.class::isInstance ) - .map( ComplexType.class::cast ) - .collect( Collectors.toMap( ComplexType::getName, Function.identity() ) ); + final Map entities = TestResources.load( TestAspect.ASPECT_WITH_MULTIPLE_ENTITIES_SAME_EXTEND ).elements() + .stream().filter( ComplexType.class::isInstance ).map( ComplexType.class::cast ) + .collect( Collectors.toMap( ComplexType::getName, Function.identity() ) ); assertThat( entities ).extracting( "AbstractTestEntity" ).isInstanceOf( AbstractEntity.class ); final AbstractEntity abstractEntity = (AbstractEntity) entities.get( "AbstractTestEntity" ); - assertThat( entities ).extracting( "testEntityOne" ).isInstanceOfSatisfying( ComplexType.class, type -> - assertThat( type ).extracting( ComplexType::getExtends ).extracting( Optional::get ).isSameAs( abstractEntity ) ); - assertThat( entities ).extracting( "testEntityTwo" ).isInstanceOfSatisfying( ComplexType.class, type -> - assertThat( type ).extracting( ComplexType::getExtends ).extracting( Optional::get ).isSameAs( abstractEntity ) ); + assertThat( entities ).extracting( "testEntityOne" ).isInstanceOfSatisfying( ComplexType.class, + type -> assertThat( type ).extracting( ComplexType::getExtends ).extracting( Optional::get ).isSameAs( abstractEntity ) ); + assertThat( entities ).extracting( "testEntityTwo" ).isInstanceOfSatisfying( ComplexType.class, + type -> assertThat( type ).extracting( ComplexType::getExtends ).extracting( Optional::get ).isSameAs( abstractEntity ) ); + } + + @Test + public void testLoadAspectModelFromZipArchive() throws URISyntaxException { + final ClassLoader classLoader = getClass().getClassLoader(); + final Path archivePath = Paths.get( classLoader.getResource( "namespaces.zip" ).toURI() ); + final AspectModel aspectModel = new AspectModelLoader().loadFromArchive( archivePath.toString() ); + + assertThat( aspectModel.namespaces() ).hasSize( 2 ); + assertThat( aspectModel.namespaces().get( 0 ).getName() ).contains( "urn:samm:org.eclipse.examples:1.1.0" ); + assertThat( aspectModel.namespaces().get( 1 ).getName() ).contains( "urn:samm:org.eclipse.examples:1.0.0" ); + + final List aspectsNames = List.of( "Movement2", "Movement3", "Movement", "SimpleAspect" ); + + assertThat( aspectModel.files() ).hasSize( 4 ); + assertThat( aspectModel.files() ) + .anySatisfy( aspectModelFile -> { + assertThat( aspectsNames ).contains( aspectModelFile.aspect().getName() ); + } ); } } \ No newline at end of file diff --git a/core/esmf-aspect-meta-model-java/src/test/resources/namespaces.zip b/core/esmf-aspect-meta-model-java/src/test/resources/namespaces.zip new file mode 100644 index 0000000000000000000000000000000000000000..5c01f800c9c0295fa403aa6c135288a03495b7e0 GIT binary patch literal 4783 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 Date: Mon, 15 Jul 2024 16:48:38 +0300 Subject: [PATCH 04/20] Fix styles --- .../eclipse/esmf/aspectmodel/loader/AspectModelLoader.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoader.java b/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoader.java index 745cf1661..a47234078 100644 --- a/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoader.java +++ b/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoader.java @@ -181,8 +181,8 @@ public AspectModel load( final InputStream inputStream ) { public AspectModel loadFromArchive( final String pathToArchive ) { File zipFile = new File( pathToArchive ); - if (!zipFile.exists() || !zipFile.isFile()) { - throw new RuntimeException(new FileNotFoundException("The specified file does not exist or is not a file.")); + if ( !zipFile.exists() || !zipFile.isFile() ) { + throw new RuntimeException( new FileNotFoundException( "The specified file does not exist or is not a file." ) ); } List aspectModelFiles = new ArrayList<>(); From 8a1b18993ba0fb9ce374be676fe8f058041ef660 Mon Sep 17 00:00:00 2001 From: Yauhenikapl Date: Thu, 18 Jul 2024 16:57:10 +0300 Subject: [PATCH 05/20] Add generation zip from Aspect Model --- .../generator/AspectModelZipGenerator.java | 63 +++++++++++++++++++ .../aspectmodel/loader/AspectModelLoader.java | 5 +- .../AspectModelZipGeneratorTest.java | 36 +++++++++++ .../pom.xml | 4 ++ .../zip/AspectModelZipGenerator.java | 49 +++++++++++++++ .../zip/AspectModelZipGeneratorTest.java | 54 ++++++++++++++++ 6 files changed, 208 insertions(+), 3 deletions(-) create mode 100644 core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/generator/AspectModelZipGenerator.java create mode 100644 core/esmf-aspect-meta-model-java/src/test/java/org/eclipse/esmf/aspectmodel/generator/AspectModelZipGeneratorTest.java create mode 100644 core/esmf-aspect-model-document-generators/src/main/java/org/eclipse/esmf/aspectmodel/generator/zip/AspectModelZipGenerator.java create mode 100644 core/esmf-aspect-model-document-generators/src/test/java/org/eclipse/esmf/aspectmodel/generator/zip/AspectModelZipGeneratorTest.java diff --git a/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/generator/AspectModelZipGenerator.java b/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/generator/AspectModelZipGenerator.java new file mode 100644 index 000000000..edb0cfc7d --- /dev/null +++ b/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/generator/AspectModelZipGenerator.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2024 Robert Bosch Manufacturing Solutions GmbH + * + * See the AUTHORS file(s) distributed with this work for additional + * information regarding authorship. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * SPDX-License-Identifier: MPL-2.0 + */ + +package org.eclipse.esmf.aspectmodel.generator; + +import java.io.BufferedOutputStream; +import java.io.BufferedWriter; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +import org.eclipse.esmf.aspectmodel.AspectModelFile; +import org.eclipse.esmf.metamodel.AspectModel; + +public class AspectModelZipGenerator { + + private static final int BUFFER_SIZE = 4096; + + public static void generateZipAspectModelArchive( final AspectModel aspectModel, final String zipFilePath ) throws IOException { + Path zipFile = Files.createFile( Paths.get( zipFilePath ) ); + try ( FileOutputStream fos = new FileOutputStream( zipFilePath ); + BufferedOutputStream bos = new BufferedOutputStream( fos ); + ZipOutputStream zos = new ZipOutputStream( bos ) ) { + + for ( final AspectModelFile aspectModelFile : aspectModel.files() ) { + addFileToZip( aspectModelFile, zos ); + } + } + } + + private static void addFileToZip( final AspectModelFile file, final ZipOutputStream zos ) throws IOException { + final String aspectString = file.aspect().toString(); +// final String aspectString = AspectSerializer.INSTANCE.apply( aspect ); + final String fileName = String.format( "%s/%s/%s.ttl", file.aspect().urn().getNamespace(), file.aspect().urn().getVersion(), + file.aspect().getName() ); + final ZipEntry zipEntry = new ZipEntry( fileName ); + zos.putNextEntry( zipEntry ); + + try ( Writer writer = new BufferedWriter( new OutputStreamWriter( zos ) ) ) { + writer.write( aspectString ); + } catch ( IOException exception ) { + throw new IOException( "Could not write to zip entry: " + fileName, exception ); + } finally { + zos.closeEntry(); + } + } +} diff --git a/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoader.java b/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoader.java index a47234078..5cc1eb3f0 100644 --- a/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoader.java +++ b/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoader.java @@ -192,19 +192,18 @@ public AspectModel loadFromArchive( final String pathToArchive ) { while ( entries.hasMoreElements() ) { ZipEntry entry = entries.nextElement(); - System.out.println( entry.getName() ); // Consider removing or modifying this debug statement in production. if ( entry.getName().endsWith( ".ttl" ) ) { try ( InputStream inputStream = zip.getInputStream( entry ) ) { AspectModelFile aspectModelFile = AspectModelFileLoader.load( inputStream ); aspectModelFiles.add( aspectModelFile ); } catch ( IOException e ) { - System.err.println( "Error reading entry: " + entry.getName() + " - " + e.getMessage() ); + LOG.error( String.format( "Error reading entry: %s - %s", entry.getName(), e.getMessage() ) ); } } } } catch ( IOException e ) { - System.err.println( "Error reading the ZIP file: " + e.getMessage() ); + LOG.error( String.format( "Error reading the ZIP file: %s", e.getMessage() ) ); } return buildAspectModel( aspectModelFiles ); diff --git a/core/esmf-aspect-meta-model-java/src/test/java/org/eclipse/esmf/aspectmodel/generator/AspectModelZipGeneratorTest.java b/core/esmf-aspect-meta-model-java/src/test/java/org/eclipse/esmf/aspectmodel/generator/AspectModelZipGeneratorTest.java new file mode 100644 index 000000000..b2a3175bf --- /dev/null +++ b/core/esmf-aspect-meta-model-java/src/test/java/org/eclipse/esmf/aspectmodel/generator/AspectModelZipGeneratorTest.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2024 Robert Bosch Manufacturing Solutions GmbH + * + * See the AUTHORS file(s) distributed with this work for additional + * information regarding authorship. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * SPDX-License-Identifier: MPL-2.0 + */ + +package org.eclipse.esmf.aspectmodel.generator; + +import java.io.IOException; + +import org.eclipse.esmf.aspectmodel.AspectModelFile; +import org.eclipse.esmf.aspectmodel.loader.AspectModelLoader; +import org.eclipse.esmf.aspectmodel.resolver.AspectModelFileLoader; +import org.eclipse.esmf.metamodel.AspectModel; +import org.eclipse.esmf.test.TestAspect; +import org.eclipse.esmf.test.TestResources; + +import org.junit.jupiter.api.Test; + +public class AspectModelZipGeneratorTest { + + @Test + public void testAspectModelZipGeneration() throws IOException { +// final AspectModelFile aspectModelFile_1 = AspectModelFileLoader.load( ) + final AspectModel aspectModel = TestResources.load( TestAspect.ASPECT_WITH_MULTIPLE_ENTITIES_SAME_EXTEND ); + + AspectModelZipGenerator.generateZipAspectModelArchive( aspectModel, "/Users/Yauheni_Kapliarchuk/Downloads/testzip.zip" ); + } +} diff --git a/core/esmf-aspect-model-document-generators/pom.xml b/core/esmf-aspect-model-document-generators/pom.xml index 17445bf47..70347443a 100644 --- a/core/esmf-aspect-model-document-generators/pom.xml +++ b/core/esmf-aspect-model-document-generators/pom.xml @@ -160,6 +160,10 @@ logback-core test + + org.eclipse.esmf + esmf-aspect-model-serializer + diff --git a/core/esmf-aspect-model-document-generators/src/main/java/org/eclipse/esmf/aspectmodel/generator/zip/AspectModelZipGenerator.java b/core/esmf-aspect-model-document-generators/src/main/java/org/eclipse/esmf/aspectmodel/generator/zip/AspectModelZipGenerator.java new file mode 100644 index 000000000..7281269c8 --- /dev/null +++ b/core/esmf-aspect-model-document-generators/src/main/java/org/eclipse/esmf/aspectmodel/generator/zip/AspectModelZipGenerator.java @@ -0,0 +1,49 @@ +package org.eclipse.esmf.aspectmodel.generator.zip; + +import java.io.BufferedOutputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +import org.eclipse.esmf.aspectmodel.AspectModelFile; +import org.eclipse.esmf.aspectmodel.serializer.AspectSerializer; +import org.eclipse.esmf.metamodel.AspectModel; + +public class AspectModelZipGenerator { + + public static void generateZipAspectModelArchive( final AspectModel aspectModel, final String zipFilePath ) throws IOException { + final Path zipFile = Paths.get( zipFilePath ); + + try ( FileOutputStream fos = new FileOutputStream( zipFile.toFile() ); + BufferedOutputStream bos = new BufferedOutputStream( fos ); + ZipOutputStream zos = new ZipOutputStream( bos ) ) { + + for ( final AspectModelFile aspectModelFile : aspectModel.files() ) { + addFileToZip( aspectModelFile, zos ); + } + } catch ( IOException e ) { + throw new IOException( "Error creating zip archive: " + zipFilePath, e ); + } + } + + private static void addFileToZip( final AspectModelFile file, ZipOutputStream zos ) throws IOException { + final String aspectString = AspectSerializer.INSTANCE.apply( file.aspect() ); + final String fileName = String.format( "%s/%s/%s.ttl", + file.aspect().urn().getNamespace(), + file.aspect().urn().getVersion(), + file.aspect().getName() ); + final ZipEntry zipEntry = new ZipEntry( fileName ); + zos.putNextEntry( zipEntry ); + + Writer writer = new OutputStreamWriter( zos ); + writer.write( aspectString ); + writer.flush(); + + zos.closeEntry(); + } +} diff --git a/core/esmf-aspect-model-document-generators/src/test/java/org/eclipse/esmf/aspectmodel/generator/zip/AspectModelZipGeneratorTest.java b/core/esmf-aspect-model-document-generators/src/test/java/org/eclipse/esmf/aspectmodel/generator/zip/AspectModelZipGeneratorTest.java new file mode 100644 index 000000000..f747253c5 --- /dev/null +++ b/core/esmf-aspect-model-document-generators/src/test/java/org/eclipse/esmf/aspectmodel/generator/zip/AspectModelZipGeneratorTest.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2024 Robert Bosch Manufacturing Solutions GmbH + * + * See the AUTHORS file(s) distributed with this work for additional + * information regarding authorship. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * SPDX-License-Identifier: MPL-2.0 + */ + +package org.eclipse.esmf.aspectmodel.generator.zip; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +import org.eclipse.esmf.aspectmodel.loader.AspectModelLoader; +import org.eclipse.esmf.metamodel.AspectModel; +import org.eclipse.esmf.test.TestAspect; +import org.eclipse.esmf.test.TestResources; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class AspectModelZipGeneratorTest { + + Path outputDirectory = null; + + @BeforeEach + void beforeEach() throws IOException { + outputDirectory = Files.createTempDirectory( "junit" ); + } + + @Test + void testAspectModelZipGeneration() throws IOException { + final AspectModel aspectModel = TestResources.load( TestAspect.ASPECT_WITH_PROPERTY ); + final String outputFileName = String.format( "%s/%s", outputDirectory.toString(), "/test_zip.zip" ); + + AspectModelZipGenerator.generateZipAspectModelArchive( aspectModel, outputFileName ); + + assertThat( new File( outputFileName ) ).exists(); + + final AspectModel aspectModelResult = new AspectModelLoader().loadFromArchive( outputFileName ); + assertThat( aspectModelResult.namespaces() ).hasSize( 1 ); + assertThat( aspectModelResult.files() ).hasSize( 1 ); + assertThat( aspectModelResult.files().get( 0 ).aspect() ).isEqualTo( aspectModel.aspect() ); + } +} From 3ac863a4a3beeb14726507db750698483734256e Mon Sep 17 00:00:00 2001 From: Yauhenikapl Date: Thu, 18 Jul 2024 17:00:42 +0300 Subject: [PATCH 06/20] Fix style and remove not needed code --- .../generator/AspectModelZipGenerator.java | 63 ------------------- .../AspectModelZipGeneratorTest.java | 36 ----------- 2 files changed, 99 deletions(-) delete mode 100644 core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/generator/AspectModelZipGenerator.java delete mode 100644 core/esmf-aspect-meta-model-java/src/test/java/org/eclipse/esmf/aspectmodel/generator/AspectModelZipGeneratorTest.java diff --git a/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/generator/AspectModelZipGenerator.java b/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/generator/AspectModelZipGenerator.java deleted file mode 100644 index edb0cfc7d..000000000 --- a/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/generator/AspectModelZipGenerator.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2024 Robert Bosch Manufacturing Solutions GmbH - * - * See the AUTHORS file(s) distributed with this work for additional - * information regarding authorship. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * SPDX-License-Identifier: MPL-2.0 - */ - -package org.eclipse.esmf.aspectmodel.generator; - -import java.io.BufferedOutputStream; -import java.io.BufferedWriter; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.io.Writer; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; - -import org.eclipse.esmf.aspectmodel.AspectModelFile; -import org.eclipse.esmf.metamodel.AspectModel; - -public class AspectModelZipGenerator { - - private static final int BUFFER_SIZE = 4096; - - public static void generateZipAspectModelArchive( final AspectModel aspectModel, final String zipFilePath ) throws IOException { - Path zipFile = Files.createFile( Paths.get( zipFilePath ) ); - try ( FileOutputStream fos = new FileOutputStream( zipFilePath ); - BufferedOutputStream bos = new BufferedOutputStream( fos ); - ZipOutputStream zos = new ZipOutputStream( bos ) ) { - - for ( final AspectModelFile aspectModelFile : aspectModel.files() ) { - addFileToZip( aspectModelFile, zos ); - } - } - } - - private static void addFileToZip( final AspectModelFile file, final ZipOutputStream zos ) throws IOException { - final String aspectString = file.aspect().toString(); -// final String aspectString = AspectSerializer.INSTANCE.apply( aspect ); - final String fileName = String.format( "%s/%s/%s.ttl", file.aspect().urn().getNamespace(), file.aspect().urn().getVersion(), - file.aspect().getName() ); - final ZipEntry zipEntry = new ZipEntry( fileName ); - zos.putNextEntry( zipEntry ); - - try ( Writer writer = new BufferedWriter( new OutputStreamWriter( zos ) ) ) { - writer.write( aspectString ); - } catch ( IOException exception ) { - throw new IOException( "Could not write to zip entry: " + fileName, exception ); - } finally { - zos.closeEntry(); - } - } -} diff --git a/core/esmf-aspect-meta-model-java/src/test/java/org/eclipse/esmf/aspectmodel/generator/AspectModelZipGeneratorTest.java b/core/esmf-aspect-meta-model-java/src/test/java/org/eclipse/esmf/aspectmodel/generator/AspectModelZipGeneratorTest.java deleted file mode 100644 index b2a3175bf..000000000 --- a/core/esmf-aspect-meta-model-java/src/test/java/org/eclipse/esmf/aspectmodel/generator/AspectModelZipGeneratorTest.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2024 Robert Bosch Manufacturing Solutions GmbH - * - * See the AUTHORS file(s) distributed with this work for additional - * information regarding authorship. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. - * - * SPDX-License-Identifier: MPL-2.0 - */ - -package org.eclipse.esmf.aspectmodel.generator; - -import java.io.IOException; - -import org.eclipse.esmf.aspectmodel.AspectModelFile; -import org.eclipse.esmf.aspectmodel.loader.AspectModelLoader; -import org.eclipse.esmf.aspectmodel.resolver.AspectModelFileLoader; -import org.eclipse.esmf.metamodel.AspectModel; -import org.eclipse.esmf.test.TestAspect; -import org.eclipse.esmf.test.TestResources; - -import org.junit.jupiter.api.Test; - -public class AspectModelZipGeneratorTest { - - @Test - public void testAspectModelZipGeneration() throws IOException { -// final AspectModelFile aspectModelFile_1 = AspectModelFileLoader.load( ) - final AspectModel aspectModel = TestResources.load( TestAspect.ASPECT_WITH_MULTIPLE_ENTITIES_SAME_EXTEND ); - - AspectModelZipGenerator.generateZipAspectModelArchive( aspectModel, "/Users/Yauheni_Kapliarchuk/Downloads/testzip.zip" ); - } -} From 8da11d27c40ba73ca334f511fbf71f53ae76cb92 Mon Sep 17 00:00:00 2001 From: Yauhenikapl Date: Tue, 23 Jul 2024 16:23:13 +0300 Subject: [PATCH 07/20] Update PR with --- .../aspectmodel/loader/AspectModelLoader.java | 89 ++++++++++++++---- .../loader/AspectModelLoaderTest.java | 50 +++++++++- .../resources/namespaces_with_old_version.zip | Bin 0 -> 6076 bytes .../AspectModelNamespacePackageCreator.java | 63 +++++++++++++ .../zip/AspectModelZipGenerator.java | 49 ---------- .../zip/AspectModelZipGeneratorTest.java | 9 +- 6 files changed, 188 insertions(+), 72 deletions(-) create mode 100644 core/esmf-aspect-meta-model-java/src/test/resources/namespaces_with_old_version.zip create mode 100644 core/esmf-aspect-model-document-generators/src/main/java/org/eclipse/esmf/aspectmodel/generator/zip/AspectModelNamespacePackageCreator.java delete mode 100644 core/esmf-aspect-model-document-generators/src/main/java/org/eclipse/esmf/aspectmodel/generator/zip/AspectModelZipGenerator.java diff --git a/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoader.java b/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoader.java index 5cc1eb3f0..69f207d0a 100644 --- a/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoader.java +++ b/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoader.java @@ -15,7 +15,10 @@ import static java.util.stream.Collectors.toSet; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.File; +import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; @@ -24,7 +27,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Deque; -import java.util.Enumeration; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -34,7 +36,7 @@ import java.util.function.Supplier; import java.util.stream.Stream; import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; +import java.util.zip.ZipInputStream; import org.eclipse.esmf.aspectmodel.AspectModelFile; import org.eclipse.esmf.aspectmodel.resolver.AspectModelFileLoader; @@ -71,6 +73,7 @@ */ public class AspectModelLoader implements ResolutionStrategySupport { private static final Logger LOG = LoggerFactory.getLogger( AspectModelLoader.class ); + private static final String ASPECT_MODELS_FOLDER = "aspect-models"; public static final Supplier DEFAULT_STRATEGY = () -> { final Path currentDirectory = Path.of( System.getProperty( "user.dir" ) ); @@ -178,37 +181,89 @@ public AspectModel load( final InputStream inputStream ) { return buildAspectModel( loaderContext.loadedFiles() ); } - public AspectModel loadFromArchive( final String pathToArchive ) { - File zipFile = new File( pathToArchive ); + @FunctionalInterface + public interface InputStreamProvider { + InputStream get() throws IOException; + } - if ( !zipFile.exists() || !zipFile.isFile() ) { + /** + * Load Namespace Package (Archive) an Aspect Model from a File + * + * @param namespacePackage the archive file + * @return the Aspect Model + */ + public AspectModel loadNamespacePackage( final File namespacePackage ) { + if ( !namespacePackage.exists() || !namespacePackage.isFile() ) { throw new RuntimeException( new FileNotFoundException( "The specified file does not exist or is not a file." ) ); } + try ( InputStream inputStream = new FileInputStream( namespacePackage ) ) { + return loadNamespacePackage( inputStream ); + } catch ( IOException e ) { + LOG.error( "Error reading the file: {}", namespacePackage.getAbsolutePath(), e ); + throw new RuntimeException( "Error reading the file: " + namespacePackage.getAbsolutePath(), e ); + } + } + + /** + * Load Namespace Package (Archive) an Aspect Model from an InputStream + * + * @param inputStream the input stream + * @return the Aspect Model + */ + public AspectModel loadNamespacePackage( final InputStream inputStream ) { + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try { + inputStream.transferTo( baos ); + } catch ( IOException e ) { + throw new RuntimeException( e ); + } + final boolean hasAspectModelsFolder = containsFolderInNamespacePackage( new ByteArrayInputStream( baos.toByteArray() ) ); + return loadNamespacePackageFromStream( new ByteArrayInputStream( baos.toByteArray() ), hasAspectModelsFolder ); + } + + private AspectModel loadNamespacePackageFromStream( final InputStream inputStream, final boolean hasAspectModelsFolder ) { List aspectModelFiles = new ArrayList<>(); - try ( ZipFile zip = new ZipFile( zipFile ) ) { - Enumeration entries = zip.entries(); + try ( ZipInputStream zis = new ZipInputStream( inputStream ) ) { + ZipEntry entry; - while ( entries.hasMoreElements() ) { - ZipEntry entry = entries.nextElement(); + while ( (entry = zis.getNextEntry()) != null ) { + boolean isRelevantEntry = + (hasAspectModelsFolder && entry.getName().startsWith( ASPECT_MODELS_FOLDER ) && entry.getName().endsWith( ".ttl" )) || + (!hasAspectModelsFolder && entry.getName().endsWith( ".ttl" )); - if ( entry.getName().endsWith( ".ttl" ) ) { - try ( InputStream inputStream = zip.getInputStream( entry ) ) { - AspectModelFile aspectModelFile = AspectModelFileLoader.load( inputStream ); - aspectModelFiles.add( aspectModelFile ); - } catch ( IOException e ) { - LOG.error( String.format( "Error reading entry: %s - %s", entry.getName(), e.getMessage() ) ); - } + if ( isRelevantEntry ) { + AspectModelFile aspectModelFile = migrate( AspectModelFileLoader.load( zis ) ); + aspectModelFiles.add( aspectModelFile ); } } + + zis.closeEntry(); } catch ( IOException e ) { - LOG.error( String.format( "Error reading the ZIP file: %s", e.getMessage() ) ); + LOG.error( "Error reading the Archive input stream", e ); + throw new RuntimeException( "Error reading the Archive input stream", e ); } + LoaderContext loaderContext = new LoaderContext(); + resolve( aspectModelFiles, loaderContext ); return buildAspectModel( aspectModelFiles ); } + private boolean containsFolderInNamespacePackage( final InputStream inputStream ) { + try ( ZipInputStream zis = new ZipInputStream( inputStream ) ) { + ZipEntry entry; + while ( (entry = zis.getNextEntry()) != null ) { + if ( entry.isDirectory() && entry.getName().equals( ASPECT_MODELS_FOLDER ) ) { + return true; + } + } + } catch ( IOException e ) { + throw new RuntimeException( e ); + } + return false; + } + private AspectModelFile migrate( final AspectModelFile file ) { return MetaModelVersionMigrator.INSTANCE.apply( file ); } diff --git a/core/esmf-aspect-meta-model-java/src/test/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoaderTest.java b/core/esmf-aspect-meta-model-java/src/test/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoaderTest.java index c68a2eda2..46f970a46 100644 --- a/core/esmf-aspect-meta-model-java/src/test/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoaderTest.java +++ b/core/esmf-aspect-meta-model-java/src/test/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoaderTest.java @@ -15,6 +15,9 @@ import static org.assertj.core.api.Assertions.assertThat; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.net.URISyntaxException; import java.nio.file.Path; import java.nio.file.Paths; @@ -34,7 +37,7 @@ class AspectModelLoaderTest { @Test - public void testOfAbstractEntityCyclomaticCreation() { + void testOfAbstractEntityCyclomaticCreation() { final Map entities = TestResources.load( TestAspect.ASPECT_WITH_MULTIPLE_ENTITIES_SAME_EXTEND ).elements() .stream().filter( ComplexType.class::isInstance ).map( ComplexType.class::cast ) .collect( Collectors.toMap( ComplexType::getName, Function.identity() ) ); @@ -48,10 +51,10 @@ public void testOfAbstractEntityCyclomaticCreation() { } @Test - public void testLoadAspectModelFromZipArchive() throws URISyntaxException { + void testLoadAspectModelFromZipArchiveFile() throws URISyntaxException { final ClassLoader classLoader = getClass().getClassLoader(); final Path archivePath = Paths.get( classLoader.getResource( "namespaces.zip" ).toURI() ); - final AspectModel aspectModel = new AspectModelLoader().loadFromArchive( archivePath.toString() ); + final AspectModel aspectModel = new AspectModelLoader().loadNamespacePackage( new File( archivePath.toString() ) ); assertThat( aspectModel.namespaces() ).hasSize( 2 ); assertThat( aspectModel.namespaces().get( 0 ).getName() ).contains( "urn:samm:org.eclipse.examples:1.1.0" ); @@ -65,4 +68,45 @@ public void testLoadAspectModelFromZipArchive() throws URISyntaxException { assertThat( aspectsNames ).contains( aspectModelFile.aspect().getName() ); } ); } + + @Test + void testLoadAspectModelFromZipArchiveInputStream() throws URISyntaxException, FileNotFoundException { + final ClassLoader classLoader = getClass().getClassLoader(); + final Path archivePath = Paths.get( classLoader.getResource( "namespaces.zip" ).toURI() ); + final AspectModel aspectModel = new AspectModelLoader().loadNamespacePackage( new FileInputStream( archivePath.toString() ) ); + + assertThat( aspectModel.namespaces() ).hasSize( 2 ); + assertThat( aspectModel.namespaces().get( 0 ).getName() ).contains( "urn:samm:org.eclipse.examples:1.1.0" ); + assertThat( aspectModel.namespaces().get( 1 ).getName() ).contains( "urn:samm:org.eclipse.examples:1.0.0" ); + + final List aspectsNames = List.of( "Movement2", "Movement3", "Movement", "SimpleAspect" ); + + assertThat( aspectModel.files() ).hasSize( 4 ); + assertThat( aspectModel.files() ) + .anySatisfy( aspectModelFile -> { + assertThat( aspectsNames ).contains( aspectModelFile.aspect().getName() ); + } ); + } + + /** + * Test migration to the latest version of Aspect Model in Archive + */ + @Test + void testLoadAspectModelFromZipArchive2_0_0() throws URISyntaxException, FileNotFoundException { + final ClassLoader classLoader = getClass().getClassLoader(); + final Path archivePath = Paths.get( classLoader.getResource( "namespaces_with_old_version.zip" ).toURI() ); + final AspectModel aspectModel = new AspectModelLoader().loadNamespacePackage( new FileInputStream( archivePath.toString() ) ); + + assertThat( aspectModel.namespaces() ).hasSize( 2 ); + assertThat( aspectModel.namespaces().get( 0 ).getName() ).contains( "urn:samm:org.eclipse.examples:1.1.0" ); + assertThat( aspectModel.namespaces().get( 1 ).getName() ).contains( "urn:samm:org.eclipse.examples:1.0.0" ); + + final List aspectsNames = List.of( "Movement2", "Movement3", "Movement4", "Movement", "SimpleAspect" ); + + assertThat( aspectModel.files() ).hasSize( 5 ); + assertThat( aspectModel.files() ) + .anySatisfy( aspectModelFile -> { + assertThat( aspectsNames ).contains( aspectModelFile.aspect().getName() ); + } ); + } } \ No newline at end of file diff --git a/core/esmf-aspect-meta-model-java/src/test/resources/namespaces_with_old_version.zip b/core/esmf-aspect-meta-model-java/src/test/resources/namespaces_with_old_version.zip new file mode 100644 index 0000000000000000000000000000000000000000..f76893c5b942cc450b0418504bc8c210aea0879d GIT binary patch literal 6076 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 P_~p9$<=X(i{(1ieKa@CV literal 0 HcmV?d00001 diff --git a/core/esmf-aspect-model-document-generators/src/main/java/org/eclipse/esmf/aspectmodel/generator/zip/AspectModelNamespacePackageCreator.java b/core/esmf-aspect-model-document-generators/src/main/java/org/eclipse/esmf/aspectmodel/generator/zip/AspectModelNamespacePackageCreator.java new file mode 100644 index 000000000..4ce0dc7e4 --- /dev/null +++ b/core/esmf-aspect-model-document-generators/src/main/java/org/eclipse/esmf/aspectmodel/generator/zip/AspectModelNamespacePackageCreator.java @@ -0,0 +1,63 @@ +package org.eclipse.esmf.aspectmodel.generator.zip; + +import java.io.BufferedOutputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +import org.eclipse.esmf.aspectmodel.AspectModelFile; +import org.eclipse.esmf.aspectmodel.serializer.AspectSerializer; +import org.eclipse.esmf.metamodel.AspectModel; + +import org.apache.commons.lang3.function.TriConsumer; + +public class AspectModelNamespacePackageCreator implements TriConsumer { + + private static final String AASX_ARCHIVE_FORMAT_PATH = "aasx/aspect-models/"; + private static final String BASE_ARCHIVE_FORMAT_PATH = "aspect-models/"; + + public static final AspectModelNamespacePackageCreator INSTANCE = new AspectModelNamespacePackageCreator(); + + private AspectModelNamespacePackageCreator() { + } + + @Override + public void accept( final AspectModel aspectModel, final OutputStream outputStream, final Boolean isAasxArchiveFormat ) { + try ( FileOutputStream fos = (FileOutputStream) outputStream; + BufferedOutputStream bos = new BufferedOutputStream( fos ); + ZipOutputStream zos = new ZipOutputStream( bos ) ) { + + for ( final AspectModelFile aspectModelFile : aspectModel.files() ) { + addFileToArchive( aspectModelFile, zos, isAasxArchiveFormat ); + } + } catch ( IOException e ) { + try { + throw new IOException( "Error creating zip archive!", e ); + } catch ( IOException ex ) { + throw new RuntimeException( ex ); + } + } + } + + private static void addFileToArchive( final AspectModelFile file, final ZipOutputStream zos, final boolean isAasxZipFormat ) + throws IOException { + final String aspectString = AspectSerializer.INSTANCE.apply( file.aspect() ); + final String fileName = String.format( "%s/%s/%s/%s.ttl", + isAasxZipFormat ? AASX_ARCHIVE_FORMAT_PATH : BASE_ARCHIVE_FORMAT_PATH, + file.aspect().urn().getNamespace(), + file.aspect().urn().getVersion(), + file.aspect().getName() ); + final ZipEntry zipEntry = new ZipEntry( fileName ); + zos.putNextEntry( zipEntry ); + + Writer writer = new OutputStreamWriter( zos ); + writer.write( aspectString ); + writer.flush(); + + zos.closeEntry(); + } +} diff --git a/core/esmf-aspect-model-document-generators/src/main/java/org/eclipse/esmf/aspectmodel/generator/zip/AspectModelZipGenerator.java b/core/esmf-aspect-model-document-generators/src/main/java/org/eclipse/esmf/aspectmodel/generator/zip/AspectModelZipGenerator.java deleted file mode 100644 index 7281269c8..000000000 --- a/core/esmf-aspect-model-document-generators/src/main/java/org/eclipse/esmf/aspectmodel/generator/zip/AspectModelZipGenerator.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.eclipse.esmf.aspectmodel.generator.zip; - -import java.io.BufferedOutputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.io.Writer; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; - -import org.eclipse.esmf.aspectmodel.AspectModelFile; -import org.eclipse.esmf.aspectmodel.serializer.AspectSerializer; -import org.eclipse.esmf.metamodel.AspectModel; - -public class AspectModelZipGenerator { - - public static void generateZipAspectModelArchive( final AspectModel aspectModel, final String zipFilePath ) throws IOException { - final Path zipFile = Paths.get( zipFilePath ); - - try ( FileOutputStream fos = new FileOutputStream( zipFile.toFile() ); - BufferedOutputStream bos = new BufferedOutputStream( fos ); - ZipOutputStream zos = new ZipOutputStream( bos ) ) { - - for ( final AspectModelFile aspectModelFile : aspectModel.files() ) { - addFileToZip( aspectModelFile, zos ); - } - } catch ( IOException e ) { - throw new IOException( "Error creating zip archive: " + zipFilePath, e ); - } - } - - private static void addFileToZip( final AspectModelFile file, ZipOutputStream zos ) throws IOException { - final String aspectString = AspectSerializer.INSTANCE.apply( file.aspect() ); - final String fileName = String.format( "%s/%s/%s.ttl", - file.aspect().urn().getNamespace(), - file.aspect().urn().getVersion(), - file.aspect().getName() ); - final ZipEntry zipEntry = new ZipEntry( fileName ); - zos.putNextEntry( zipEntry ); - - Writer writer = new OutputStreamWriter( zos ); - writer.write( aspectString ); - writer.flush(); - - zos.closeEntry(); - } -} diff --git a/core/esmf-aspect-model-document-generators/src/test/java/org/eclipse/esmf/aspectmodel/generator/zip/AspectModelZipGeneratorTest.java b/core/esmf-aspect-model-document-generators/src/test/java/org/eclipse/esmf/aspectmodel/generator/zip/AspectModelZipGeneratorTest.java index f747253c5..89096e4b8 100644 --- a/core/esmf-aspect-model-document-generators/src/test/java/org/eclipse/esmf/aspectmodel/generator/zip/AspectModelZipGeneratorTest.java +++ b/core/esmf-aspect-model-document-generators/src/test/java/org/eclipse/esmf/aspectmodel/generator/zip/AspectModelZipGeneratorTest.java @@ -16,9 +16,11 @@ import static org.assertj.core.api.Assertions.assertThat; import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; import org.eclipse.esmf.aspectmodel.loader.AspectModelLoader; import org.eclipse.esmf.metamodel.AspectModel; @@ -38,15 +40,16 @@ void beforeEach() throws IOException { } @Test - void testAspectModelZipGeneration() throws IOException { + void testAspectModelArchiveGeneration() throws IOException { final AspectModel aspectModel = TestResources.load( TestAspect.ASPECT_WITH_PROPERTY ); final String outputFileName = String.format( "%s/%s", outputDirectory.toString(), "/test_zip.zip" ); - AspectModelZipGenerator.generateZipAspectModelArchive( aspectModel, outputFileName ); + AspectModelNamespacePackageCreator.INSTANCE.accept( aspectModel, new FileOutputStream( Paths.get( outputFileName ).toFile() ), + false ); assertThat( new File( outputFileName ) ).exists(); - final AspectModel aspectModelResult = new AspectModelLoader().loadFromArchive( outputFileName ); + final AspectModel aspectModelResult = new AspectModelLoader().loadNamespacePackage( new File( outputFileName ) ); assertThat( aspectModelResult.namespaces() ).hasSize( 1 ); assertThat( aspectModelResult.files() ).hasSize( 1 ); assertThat( aspectModelResult.files().get( 0 ).aspect() ).isEqualTo( aspectModel.aspect() ); From 05839a32143f83438799a9cf99a4482e074c41a2 Mon Sep 17 00:00:00 2001 From: Yauhenikapl Date: Tue, 23 Jul 2024 16:28:22 +0300 Subject: [PATCH 08/20] Fix styles --- .../aspectmodel/loader/AspectModelLoader.java | 65 +++++++------------ 1 file changed, 23 insertions(+), 42 deletions(-) diff --git a/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoader.java b/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoader.java index 69f207d0a..54b81ddc3 100644 --- a/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoader.java +++ b/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoader.java @@ -133,10 +133,7 @@ public AspectModel load( final File file ) { * @return the Aspect Model */ public AspectModel load( final Collection files ) { - final List migratedFiles = files.stream() - .map( AspectModelFileLoader::load ) - .map( this::migrate ) - .toList(); + final List migratedFiles = files.stream().map( AspectModelFileLoader::load ).map( this::migrate ).toList(); final LoaderContext loaderContext = new LoaderContext(); resolve( migratedFiles, loaderContext ); return buildAspectModel( loaderContext.loadedFiles() ); @@ -230,8 +227,8 @@ private AspectModel loadNamespacePackageFromStream( final InputStream inputStrea while ( (entry = zis.getNextEntry()) != null ) { boolean isRelevantEntry = - (hasAspectModelsFolder && entry.getName().startsWith( ASPECT_MODELS_FOLDER ) && entry.getName().endsWith( ".ttl" )) || - (!hasAspectModelsFolder && entry.getName().endsWith( ".ttl" )); + (hasAspectModelsFolder && entry.getName().startsWith( ASPECT_MODELS_FOLDER ) && entry.getName().endsWith( ".ttl" )) || ( + !hasAspectModelsFolder && entry.getName().endsWith( ".ttl" )); if ( isRelevantEntry ) { AspectModelFile aspectModelFile = migrate( AspectModelFileLoader.load( zis ) ); @@ -268,12 +265,8 @@ private AspectModelFile migrate( final AspectModelFile file ) { return MetaModelVersionMigrator.INSTANCE.apply( file ); } - private record LoaderContext( - Set resolvedUrns, - Set loadedFiles, - Deque unresolvedUrns, - Deque unresolvedFiles - ) { + private record LoaderContext( Set resolvedUrns, Set loadedFiles, Deque unresolvedUrns, + Deque unresolvedFiles ) { private LoaderContext() { this( new HashSet<>(), new HashSet<>(), new ArrayDeque<>(), new ArrayDeque<>() ); } @@ -281,18 +274,16 @@ private LoaderContext() { private Set getAllUrnsInModel( final Model model ) { return Streams.stream( model.listStatements().mapWith( statement -> { - final Stream subjectUri = statement.getSubject().isURIResource() - ? Stream.of( statement.getSubject().getURI() ) - : Stream.empty(); + final Stream subjectUri = statement.getSubject().isURIResource() ? + Stream.of( statement.getSubject().getURI() ) : + Stream.empty(); final Stream propertyUri = Stream.of( statement.getPredicate().getURI() ); - final Stream objectUri = statement.getObject().isURIResource() - ? Stream.of( statement.getObject().asResource().getURI() ) - : Stream.empty(); - - return Stream.of( subjectUri, propertyUri, objectUri ) - .flatMap( Function.identity() ) - .flatMap( urn -> AspectModelUrn.from( urn ).toJavaOptional().stream() ) - .map( AspectModelUrn::toString ); + final Stream objectUri = statement.getObject().isURIResource() ? + Stream.of( statement.getObject().asResource().getURI() ) : + Stream.empty(); + + return Stream.of( subjectUri, propertyUri, objectUri ).flatMap( Function.identity() ) + .flatMap( urn -> AspectModelUrn.from( urn ).toJavaOptional().stream() ).map( AspectModelUrn::toString ); } ) ).flatMap( Function.identity() ).collect( toSet() ); } @@ -351,21 +342,14 @@ private Optional applyResolutionStrategy( final String urn ) { } private void urnsFromModelNeedResolution( final AspectModelFile modelFile, final LoaderContext context ) { - Streams.stream( modelFile.sourceModel().listStatements( null, RDF.type, (RDFNode) null ) ) - .map( Statement::getSubject ) - .filter( Resource::isURIResource ) - .map( Resource::getURI ) - .filter( uri -> uri.startsWith( "urn:samm:" ) ) + Streams.stream( modelFile.sourceModel().listStatements( null, RDF.type, (RDFNode) null ) ).map( Statement::getSubject ) + .filter( Resource::isURIResource ).map( Resource::getURI ).filter( uri -> uri.startsWith( "urn:samm:" ) ) .forEach( urn -> context.resolvedUrns().add( urn ) ); - getAllUrnsInModel( modelFile.sourceModel() ).stream() - .filter( urn -> !context.resolvedUrns().contains( urn ) ) - .filter( urn -> !urn.startsWith( XSD.NS ) ) - .filter( urn -> !urn.startsWith( RDF.uri ) ) - .filter( urn -> !urn.startsWith( SammNs.SAMM.getNamespace() ) ) - .filter( urn -> !urn.startsWith( SammNs.SAMMC.getNamespace() ) ) - .filter( urn -> !urn.startsWith( SammNs.SAMME.getNamespace() ) ) - .filter( urn -> !urn.startsWith( SammNs.UNIT.getNamespace() ) ) + getAllUrnsInModel( modelFile.sourceModel() ).stream().filter( urn -> !context.resolvedUrns().contains( urn ) ) + .filter( urn -> !urn.startsWith( XSD.NS ) ).filter( urn -> !urn.startsWith( RDF.uri ) ) + .filter( urn -> !urn.startsWith( SammNs.SAMM.getNamespace() ) ).filter( urn -> !urn.startsWith( SammNs.SAMMC.getNamespace() ) ) + .filter( urn -> !urn.startsWith( SammNs.SAMME.getNamespace() ) ).filter( urn -> !urn.startsWith( SammNs.UNIT.getNamespace() ) ) .forEach( urn -> context.unresolvedUrns().add( urn ) ); } @@ -391,8 +375,7 @@ private void resolve( final List inputFiles, final LoaderContex } while ( !context.unresolvedUrns().isEmpty() ) { - applyResolutionStrategy( context.unresolvedUrns().pop() ) - .map( this::migrate ) + applyResolutionStrategy( context.unresolvedUrns().pop() ).map( this::migrate ) .ifPresent( resolvedFile -> markModelFileAsLoaded( resolvedFile, context ) ); } } @@ -412,11 +395,9 @@ private AspectModel buildAspectModel( final Collection inputFil final Model model = file.sourceModel(); final ModelElementFactory modelElementFactory = new ModelElementFactory( mergedModel, Map.of(), element -> aspectModelFile ); final List fileElements = model.listStatements( null, RDF.type, (RDFNode) null ).toList().stream() - .map( Statement::getSubject ) - .filter( RDFNode::isURIResource ) + .map( Statement::getSubject ).filter( RDFNode::isURIResource ) .map( resource -> mergedModel.createResource( resource.getURI() ) ) - .map( resource -> modelElementFactory.create( ModelElement.class, resource ) ) - .toList(); + .map( resource -> modelElementFactory.create( ModelElement.class, resource ) ).toList(); aspectModelFile.setElements( fileElements ); elements.addAll( fileElements ); } From 261ce43b65294f1b5deeea47f73c4b73cec53467 Mon Sep 17 00:00:00 2001 From: Yauhenikapl Date: Tue, 23 Jul 2024 16:33:43 +0300 Subject: [PATCH 09/20] Fix styles --- .../esmf/aspectmodel/loader/AspectModelLoader.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoader.java b/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoader.java index 54b81ddc3..d9fd65c56 100644 --- a/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoader.java +++ b/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoader.java @@ -274,12 +274,12 @@ private LoaderContext() { private Set getAllUrnsInModel( final Model model ) { return Streams.stream( model.listStatements().mapWith( statement -> { - final Stream subjectUri = statement.getSubject().isURIResource() ? - Stream.of( statement.getSubject().getURI() ) : + final Stream subjectUri = statement.getSubject().isURIResource() + ? Stream.of( statement.getSubject().getURI() ) : Stream.empty(); final Stream propertyUri = Stream.of( statement.getPredicate().getURI() ); - final Stream objectUri = statement.getObject().isURIResource() ? - Stream.of( statement.getObject().asResource().getURI() ) : + final Stream objectUri = statement.getObject().isURIResource() + ? Stream.of( statement.getObject().asResource().getURI() ) : Stream.empty(); return Stream.of( subjectUri, propertyUri, objectUri ).flatMap( Function.identity() ) From 521b3e2a6b7f791a45277dd048f9ca0f6e9734f7 Mon Sep 17 00:00:00 2001 From: Yauhenikapl Date: Fri, 26 Jul 2024 19:08:34 +0300 Subject: [PATCH 10/20] Update tests, update AspectModelLoader --- .../aspectmodel/loader/AspectModelLoader.java | 46 +++++---- .../loader/AspectModelLoaderTest.java | 91 ++++++++++++++++-- .../1.0.0/propertyWithExampleValue.ttl | 19 ++++ .../AspectModelNamespacePackageCreator.java | 11 +-- .../zip/AspectModelZipGeneratorTest.java | 2 +- .../namespace-with-shared-property.zip | Bin 0 -> 2263 bytes .../namespaces-aspect-models-root.zip | Bin 0 -> 7535 bytes .../namespaces-aspect-models-subfolder.zip | Bin 0 -> 10352 bytes .../main/resources/packages}/namespaces.zip | Bin .../packages}/namespaces_with_old_version.zip | Bin 10 files changed, 136 insertions(+), 33 deletions(-) create mode 100644 core/esmf-aspect-meta-model-java/src/test/resources/samm_2_1_0/org.eclipse.esmf.test/1.0.0/propertyWithExampleValue.ttl create mode 100644 core/esmf-test-aspect-models/src/main/resources/packages/namespace-with-shared-property.zip create mode 100644 core/esmf-test-aspect-models/src/main/resources/packages/namespaces-aspect-models-root.zip create mode 100644 core/esmf-test-aspect-models/src/main/resources/packages/namespaces-aspect-models-subfolder.zip rename core/{esmf-aspect-meta-model-java/src/test/resources => esmf-test-aspect-models/src/main/resources/packages}/namespaces.zip (100%) rename core/{esmf-aspect-meta-model-java/src/test/resources => esmf-test-aspect-models/src/main/resources/packages}/namespaces_with_old_version.zip (100%) diff --git a/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoader.java b/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoader.java index d9fd65c56..5ce3cb4dd 100644 --- a/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoader.java +++ b/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoader.java @@ -227,8 +227,9 @@ private AspectModel loadNamespacePackageFromStream( final InputStream inputStrea while ( (entry = zis.getNextEntry()) != null ) { boolean isRelevantEntry = - (hasAspectModelsFolder && entry.getName().startsWith( ASPECT_MODELS_FOLDER ) && entry.getName().endsWith( ".ttl" )) || ( - !hasAspectModelsFolder && entry.getName().endsWith( ".ttl" )); + (hasAspectModelsFolder && entry.getName().contains( String.format( "%s/", ASPECT_MODELS_FOLDER ) ) && entry.getName() + .endsWith( ".ttl" )) + || (!hasAspectModelsFolder && entry.getName().endsWith( ".ttl" )); if ( isRelevantEntry ) { AspectModelFile aspectModelFile = migrate( AspectModelFileLoader.load( zis ) ); @@ -244,14 +245,14 @@ private AspectModel loadNamespacePackageFromStream( final InputStream inputStrea LoaderContext loaderContext = new LoaderContext(); resolve( aspectModelFiles, loaderContext ); - return buildAspectModel( aspectModelFiles ); + return buildAspectModel( loaderContext.loadedFiles() ); } private boolean containsFolderInNamespacePackage( final InputStream inputStream ) { try ( ZipInputStream zis = new ZipInputStream( inputStream ) ) { ZipEntry entry; while ( (entry = zis.getNextEntry()) != null ) { - if ( entry.isDirectory() && entry.getName().equals( ASPECT_MODELS_FOLDER ) ) { + if ( entry.isDirectory() && entry.getName().contains( String.format( "%s/", ASPECT_MODELS_FOLDER ) ) ) { return true; } } @@ -265,8 +266,12 @@ private AspectModelFile migrate( final AspectModelFile file ) { return MetaModelVersionMigrator.INSTANCE.apply( file ); } - private record LoaderContext( Set resolvedUrns, Set loadedFiles, Deque unresolvedUrns, - Deque unresolvedFiles ) { + private record LoaderContext( + Set resolvedUrns, + Set loadedFiles, + Deque unresolvedUrns, + Deque unresolvedFiles + ) { private LoaderContext() { this( new HashSet<>(), new HashSet<>(), new ArrayDeque<>(), new ArrayDeque<>() ); } @@ -275,12 +280,12 @@ private LoaderContext() { private Set getAllUrnsInModel( final Model model ) { return Streams.stream( model.listStatements().mapWith( statement -> { final Stream subjectUri = statement.getSubject().isURIResource() - ? Stream.of( statement.getSubject().getURI() ) : - Stream.empty(); + ? Stream.of( statement.getSubject().getURI() ) + : Stream.empty(); final Stream propertyUri = Stream.of( statement.getPredicate().getURI() ); final Stream objectUri = statement.getObject().isURIResource() - ? Stream.of( statement.getObject().asResource().getURI() ) : - Stream.empty(); + ? Stream.of( statement.getObject().asResource().getURI() ) + : Stream.empty(); return Stream.of( subjectUri, propertyUri, objectUri ).flatMap( Function.identity() ) .flatMap( urn -> AspectModelUrn.from( urn ).toJavaOptional().stream() ).map( AspectModelUrn::toString ); @@ -342,14 +347,21 @@ private Optional applyResolutionStrategy( final String urn ) { } private void urnsFromModelNeedResolution( final AspectModelFile modelFile, final LoaderContext context ) { - Streams.stream( modelFile.sourceModel().listStatements( null, RDF.type, (RDFNode) null ) ).map( Statement::getSubject ) - .filter( Resource::isURIResource ).map( Resource::getURI ).filter( uri -> uri.startsWith( "urn:samm:" ) ) + Streams.stream( modelFile.sourceModel().listStatements( null, RDF.type, (RDFNode) null ) ) + .map( Statement::getSubject ) + .filter( Resource::isURIResource ) + .map( Resource::getURI ) + .filter( uri -> uri.startsWith( "urn:samm:" ) ) .forEach( urn -> context.resolvedUrns().add( urn ) ); - getAllUrnsInModel( modelFile.sourceModel() ).stream().filter( urn -> !context.resolvedUrns().contains( urn ) ) - .filter( urn -> !urn.startsWith( XSD.NS ) ).filter( urn -> !urn.startsWith( RDF.uri ) ) - .filter( urn -> !urn.startsWith( SammNs.SAMM.getNamespace() ) ).filter( urn -> !urn.startsWith( SammNs.SAMMC.getNamespace() ) ) - .filter( urn -> !urn.startsWith( SammNs.SAMME.getNamespace() ) ).filter( urn -> !urn.startsWith( SammNs.UNIT.getNamespace() ) ) + getAllUrnsInModel( modelFile.sourceModel() ).stream() + .filter( urn -> !context.resolvedUrns().contains( urn ) ) + .filter( urn -> !urn.startsWith( XSD.NS ) ) + .filter( urn -> !urn.startsWith( RDF.uri ) ) + .filter( urn -> !urn.startsWith( SammNs.SAMM.getNamespace() ) ) + .filter( urn -> !urn.startsWith( SammNs.SAMMC.getNamespace() ) ) + .filter( urn -> !urn.startsWith( SammNs.SAMME.getNamespace() ) ) + .filter( urn -> !urn.startsWith( SammNs.UNIT.getNamespace() ) ) .forEach( urn -> context.unresolvedUrns().add( urn ) ); } @@ -360,7 +372,7 @@ private void markModelFileAsLoaded( final AspectModelFile modelFile, final Loade } } - private void resolve( final List inputFiles, final LoaderContext context ) { + private void resolve( List inputFiles, final LoaderContext context ) { for ( final AspectModelFile aspectModelFile : inputFiles ) { context.unresolvedFiles().push( aspectModelFile ); } diff --git a/core/esmf-aspect-meta-model-java/src/test/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoaderTest.java b/core/esmf-aspect-meta-model-java/src/test/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoaderTest.java index 46f970a46..abe9f90c1 100644 --- a/core/esmf-aspect-meta-model-java/src/test/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoaderTest.java +++ b/core/esmf-aspect-meta-model-java/src/test/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoaderTest.java @@ -27,9 +27,12 @@ import java.util.function.Function; import java.util.stream.Collectors; +import org.eclipse.esmf.aspectmodel.resolver.FileSystemStrategy; +import org.eclipse.esmf.aspectmodel.resolver.ResolutionStrategy; import org.eclipse.esmf.metamodel.AbstractEntity; import org.eclipse.esmf.metamodel.AspectModel; import org.eclipse.esmf.metamodel.ComplexType; +import org.eclipse.esmf.samm.KnownVersion; import org.eclipse.esmf.test.TestAspect; import org.eclipse.esmf.test.TestResources; @@ -51,9 +54,8 @@ void testOfAbstractEntityCyclomaticCreation() { } @Test - void testLoadAspectModelFromZipArchiveFile() throws URISyntaxException { - final ClassLoader classLoader = getClass().getClassLoader(); - final Path archivePath = Paths.get( classLoader.getResource( "namespaces.zip" ).toURI() ); + void testLoadAspectModelFromZipArchiveFile() { + final Path archivePath = getPackage( "namespaces.zip" ); final AspectModel aspectModel = new AspectModelLoader().loadNamespacePackage( new File( archivePath.toString() ) ); assertThat( aspectModel.namespaces() ).hasSize( 2 ); @@ -70,9 +72,8 @@ void testLoadAspectModelFromZipArchiveFile() throws URISyntaxException { } @Test - void testLoadAspectModelFromZipArchiveInputStream() throws URISyntaxException, FileNotFoundException { - final ClassLoader classLoader = getClass().getClassLoader(); - final Path archivePath = Paths.get( classLoader.getResource( "namespaces.zip" ).toURI() ); + void testLoadAspectModelFromZipArchiveInputStream() throws FileNotFoundException { + final Path archivePath = getPackage( "namespaces.zip" ); final AspectModel aspectModel = new AspectModelLoader().loadNamespacePackage( new FileInputStream( archivePath.toString() ) ); assertThat( aspectModel.namespaces() ).hasSize( 2 ); @@ -92,9 +93,8 @@ void testLoadAspectModelFromZipArchiveInputStream() throws URISyntaxException, F * Test migration to the latest version of Aspect Model in Archive */ @Test - void testLoadAspectModelFromZipArchive2_0_0() throws URISyntaxException, FileNotFoundException { - final ClassLoader classLoader = getClass().getClassLoader(); - final Path archivePath = Paths.get( classLoader.getResource( "namespaces_with_old_version.zip" ).toURI() ); + void testLoadAspectModelFromZipArchive2_0_0() throws FileNotFoundException { + final Path archivePath = getPackage( "namespaces_with_old_version.zip" ); final AspectModel aspectModel = new AspectModelLoader().loadNamespacePackage( new FileInputStream( archivePath.toString() ) ); assertThat( aspectModel.namespaces() ).hasSize( 2 ); @@ -109,4 +109,77 @@ void testLoadAspectModelFromZipArchive2_0_0() throws URISyntaxException, FileNot assertThat( aspectsNames ).contains( aspectModelFile.aspect().getName() ); } ); } + + @Test + void testLoadAspectModelFromZipArchiveAspectModelsRoot() throws FileNotFoundException { + final Path archivePath = getPackage( "namespaces-aspect-models-root.zip" ); + final AspectModel aspectModel = new AspectModelLoader().loadNamespacePackage( new FileInputStream( archivePath.toString() ) ); + + assertThat( aspectModel.namespaces() ).hasSize( 2 ); + assertThat( aspectModel.namespaces().get( 0 ).getName() ).contains( "urn:samm:org.eclipse.examples:1.1.0" ); + assertThat( aspectModel.namespaces().get( 1 ).getName() ).contains( "urn:samm:org.eclipse.examples:1.0.0" ); + + final List aspectsNames = List.of( "Movement2", "Movement3", "Movement", "SimpleAspect" ); + + assertThat( aspectModel.files() ).hasSize( 4 ); + assertThat( aspectModel.files() ) + .anySatisfy( aspectModelFile -> { + assertThat( aspectsNames ).contains( aspectModelFile.aspect().getName() ); + } ); + } + + @Test + void testLoadAspectModelFromZipArchiveAspectModelsSubfolder() throws FileNotFoundException { + final Path archivePath = getPackage( "namespaces-aspect-models-subfolder.zip" ); + final AspectModel aspectModel = new AspectModelLoader().loadNamespacePackage( new FileInputStream( archivePath.toString() ) ); + + assertThat( aspectModel.namespaces() ).hasSize( 2 ); + assertThat( aspectModel.namespaces().get( 0 ).getName() ).contains( "urn:samm:org.eclipse.examples:1.1.0" ); + assertThat( aspectModel.namespaces().get( 1 ).getName() ).contains( "urn:samm:org.eclipse.examples:1.0.0" ); + + final List aspectsNames = List.of( "Movement2", "Movement3", "Movement", "SimpleAspect" ); + + assertThat( aspectModel.files() ).hasSize( 4 ); + assertThat( aspectModel.files() ) + .anySatisfy( aspectModelFile -> { + assertThat( aspectsNames ).contains( aspectModelFile.aspect().getName() ); + } ); + } + + @Test + void testLoadAspectModelFromZipArchiveWithSharedProperty() throws FileNotFoundException, URISyntaxException { + final Path archivePath = getPackage( "namespace-with-shared-property.zip" ); + + final File aspectModelsRootDirectory = new File( + AspectModelLoaderTest.class.getClassLoader() + .getResource( KnownVersion.getLatest().toString().toLowerCase() ) + .toURI().getPath() ); + + final ResolutionStrategy urnStrategy = new FileSystemStrategy( aspectModelsRootDirectory.toPath() ); + + final AspectModel aspectModel = new AspectModelLoader( urnStrategy ).loadNamespacePackage( + new FileInputStream( archivePath.toString() ) ); + + assertThat( aspectModel.namespaces() ).hasSize( 1 ); + assertThat( aspectModel.namespaces().get( 0 ).getName() ).contains( "urn:samm:org.eclipse.esmf.test:1.0.0" ); + + final List aspectsNames = List.of( "Movement" ); + + assertThat( aspectModel.files() ).hasSize( 2 ); + assertThat( aspectModel.files() ) + .anySatisfy( aspectModelFile -> { + if ( !aspectModelFile.aspects().isEmpty() ) { + assertThat( aspectsNames ).contains( aspectModelFile.aspect().getName() ); + } + } ); + } + + /** + * Returns the File object for a test model file + */ + private Path getPackage( final String packageName ) { + return Paths.get( String.format( + "%s/../../core/esmf-test-aspect-models/src/main/resources/packages/%s", + System.getProperty( "user.dir" ), packageName ) ); + } } \ No newline at end of file diff --git a/core/esmf-aspect-meta-model-java/src/test/resources/samm_2_1_0/org.eclipse.esmf.test/1.0.0/propertyWithExampleValue.ttl b/core/esmf-aspect-meta-model-java/src/test/resources/samm_2_1_0/org.eclipse.esmf.test/1.0.0/propertyWithExampleValue.ttl new file mode 100644 index 000000000..b0feb8659 --- /dev/null +++ b/core/esmf-aspect-meta-model-java/src/test/resources/samm_2_1_0/org.eclipse.esmf.test/1.0.0/propertyWithExampleValue.ttl @@ -0,0 +1,19 @@ +# Copyright (c) 2023 Robert Bosch Manufacturing Solutions GmbH +# +# See the AUTHORS file(s) distributed with this work for additional +# information regarding authorship. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at https://mozilla.org/MPL/2.0/. +# +# SPDX-License-Identifier: MPL-2.0 + +@prefix : . +@prefix samm: . +@prefix samm-c: . +@prefix xsd: . + +:propertyWithExampleValue a samm:Property ; + samm:characteristic samm-c:Text ; + samm:exampleValue "test" . diff --git a/core/esmf-aspect-model-document-generators/src/main/java/org/eclipse/esmf/aspectmodel/generator/zip/AspectModelNamespacePackageCreator.java b/core/esmf-aspect-model-document-generators/src/main/java/org/eclipse/esmf/aspectmodel/generator/zip/AspectModelNamespacePackageCreator.java index 4ce0dc7e4..021cc91ec 100644 --- a/core/esmf-aspect-model-document-generators/src/main/java/org/eclipse/esmf/aspectmodel/generator/zip/AspectModelNamespacePackageCreator.java +++ b/core/esmf-aspect-model-document-generators/src/main/java/org/eclipse/esmf/aspectmodel/generator/zip/AspectModelNamespacePackageCreator.java @@ -15,9 +15,8 @@ import org.apache.commons.lang3.function.TriConsumer; -public class AspectModelNamespacePackageCreator implements TriConsumer { +public class AspectModelNamespacePackageCreator implements TriConsumer { - private static final String AASX_ARCHIVE_FORMAT_PATH = "aasx/aspect-models/"; private static final String BASE_ARCHIVE_FORMAT_PATH = "aspect-models/"; public static final AspectModelNamespacePackageCreator INSTANCE = new AspectModelNamespacePackageCreator(); @@ -26,13 +25,13 @@ private AspectModelNamespacePackageCreator() { } @Override - public void accept( final AspectModel aspectModel, final OutputStream outputStream, final Boolean isAasxArchiveFormat ) { + public void accept( final AspectModel aspectModel, final OutputStream outputStream, final String rootPath ) { try ( FileOutputStream fos = (FileOutputStream) outputStream; BufferedOutputStream bos = new BufferedOutputStream( fos ); ZipOutputStream zos = new ZipOutputStream( bos ) ) { for ( final AspectModelFile aspectModelFile : aspectModel.files() ) { - addFileToArchive( aspectModelFile, zos, isAasxArchiveFormat ); + addFileToArchive( aspectModelFile, zos, rootPath ); } } catch ( IOException e ) { try { @@ -43,11 +42,11 @@ public void accept( final AspectModel aspectModel, final OutputStream outputStre } } - private static void addFileToArchive( final AspectModelFile file, final ZipOutputStream zos, final boolean isAasxZipFormat ) + private static void addFileToArchive( final AspectModelFile file, final ZipOutputStream zos, final String rootPath ) throws IOException { final String aspectString = AspectSerializer.INSTANCE.apply( file.aspect() ); final String fileName = String.format( "%s/%s/%s/%s.ttl", - isAasxZipFormat ? AASX_ARCHIVE_FORMAT_PATH : BASE_ARCHIVE_FORMAT_PATH, + !rootPath.isBlank() ? String.format( "%s/%s", rootPath, BASE_ARCHIVE_FORMAT_PATH ) : BASE_ARCHIVE_FORMAT_PATH, file.aspect().urn().getNamespace(), file.aspect().urn().getVersion(), file.aspect().getName() ); diff --git a/core/esmf-aspect-model-document-generators/src/test/java/org/eclipse/esmf/aspectmodel/generator/zip/AspectModelZipGeneratorTest.java b/core/esmf-aspect-model-document-generators/src/test/java/org/eclipse/esmf/aspectmodel/generator/zip/AspectModelZipGeneratorTest.java index 89096e4b8..305325bbd 100644 --- a/core/esmf-aspect-model-document-generators/src/test/java/org/eclipse/esmf/aspectmodel/generator/zip/AspectModelZipGeneratorTest.java +++ b/core/esmf-aspect-model-document-generators/src/test/java/org/eclipse/esmf/aspectmodel/generator/zip/AspectModelZipGeneratorTest.java @@ -45,7 +45,7 @@ void testAspectModelArchiveGeneration() throws IOException { final String outputFileName = String.format( "%s/%s", outputDirectory.toString(), "/test_zip.zip" ); AspectModelNamespacePackageCreator.INSTANCE.accept( aspectModel, new FileOutputStream( Paths.get( outputFileName ).toFile() ), - false ); + "" ); assertThat( new File( outputFileName ) ).exists(); diff --git a/core/esmf-test-aspect-models/src/main/resources/packages/namespace-with-shared-property.zip b/core/esmf-test-aspect-models/src/main/resources/packages/namespace-with-shared-property.zip new file mode 100644 index 0000000000000000000000000000000000000000..ae0b95181a02ebbeff7f9523707864ae2ea05b72 GIT binary patch literal 2263 zcmWIWW@Zs#0D-9d9}!>%l;B}dU?@o~F40ZP&q+xw(hm*cWnj;_w;*lv!v$#|y0n6u zfsy4aBLf52gaEin5yhw`NuimPSX_{rT%wzspOTtW3^DiTlLcwNfEYyMG?%*o)m#I- z=H?fr>!l{=WEK>s>ZKOvrs;t^1F`KG)E9Vd6DdTs&5R7&4D}533?O#ye6S#G7Z8JJ z96sb=xC{(Aw&fr1X0k9abnr7UIFW6qZ+=;7ZfahMUP(y~IOgs@U6A$=h(R=({aeFx z^KY98{F@i=xFcR@!L&CjM`cPmCW+pRQn=Z)Gn$Pj`+%2vr?xAXO6t+SU#)}Im+9Qh z+^FBFbl0~0`<;)L&$Pk?HmeIwkmpuq^4+X6LF=Q!6P@c18qX!2Z!kM}XLjZ0@aada zcde?O^Kr)f>e-D8FZ;M1Xb#Tb$DAbfj-4}jRYrz`VQz#43(N0D2Z^+6)(l(+&(xKt zf4vjwYWQo}u_ul1r>DN0nl8um<8ya6cYWEb`SbiPrmVVt=)&@q7jB=cTK@fIj@jq* z;`=+>G*e0rzxQ-^&MW@Ee)sLv=S3oSPKu^P*enday{?pRp<;eN$I7^ffB>#V@tJHX zldgW7tSw->nxkYzMBWUMl%V7zK@*S7F=(t$yCRjd^O@JP1w72YeVzwQ(vG+|HN|8- z`@q!Fyy9Q!X`?i`6+%;epYEU$Zk9bw(Z_)9*ab!Mo(u4wLy zSzW)SYG&{(%WZsNbnMvqIcgDgN1S|^E}j~len_<5E zvAU*Zz{5%TH?1sw9!u8w&L4W~hLjiEo9#i|(=4ZX{;bXYoA-IM@7Ap62P>^UZ&cB? zk(?~LMCZu{bI0s^YMTrL^u43eOyh zp0?zesNp&D+_cnA$)X*FTIONXn6s;W%?|fZ{b8*zt&E+kc~^!kk8p$`Z{w7TfX)&< ziD%lJOG5;OJKO*idaz|eh*;JJj@2g(r*D}qw=8$N+t!3E9oFv)?kP{uE?Rs& zcdhxN6IqVZ>$cAGJQVo&M`LdCUZ>y83PKx;!y0KJLBQ=$1aQ=ldqo*Z|+*M z;((w0`o`kON9r-mn+#^TZg|`Ca$Zl+vffRhUo4{|Yqu}5EnKLc62y9ly=C^5sC~A^ zUk}#3{3Cxt#$7+y<-@E3O`-1{i<>^5T>bs;+jRBgS_cm6pFV2o$)NA>ZNV;^148XA zA~(Ylcmr}v{^l&5e{(j&p&!$mt+#se&%gEM-#vqv$qPI@&9P5Xk5~Nnv}4J>*NeWrWBYsi$df~}|8JP# zZ&$m?S@I!I`iUOpC9l69>@m?>JY~y{|KjQr53D^c<14yvK6-POFY4Ao`x#S@CHG8` z4%z&Q=i>Q_^(s;sss&H9HGbOWBz!S6dbh^tb+)vKd2a;M-qOVO88i1=uJ&AMazE&j z@|V=?)zS^kS5CZIdR1Jj7%cTxT_mj z_4C#d#3HToL70rK`aziNg=R9Tl@Y=oY}FCWp1+QZ@Y+Le<%F;uTlIvnU4Ria{7`*~ p-F9LtE0`OwS647MENN^Z+YO{tUIE^$Y#=*XfiQ%Lfgu;n0{}TSUsnJC literal 0 HcmV?d00001 diff --git a/core/esmf-test-aspect-models/src/main/resources/packages/namespaces-aspect-models-root.zip b/core/esmf-test-aspect-models/src/main/resources/packages/namespaces-aspect-models-root.zip new file mode 100644 index 0000000000000000000000000000000000000000..8a33c9437a738aaaf64319059366f321cffbf54e GIT binary patch literal 7535 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 Lymu!~hxzqC(9WHO literal 0 HcmV?d00001 diff --git a/core/esmf-test-aspect-models/src/main/resources/packages/namespaces-aspect-models-subfolder.zip b/core/esmf-test-aspect-models/src/main/resources/packages/namespaces-aspect-models-subfolder.zip new file mode 100644 index 0000000000000000000000000000000000000000..bc9701eb6abed18924be428d00c65b61d3cbf763 GIT binary patch literal 10352 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 XI~QenOf0|*r28+q{ft2Z0cQUN#%L*y literal 0 HcmV?d00001 diff --git a/core/esmf-aspect-meta-model-java/src/test/resources/namespaces.zip b/core/esmf-test-aspect-models/src/main/resources/packages/namespaces.zip similarity index 100% rename from core/esmf-aspect-meta-model-java/src/test/resources/namespaces.zip rename to core/esmf-test-aspect-models/src/main/resources/packages/namespaces.zip diff --git a/core/esmf-aspect-meta-model-java/src/test/resources/namespaces_with_old_version.zip b/core/esmf-test-aspect-models/src/main/resources/packages/namespaces_with_old_version.zip similarity index 100% rename from core/esmf-aspect-meta-model-java/src/test/resources/namespaces_with_old_version.zip rename to core/esmf-test-aspect-models/src/main/resources/packages/namespaces_with_old_version.zip From 3f71702d7210e933978cdec4924bd8e4e58d0132 Mon Sep 17 00:00:00 2001 From: Yauhenikapl Date: Fri, 26 Jul 2024 19:16:23 +0300 Subject: [PATCH 11/20] Revert styles --- .../aspectmodel/loader/AspectModelLoader.java | 22 +++++++++++++------ .../loader/AspectModelLoaderTest.java | 16 ++++++++------ 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoader.java b/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoader.java index 5ce3cb4dd..f48435df5 100644 --- a/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoader.java +++ b/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoader.java @@ -133,7 +133,10 @@ public AspectModel load( final File file ) { * @return the Aspect Model */ public AspectModel load( final Collection files ) { - final List migratedFiles = files.stream().map( AspectModelFileLoader::load ).map( this::migrate ).toList(); + final List migratedFiles = files.stream() + .map( AspectModelFileLoader::load ) + .map( this::migrate ) + .toList(); final LoaderContext loaderContext = new LoaderContext(); resolve( migratedFiles, loaderContext ); return buildAspectModel( loaderContext.loadedFiles() ); @@ -287,8 +290,10 @@ private Set getAllUrnsInModel( final Model model ) { ? Stream.of( statement.getObject().asResource().getURI() ) : Stream.empty(); - return Stream.of( subjectUri, propertyUri, objectUri ).flatMap( Function.identity() ) - .flatMap( urn -> AspectModelUrn.from( urn ).toJavaOptional().stream() ).map( AspectModelUrn::toString ); + return Stream.of( subjectUri, propertyUri, objectUri ) + .flatMap( Function.identity() ) + .flatMap( urn -> AspectModelUrn.from( urn ).toJavaOptional().stream() ) + .map( AspectModelUrn::toString ); } ) ).flatMap( Function.identity() ).collect( toSet() ); } @@ -372,7 +377,7 @@ private void markModelFileAsLoaded( final AspectModelFile modelFile, final Loade } } - private void resolve( List inputFiles, final LoaderContext context ) { + private void resolve( final List inputFiles, final LoaderContext context ) { for ( final AspectModelFile aspectModelFile : inputFiles ) { context.unresolvedFiles().push( aspectModelFile ); } @@ -387,7 +392,8 @@ private void resolve( List inputFiles, final LoaderContext cont } while ( !context.unresolvedUrns().isEmpty() ) { - applyResolutionStrategy( context.unresolvedUrns().pop() ).map( this::migrate ) + applyResolutionStrategy( context.unresolvedUrns().pop() ) + .map( this::migrate ) .ifPresent( resolvedFile -> markModelFileAsLoaded( resolvedFile, context ) ); } } @@ -407,9 +413,11 @@ private AspectModel buildAspectModel( final Collection inputFil final Model model = file.sourceModel(); final ModelElementFactory modelElementFactory = new ModelElementFactory( mergedModel, Map.of(), element -> aspectModelFile ); final List fileElements = model.listStatements( null, RDF.type, (RDFNode) null ).toList().stream() - .map( Statement::getSubject ).filter( RDFNode::isURIResource ) + .map( Statement::getSubject ) + .filter( RDFNode::isURIResource ) .map( resource -> mergedModel.createResource( resource.getURI() ) ) - .map( resource -> modelElementFactory.create( ModelElement.class, resource ) ).toList(); + .map( resource -> modelElementFactory.create( ModelElement.class, resource ) ) + .toList(); aspectModelFile.setElements( fileElements ); elements.addAll( fileElements ); } diff --git a/core/esmf-aspect-meta-model-java/src/test/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoaderTest.java b/core/esmf-aspect-meta-model-java/src/test/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoaderTest.java index abe9f90c1..b7423deec 100644 --- a/core/esmf-aspect-meta-model-java/src/test/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoaderTest.java +++ b/core/esmf-aspect-meta-model-java/src/test/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoaderTest.java @@ -41,16 +41,18 @@ class AspectModelLoaderTest { @Test void testOfAbstractEntityCyclomaticCreation() { - final Map entities = TestResources.load( TestAspect.ASPECT_WITH_MULTIPLE_ENTITIES_SAME_EXTEND ).elements() - .stream().filter( ComplexType.class::isInstance ).map( ComplexType.class::cast ) - .collect( Collectors.toMap( ComplexType::getName, Function.identity() ) ); + final Map entities = + TestResources.load( TestAspect.ASPECT_WITH_MULTIPLE_ENTITIES_SAME_EXTEND ).elements().stream() + .filter( ComplexType.class::isInstance ) + .map( ComplexType.class::cast ) + .collect( Collectors.toMap( ComplexType::getName, Function.identity() ) ); assertThat( entities ).extracting( "AbstractTestEntity" ).isInstanceOf( AbstractEntity.class ); final AbstractEntity abstractEntity = (AbstractEntity) entities.get( "AbstractTestEntity" ); - assertThat( entities ).extracting( "testEntityOne" ).isInstanceOfSatisfying( ComplexType.class, - type -> assertThat( type ).extracting( ComplexType::getExtends ).extracting( Optional::get ).isSameAs( abstractEntity ) ); - assertThat( entities ).extracting( "testEntityTwo" ).isInstanceOfSatisfying( ComplexType.class, - type -> assertThat( type ).extracting( ComplexType::getExtends ).extracting( Optional::get ).isSameAs( abstractEntity ) ); + assertThat( entities ).extracting( "testEntityOne" ).isInstanceOfSatisfying( ComplexType.class, type -> + assertThat( type ).extracting( ComplexType::getExtends ).extracting( Optional::get ).isSameAs( abstractEntity ) ); + assertThat( entities ).extracting( "testEntityTwo" ).isInstanceOfSatisfying( ComplexType.class, type -> + assertThat( type ).extracting( ComplexType::getExtends ).extracting( Optional::get ).isSameAs( abstractEntity ) ); } @Test From 3f05c49bc49d77639597ee5476ebe4a61e9e95fd Mon Sep 17 00:00:00 2001 From: Yauhenikapl Date: Mon, 29 Jul 2024 17:06:08 +0300 Subject: [PATCH 12/20] Test github resolution strategy --- core/esmf-aspect-meta-model-java/pom.xml | 6 ++ .../aspectmodel/resolver/GitHubStrategy.java | 63 +++++++++++++++++++ .../resolver/AspectModelResolverTest.java | 18 ++++++ 3 files changed, 87 insertions(+) create mode 100644 core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/resolver/GitHubStrategy.java diff --git a/core/esmf-aspect-meta-model-java/pom.xml b/core/esmf-aspect-meta-model-java/pom.xml index 687c30a88..38d6dea84 100644 --- a/core/esmf-aspect-meta-model-java/pom.xml +++ b/core/esmf-aspect-meta-model-java/pom.xml @@ -58,6 +58,12 @@ com.google.guava guava + + org.kohsuke + github-api + 1.123 + + diff --git a/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/resolver/GitHubStrategy.java b/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/resolver/GitHubStrategy.java new file mode 100644 index 000000000..c5859e326 --- /dev/null +++ b/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/resolver/GitHubStrategy.java @@ -0,0 +1,63 @@ +package org.eclipse.esmf.aspectmodel.resolver; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.List; + +import org.eclipse.esmf.aspectmodel.AspectModelFile; +import org.eclipse.esmf.aspectmodel.resolver.fs.ModelsRoot; +import org.eclipse.esmf.aspectmodel.resolver.fs.StructuredModelsRoot; +import org.eclipse.esmf.aspectmodel.urn.AspectModelUrn; + +import org.kohsuke.github.GHContent; +import org.kohsuke.github.GHRepository; +import org.kohsuke.github.GitHub; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class GitHubStrategy implements ResolutionStrategy { + private static final Logger LOG = LoggerFactory.getLogger( GitHubStrategy.class ); + protected final ModelsRoot modelsRoot; + + protected final String repositoryUrl; + + protected final String searchDirectory; + + public GitHubStrategy( final Path modelsRoot, final String repositoryUrl, final String searchDirectory ) { + this( new StructuredModelsRoot( modelsRoot ), repositoryUrl, searchDirectory ); + } + + public GitHubStrategy( final ModelsRoot modelsRoot, final String repositoryUrl, final String searchDirectory ) { + this.modelsRoot = modelsRoot; + this.repositoryUrl = repositoryUrl; + this.searchDirectory = searchDirectory; // "." + } + + @Override + public AspectModelFile apply( final AspectModelUrn aspectModelUrn, final ResolutionStrategySupport resolutionStrategySupport ) + throws ModelResolutionException { + + try { + GitHub github = GitHub.connectAnonymously(); + + GHRepository repository = github.getRepository( repositoryUrl ); + + findTtlFiles( repository, searchDirectory ); + } catch ( IOException e ) { + e.printStackTrace(); + } + + return null; + } + + public static void findTtlFiles( GHRepository repository, String path ) throws IOException { + List contents = repository.getDirectoryContent( path ); + for ( GHContent content : contents ) { + if ( content.isFile() && content.getName().endsWith( ".ttl" ) ) { + System.out.println( "Found TTL file: " + content.getPath() ); + } else if ( content.isDirectory() ) { + findTtlFiles( repository, content.getPath() ); + } + } + } +} diff --git a/core/esmf-aspect-meta-model-java/src/test/java/org/eclipse/esmf/aspectmodel/resolver/AspectModelResolverTest.java b/core/esmf-aspect-meta-model-java/src/test/java/org/eclipse/esmf/aspectmodel/resolver/AspectModelResolverTest.java index da718aad6..b4e1adbe0 100644 --- a/core/esmf-aspect-meta-model-java/src/test/java/org/eclipse/esmf/aspectmodel/resolver/AspectModelResolverTest.java +++ b/core/esmf-aspect-meta-model-java/src/test/java/org/eclipse/esmf/aspectmodel/resolver/AspectModelResolverTest.java @@ -191,4 +191,22 @@ public void testResolutionMissingModelElementExpectFailure() throws Throwable { final AspectModel result = new AspectModelLoader( urnStrategy ).load( testUrn ); } ).isInstanceOf( ModelResolutionException.class ); } + + @Test + public void testGithubStrategy() throws Throwable { + final File aspectModelsRootDirectory = new File( + AspectModelResolverTest.class.getClassLoader().getResource( KnownVersion.getLatest().toString().toLowerCase() ) + .toURI().getPath() ); + + final AspectModelUrn testUrn = AspectModelUrn.fromUrn( TestModel.TEST_NAMESPACE + "FailingTest" ); + + final ResolutionStrategy gitHubStrategy = new GitHubStrategy( + aspectModelsRootDirectory.toPath(), + "eclipse-esmf/esmf-sdk", + "core/esmf-test-aspect-models/src/main/resources/valid/org.eclipse.esmf.test/1.0.0" ); + + assertThatThrownBy( () -> { + final AspectModel result = new AspectModelLoader( gitHubStrategy ).load( testUrn ); + } ).isInstanceOf( ModelResolutionException.class ); + } } From 155d2667f1ca3a6bfef74d2394dd77b7b7865a08 Mon Sep 17 00:00:00 2001 From: Yauhenikapl Date: Thu, 1 Aug 2024 16:03:50 +0300 Subject: [PATCH 13/20] Add githubScanner and GitHub strategy, update samm cli --- core/esmf-aspect-meta-model-java/pom.xml | 6 - .../aspectmodel/loader/AspectModelLoader.java | 6 +- .../aspectmodel/resolver/GitHubStrategy.java | 63 ------ .../scanner/AspectModelScanner.java | 23 ++ .../scanner/FileSystemScanner.java | 90 ++++++++ .../resolver/AspectModelResolverTest.java | 18 -- esmf-sdk-github-resolver/pom.xml | 53 +++++ .../java/org/eclipse/esmf/GitHubScanner.java | 198 ++++++++++++++++++ .../java/org/eclipse/esmf/GitHubStrategy.java | 84 ++++++++ .../org/eclipse/esmf/GitHubScannerTest.java | 74 +++++++ .../org/eclipse/esmf/GitHubStrategyTest.java | 33 +++ pom.xml | 1 + tools/samm-cli/pom.xml | 6 + .../org/eclipse/esmf/AspectSearchCommand.java | 87 +++++--- 14 files changed, 624 insertions(+), 118 deletions(-) delete mode 100644 core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/resolver/GitHubStrategy.java create mode 100644 core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/scanner/AspectModelScanner.java create mode 100644 core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/scanner/FileSystemScanner.java create mode 100644 esmf-sdk-github-resolver/pom.xml create mode 100644 esmf-sdk-github-resolver/src/main/java/org/eclipse/esmf/GitHubScanner.java create mode 100644 esmf-sdk-github-resolver/src/main/java/org/eclipse/esmf/GitHubStrategy.java create mode 100644 esmf-sdk-github-resolver/src/test/java/org/eclipse/esmf/GitHubScannerTest.java create mode 100644 esmf-sdk-github-resolver/src/test/java/org/eclipse/esmf/GitHubStrategyTest.java diff --git a/core/esmf-aspect-meta-model-java/pom.xml b/core/esmf-aspect-meta-model-java/pom.xml index 38d6dea84..687c30a88 100644 --- a/core/esmf-aspect-meta-model-java/pom.xml +++ b/core/esmf-aspect-meta-model-java/pom.xml @@ -58,12 +58,6 @@ com.google.guava guava - - org.kohsuke - github-api - 1.123 - - diff --git a/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoader.java b/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoader.java index f48435df5..337453f4c 100644 --- a/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoader.java +++ b/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoader.java @@ -280,7 +280,7 @@ private LoaderContext() { } } - private Set getAllUrnsInModel( final Model model ) { + public static Set getAllUrnsInModel( final Model model ) { return Streams.stream( model.listStatements().mapWith( statement -> { final Stream subjectUri = statement.getSubject().isURIResource() ? Stream.of( statement.getSubject().getURI() ) @@ -292,8 +292,7 @@ private Set getAllUrnsInModel( final Model model ) { return Stream.of( subjectUri, propertyUri, objectUri ) .flatMap( Function.identity() ) - .flatMap( urn -> AspectModelUrn.from( urn ).toJavaOptional().stream() ) - .map( AspectModelUrn::toString ); + .flatMap( urn -> AspectModelUrn.from( urn ).toJavaOptional().stream() ); } ) ).flatMap( Function.identity() ).collect( toSet() ); } @@ -360,6 +359,7 @@ private void urnsFromModelNeedResolution( final AspectModelFile modelFile, final .forEach( urn -> context.resolvedUrns().add( urn ) ); getAllUrnsInModel( modelFile.sourceModel() ).stream() + .map( urn -> urn.toString()) .filter( urn -> !context.resolvedUrns().contains( urn ) ) .filter( urn -> !urn.startsWith( XSD.NS ) ) .filter( urn -> !urn.startsWith( RDF.uri ) ) diff --git a/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/resolver/GitHubStrategy.java b/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/resolver/GitHubStrategy.java deleted file mode 100644 index c5859e326..000000000 --- a/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/resolver/GitHubStrategy.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.eclipse.esmf.aspectmodel.resolver; - -import java.io.IOException; -import java.nio.file.Path; -import java.util.List; - -import org.eclipse.esmf.aspectmodel.AspectModelFile; -import org.eclipse.esmf.aspectmodel.resolver.fs.ModelsRoot; -import org.eclipse.esmf.aspectmodel.resolver.fs.StructuredModelsRoot; -import org.eclipse.esmf.aspectmodel.urn.AspectModelUrn; - -import org.kohsuke.github.GHContent; -import org.kohsuke.github.GHRepository; -import org.kohsuke.github.GitHub; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class GitHubStrategy implements ResolutionStrategy { - private static final Logger LOG = LoggerFactory.getLogger( GitHubStrategy.class ); - protected final ModelsRoot modelsRoot; - - protected final String repositoryUrl; - - protected final String searchDirectory; - - public GitHubStrategy( final Path modelsRoot, final String repositoryUrl, final String searchDirectory ) { - this( new StructuredModelsRoot( modelsRoot ), repositoryUrl, searchDirectory ); - } - - public GitHubStrategy( final ModelsRoot modelsRoot, final String repositoryUrl, final String searchDirectory ) { - this.modelsRoot = modelsRoot; - this.repositoryUrl = repositoryUrl; - this.searchDirectory = searchDirectory; // "." - } - - @Override - public AspectModelFile apply( final AspectModelUrn aspectModelUrn, final ResolutionStrategySupport resolutionStrategySupport ) - throws ModelResolutionException { - - try { - GitHub github = GitHub.connectAnonymously(); - - GHRepository repository = github.getRepository( repositoryUrl ); - - findTtlFiles( repository, searchDirectory ); - } catch ( IOException e ) { - e.printStackTrace(); - } - - return null; - } - - public static void findTtlFiles( GHRepository repository, String path ) throws IOException { - List contents = repository.getDirectoryContent( path ); - for ( GHContent content : contents ) { - if ( content.isFile() && content.getName().endsWith( ".ttl" ) ) { - System.out.println( "Found TTL file: " + content.getPath() ); - } else if ( content.isDirectory() ) { - findTtlFiles( repository, content.getPath() ); - } - } - } -} diff --git a/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/scanner/AspectModelScanner.java b/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/scanner/AspectModelScanner.java new file mode 100644 index 000000000..df3d59fd9 --- /dev/null +++ b/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/scanner/AspectModelScanner.java @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2024 Robert Bosch Manufacturing Solutions GmbH + * + * See the AUTHORS file(s) distributed with this work for additional + * information regarding authorship. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * SPDX-License-Identifier: MPL-2.0 + */ + +package org.eclipse.esmf.aspectmodel.scanner; + +import java.util.List; + +import org.eclipse.esmf.aspectmodel.AspectModelFile; + +public interface AspectModelScanner { + + List find( final String aspectModelFileName ); +} diff --git a/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/scanner/FileSystemScanner.java b/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/scanner/FileSystemScanner.java new file mode 100644 index 000000000..71f89ed07 --- /dev/null +++ b/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/scanner/FileSystemScanner.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2024 Robert Bosch Manufacturing Solutions GmbH + * + * See the AUTHORS file(s) distributed with this work for additional + * information regarding authorship. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * SPDX-License-Identifier: MPL-2.0 + */ + +package org.eclipse.esmf.aspectmodel.scanner; + +import java.io.File; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.Set; + +import org.eclipse.esmf.aspectmodel.AspectModelFile; +import org.eclipse.esmf.aspectmodel.loader.AspectModelLoader; +import org.eclipse.esmf.aspectmodel.resolver.AspectModelFileLoader; +import org.eclipse.esmf.aspectmodel.urn.AspectModelUrn; +import org.eclipse.esmf.metamodel.AspectModel; +import org.eclipse.esmf.metamodel.ModelElement; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class FileSystemScanner implements AspectModelScanner { + + private static final Logger LOG = LoggerFactory.getLogger( FileSystemScanner.class ); + + protected final String searchDirectory; + + public FileSystemScanner( final String searchDirectory ) { + this.searchDirectory = searchDirectory; + } + + @Override + public List find( final String aspectModelFileName ) { + List result = new ArrayList<>(); + + final AspectModel searchAspectModel = new AspectModelLoader().load( new File( aspectModelFileName ) ); + + final Path directory = Paths.get( searchDirectory ); + final List files = Arrays.stream( Optional.ofNullable( directory.toFile().listFiles() ).orElse( new File[] {} ) ) + .filter( file -> file.isFile() && file.getName().endsWith( ".ttl" ) && !file.getName() + .equals( Paths.get( aspectModelFileName ).getFileName().toString() ) ) + .sorted() + .toList(); + + if ( files.isEmpty() ) { + LOG.info( "No .ttl files found in the directory '{}'", directory ); + return result; + } + + final List modelUrns = searchAspectModel.elements().stream().map( ModelElement::urn ).toList(); + + for ( final File file : files ) { + result.addAll( processFile( file, modelUrns ) ); + } + + return result; + } + + private List processFile( final File inputFile, final List modelUrns ) { + final List aspectModelFiles = new ArrayList<>(); + final File absoluteFile = inputFile.isAbsolute() + ? inputFile + : Path.of( System.getProperty( "user.dir" ) ).resolve( inputFile.toPath() ).toFile().getAbsoluteFile(); + + final AspectModelFile aspectModelFile = AspectModelFileLoader.load( absoluteFile ); + + final Set urnsAspectModelFile = AspectModelLoader.getAllUrnsInModel( aspectModelFile.sourceModel() ); + + for ( final AspectModelUrn aspectModelUrn : modelUrns ) { + if ( urnsAspectModelFile.contains( aspectModelUrn ) ) { + aspectModelFiles.add( aspectModelFile ); + } + } + + return aspectModelFiles; + } +} diff --git a/core/esmf-aspect-meta-model-java/src/test/java/org/eclipse/esmf/aspectmodel/resolver/AspectModelResolverTest.java b/core/esmf-aspect-meta-model-java/src/test/java/org/eclipse/esmf/aspectmodel/resolver/AspectModelResolverTest.java index b4e1adbe0..da718aad6 100644 --- a/core/esmf-aspect-meta-model-java/src/test/java/org/eclipse/esmf/aspectmodel/resolver/AspectModelResolverTest.java +++ b/core/esmf-aspect-meta-model-java/src/test/java/org/eclipse/esmf/aspectmodel/resolver/AspectModelResolverTest.java @@ -191,22 +191,4 @@ public void testResolutionMissingModelElementExpectFailure() throws Throwable { final AspectModel result = new AspectModelLoader( urnStrategy ).load( testUrn ); } ).isInstanceOf( ModelResolutionException.class ); } - - @Test - public void testGithubStrategy() throws Throwable { - final File aspectModelsRootDirectory = new File( - AspectModelResolverTest.class.getClassLoader().getResource( KnownVersion.getLatest().toString().toLowerCase() ) - .toURI().getPath() ); - - final AspectModelUrn testUrn = AspectModelUrn.fromUrn( TestModel.TEST_NAMESPACE + "FailingTest" ); - - final ResolutionStrategy gitHubStrategy = new GitHubStrategy( - aspectModelsRootDirectory.toPath(), - "eclipse-esmf/esmf-sdk", - "core/esmf-test-aspect-models/src/main/resources/valid/org.eclipse.esmf.test/1.0.0" ); - - assertThatThrownBy( () -> { - final AspectModel result = new AspectModelLoader( gitHubStrategy ).load( testUrn ); - } ).isInstanceOf( ModelResolutionException.class ); - } } diff --git a/esmf-sdk-github-resolver/pom.xml b/esmf-sdk-github-resolver/pom.xml new file mode 100644 index 000000000..baf59fdc3 --- /dev/null +++ b/esmf-sdk-github-resolver/pom.xml @@ -0,0 +1,53 @@ + + + 4.0.0 + + org.eclipse.esmf + esmf-sdk-parent + DEV-SNAPSHOT + + + esmf-sdk-github-resolver + + + 17 + 17 + UTF-8 + + + + org.eclipse.esmf + esmf-aspect-meta-model-java + + + + org.kohsuke + github-api + 1.123 + + + + + org.junit.jupiter + junit-jupiter + test + + + org.assertj + assertj-core + test + + + org.eclipse.esmf + esmf-test-aspect-models + test + + + org.eclipse.esmf + esmf-aspect-model-validator + + + + \ No newline at end of file diff --git a/esmf-sdk-github-resolver/src/main/java/org/eclipse/esmf/GitHubScanner.java b/esmf-sdk-github-resolver/src/main/java/org/eclipse/esmf/GitHubScanner.java new file mode 100644 index 000000000..877c0a5f5 --- /dev/null +++ b/esmf-sdk-github-resolver/src/main/java/org/eclipse/esmf/GitHubScanner.java @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2024 Robert Bosch Manufacturing Solutions GmbH + * + * See the AUTHORS file(s) distributed with this work for additional + * information regarding authorship. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * SPDX-License-Identifier: MPL-2.0 + */ + +package org.eclipse.esmf; + +import java.io.BufferedInputStream; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; +import java.nio.channels.Channels; +import java.nio.channels.ReadableByteChannel; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import org.eclipse.esmf.aspectmodel.AspectModelFile; +import org.eclipse.esmf.aspectmodel.loader.AspectModelLoader; +import org.eclipse.esmf.aspectmodel.resolver.modelfile.RawAspectModelFile; +import org.eclipse.esmf.aspectmodel.resolver.services.TurtleLoader; +import org.eclipse.esmf.aspectmodel.scanner.AspectModelScanner; +import org.eclipse.esmf.aspectmodel.urn.AspectModelUrn; +import org.eclipse.esmf.metamodel.AspectModel; +import org.eclipse.esmf.metamodel.ModelElement; + +import io.vavr.control.Try; +import org.apache.jena.rdf.model.Model; +import org.kohsuke.github.GHContent; +import org.kohsuke.github.GHRepository; +import org.kohsuke.github.GitHub; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class GitHubScanner implements AspectModelScanner { + + private static final Logger LOG = LoggerFactory.getLogger( GitHubScanner.class ); + + private static final String GITHUB_BASE = "https://github.com"; + + private static final String GITHUB_ZIP_URL = GITHUB_BASE + "/%s/archive/refs/heads/%s.zip"; + + private static final String DOWNLOADED_ZIP_NAME = "%s.zip"; + protected final String repositoryName; + + protected final String branchName; + + public GitHubScanner( final String repositoryName, final String branchName ) { + this.repositoryName = repositoryName; + this.branchName = branchName; + } + + /** + * Finds and returns a list of valid {@link AspectModelFile} objects + * that match the specified aspect model file name. + * + *
    + *
  1. Connects to GitHub anonymously and retrieves the specified repository.
  2. + *
  3. Checks if the specified aspect model file exists in the repository.
  4. + *
  5. If the file exists, it retrieves the file content and loads the aspect model using {@link AspectModelLoader}.
  6. + *
  7. Downloads the entire repository (or specified branch) as a ZIP file.
  8. + *
  9. Processes the downloaded package to extract aspect model files.
  10. + *
  11. Deletes the downloaded package after processing.
  12. + *
  13. Finds and returns the aspect model files that contain definitions matching the URNs in the search aspect model.
  14. + *
+ * + * @param aspectModelFileUrl The url of the aspect model file to search for in the repository. + * @return A list of {@link AspectModelFile} objects that match the specified aspect model file name + * by {@link AspectModelUrn}. + * @throws RuntimeException if an I/O error occurs during the process. + */ + @Override + public List find( final String aspectModelFileUrl ) { + List resultAspectModelFiles = new ArrayList<>(); + try { + final GitHub github = GitHub.connectAnonymously(); + final GHRepository repository = github.getRepository( repositoryName ); + + if ( checkFileExists( repository, aspectModelFileUrl ) ) { + + final GHContent contentOfSearchFile = repository.getFileContent( aspectModelFileUrl, branchName ); + + final AspectModelLoader aspectModelLoader = new AspectModelLoader(); + + final AspectModel searchAspectModel = aspectModelLoader.load( new URL( contentOfSearchFile.getDownloadUrl() ).openStream() ); + + final String githubUrl = String.format( GITHUB_ZIP_URL, repositoryName, branchName ); + final String downloadedPackageName = String.format( DOWNLOADED_ZIP_NAME, branchName ); + final File downloadedPackage = downloadFile( new URL( githubUrl ), downloadedPackageName ); + + final List filesInPackage = processPackage( new FileInputStream( downloadedPackage ) ); + + final boolean packageIsDeleted = downloadedPackage.delete(); + if ( packageIsDeleted ) { + LOG.info( String.format( "Package %s was deleted!", downloadedPackage.getName() ) ); + } + + final List searchAspectUrns = searchAspectModel.elements().stream().map( ModelElement::urn ).toList(); + + for ( final AspectModelFile aspectModelFile : filesInPackage ) { + final Set urnsAspectModelFile = AspectModelLoader.getAllUrnsInModel( aspectModelFile.sourceModel() ); + + for ( final AspectModelUrn aspectModelUrn : searchAspectUrns ) { + if ( urnsAspectModelFile.contains( aspectModelUrn ) ) { + resultAspectModelFiles.add( aspectModelFile ); + } + } + } + } + } catch ( IOException e ) { + throw new RuntimeException( e ); + } + + return resultAspectModelFiles; + } + + private boolean checkFileExists( final GHRepository repository, final String aspectModelFileUrl ) { + try { + final GHContent content = repository.getFileContent( aspectModelFileUrl, branchName ); + return content != null; + } catch ( IOException e ) { + throw new RuntimeException( + new IOException( String.format( "File %s can't found in %s repository.", aspectModelFileUrl, repository.getUrl() ) ) ); + } + } + + private File downloadFile( final URL repositoryUrl, final String outputFileName ) throws IOException { + LOG.info( String.format( "Downloading %s repository to local...", repositoryUrl.getPath() ) ); + + ReadableByteChannel rbc; + File outputFile = new File( outputFileName ); + try ( final BufferedInputStream bis = new BufferedInputStream( repositoryUrl.openStream() ); + final FileOutputStream fos = new FileOutputStream( outputFileName ) ) { + rbc = Channels.newChannel( bis ); + fos.getChannel().transferFrom( rbc, 0, Long.MAX_VALUE ); + } catch ( FileNotFoundException e ) { + throw new FileNotFoundException( String.format( "Can't download repository, file %s not found! %s", repositoryName, e ) ); + } catch ( IOException e ) { + throw new IOException( String.format( "Can't write zip file %s", outputFileName ) ); + } + + LOG.info( String.format( "Downloaded %s repository to local.", repositoryUrl.getPath() ) ); + + return outputFile; + } + + /** + * This method provides valid files from package + * + * @param inputStream of repository package + * @return list of valid {@link AspectModelFile} from package + */ + private List processPackage( final InputStream inputStream ) { + List aspectModelFiles = new ArrayList<>(); + + try ( ZipInputStream zis = new ZipInputStream( inputStream ) ) { + ZipEntry entry; + + while ( (entry = zis.getNextEntry()) != null ) { + if ( entry.getName().endsWith( ".ttl" ) ) { + final String content = new BufferedReader( new InputStreamReader( zis, StandardCharsets.UTF_8 ) ).lines() + .collect( Collectors.joining( "\n" ) ); + final Try tryModel = TurtleLoader.loadTurtle( content ); + if ( !tryModel.isFailure() ) { + final AspectModelFile aspectModelFile = new RawAspectModelFile( tryModel.get(), new ArrayList<>(), Optional.empty() ); + aspectModelFiles.add( aspectModelFile ); + } + } + } + + zis.closeEntry(); + } catch ( IOException e ) { + LOG.error( "Error reading the Package input stream", e ); + throw new RuntimeException( new IOException( "Error reading the Package input stream", e ) ); + } + + return aspectModelFiles; + } +} diff --git a/esmf-sdk-github-resolver/src/main/java/org/eclipse/esmf/GitHubStrategy.java b/esmf-sdk-github-resolver/src/main/java/org/eclipse/esmf/GitHubStrategy.java new file mode 100644 index 000000000..5065e63bf --- /dev/null +++ b/esmf-sdk-github-resolver/src/main/java/org/eclipse/esmf/GitHubStrategy.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2024 Robert Bosch Manufacturing Solutions GmbH + * + * See the AUTHORS file(s) distributed with this work for additional + * information regarding authorship. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * SPDX-License-Identifier: MPL-2.0 + */ + +package org.eclipse.esmf; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.util.List; + +import org.eclipse.esmf.aspectmodel.AspectModelFile; +import org.eclipse.esmf.aspectmodel.resolver.AspectModelFileLoader; +import org.eclipse.esmf.aspectmodel.resolver.ModelResolutionException; +import org.eclipse.esmf.aspectmodel.resolver.ResolutionStrategy; +import org.eclipse.esmf.aspectmodel.resolver.ResolutionStrategySupport; +import org.eclipse.esmf.aspectmodel.urn.AspectModelUrn; + +import io.vavr.control.Try; +import org.kohsuke.github.GHContent; +import org.kohsuke.github.GHRepository; +import org.kohsuke.github.GitHub; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class GitHubStrategy implements ResolutionStrategy { + + private static final Logger LOG = LoggerFactory.getLogger( GitHubStrategy.class ); + + protected final String repositoryUrl; + + protected final String searchDirectory; + + public GitHubStrategy( final String repositoryUrl, final String searchDirectory ) { + this.repositoryUrl = repositoryUrl; + this.searchDirectory = searchDirectory; // "." + } + + @Override + public AspectModelFile apply( final AspectModelUrn aspectModelUrn, final ResolutionStrategySupport resolutionStrategySupport ) + throws ModelResolutionException { + + try { + GitHub github = GitHub.connectAnonymously(); + + GHRepository repository = github.getRepository( repositoryUrl ); + + final List contents = repository.getDirectoryContent( searchDirectory ); + for ( GHContent content : contents ) { + if ( content.isFile() && content.getName().endsWith( ".ttl" ) ) { + + final File file = new File( content.getDownloadUrl() ); + + final Try tryModel = Try.of( + () -> AspectModelFileLoader.load( new URL( content.getDownloadUrl() ).openStream() ) ); + + if ( tryModel.isFailure() ) { + LOG.debug( "Could not load model from {}", file, tryModel.getCause() ); + } else { + final AspectModelFile model = tryModel.get(); + if ( resolutionStrategySupport.containsDefinition( model, aspectModelUrn ) ) { + return model; + } else { + LOG.debug( "File {} does not contain {}", file, aspectModelUrn ); + } + } + } + } + } catch ( IOException e ) { + e.printStackTrace(); + } + + return null; + } +} diff --git a/esmf-sdk-github-resolver/src/test/java/org/eclipse/esmf/GitHubScannerTest.java b/esmf-sdk-github-resolver/src/test/java/org/eclipse/esmf/GitHubScannerTest.java new file mode 100644 index 000000000..5430db135 --- /dev/null +++ b/esmf-sdk-github-resolver/src/test/java/org/eclipse/esmf/GitHubScannerTest.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2024 Robert Bosch Manufacturing Solutions GmbH + * + * See the AUTHORS file(s) distributed with this work for additional + * information regarding authorship. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + * + * SPDX-License-Identifier: MPL-2.0 + */ + +package org.eclipse.esmf; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.List; + +import org.eclipse.esmf.aspectmodel.AspectModelFile; +import org.eclipse.esmf.aspectmodel.scanner.AspectModelScanner; + +import org.junit.jupiter.api.Test; + +class GitHubScannerTest { + + @Test + void testGithubScannerExpectSuccess() { + final String aspectModelFileName = "core/esmf-test-aspect-models/src/main/resources/valid/org.eclipse.esmf.test/1.0" + + ".0/propertyWithoutExampleValue.ttl"; + final String repositoryUrl = "eclipse-esmf/esmf-sdk"; + final String branch = "main"; + + final AspectModelScanner aspectModelScanner = new GitHubScanner( repositoryUrl, branch ); + final List aspectModelFiles = aspectModelScanner.find( aspectModelFileName ); + + assertThat( aspectModelFiles ).hasSize( 1 ); + } + + @Test + void testGithubScannerWithInvalidFileUrl() { + final String aspectModelFileName = "core/esmf-test-aspect-models/src/main/resources/valid/org.eclipse.esmf.test/1.0" + + ".0/test-test-test.ttl"; + final String repositoryUrl = "eclipse-esmf/esmf-sdk"; + final String branch = "main"; + + final AspectModelScanner aspectModelScanner = new GitHubScanner( repositoryUrl, branch ); + + final RuntimeException exception = assertThrows( RuntimeException.class, () -> { + aspectModelScanner.find( aspectModelFileName ); + } ); + + assertEquals( + "java.io.IOException: File core/esmf-test-aspect-models/src/main/resources/valid/org.eclipse.esmf.test/1.0.0/test-test-test" + + ".ttl can't found in https://api.github.com/repos/eclipse-esmf/esmf-sdk repository.", + exception.getMessage() ); + } + + @Test + void testGithubScannerWithInvalidRepositoryName() { + final String aspectModelFileName = "core/esmf-test-aspect-models/src/main/resources/valid/org.eclipse.esmf.test/1.0" + + ".0/test-test-test.ttl"; + final String repositoryUrl = "eclipse-esmf/esmf-sdk2"; + final String branch = "main"; + + final AspectModelScanner aspectModelScanner = new GitHubScanner( repositoryUrl, branch ); + + assertThrows( RuntimeException.class, () -> { + aspectModelScanner.find( aspectModelFileName ); + } ); + } +} diff --git a/esmf-sdk-github-resolver/src/test/java/org/eclipse/esmf/GitHubStrategyTest.java b/esmf-sdk-github-resolver/src/test/java/org/eclipse/esmf/GitHubStrategyTest.java new file mode 100644 index 000000000..e43d65d05 --- /dev/null +++ b/esmf-sdk-github-resolver/src/test/java/org/eclipse/esmf/GitHubStrategyTest.java @@ -0,0 +1,33 @@ +package org.eclipse.esmf; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.io.File; + +import org.eclipse.esmf.aspectmodel.loader.AspectModelLoader; +import org.eclipse.esmf.aspectmodel.resolver.ModelResolutionException; +import org.eclipse.esmf.aspectmodel.resolver.ResolutionStrategy; +import org.eclipse.esmf.aspectmodel.urn.AspectModelUrn; +import org.eclipse.esmf.metamodel.AspectModel; +import org.eclipse.esmf.samm.KnownVersion; +import org.eclipse.esmf.test.TestModel; + +import org.junit.jupiter.api.Test; + +class GitHubStrategyTest { + + @Test + void testGithubStrategy() { + final AspectModelUrn testUrn = AspectModelUrn.fromUrn( "urn:samm:org.eclipse.esmf.test:1.0.0#Aspect" ); + + final ResolutionStrategy gitHubStrategy = new GitHubStrategy( "eclipse-esmf/esmf-sdk", + "core/esmf-test-aspect-models/src/main/resources/valid/org.eclipse.esmf.test/1.0.0" ); + + final AspectModel result = new AspectModelLoader( gitHubStrategy ).load( testUrn ); + assertThat( result.files() ).hasSize( 1 ); + assertThat( result.elements() ).hasSize( 1 ); + assertThat( result.aspect().getName() ).isEqualTo( "Aspect" ); + assertThat( result.aspect().urn() ).isEqualTo( testUrn ); + } +} diff --git a/pom.xml b/pom.xml index 5f28da14f..b53cd37a1 100644 --- a/pom.xml +++ b/pom.xml @@ -67,6 +67,7 @@ tools/esmf-aspect-model-maven-plugin tools/samm-cli documentation + esmf-sdk-github-resolver diff --git a/tools/samm-cli/pom.xml b/tools/samm-cli/pom.xml index 8a3966095..3cfe22858 100644 --- a/tools/samm-cli/pom.xml +++ b/tools/samm-cli/pom.xml @@ -129,6 +129,12 @@ tika-core test
+ + org.eclipse.esmf + esmf-sdk-github-resolver + DEV-SNAPSHOT + compile + diff --git a/tools/samm-cli/src/main/java/org/eclipse/esmf/AspectSearchCommand.java b/tools/samm-cli/src/main/java/org/eclipse/esmf/AspectSearchCommand.java index 0bd227c40..19b2685a7 100644 --- a/tools/samm-cli/src/main/java/org/eclipse/esmf/AspectSearchCommand.java +++ b/tools/samm-cli/src/main/java/org/eclipse/esmf/AspectSearchCommand.java @@ -14,14 +14,15 @@ package org.eclipse.esmf; import java.io.File; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Arrays; import java.util.List; -import java.util.Optional; import org.eclipse.esmf.aspectmodel.AspectModelFile; import org.eclipse.esmf.aspectmodel.loader.AspectModelLoader; +import org.eclipse.esmf.aspectmodel.resolver.FileSystemStrategy; +import org.eclipse.esmf.aspectmodel.resolver.ResolutionStrategy; +import org.eclipse.esmf.aspectmodel.resolver.fs.FlatModelsRoot; +import org.eclipse.esmf.aspectmodel.scanner.AspectModelScanner; +import org.eclipse.esmf.aspectmodel.scanner.FileSystemScanner; import org.eclipse.esmf.aspectmodel.urn.AspectModelUrn; import org.eclipse.esmf.metamodel.AspectModel; import org.eclipse.esmf.metamodel.ModelElement; @@ -55,30 +56,40 @@ public class AspectSearchCommand extends AbstractCommand { @CommandLine.Option( names = { "--models-path", "-msp" }, description = "Path to Models, where have to search" ) private String pathToModels = "-"; + @CommandLine.Option( names = { "--github", "-gh" }, description = "Use this flag to introduce what has to be scanned" ) + private boolean searchInGithub = false; + + @CommandLine.Option( names = { "--github-name", "-ghn" }, description = "Provide GitHub name. Example: eclipse-esmf/esmf-sdk." ) + private String gitHubName = ""; + + @CommandLine.Option( names = { "--github-directory", "-ghd" }, description = "Provide GitHub directory for scanning" ) + private String gitHubDirectory = ""; + + @CommandLine.Option( names = { "--github-branch", "-ghb" }, description = "Provide GitHub branch for scanning" ) + private String gitHubBranch = ""; + public String getInput() { return input; } @Override public void run() { - final AspectModel aspectModel = loadAspectModelOrFail( input, customResolver ); - - final Path directory = Paths.get( pathToModels ); - final List files = Arrays.stream( Optional.ofNullable( directory.toFile().listFiles() ).orElse( new File[] {} ) ) - .filter( file -> file.isFile() && file.getName().endsWith( ".ttl" ) && !file.getName() - .equals( Paths.get( input ).getFileName().toString() ) ) - .sorted() - .toList(); + final AspectModelScanner aspectModelScanner; + final List aspectModelFiles; - if ( files.isEmpty() ) { - LOG.info( "No .ttl files found in the directory '{}'", directory ); + if ( searchInGithub && (gitHubName.isBlank() || gitHubDirectory.isBlank()) ) { + System.out.println( "Parameters '--github-url' and '--github-directory' have to be provided!" ); return; + } else if ( !searchInGithub ) { + aspectModelScanner = new FileSystemScanner( pathToModels ); + aspectModelFiles = aspectModelScanner.find( input ); + } else { + aspectModelScanner = new GitHubScanner( gitHubName, gitHubBranch.isBlank() ? "main" : gitHubBranch ); + aspectModelFiles = aspectModelScanner.find( input ); } - final List modelUrns = aspectModel.elements().stream().map( ModelElement::urn ).toList(); - - String header = String.format( "| %-60s | %-100s | %-50s | %-60s |", - "URN of the element", "File location", "Model source", "Target element that it is referring to" ); + String header = String.format( "| %-60s | %-100s | %-50s |", + "URN of the element", "File location", "Model source" ); String separator = new String( new char[header.length()] ).replace( "\0", "-" ); // Print Table header @@ -86,21 +97,41 @@ public void run() { System.out.println( header ); System.out.println( separator ); - final AspectModelLoader aspectModelLoader = new AspectModelLoader(); + final AspectModel aspectModel = new AspectModelLoader().load( new File( input ) ); - for ( final File file : files ) { - processFile( file, modelUrns, aspectModelLoader ); + if ( !aspectModelFiles.isEmpty() ) { + for ( final AspectModelFile aspectModelFile : aspectModelFiles ) { + processFile( aspectModelFile, aspectModel.elements().stream().map( ModelElement::urn ).toList() ); + } } } - private void processFile( File file, List modelUrns, AspectModelLoader aspectModelLoader ) { - final AspectModel aspectModel = loadAspectModelOrFail( file.getPath(), customResolver ); + private void processFile( final AspectModelFile aspectModelFile, final List modelUrns ) { + if ( aspectModelFile.sourceLocation().isPresent() ) { + final File file = new File( aspectModelFile.sourceLocation().get() ); + + final AspectModelLoader aspectModelLoader; + final AspectModel aspectModel; + + if ( searchInGithub ) { + final ResolutionStrategy resolutionStrategy = new GitHubStrategy( gitHubName, gitHubDirectory ); + aspectModelLoader = new AspectModelLoader( resolutionStrategy ); + + aspectModel = aspectModelLoader.load( file ); + } else { + final ResolutionStrategy resolutionStrategy = new FileSystemStrategy( + new FlatModelsRoot( file.toPath().getParent() ) ); + aspectModelLoader = new AspectModelLoader( resolutionStrategy ); + + aspectModel = aspectModelLoader.load( file ); + } - for ( final AspectModelUrn modelUrn : modelUrns ) { - final List modelFiles = aspectModel.files(); - for ( final AspectModelFile modelFile : modelFiles ) { - if ( aspectModelLoader.containsDefinition( modelFile, modelUrn ) ) { - System.out.printf( "| %-60s | %-100s | %-50s | %-60s |%n", modelUrn, file.getPath(), file.getName(), "" ); + for ( final AspectModelUrn modelUrn : modelUrns ) { + final List modelFiles = aspectModel.files(); + for ( final AspectModelFile modelFile : modelFiles ) { + if ( aspectModelLoader.containsDefinition( modelFile, modelUrn ) ) { + System.out.printf( "| %-60s | %-100s | %-50s |%n", modelUrn, file.getPath(), file.getName(), "" ); + } } } } From 0bb0e19d957653c4d3c1725e54d3893b7232ee9e Mon Sep 17 00:00:00 2001 From: Yauhenikapl Date: Thu, 1 Aug 2024 16:08:38 +0300 Subject: [PATCH 14/20] Fix styles --- .../org/eclipse/esmf/aspectmodel/loader/AspectModelLoader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoader.java b/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoader.java index 337453f4c..ca09ecd8d 100644 --- a/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoader.java +++ b/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoader.java @@ -359,7 +359,7 @@ private void urnsFromModelNeedResolution( final AspectModelFile modelFile, final .forEach( urn -> context.resolvedUrns().add( urn ) ); getAllUrnsInModel( modelFile.sourceModel() ).stream() - .map( urn -> urn.toString()) + .map( AspectModelUrn::toString ) .filter( urn -> !context.resolvedUrns().contains( urn ) ) .filter( urn -> !urn.startsWith( XSD.NS ) ) .filter( urn -> !urn.startsWith( RDF.uri ) ) From 0c4bde332119f9a530a5f775f9c81471f44b9869 Mon Sep 17 00:00:00 2001 From: Yauhenikapl Date: Thu, 15 Aug 2024 17:57:53 +0300 Subject: [PATCH 15/20] Fixes --- .../scanner/FileSystemScanner.java | 12 +++++----- .../pom.xml | 13 +++++------ .../FileNotFoundInRepositoryException.java | 9 ++++++++ .../java/org/eclipse/esmf/GitHubScanner.java | 16 ++++++++------ .../java/org/eclipse/esmf/GitHubStrategy.java | 0 .../org/eclipse/esmf/GitHubScannerTest.java | 4 ++-- .../org/eclipse/esmf/GitHubStrategyTest.java | 0 pom.xml | 12 +++++++++- tools/samm-cli/pom.xml | 4 +--- ...chCommand.java => AspectUsageCommand.java} | 22 ++++++++++--------- .../main/java/org/eclipse/esmf/SammCli.java | 2 +- 11 files changed, 58 insertions(+), 36 deletions(-) rename {esmf-sdk-github-resolver => esmf-aspect-model-github-resolver}/pom.xml (93%) create mode 100644 esmf-aspect-model-github-resolver/src/main/java/org/eclipse/esmf/FileNotFoundInRepositoryException.java rename {esmf-sdk-github-resolver => esmf-aspect-model-github-resolver}/src/main/java/org/eclipse/esmf/GitHubScanner.java (92%) rename {esmf-sdk-github-resolver => esmf-aspect-model-github-resolver}/src/main/java/org/eclipse/esmf/GitHubStrategy.java (100%) rename {esmf-sdk-github-resolver => esmf-aspect-model-github-resolver}/src/test/java/org/eclipse/esmf/GitHubScannerTest.java (91%) rename {esmf-sdk-github-resolver => esmf-aspect-model-github-resolver}/src/test/java/org/eclipse/esmf/GitHubStrategyTest.java (100%) rename tools/samm-cli/src/main/java/org/eclipse/esmf/{AspectSearchCommand.java => AspectUsageCommand.java} (87%) diff --git a/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/scanner/FileSystemScanner.java b/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/scanner/FileSystemScanner.java index 71f89ed07..231f02577 100644 --- a/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/scanner/FileSystemScanner.java +++ b/core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/scanner/FileSystemScanner.java @@ -23,8 +23,10 @@ import java.util.Set; import org.eclipse.esmf.aspectmodel.AspectModelFile; +import org.eclipse.esmf.aspectmodel.RdfUtil; import org.eclipse.esmf.aspectmodel.loader.AspectModelLoader; import org.eclipse.esmf.aspectmodel.resolver.AspectModelFileLoader; +import org.eclipse.esmf.aspectmodel.resolver.fs.ModelsRoot; import org.eclipse.esmf.aspectmodel.urn.AspectModelUrn; import org.eclipse.esmf.metamodel.AspectModel; import org.eclipse.esmf.metamodel.ModelElement; @@ -36,10 +38,10 @@ public class FileSystemScanner implements AspectModelScanner { private static final Logger LOG = LoggerFactory.getLogger( FileSystemScanner.class ); - protected final String searchDirectory; + protected final ModelsRoot modelsRoot; - public FileSystemScanner( final String searchDirectory ) { - this.searchDirectory = searchDirectory; + public FileSystemScanner( final ModelsRoot modelsRoot ) { + this.modelsRoot = modelsRoot; } @Override @@ -48,7 +50,7 @@ public List find( final String aspectModelFileName ) { final AspectModel searchAspectModel = new AspectModelLoader().load( new File( aspectModelFileName ) ); - final Path directory = Paths.get( searchDirectory ); + final Path directory = modelsRoot.rootPath(); final List files = Arrays.stream( Optional.ofNullable( directory.toFile().listFiles() ).orElse( new File[] {} ) ) .filter( file -> file.isFile() && file.getName().endsWith( ".ttl" ) && !file.getName() .equals( Paths.get( aspectModelFileName ).getFileName().toString() ) ) @@ -77,7 +79,7 @@ private List processFile( final File inputFile, final List urnsAspectModelFile = AspectModelLoader.getAllUrnsInModel( aspectModelFile.sourceModel() ); + final Set urnsAspectModelFile = RdfUtil.getAllUrnsInModel( aspectModelFile.sourceModel() ); for ( final AspectModelUrn aspectModelUrn : modelUrns ) { if ( urnsAspectModelFile.contains( aspectModelUrn ) ) { diff --git a/esmf-sdk-github-resolver/pom.xml b/esmf-aspect-model-github-resolver/pom.xml similarity index 93% rename from esmf-sdk-github-resolver/pom.xml rename to esmf-aspect-model-github-resolver/pom.xml index baf59fdc3..a57b2fcd0 100644 --- a/esmf-sdk-github-resolver/pom.xml +++ b/esmf-aspect-model-github-resolver/pom.xml @@ -9,7 +9,8 @@ DEV-SNAPSHOT - esmf-sdk-github-resolver + esmf-aspect-model-github-resolver + ESMF Aspect Model GitHub Resolver 17 @@ -22,12 +23,6 @@ esmf-aspect-meta-model-java - - org.kohsuke - github-api - 1.123 - - org.junit.jupiter @@ -48,6 +43,10 @@ org.eclipse.esmf esmf-aspect-model-validator + + org.kohsuke + github-api + \ No newline at end of file diff --git a/esmf-aspect-model-github-resolver/src/main/java/org/eclipse/esmf/FileNotFoundInRepositoryException.java b/esmf-aspect-model-github-resolver/src/main/java/org/eclipse/esmf/FileNotFoundInRepositoryException.java new file mode 100644 index 000000000..2551e673a --- /dev/null +++ b/esmf-aspect-model-github-resolver/src/main/java/org/eclipse/esmf/FileNotFoundInRepositoryException.java @@ -0,0 +1,9 @@ +package org.eclipse.esmf; + +import java.io.IOException; + +public class FileNotFoundInRepositoryException extends RuntimeException { + public FileNotFoundInRepositoryException( String message ) { + super( message ); + } +} diff --git a/esmf-sdk-github-resolver/src/main/java/org/eclipse/esmf/GitHubScanner.java b/esmf-aspect-model-github-resolver/src/main/java/org/eclipse/esmf/GitHubScanner.java similarity index 92% rename from esmf-sdk-github-resolver/src/main/java/org/eclipse/esmf/GitHubScanner.java rename to esmf-aspect-model-github-resolver/src/main/java/org/eclipse/esmf/GitHubScanner.java index 877c0a5f5..a56fb2291 100644 --- a/esmf-sdk-github-resolver/src/main/java/org/eclipse/esmf/GitHubScanner.java +++ b/esmf-aspect-model-github-resolver/src/main/java/org/eclipse/esmf/GitHubScanner.java @@ -26,6 +26,7 @@ import java.nio.channels.Channels; import java.nio.channels.ReadableByteChannel; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -35,6 +36,7 @@ import java.util.zip.ZipInputStream; import org.eclipse.esmf.aspectmodel.AspectModelFile; +import org.eclipse.esmf.aspectmodel.RdfUtil; import org.eclipse.esmf.aspectmodel.loader.AspectModelLoader; import org.eclipse.esmf.aspectmodel.resolver.modelfile.RawAspectModelFile; import org.eclipse.esmf.aspectmodel.resolver.services.TurtleLoader; @@ -59,7 +61,7 @@ public class GitHubScanner implements AspectModelScanner { private static final String GITHUB_ZIP_URL = GITHUB_BASE + "/%s/archive/refs/heads/%s.zip"; - private static final String DOWNLOADED_ZIP_NAME = "%s.zip"; + private static final String DOWNLOADED_ZIP_NAME = "%s/%s.zip"; protected final String repositoryName; protected final String branchName; @@ -104,20 +106,21 @@ public List find( final String aspectModelFileUrl ) { final AspectModel searchAspectModel = aspectModelLoader.load( new URL( contentOfSearchFile.getDownloadUrl() ).openStream() ); final String githubUrl = String.format( GITHUB_ZIP_URL, repositoryName, branchName ); - final String downloadedPackageName = String.format( DOWNLOADED_ZIP_NAME, branchName ); + final String downloadedPackageName = String.format( DOWNLOADED_ZIP_NAME, Files.createTempDirectory( "temporally" ).toString(), + branchName ); final File downloadedPackage = downloadFile( new URL( githubUrl ), downloadedPackageName ); final List filesInPackage = processPackage( new FileInputStream( downloadedPackage ) ); final boolean packageIsDeleted = downloadedPackage.delete(); if ( packageIsDeleted ) { - LOG.info( String.format( "Package %s was deleted!", downloadedPackage.getName() ) ); + LOG.debug( String.format( "Package %s was deleted", downloadedPackage.getName() ) ); } final List searchAspectUrns = searchAspectModel.elements().stream().map( ModelElement::urn ).toList(); for ( final AspectModelFile aspectModelFile : filesInPackage ) { - final Set urnsAspectModelFile = AspectModelLoader.getAllUrnsInModel( aspectModelFile.sourceModel() ); + final Set urnsAspectModelFile = RdfUtil.getAllUrnsInModel( aspectModelFile.sourceModel() ); for ( final AspectModelUrn aspectModelUrn : searchAspectUrns ) { if ( urnsAspectModelFile.contains( aspectModelUrn ) ) { @@ -138,13 +141,12 @@ private boolean checkFileExists( final GHRepository repository, final String asp final GHContent content = repository.getFileContent( aspectModelFileUrl, branchName ); return content != null; } catch ( IOException e ) { - throw new RuntimeException( - new IOException( String.format( "File %s can't found in %s repository.", aspectModelFileUrl, repository.getUrl() ) ) ); + throw new FileNotFoundInRepositoryException( + String.format( "File %s can't be found in repository %s.", aspectModelFileUrl, repository.getUrl() ) ); } } private File downloadFile( final URL repositoryUrl, final String outputFileName ) throws IOException { - LOG.info( String.format( "Downloading %s repository to local...", repositoryUrl.getPath() ) ); ReadableByteChannel rbc; File outputFile = new File( outputFileName ); diff --git a/esmf-sdk-github-resolver/src/main/java/org/eclipse/esmf/GitHubStrategy.java b/esmf-aspect-model-github-resolver/src/main/java/org/eclipse/esmf/GitHubStrategy.java similarity index 100% rename from esmf-sdk-github-resolver/src/main/java/org/eclipse/esmf/GitHubStrategy.java rename to esmf-aspect-model-github-resolver/src/main/java/org/eclipse/esmf/GitHubStrategy.java diff --git a/esmf-sdk-github-resolver/src/test/java/org/eclipse/esmf/GitHubScannerTest.java b/esmf-aspect-model-github-resolver/src/test/java/org/eclipse/esmf/GitHubScannerTest.java similarity index 91% rename from esmf-sdk-github-resolver/src/test/java/org/eclipse/esmf/GitHubScannerTest.java rename to esmf-aspect-model-github-resolver/src/test/java/org/eclipse/esmf/GitHubScannerTest.java index 5430db135..8327a833e 100644 --- a/esmf-sdk-github-resolver/src/test/java/org/eclipse/esmf/GitHubScannerTest.java +++ b/esmf-aspect-model-github-resolver/src/test/java/org/eclipse/esmf/GitHubScannerTest.java @@ -53,8 +53,8 @@ void testGithubScannerWithInvalidFileUrl() { } ); assertEquals( - "java.io.IOException: File core/esmf-test-aspect-models/src/main/resources/valid/org.eclipse.esmf.test/1.0.0/test-test-test" - + ".ttl can't found in https://api.github.com/repos/eclipse-esmf/esmf-sdk repository.", + "File core/esmf-test-aspect-models/src/main/resources/valid/org.eclipse.esmf.test/1.0.0/test-test-test.ttl can't be found in " + + "repository https://api.github.com/repos/eclipse-esmf/esmf-sdk.", exception.getMessage() ); } diff --git a/esmf-sdk-github-resolver/src/test/java/org/eclipse/esmf/GitHubStrategyTest.java b/esmf-aspect-model-github-resolver/src/test/java/org/eclipse/esmf/GitHubStrategyTest.java similarity index 100% rename from esmf-sdk-github-resolver/src/test/java/org/eclipse/esmf/GitHubStrategyTest.java rename to esmf-aspect-model-github-resolver/src/test/java/org/eclipse/esmf/GitHubStrategyTest.java diff --git a/pom.xml b/pom.xml index b53cd37a1..9e942e79d 100644 --- a/pom.xml +++ b/pom.xml @@ -67,7 +67,6 @@ tools/esmf-aspect-model-maven-plugin tools/samm-cli documentation - esmf-sdk-github-resolver @@ -76,6 +75,7 @@ 2.22.1 + 1.123 @@ -161,6 +161,16 @@ esmf-aspect-model-aas-generator ${project.version} + + org.eclipse.esmf + esmf-aspect-model-github-resolver + ${project.version} + + + org.kohsuke + github-api + ${github-api-version} + diff --git a/tools/samm-cli/pom.xml b/tools/samm-cli/pom.xml index 3cfe22858..aa0490123 100644 --- a/tools/samm-cli/pom.xml +++ b/tools/samm-cli/pom.xml @@ -131,9 +131,7 @@ org.eclipse.esmf - esmf-sdk-github-resolver - DEV-SNAPSHOT - compile + esmf-aspect-model-github-resolver diff --git a/tools/samm-cli/src/main/java/org/eclipse/esmf/AspectSearchCommand.java b/tools/samm-cli/src/main/java/org/eclipse/esmf/AspectUsageCommand.java similarity index 87% rename from tools/samm-cli/src/main/java/org/eclipse/esmf/AspectSearchCommand.java rename to tools/samm-cli/src/main/java/org/eclipse/esmf/AspectUsageCommand.java index 19b2685a7..c263439fa 100644 --- a/tools/samm-cli/src/main/java/org/eclipse/esmf/AspectSearchCommand.java +++ b/tools/samm-cli/src/main/java/org/eclipse/esmf/AspectUsageCommand.java @@ -14,6 +14,7 @@ package org.eclipse.esmf; import java.io.File; +import java.nio.file.Path; import java.util.List; import org.eclipse.esmf.aspectmodel.AspectModelFile; @@ -21,6 +22,7 @@ import org.eclipse.esmf.aspectmodel.resolver.FileSystemStrategy; import org.eclipse.esmf.aspectmodel.resolver.ResolutionStrategy; import org.eclipse.esmf.aspectmodel.resolver.fs.FlatModelsRoot; +import org.eclipse.esmf.aspectmodel.resolver.fs.StructuredModelsRoot; import org.eclipse.esmf.aspectmodel.scanner.AspectModelScanner; import org.eclipse.esmf.aspectmodel.scanner.FileSystemScanner; import org.eclipse.esmf.aspectmodel.urn.AspectModelUrn; @@ -31,18 +33,18 @@ import org.slf4j.LoggerFactory; import picocli.CommandLine; -@CommandLine.Command( name = AspectSearchCommand.COMMAND_NAME, - description = "Search separate Properties files used by Aspect Model", +@CommandLine.Command( name = AspectUsageCommand.COMMAND_NAME, + description = "Shows where model elements are used in Aspect Models", headerHeading = "@|bold Usage|@:%n%n", descriptionHeading = "%n@|bold Description|@:%n%n", parameterListHeading = "%n@|bold Parameters|@:%n", optionListHeading = "%n@|bold Options|@:%n", mixinStandardHelpOptions = true ) -public class AspectSearchCommand extends AbstractCommand { +public class AspectUsageCommand extends AbstractCommand { public static final String COMMAND_NAME = "search"; - private static final Logger LOG = LoggerFactory.getLogger( AspectSearchCommand.class ); + private static final Logger LOG = LoggerFactory.getLogger( AspectUsageCommand.class ); @CommandLine.Mixin private LoggingMixin loggingMixin; @@ -53,19 +55,19 @@ public class AspectSearchCommand extends AbstractCommand { @CommandLine.Parameters( paramLabel = "INPUT", description = "Input file name of the Aspect Model .ttl file", arity = "1", index = "0" ) private String input; - @CommandLine.Option( names = { "--models-path", "-msp" }, description = "Path to Models, where have to search" ) + @CommandLine.Option( names = { "--models-root", "-mr" }, description = "Set the models root directory" ) private String pathToModels = "-"; - @CommandLine.Option( names = { "--github", "-gh" }, description = "Use this flag to introduce what has to be scanned" ) + @CommandLine.Option( names = { "--github", "-gh" }, description = "Enable loading Aspect Models from GitHub" ) private boolean searchInGithub = false; - @CommandLine.Option( names = { "--github-name", "-ghn" }, description = "Provide GitHub name. Example: eclipse-esmf/esmf-sdk." ) + @CommandLine.Option( names = { "--github-name", "-ghn" }, description = "Set the GitHub repository name. Example: eclipse-esmf/esmf-sdk." ) private String gitHubName = ""; - @CommandLine.Option( names = { "--github-directory", "-ghd" }, description = "Provide GitHub directory for scanning" ) + @CommandLine.Option( names = { "--github-directory", "-ghd" }, description = "Set the GitHub directory" ) private String gitHubDirectory = ""; - @CommandLine.Option( names = { "--github-branch", "-ghb" }, description = "Provide GitHub branch for scanning" ) + @CommandLine.Option( names = { "--github-branch", "-ghb" }, description = "Set the GitHub branch" ) private String gitHubBranch = ""; public String getInput() { @@ -81,7 +83,7 @@ public void run() { System.out.println( "Parameters '--github-url' and '--github-directory' have to be provided!" ); return; } else if ( !searchInGithub ) { - aspectModelScanner = new FileSystemScanner( pathToModels ); + aspectModelScanner = new FileSystemScanner( new StructuredModelsRoot( Path.of( pathToModels ) ) ); aspectModelFiles = aspectModelScanner.find( input ); } else { aspectModelScanner = new GitHubScanner( gitHubName, gitHubBranch.isBlank() ? "main" : gitHubBranch ); diff --git a/tools/samm-cli/src/main/java/org/eclipse/esmf/SammCli.java b/tools/samm-cli/src/main/java/org/eclipse/esmf/SammCli.java index 8a51ecca2..0f5e6a795 100644 --- a/tools/samm-cli/src/main/java/org/eclipse/esmf/SammCli.java +++ b/tools/samm-cli/src/main/java/org/eclipse/esmf/SammCli.java @@ -98,7 +98,7 @@ public SammCli() { final CommandLine initialCommandLine = new CommandLine( this ) .addSubcommand( new AspectCommand() ) .addSubcommand( new AasCommand() ) - .addSubcommand( new AspectSearchCommand() ) + .addSubcommand( new AspectUsageCommand() ) .setCaseInsensitiveEnumValuesAllowed( true ) .setExecutionStrategy( LoggingMixin::executionStrategy ); initialCommandLine.getHelpSectionMap().put( SECTION_KEY_COMMAND_LIST, new CustomCommandListRenderer() ); From a144549fe9047bc9dec5382044538eeb359995df Mon Sep 17 00:00:00 2001 From: Yauhenikapl Date: Thu, 15 Aug 2024 17:59:38 +0300 Subject: [PATCH 16/20] Fix styles --- .../src/main/java/org/eclipse/esmf/AspectUsageCommand.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/samm-cli/src/main/java/org/eclipse/esmf/AspectUsageCommand.java b/tools/samm-cli/src/main/java/org/eclipse/esmf/AspectUsageCommand.java index c263439fa..94042130c 100644 --- a/tools/samm-cli/src/main/java/org/eclipse/esmf/AspectUsageCommand.java +++ b/tools/samm-cli/src/main/java/org/eclipse/esmf/AspectUsageCommand.java @@ -61,7 +61,8 @@ public class AspectUsageCommand extends AbstractCommand { @CommandLine.Option( names = { "--github", "-gh" }, description = "Enable loading Aspect Models from GitHub" ) private boolean searchInGithub = false; - @CommandLine.Option( names = { "--github-name", "-ghn" }, description = "Set the GitHub repository name. Example: eclipse-esmf/esmf-sdk." ) + @CommandLine.Option( names = { "--github-name", + "-ghn" }, description = "Set the GitHub repository name. Example: eclipse-esmf/esmf-sdk." ) private String gitHubName = ""; @CommandLine.Option( names = { "--github-directory", "-ghd" }, description = "Set the GitHub directory" ) From 50ed464f0b4d5250e1d7d92b346f95f5e0364bc4 Mon Sep 17 00:00:00 2001 From: Yauhenikapl Date: Thu, 15 Aug 2024 18:10:02 +0300 Subject: [PATCH 17/20] Update github resolver pom --- esmf-aspect-model-github-resolver/pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/esmf-aspect-model-github-resolver/pom.xml b/esmf-aspect-model-github-resolver/pom.xml index a57b2fcd0..4c5726ba8 100644 --- a/esmf-aspect-model-github-resolver/pom.xml +++ b/esmf-aspect-model-github-resolver/pom.xml @@ -11,6 +11,7 @@ esmf-aspect-model-github-resolver ESMF Aspect Model GitHub Resolver + jar 17 From e907b47a2f2c68dc54fdc05dd0e1b690217b91c1 Mon Sep 17 00:00:00 2001 From: Yauhenikapl Date: Thu, 15 Aug 2024 18:19:43 +0300 Subject: [PATCH 18/20] Update github resolver pom --- tools/samm-cli/pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/samm-cli/pom.xml b/tools/samm-cli/pom.xml index aa0490123..3b65ee8b0 100644 --- a/tools/samm-cli/pom.xml +++ b/tools/samm-cli/pom.xml @@ -132,6 +132,7 @@ org.eclipse.esmf esmf-aspect-model-github-resolver + compile From 2d6e9f389356d116657acdb91dc6bdcc5442b0d0 Mon Sep 17 00:00:00 2001 From: Yauhenikapl Date: Fri, 16 Aug 2024 08:58:21 +0300 Subject: [PATCH 19/20] Update github resolver pom --- esmf-aspect-model-github-resolver/pom.xml | 2 +- tools/samm-cli/pom.xml | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/esmf-aspect-model-github-resolver/pom.xml b/esmf-aspect-model-github-resolver/pom.xml index 4c5726ba8..8a20c4af7 100644 --- a/esmf-aspect-model-github-resolver/pom.xml +++ b/esmf-aspect-model-github-resolver/pom.xml @@ -7,11 +7,11 @@ org.eclipse.esmf esmf-sdk-parent DEV-SNAPSHOT + ../pom.xml esmf-aspect-model-github-resolver ESMF Aspect Model GitHub Resolver - jar 17 diff --git a/tools/samm-cli/pom.xml b/tools/samm-cli/pom.xml index 3b65ee8b0..a8991da68 100644 --- a/tools/samm-cli/pom.xml +++ b/tools/samm-cli/pom.xml @@ -49,6 +49,10 @@ org.eclipse.esmf esmf-aspect-model-starter + + org.eclipse.esmf + esmf-aspect-model-github-resolver + com.fasterxml.jackson.core jackson-databind @@ -129,11 +133,6 @@ tika-core test - - org.eclipse.esmf - esmf-aspect-model-github-resolver - compile - From a20a57047dd02053254f95f799e34e23d5e35cc3 Mon Sep 17 00:00:00 2001 From: Yauhenikapl Date: Fri, 16 Aug 2024 09:59:12 +0300 Subject: [PATCH 20/20] Fix build --- pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/pom.xml b/pom.xml index 9e942e79d..08e76e99a 100644 --- a/pom.xml +++ b/pom.xml @@ -64,6 +64,7 @@ core/esmf-aspect-static-meta-model-java core/esmf-test-aspect-models core/esmf-test-resources + esmf-aspect-model-github-resolver tools/esmf-aspect-model-maven-plugin tools/samm-cli documentation