Skip to content

Commit c9e3f61

Browse files
committed
Merge branch 'main' into 2.9.x
2 parents 9bf5e4b + 87be831 commit c9e3f61

File tree

122 files changed

+5826
-1771
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

122 files changed

+5826
-1771
lines changed

.github/workflows/pull-request-check.yml

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,23 +67,21 @@ jobs:
6767
java --version
6868
export MAVEN_OPTS="-Xmx4096m"
6969
export JAVA_TOOL_OPTIONS="-Dfile.encoding=UTF8"
70-
mvn -B -pl '!org.eclipse.esmf:samm-cli' clean install -Dmaven.wagon.httpconnectionManager.ttlSeconds=60
71-
cd tools/samm-cli
72-
unset JAVA_TOOL_OPTIONS
73-
mvn -B clean verify -Dmaven.wagon.httpconnectionManager.ttlSeconds=60
70+
mvn -B -pl '!org.eclipse.esmf:samm-cli' clean install -Pnative -Dmaven.wagon.httpconnectionManager.ttlSeconds=60
7471
shell: bash
7572

7673
- name: Build native image
7774
if: matrix.os != 'macos-13'
7875
run: |
7976
export MAVEN_OPTS="-Xmx4096m"
80-
cd tools/samm-cli
81-
mvn -B package -Pnative -Dmaven.wagon.httpconnectionManager.ttlSeconds=60
77+
mvn -B -pl tools/samm-cli clean verify -Pnative -Dmaven.wagon.httpconnectionManager.ttlSeconds=60
8278
shell: bash
8379

8480
- name: Build native image (Mac)
8581
if: matrix.os == 'macos-13'
8682
run: |
83+
export MAVEN_OPTS="-Xmx4096m"
84+
mvn -B -pl tools/samm-cli clean verify -Dmaven.wagon.httpconnectionManager.ttlSeconds=60
8785
bundle="samm-bundle-DEV-SNAPSHOT-$(date +%s)"
8886
mkdir ${bundle}
8987
curl -Lo jre.tar.gz https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.3%2B9/OpenJDK21U-jre_x64_mac_hotspot_21.0.3_9.tar.gz

.github/workflows/release-workflow.yml

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ jobs:
6767
- name: Setup JDK
6868
uses: graalvm/setup-graalvm@2f25c0caae5b220866f732832d5e3e29ff493338 # v1.2.1
6969
with:
70-
java-version: '17.0.8'
70+
java-version: '17.0.10'
7171
distribution: 'graalvm'
7272
components: 'native-image,js'
7373
github-token: ${{ secrets.GITHUB_TOKEN }}
@@ -100,13 +100,10 @@ jobs:
100100
release_version=${{ github.event.inputs.release_version }}
101101
102102
# Actual build of core SDK
103-
mvn -B -pl '!org.eclipse.esmf:samm-cli' clean deploy -Dmaven.wagon.httpconnectionManager.ttlSeconds=60 -DaltDeploymentRepository=local::default::file://nexus-staging -Psign
103+
mvn -B -pl '!org.eclipse.esmf:samm-cli' clean deploy -Pnative -Dmaven.wagon.httpconnectionManager.ttlSeconds=60 -DaltDeploymentRepository=local::default::file://nexus-staging -Psign
104104
# Build of CLI
105-
pushd tools/samm-cli
106105
unset JAVA_TOOL_OPTIONS
107-
mvn -B clean verify -Dmaven.wagon.httpconnectionManager.ttlSeconds=60
108-
mvn -B verify -Pnative -Dmaven.wagon.httpconnectionManager.ttlSeconds=60
109-
popd
106+
mvn -B -pl tools/samm-cli clean verify -Pnative -Dmaven.wagon.httpconnectionManager.ttlSeconds=60
110107
111108
# Create .tar.gz of samm-cli
112109
pushd tools/samm-cli/target
@@ -153,7 +150,7 @@ jobs:
153150
- name: Setup JDK
154151
uses: graalvm/setup-graalvm@2f25c0caae5b220866f732832d5e3e29ff493338 # v1.2.1
155152
with:
156-
java-version: '17.0.8'
153+
java-version: '17.0.10'
157154
distribution: 'graalvm'
158155
components: 'native-image,js'
159156
github-token: ${{ secrets.GITHUB_TOKEN }}
@@ -175,11 +172,10 @@ jobs:
175172
mvn versions:set -DnewVersion=${{ github.event.inputs.release_version }}
176173
mvn versions:commit
177174
# Actual build of core SDK
178-
mvn -B -pl '!org.eclipse.esmf:samm-cli' clean install -Dmaven.wagon.httpconnectionManager.ttlSeconds=60
175+
mvn -B -pl '!org.eclipse.esmf:samm-cli' clean install -Pnative -Dmaven.wagon.httpconnectionManager.ttlSeconds=60
179176
# Build of CLI
180-
cd tools/samm-cli
181177
unset JAVA_TOOL_OPTIONS
182-
mvn -B clean verify -Dmaven.wagon.httpconnectionManager.ttlSeconds=60
178+
mvn -B -pl tools/samm-cli clean verify -Dmaven.wagon.httpconnectionManager.ttlSeconds=60
183179
shell: bash
184180

