1616import java .io .File ;
1717import java .net .URI ;
1818import java .nio .file .Path ;
19- import java .util .*;
19+ import java .util .AbstractMap ;
20+ import java .util .Comparator ;
21+ import java .util .LinkedHashMap ;
22+ import java .util .List ;
23+ import java .util .Map ;
24+ import java .util .Optional ;
2025import java .util .stream .Collectors ;
2126import java .util .stream .Stream ;
2227
23- import org .apache .jena .rdf .model .*;
24- import org .apache .jena .vocabulary .RDF ;
2528import org .eclipse .esmf .ame .services .models .Model ;
2629import org .eclipse .esmf .ame .services .models .Version ;
2730import org .eclipse .esmf .aspectmodel .AspectModelFile ;
3639import org .eclipse .esmf .metamodel .vocabulary .SammNs ;
3740import org .eclipse .esmf .samm .KnownVersion ;
3841
39- import io .vavr .control .Try ;
42+ import org .apache .jena .rdf .model .Resource ;
43+ import org .apache .jena .rdf .model .Statement ;
44+ import org .apache .jena .vocabulary .RDF ;
4045
4146/**
4247 * A utility class for grouping model URIs by namespace and version.
4348 *
4449 * @param aspectModelLoader the loader for aspect models
4550 */
46- public record ModelGroupingUtils (AspectModelLoader aspectModelLoader ) {
51+ public record ModelGroupingUtils ( AspectModelLoader aspectModelLoader ) {
4752 /**
4853 * Constructs a ModelGrouper with the given base model path.
4954 */
@@ -53,7 +58,7 @@ public record ModelGroupingUtils(AspectModelLoader aspectModelLoader) {
5358 /**
5459 * Groups model URIs by namespace and version, setting the existing field as specified.
5560 *
56- * @param uriStream a stream of model URIs
61+ * @param uriStream a stream of model URIs
5762 * @param onlyAspectModels get only Aspect Models with Aspects as namespace list.
5863 * @return a map where the keys are namespaces and the values are lists of maps containing versions and their associated models
5964 */
@@ -64,28 +69,22 @@ public Map<String, List<Version>> groupModelsByNamespaceAndVersion( final Stream
6469 /**
6570 * Groups model URIs by namespace and version, setting the existing field as specified.
6671 *
67- * @param files a List of model Files
72+ * @param files a List of model Files
6873 * @param onlyAspectModels get only Aspect Models with Aspects as namespace list.
6974 * @return a map where the keys are namespaces and the values are lists of maps containing versions and their associated models
7075 */
7176 public Map <String , List <Version >> groupModelsByNamespaceAndVersion ( final List <File > files , final boolean onlyAspectModels ) {
7277 final List <Model > allModels = loadAndExtractModels ( files , onlyAspectModels );
7378 final Map <String , List <Model >> modelsByNamespace = groupByNamespace ( allModels );
7479
75- return modelsByNamespace .entrySet ().stream ()
76- .sorted ( Map .Entry .comparingByKey () )
77- .collect ( Collectors .toMap (
78- Map .Entry ::getKey ,
79- entry -> groupByVersion ( entry .getValue () ),
80- this ::throwOnDuplicateKey ,
81- LinkedHashMap ::new ) );
80+ return modelsByNamespace .entrySet ().stream ().sorted ( Map .Entry .comparingByKey () ).collect (
81+ Collectors .toMap ( Map .Entry ::getKey , entry -> groupByVersion ( entry .getValue () ), this ::throwOnDuplicateKey ,
82+ LinkedHashMap ::new ) );
8283 }
8384
8485 private List <Model > loadAndExtractModels ( final List <File > files , final boolean onlyAspectModels ) {
85- return files .stream ()
86- .map ( this ::loadModelWithVersion )
87- .flatMap ( entry -> extractModelsFromEntry ( entry , onlyAspectModels ) )
88- .toList ();
86+ return files .stream ().map ( this ::loadModelWithVersion ).flatMap ( entry -> extractModelsFromEntry ( entry , onlyAspectModels ) )
87+ .toList ();
8988 }
9089
9190 private Map .Entry <RawAspectModelFile , Optional <KnownVersion >> loadModelWithVersion ( final File file ) {
@@ -96,123 +95,99 @@ private Map.Entry<RawAspectModelFile, Optional<KnownVersion>> loadModelWithVersi
9695 }
9796
9897 private Optional <KnownVersion > extractMetaModelVersion ( final RawAspectModelFile rawFile ) {
99- return Try .of ( () -> rawFile .sourceModel ().getNsPrefixMap ().get ( SammNs .SAMM .getShortForm () ) )
100- .flatMap ( AspectModelUrn ::from )
101- .toJavaOptional ()
102- .map ( AspectModelUrn ::getVersion )
103- .flatMap ( KnownVersion ::fromVersionString );
98+ final String sammPrefix = rawFile .sourceModel ().getNsPrefixMap ().get ( SammNs .SAMM .getShortForm () );
99+
100+ if ( sammPrefix == null ) {
101+ final String bammPrefix = rawFile .sourceModel ().getNsPrefixMap ().get ( "bamm" );
102+ throw new IllegalStateException ( String .format (
103+ "The model uses an outdated BAMM definition '%s', which is no longer supported by the Aspect Model Editor. "
104+ + "Please migrate your model to the current SAMM specification before reloading." ,
105+ bammPrefix ) );
106+ }
107+
108+ return AspectModelUrn .from ( sammPrefix ).toJavaOptional ()
109+ .map ( AspectModelUrn ::getVersion )
110+ .flatMap ( KnownVersion ::fromVersionString );
104111 }
105112
106- private Stream <Model > extractModelsFromEntry (final Map .Entry <RawAspectModelFile , Optional <KnownVersion >> entry , final boolean onlyAspectModels ) {
107- final KnownVersion version = entry . getValue ()
108- . orElseThrow (() -> new IllegalStateException ("Meta model version is required" ) );
113+ private Stream <Model > extractModelsFromEntry ( final Map .Entry <RawAspectModelFile , Optional <KnownVersion >> entry ,
114+ final boolean onlyAspectModels ) {
115+ final KnownVersion version = entry . getValue (). orElseThrow ( () -> new IllegalStateException ( "Meta model version is required" ) );
109116 final RawAspectModelFile rawFile = entry .getKey ();
110117
111- final String filename = extractFilename (rawFile );
112- final List <Resource > resources = collectMetaModelResources (version );
113- final Resource firstNonBlankSubject = findFirstNonBlankSubject (rawFile .sourceModel (), resources , filename );
118+ final String filename = extractFilename ( rawFile );
119+ final List <Resource > resources = collectMetaModelResources ( version );
120+ final Resource firstNonBlankSubject = findFirstNonBlankSubject ( rawFile .sourceModel (), resources , filename );
114121
115- final Model model = new Model (filename , AspectModelUrn .fromUrn (firstNonBlankSubject .getURI ()),
116- version .toVersionString (), true );
122+ final Model model = new Model ( filename , AspectModelUrn .fromUrn ( firstNonBlankSubject .getURI () ), version .toVersionString (), true );
117123
118- return Stream .of (model );
124+ return Stream .of ( model );
119125 }
120126
121- private String extractFilename (final RawAspectModelFile rawFile ) {
122- return rawFile .sourceLocation ()
123- .map (uri -> Path .of (uri ).getFileName ().toString ())
124- .orElse ("unnamed file" );
127+ private String extractFilename ( final RawAspectModelFile rawFile ) {
128+ return rawFile .sourceLocation ().map ( uri -> Path .of ( uri ).getFileName ().toString () ).orElse ( "unnamed file" );
125129 }
126130
127- private List <Resource > collectMetaModelResources (final KnownVersion version ) {
128- final SAMM samm = new SAMM (version );
129- final SAMMC sammc = new SAMMC (version );
130- final SAMME samme = new SAMME (version , samm );
131+ private List <Resource > collectMetaModelResources ( final KnownVersion version ) {
132+ final SAMM samm = new SAMM ( version );
133+ final SAMMC sammc = new SAMMC ( version );
134+ final SAMME samme = new SAMME ( version , samm );
131135
132136 return Stream .of (
133- Stream .of (samm .Aspect (), samm .Property (), samm .Operation (), samm .Event (),
134- samm .Entity (), samm .Value (), samm .Characteristic (), samm .Constraint (),
135- samm .AbstractEntity (), samm .AbstractProperty ()),
136- samme .allEntities (),
137- sammc .allCharacteristics (),
138- sammc .allConstraints (),
139- sammc .allCollections ()
140- ).flatMap (s -> s ).toList ();
137+ Stream .of ( samm .Aspect (), samm .Property (), samm .Operation (), samm .Event (), samm .Entity (), samm .Value (), samm .Characteristic (),
138+ samm .Constraint (), samm .AbstractEntity (), samm .AbstractProperty () ), samme .allEntities (), sammc .allCharacteristics (),
139+ sammc .allConstraints (), sammc .allCollections () ).flatMap ( s -> s ).toList ();
141140 }
142141
143- private Resource findFirstNonBlankSubject (final org .apache .jena .rdf .model .Model sourceModel , final List <Resource > resources , final String filename ) {
144- return resources .stream ()
145- .flatMap (resource -> sourceModel .listStatements (null , RDF .type , resource ).toList ().stream ())
146- .map (Statement ::getSubject )
147- .filter (subject -> !subject .isAnon ())
148- .findFirst ()
149- .orElseThrow (() -> new IllegalStateException ("No non-blank subject found in " + filename ));
142+ private Resource findFirstNonBlankSubject ( final org .apache .jena .rdf .model .Model sourceModel , final List <Resource > resources ,
143+ final String filename ) {
144+ return resources .stream ().flatMap ( resource -> sourceModel .listStatements ( null , RDF .type , resource ).toList ().stream () )
145+ .map ( Statement ::getSubject ).filter ( subject -> !subject .isAnon () ).findFirst ()
146+ .orElseThrow ( () -> new IllegalStateException ( "No non-blank subject found in " + filename ) );
150147 }
151148
152149 private Map <String , List <Model >> groupByNamespace ( final List <Model > models ) {
153- return models .stream ()
154- .collect ( Collectors .groupingBy ( model ->
155- model .aspectModelUrn ().getNamespaceMainPart () ) );
150+ return models .stream ().collect ( Collectors .groupingBy ( model -> model .aspectModelUrn ().getNamespaceMainPart () ) );
156151 }
157152
158153 private Stream <ModelElement > extractModelElement ( final AspectModelFile file , final boolean onlyAspectModels ) {
159154
160- final Optional <ModelElement > aspectElement = file .aspects ().stream ()
161- .map ( ModelElement .class ::cast )
162- .findFirst ();
155+ final Optional <ModelElement > aspectElement = file .aspects ().stream ().map ( ModelElement .class ::cast ).findFirst ();
163156
164157 if ( onlyAspectModels ) {
165158 return aspectElement .stream ();
166159 }
167160
168- return aspectElement
169- .or ( () -> findFirstNonAnonymousElement ( file ) )
170- .stream ();
161+ return aspectElement .or ( () -> findFirstNonAnonymousElement ( file ) ).stream ();
171162 }
172163
173164 private Optional <ModelElement > findFirstNonAnonymousElement ( final AspectModelFile file ) {
174- return file .elements ().stream ()
175- .filter ( element -> !element .isAnonymous () )
176- .findAny ();
165+ return file .elements ().stream ().filter ( element -> !element .isAnonymous () ).findAny ();
177166 }
178167
179168 private List <Version > groupByVersion ( final List <Model > models ) {
180169 final Map <AspectModelUrn , Model > uniqueModels = removeDuplicateModels ( models );
181170 final Map <String , List <Model >> modelsByVersion = groupModelsByVersionString ( uniqueModels );
182171
183- return modelsByVersion .entrySet ().stream ()
184- .sorted ( Map .Entry .comparingByKey () )
185- .map ( this ::createVersionEntry )
186- .toList ();
172+ return modelsByVersion .entrySet ().stream ().sorted ( Map .Entry .comparingByKey () ).map ( this ::createVersionEntry ).toList ();
187173 }
188174
189175 private Map <AspectModelUrn , Model > removeDuplicateModels ( final List <Model > models ) {
190176 return models .stream ()
191- .collect ( Collectors .toMap (
192- Model ::aspectModelUrn ,
193- model -> model ,
194- ( existing , duplicate ) -> existing ,
195- LinkedHashMap ::new ) );
177+ .collect ( Collectors .toMap ( Model ::aspectModelUrn , model -> model , ( existing , duplicate ) -> existing , LinkedHashMap ::new ) );
196178 }
197179
198- private Map <String , List <Model >> groupModelsByVersionString (
199- final Map <AspectModelUrn , Model > uniqueModels ) {
180+ private Map <String , List <Model >> groupModelsByVersionString ( final Map <AspectModelUrn , Model > uniqueModels ) {
200181
201- return uniqueModels .values ().stream ()
202- .collect ( Collectors .groupingBy ( model ->
203- model .aspectModelUrn ().getVersion () ) );
182+ return uniqueModels .values ().stream ().collect ( Collectors .groupingBy ( model -> model .aspectModelUrn ().getVersion () ) );
204183 }
205184
206185 private Version createVersionEntry ( final Map .Entry <String , List <Model >> entry ) {
207- final List <Model > sortedModels = entry .getValue ().stream ()
208- .sorted ( Comparator .comparing ( Model ::model ) )
209- .toList ();
186+ final List <Model > sortedModels = entry .getValue ().stream ().sorted ( Comparator .comparing ( Model ::model ) ).toList ();
210187 return new Version ( entry .getKey (), sortedModels );
211188 }
212189
213190 private <T > T throwOnDuplicateKey ( final T v1 , final T v2 ) {
214- throw new RuntimeException (
215- String .format ( "Duplicate key for values %s and %s" , v1 , v2 ) );
191+ throw new RuntimeException ( String .format ( "Duplicate key for values %s and %s" , v1 , v2 ) );
216192 }
217-
218193}
0 commit comments