185181
- name: Build native executable
@@ -227,7 +223,7 @@ jobs:
227223
- name: Setup JDK
228224
uses: graalvm/setup-graalvm@2f25c0caae5b220866f732832d5e3e29ff493338 # v1.2.1
229225
with:
230-
java-version: '17.0.8'
226+
java-version: '17.0.10'
231227
distribution: 'graalvm'
232228
components: 'native-image,js'
233229
github-token: ${{ secrets.GITHUB_TOKEN }}
@@ -262,12 +258,10 @@ jobs:
262258
mvn versions:commit
263259
264260
# Actual build of core SDK
265-
mvn -B -pl '!org.eclipse.esmf:samm-cli' clean install -Dmaven.wagon.httpconnectionManager.ttlSeconds=60
261+
mvn -B -pl '!org.eclipse.esmf:samm-cli' clean install -Pnative -Dmaven.wagon.httpconnectionManager.ttlSeconds=60
266262
# Build of CLI
267-
cd tools/samm-cli
268263
unset JAVA_TOOL_OPTIONS
269-
mvn -B clean verify -Dmaven.wagon.httpconnectionManager.ttlSeconds=60
270-
mvn -B verify -Pnative -Dmaven.wagon.httpconnectionManager.ttlSeconds=60
264+
mvn -B -pl tools/samm-cli clean verify -Pnative -Dmaven.wagon.httpconnectionManager.ttlSeconds=60
271265
shell: bash
272266

273267
- name: Upload Windows binary

core/esmf-aspect-meta-model-java/pom.xml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,6 @@
2828
<name>ESMF Aspect Meta Model Java</name>
2929
<packaging>jar</packaging>
3030

31-
<properties>
32-
<generated-sources>${project.basedir}/src-gen</generated-sources>
33-
<build-time-sources>${project.basedir}/src-buildtime</build-time-sources>
34-
</properties>
35-
3631
<dependencies>
3732
<dependency>
3833
<groupId>org.eclipse.esmf</groupId>

core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/RdfUtil.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import org.apache.jena.rdf.model.ModelFactory;
3737
import org.apache.jena.rdf.model.Property;
3838
import org.apache.jena.rdf.model.RDFNode;
39+
import org.apache.jena.rdf.model.ResIterator;
3940
import org.apache.jena.rdf.model.Resource;
4041
import org.apache.jena.rdf.model.Statement;
4142
import org.apache.jena.vocabulary.RDF;
@@ -165,4 +166,32 @@ public static List<Resource> getNamedElementsReferringTo( final RDFNode node ) {
165166
} ).toList();
166167
}
167168
}
169+
170+
/**
171+
* Merges an RDF-model into another on a per-element basis instead of a per-statement basis. This means only those model element
172+
* definitions from the model to merge are merged into the target model that are not already present in the target model.
173+
* This prevents duplicate assertions of statements where the object is a blank node.
174+
*
175+
* @param target the model to merge into
176+
* @param modelToMerge the source model of model element definitions to merge
177+
*/
178+
public static void mergeModel( final Model target, final Model modelToMerge ) {
179+
final Set<String> targetSubjects = Streams.stream( target.listSubjects() )
180+
.filter( Resource::isURIResource )
181+
.map( Resource::getURI )
182+
.collect( toSet() );
183+
for ( final ResIterator it = modelToMerge.listSubjects(); it.hasNext(); ) {
184+
final Resource resource = it.next();
185+
if ( resource.isAnon() ) {
186+
continue;
187+
}
188+
if ( !targetSubjects.contains( resource.getURI() ) ) {
189+
final Model modelElementDefinition = getModelElementDefinition( resource );
190+
target.add( modelElementDefinition );
191+
}
192+
}
193+
for ( final Map.Entry<String, String> prefixEntry : modelToMerge.getNsPrefixMap().entrySet() ) {
194+
target.setNsPrefix( prefixEntry.getKey(), prefixEntry.getValue() );
195+
}
196+
}
168197
}

core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/loader/AspectModelLoader.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,20 @@
4343
import org.eclipse.esmf.aspectmodel.resolver.AspectModelFileLoader;
4444
import org.eclipse.esmf.aspectmodel.resolver.EitherStrategy;
4545
import org.eclipse.esmf.aspectmodel.resolver.FileSystemStrategy;
46-
import org.eclipse.esmf.aspectmodel.resolver.ModelResolutionException;
4746
import org.eclipse.esmf.aspectmodel.resolver.ModelSource;
4847
import org.eclipse.esmf.aspectmodel.resolver.ResolutionStrategy;
4948
import org.eclipse.esmf.aspectmodel.resolver.ResolutionStrategySupport;
49+
import org.eclipse.esmf.aspectmodel.resolver.exceptions.ModelResolutionException;
5050
import org.eclipse.esmf.aspectmodel.resolver.fs.FlatModelsRoot;
5151
import org.eclipse.esmf.aspectmodel.resolver.modelfile.DefaultAspectModelFile;
5252
import org.eclipse.esmf.aspectmodel.resolver.modelfile.MetaModelFile;
5353
import org.eclipse.esmf.aspectmodel.resolver.modelfile.RawAspectModelFile;
54+
import org.eclipse.esmf.aspectmodel.resolver.services.TurtleLoader;
5455
import org.eclipse.esmf.aspectmodel.urn.AspectModelUrn;
5556
import org.eclipse.esmf.aspectmodel.urn.ElementType;
5657
import org.eclipse.esmf.aspectmodel.urn.UrnSyntaxException;
5758
import org.eclipse.esmf.aspectmodel.versionupdate.MetaModelVersionMigrator;
59+
import org.eclipse.esmf.metamodel.Aspect;
5860
import org.eclipse.esmf.metamodel.AspectModel;
5961
import org.eclipse.esmf.metamodel.ModelElement;
6062
import org.eclipse.esmf.metamodel.Namespace;
@@ -113,6 +115,7 @@ public AspectModelLoader( final ResolutionStrategy resolutionStrategy ) {
113115
* @param resolutionStrategies the strategies
114116
*/
115117
public AspectModelLoader( final List<ResolutionStrategy> resolutionStrategies ) {
118+
TurtleLoader.init();
116119
if ( resolutionStrategies.size() == 1 ) {
117120
resolutionStrategy = resolutionStrategies.get( 0 );
118121
} else if ( resolutionStrategies.isEmpty() ) {
@@ -434,10 +437,10 @@ public AspectModel emptyModel() {
434437
*/
435438
public AspectModel loadAspectModelFiles( final Collection<AspectModelFile> inputFiles ) {
436439
final Model mergedModel = ModelFactory.createDefaultModel();
437-
mergedModel.add( MetaModelFile.metaModelDefinitions() );
438440
for ( final AspectModelFile file : inputFiles ) {
439-
mergedModel.add( file.sourceModel() );
441+
RdfUtil.mergeModel( mergedModel, file.sourceModel() );
440442
}
443+
mergedModel.add( MetaModelFile.metaModelDefinitions() );
441444

442445
final List<ModelElement> elements = new ArrayList<>();
443446
final List<AspectModelFile> files = new ArrayList<>();
@@ -460,6 +463,10 @@ public AspectModel loadAspectModelFiles( final Collection<AspectModelFile> input
460463
}
461464

462465
setNamespaces( files, elements );
466+
elements.stream()
467+
.filter( modelElement -> modelElement.is( Aspect.class ) )
468+
.findFirst()
469+
.ifPresent( aspect -> mergedModel.setNsPrefix( "", aspect.urn().getUrnPrefix() ) );
463470
return new DefaultAspectModel( files, mergedModel, elements );
464471
}
465472

core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/resolver/AspectModelFileLoader.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import static org.apache.commons.lang3.StringUtils.isBlank;
1717

1818
import java.io.BufferedReader;
19+
import java.io.ByteArrayInputStream;
1920
import java.io.File;
2021
import java.io.FileInputStream;
2122
import java.io.FileNotFoundException;
@@ -34,6 +35,7 @@
3435

3536
import org.eclipse.esmf.aspectmodel.AspectModelFile;
3637
import org.eclipse.esmf.aspectmodel.loader.AspectModelLoader;
38+
import org.eclipse.esmf.aspectmodel.resolver.exceptions.ModelResolutionException;
3739
import org.eclipse.esmf.aspectmodel.resolver.exceptions.ParserException;
3840
import org.eclipse.esmf.aspectmodel.resolver.modelfile.RawAspectModelFile;
3941
import org.eclipse.esmf.aspectmodel.resolver.services.TurtleLoader;
@@ -96,15 +98,24 @@ public static RawAspectModelFile load( final Model model ) {
9698
return new RawAspectModelFile( model, List.of(), Optional.empty() );
9799
}
98100

101+
public static RawAspectModelFile load( final byte[] content ) {
102+
return load( new ByteArrayInputStream( content ) );
103+
}
104+
99105
public static RawAspectModelFile load( final URL url ) {
100106
if ( url.getProtocol().equals( "file" ) ) {
101107
try {
102108
return load( Paths.get( url.toURI() ).toFile() );
103109
} catch ( final URISyntaxException exception ) {
104110
throw new ModelResolutionException( "Can not load model from file URL", exception );
105111
}
112+
} else if ( url.getProtocol().equals( "http" ) || url.getProtocol().equals( "https" ) ) {
113+
// Downloading from http(s) should take proxy settings into consideration, so we don't just .openStream() here
114+
final byte[] fileContent = new Download().downloadFile( url );
115+
return load( fileContent );
106116
}
107117
try {
118+
// Other URLs (e.g. resource://) we just load using openStream()
108119
return load( url.openStream(), Optional.of( url.toURI() ) );
109120
} catch ( final IOException | URISyntaxException exception ) {
110121
throw new ModelResolutionException( "Can not load model from URL", exception );

core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/resolver/ClasspathStrategy.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import java.util.stream.Stream;
3434

3535
import org.eclipse.esmf.aspectmodel.AspectModelFile;
36+
import org.eclipse.esmf.aspectmodel.resolver.exceptions.ModelResolutionException;
3637
import org.eclipse.esmf.aspectmodel.urn.AspectModelUrn;
3738

3839
import org.apache.commons.io.IOUtils;

core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/resolver/CommandExecutor.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
import java.util.Scanner;
1919
import java.util.StringTokenizer;
2020

21+
import org.eclipse.esmf.aspectmodel.resolver.exceptions.ModelResolutionException;
22+
2123
/**
2224
* Executes an external resolver via the underlying OS command and returns the stdout from the command as result.
2325
*/
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
* Copyright (c) 2024 Robert Bosch Manufacturing Solutions GmbH
3+
*
4+
* See the AUTHORS file(s) distributed with this work for additional
5+
* information regarding authorship.
6+
*
7+
* This Source Code Form is subject to the terms of the Mozilla Public
8+
* License, v. 2.0. If a copy of the MPL was not distributed with this
9+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
10+
*
11+
* SPDX-License-Identifier: MPL-2.0
12+
*/
13+
14+
package org.eclipse.esmf.aspectmodel.resolver;
15+
16+
import java.io.File;
17+
import java.io.FileOutputStream;
18+
import java.io.IOException;
19+
import java.net.URISyntaxException;
20+
import java.net.URL;
21+
import java.net.http.HttpClient;
22+
import java.net.http.HttpRequest;
23+
import java.net.http.HttpResponse;
24+
import java.time.Duration;
25+
import java.util.Optional;
26+
27+
import org.eclipse.esmf.aspectmodel.resolver.exceptions.ModelResolutionException;
28+
29+
import org.slf4j.Logger;
30+
import org.slf4j.LoggerFactory;
31+
32+
/**
33+
* Convenience class to download a file via HTTP, which the ability to auto-detect and use proxy settings
34+
*/
35+
public class Download {
36+
private static final Logger LOG = LoggerFactory.getLogger( Download.class );
37+
private final ProxyConfig proxyConfig;
38+
39+
public Download( final ProxyConfig proxyConfig ) {
40+
this.proxyConfig = proxyConfig;
41+
}
42+
43+
public Download() {
44+
this( ProxyConfig.detectProxySettings() );
45+
}
46+
47+
/**
48+
* Download the file and return the contents as byte array
49+
*
50+
* @param fileUrl the URL
51+
* @return the file contents
52+
*/
53+
public byte[] downloadFile( final URL fileUrl ) {
54+
try {
55+
final HttpClient.Builder clientBuilder = HttpClient.newBuilder()
56+
.version( HttpClient.Version.HTTP_1_1 )
57+
.followRedirects( HttpClient.Redirect.ALWAYS )
58+
.connectTimeout( Duration.ofSeconds( 10 ) );
59+
Optional.ofNullable( proxyConfig.proxy() ).ifPresent( clientBuilder::proxy );
60+
Optional.ofNullable( proxyConfig.authenticator() ).ifPresent( clientBuilder::authenticator );
61+
final HttpClient client = clientBuilder.build();
62+
final HttpRequest request = HttpRequest.newBuilder().uri( fileUrl.toURI() ).build();
63+
final HttpResponse<byte[]> response = client.send( request, HttpResponse.BodyHandlers.ofByteArray() );
64+
return response.body();
65+
} catch ( final InterruptedException | URISyntaxException | IOException exception ) {
66+
throw new ModelResolutionException( "Could not retrieve " + fileUrl, exception );
67+
}
68+
}
69+
70+
/**
71+
* Download the file and write it to the file system
72+
*
73+
* @param fileUrl the URL
74+
* @param outputFile the output file to write
75+
* @return the file written
76+
*/
77+
public File downloadFile( final URL fileUrl, final File outputFile ) {
78+
try ( final FileOutputStream outputStream = new FileOutputStream( outputFile ) ) {
79+
final byte[] fileContent = downloadFile( fileUrl );
80+
outputStream.write( fileContent );
81+
} catch ( final IOException exception ) {
82+
throw new ModelResolutionException( "Could not write file " + outputFile, exception );
83+
}
84+
85+
LOG.info( "Downloaded {} to local file {}", fileUrl.getPath(), outputFile );
86+
return outputFile;
87+
}
88+
}

core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/resolver/EitherStrategy.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.util.stream.Stream;
2121

2222
import org.eclipse.esmf.aspectmodel.AspectModelFile;
23+
import org.eclipse.esmf.aspectmodel.resolver.exceptions.ModelResolutionException;
2324
import org.eclipse.esmf.aspectmodel.urn.AspectModelUrn;
2425

2526
import io.vavr.control.Try;

0 commit comments

Comments
 (0)