Skip to content

Commit 867fbe0

Browse files
authored
Merge pull request #724 from bci-oss/709-support-samm-value
709 support samm value
2 parents a77ddb6 + 0052262 commit 867fbe0

File tree

33 files changed

+383
-89
lines changed

33 files changed

+383
-89
lines changed

core/esmf-aspect-meta-model-interface/src/main/java/org/eclipse/esmf/metamodel/Property.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public interface Property extends ModelElement {
3232

3333
/**
3434
* @return an {@link Optional} which may contain an example value for the Property. The type of the value is
35-
* determined by the {@link Type} returned by {@link Property#getDataType()}.
35+
* determined by the {@link Type} returned by {@link Property#getDataType()}.
3636
*/
3737
Optional<ScalarValue> getExampleValue();
3838

core/esmf-aspect-meta-model-interface/src/main/java/org/eclipse/esmf/metamodel/vocabulary/SAMM.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,11 @@ public Resource AbstractEntity() {
181181
return resource( "AbstractEntity" );
182182
}
183183

184+
@SuppressWarnings( "checkstyle:MethodName" )
185+
public Resource Value() {
186+
return resource( "Value" );
187+
}
188+
184189
@SuppressWarnings( "checkstyle:MethodName" )
185190
public Property _extends() {
186191
return property( "extends" );

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ private void resolve( final List<AspectModelFile> inputFiles, final LoaderContex
395395
.ifPresent( resolvedFile -> markModelFileAsLoaded( resolvedFile, context ) );
396396
} catch ( final ModelResolutionException exception ) {
397397
// If one element can not be resolved, collect its cause and continue, so that
398-
// we can create an comprehensive overview of all elements that can not be resolved
398+
// we can create a comprehensive overview of all elements that can not be resolved
399399
if ( exception.getCheckedLocations().isEmpty() ) {
400400
throw exception;
401401
} else {

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import org.eclipse.esmf.metamodel.impl.DefaultCollectionValue;
3838
import org.eclipse.esmf.metamodel.impl.DefaultEntityInstance;
3939
import org.eclipse.esmf.metamodel.impl.DefaultScalar;
40+
import org.eclipse.esmf.metamodel.impl.DefaultScalarValue;
4041
import org.eclipse.esmf.metamodel.vocabulary.SAMM;
4142
import org.eclipse.esmf.metamodel.vocabulary.SammNs;
4243

@@ -162,6 +163,20 @@ protected Value buildValue( final RDFNode node, final Optional<Resource> charact
162163
.orElseThrow( () -> new AspectLoadingException( "Literal can not be parsed: " + literal ) );
163164
}
164165

166+
if ( node.isResource() ) {
167+
Resource resource = node.asResource();
168+
169+
if ( resource.hasProperty( RDF.type, SammNs.SAMM.Value() ) ) {
170+
Optional<String> valueOpt = optionalAttributeValue( resource, SammNs.SAMM.value() ).map( Statement::getString );
171+
172+
if ( valueOpt.isEmpty() ) {
173+
throw new AspectLoadingException( "samm:Value must contain a samm:value property" );
174+
}
175+
176+
return new DefaultScalarValue( buildBaseAttributes( resource ), valueOpt.get(), new DefaultScalar( type.getUrn() ) );
177+
}
178+
}
179+
165180
// Collections
166181
if ( characteristicResource.isPresent() ) {
167182
final Resource characteristic = characteristicResource.get();

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
import org.eclipse.esmf.aspectmodel.loader.instantiator.QuantifiableInstantiator;
5252
import org.eclipse.esmf.aspectmodel.loader.instantiator.RangeConstraintInstantiator;
5353
import org.eclipse.esmf.aspectmodel.loader.instantiator.RegularExpressionConstraintInstantiator;
54+
import org.eclipse.esmf.aspectmodel.loader.instantiator.ScalarValueInstantiator;
5455
import org.eclipse.esmf.aspectmodel.loader.instantiator.SetInstantiator;
5556
import org.eclipse.esmf.aspectmodel.loader.instantiator.SingleEntityInstantiator;
5657
import org.eclipse.esmf.aspectmodel.loader.instantiator.SortedSetInstantiator;
@@ -110,6 +111,12 @@ public ModelElementFactory( final Model model, final Map<Resource, Instantiator<
110111
registerInstantiator( SammNs.SAMM.Operation(), new OperationInstantiator( this ) );
111112
registerInstantiator( SammNs.SAMM.Property(), new PropertyInstantiator( this ) );
112113

114+
/*
115+
* Registers an instantiator for the {@link Value} type.
116+
* In aspect-meta-model, {@link Value} corresponds to {@link ScalarValueInstantiator} in the SDK.
117+
*/
118+
registerInstantiator( SammNs.SAMM.Value(), new ScalarValueInstantiator( this ) );
119+
113120
registerInstantiator( SammNs.SAMMC.Code(), new CodeInstantiator( this ) );
114121
registerInstantiator( SammNs.SAMMC.Collection(), new CollectionInstantiator( this ) );
115122
registerInstantiator( SammNs.SAMMC.Duration(), new DurationInstantiator( this ) );

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,14 @@ public Optional<ScalarValue> buildScalarValue( final String lexicalRepresentatio
5151
return SammXsdType.ALL_TYPES.stream()
5252
.filter( type -> type.getURI().equals( datatypeUri ) )
5353
.map( type -> type.parse( lexicalRepresentation ) )
54-
.<ScalarValue> map( value -> new DefaultScalarValue( value, new DefaultScalar( datatypeUri ) ) )
54+
.<ScalarValue> map(
55+
value -> new DefaultScalarValue( MetaModelBaseAttributes.builder().build(), value, new DefaultScalar( datatypeUri ) ) )
5556
.findAny();
5657
}
5758

5859
public ScalarValue buildLanguageString( final String lexicalRepresentation, final String languageTag ) {
5960
final LangString langString = new LangString( lexicalRepresentation, Locale.forLanguageTag( languageTag ) );
6061
final Scalar type = new DefaultScalar( RDF.langString.getURI() );
61-
return new DefaultScalarValue( langString, type );
62+
return new DefaultScalarValue( MetaModelBaseAttributes.builder().build(), langString, type );
6263
}
6364
}

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

Lines changed: 43 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,16 @@
2424
import org.eclipse.esmf.aspectmodel.loader.ModelElementFactory;
2525
import org.eclipse.esmf.metamodel.Characteristic;
2626
import org.eclipse.esmf.metamodel.Property;
27-
import org.eclipse.esmf.metamodel.Scalar;
2827
import org.eclipse.esmf.metamodel.ScalarValue;
28+
import org.eclipse.esmf.metamodel.Type;
2929
import org.eclipse.esmf.metamodel.impl.DefaultCharacteristic;
3030
import org.eclipse.esmf.metamodel.impl.DefaultProperty;
31+
import org.eclipse.esmf.metamodel.impl.DefaultScalar;
3132
import org.eclipse.esmf.metamodel.impl.DefaultScalarValue;
3233
import org.eclipse.esmf.metamodel.vocabulary.SammNs;
3334

34-
import org.apache.jena.datatypes.BaseDatatype;
3535
import org.apache.jena.rdf.model.Literal;
36+
import org.apache.jena.rdf.model.RDFNode;
3637
import org.apache.jena.rdf.model.Resource;
3738
import org.apache.jena.rdf.model.Statement;
3839
import org.apache.jena.vocabulary.RDF;
@@ -51,15 +52,18 @@ public PropertyInstantiator( final ModelElementFactory modelElementFactory ) {
5152

5253
@Override
5354
public Property apply( final Resource property ) {
54-
final boolean isOptional = optionalAttributeValue( property, SammNs.SAMM.optional() ).map( Statement::getBoolean ).orElse( false );
55-
final boolean isNotInPayload = optionalAttributeValue( property, SammNs.SAMM.notInPayload() ).map( Statement::getBoolean )
56-
.orElse( false );
57-
final Optional<String> payloadName = optionalAttributeValue( property, SammNs.SAMM.payloadName() ).map( Statement::getString );
55+
final boolean isOptional = optionalAttributeValue( property, SammNs.SAMM.optional() )
56+
.map( Statement::getBoolean ).orElse( false );
57+
final boolean isNotInPayload = optionalAttributeValue( property, SammNs.SAMM.notInPayload() )
58+
.map( Statement::getBoolean ).orElse( false );
59+
final Optional<String> payloadName = optionalAttributeValue( property, SammNs.SAMM.payloadName() )
60+
.map( Statement::getString );
5861
final Optional<Resource> extendsResource = optionalAttributeValue( property, SammNs.SAMM._extends() )
5962
.map( Statement::getResource );
6063
final Optional<Property> extends_ = extendsResource.map( superElementResource ->
6164
modelElementFactory.create( Property.class, superElementResource ) );
62-
final boolean isAbstract = !property.isAnon() && property.getModel().contains( property, RDF.type, SammNs.SAMM.AbstractProperty() );
65+
final boolean isAbstract = !property.isAnon()
66+
&& property.getModel().contains( property, RDF.type, SammNs.SAMM.AbstractProperty() );
6367

6468
final MetaModelBaseAttributes metaModelBaseAttributes = property.isAnon()
6569
? buildBaseAttributes( extendsResource.orElse( property ) )
@@ -70,37 +74,49 @@ public Property apply( final Resource property ) {
7074
return resourcePropertyMap.get( property );
7175
}
7276
resourcePropertyMap.put( property, defaultPropertyWrapper );
77+
7378
final DefaultProperty defProperty;
7479
if ( isAbstract ) {
75-
defProperty = new DefaultProperty( metaModelBaseAttributes, Optional.of( fallbackCharacteristic ), Optional.empty(), isOptional,
76-
isNotInPayload, payloadName, isAbstract, extends_ );
80+
defProperty = new DefaultProperty( metaModelBaseAttributes, Optional.of( fallbackCharacteristic ),
81+
Optional.empty(), isOptional, isNotInPayload, payloadName, isAbstract, extends_ );
7782
} else {
7883
final Resource characteristicResource = attributeValue( property, SammNs.SAMM.characteristic() ).getResource();
7984
final Characteristic characteristic = modelElementFactory.create( Characteristic.class, characteristicResource );
85+
8086
final Optional<ScalarValue> exampleValue = optionalAttributeValue( property, SammNs.SAMM.exampleValue() )
81-
.flatMap( statement -> characteristic.getDataType()
82-
.map( type -> {
83-
if ( !type.is( Scalar.class ) ) {
84-
throw new AspectLoadingException( "Type of example value on Property " + property + " has incorrect type" );
85-
}
86-
return type.as( Scalar.class );
87-
} )
88-
.map( type -> buildScalarValue( statement.getLiteral(), type ) ) );
89-
90-
defProperty = new DefaultProperty( metaModelBaseAttributes, Optional.of( characteristic ), exampleValue, isOptional,
91-
isNotInPayload, payloadName, isAbstract, extends_ );
87+
.map( statement -> buildScalarValue( statement.getObject(), characteristic.getDataType().orElseThrow() ) );
88+
89+
defProperty = new DefaultProperty( metaModelBaseAttributes, Optional.of( characteristic ),
90+
exampleValue, isOptional, isNotInPayload, payloadName, isAbstract, extends_ );
9291
}
92+
9393
defaultPropertyWrapper.setProperty( defProperty );
9494
return defaultPropertyWrapper;
9595
}
9696

97-
private ScalarValue buildScalarValue( final Literal literal, final Scalar type ) {
98-
final Object literalValue = literal.getValue();
99-
if ( literalValue instanceof BaseDatatype.TypedValue ) {
100-
return new DefaultScalarValue( literal.getLexicalForm(), type );
101-
} else if ( literal.getDatatypeURI().equals( RDF.langString.getURI() ) ) {
102-
return valueInstantiator.buildLanguageString( literal.getLexicalForm(), literal.getLanguage() );
97+
private ScalarValue buildScalarValue( final RDFNode node, final Type expectedType ) {
98+
if ( node.isLiteral() ) {
99+
final Literal literal = node.asLiteral();
100+
return valueInstantiator.buildScalarValue( literal.getLexicalForm(), literal.getLanguage(), literal.getDatatypeURI() )
101+
.orElseThrow( () -> new AspectLoadingException( "Literal cannot be parsed: " + literal ) );
103102
}
104-
return new DefaultScalarValue( literalValue, type );
103+
104+
if ( node.isResource() ) {
105+
Resource resource = node.asResource();
106+
107+
if ( resource.hasProperty( RDF.type, SammNs.SAMM.Value() ) ) {
108+
Optional<String> valueOpt = optionalAttributeValue( resource, SammNs.SAMM.value() ).map( Statement::getString );
109+
110+
if ( valueOpt.isEmpty() ) {
111+
throw new AspectLoadingException( "samm:Value must contain a samm:value property" );
112+
}
113+
114+
return new DefaultScalarValue( buildBaseAttributes( resource ), valueOpt.get(), new DefaultScalar( expectedType.toString() ) );
115+
}
116+
117+
return new DefaultScalarValue( buildBaseAttributes( resource ), resource.getURI(), new DefaultScalar( expectedType.toString() ) );
118+
}
119+
120+
throw new AspectLoadingException( "Unexpected RDF node type: " + node );
105121
}
106122
}

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,12 @@ public RangeConstraint apply( final Resource rangeConstraint ) {
4242

4343
final Optional<ScalarValue> minValue = optionalAttributeValue( rangeConstraint, SammNs.SAMMC.minValue() )
4444
.map( Statement::getLiteral )
45-
.map( literal -> new DefaultScalarValue( literal.getValue(), new DefaultScalar( literal.getDatatypeURI() ) ) );
45+
.map( literal -> new DefaultScalarValue( buildBaseAttributes( rangeConstraint ), literal.getValue(),
46+
new DefaultScalar( literal.getDatatypeURI() ) ) );
4647
final Optional<ScalarValue> maxValue = optionalAttributeValue( rangeConstraint, SammNs.SAMMC.maxValue() )
4748
.map( Statement::getLiteral )
48-
.map( literal -> new DefaultScalarValue( literal.getValue(), new DefaultScalar( literal.getDatatypeURI() ) ) );
49+
.map( literal -> new DefaultScalarValue( buildBaseAttributes( rangeConstraint ), literal.getValue(),
50+
new DefaultScalar( literal.getDatatypeURI() ) ) );
4951
final BoundDefinition lowerBoundDefinition = getBoundDefinitionForRangeValue( minValue,
5052
SammNs.SAMMC.lowerBoundDefinition(), rangeConstraint, BoundDefinition.AT_LEAST );
5153
final BoundDefinition upperBoundDefinition = getBoundDefinitionForRangeValue( maxValue,
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package org.eclipse.esmf.aspectmodel.loader.instantiator;
2+
3+
import org.eclipse.esmf.aspectmodel.loader.Instantiator;
4+
import org.eclipse.esmf.aspectmodel.loader.MetaModelBaseAttributes;
5+
import org.eclipse.esmf.aspectmodel.loader.ModelElementFactory;
6+
import org.eclipse.esmf.metamodel.ScalarValue;
7+
import org.eclipse.esmf.metamodel.impl.DefaultScalar;
8+
import org.eclipse.esmf.metamodel.impl.DefaultScalarValue;
9+
10+
import org.apache.jena.rdf.model.Resource;
11+
12+
public class ScalarValueInstantiator extends Instantiator<ScalarValue> {
13+
14+
public ScalarValueInstantiator( final ModelElementFactory modelElementFactory ) {
15+
super( modelElementFactory, ScalarValue.class );
16+
}
17+
18+
@Override
19+
public ScalarValue apply( final Resource value ) {
20+
final MetaModelBaseAttributes metaModelBaseAttributes = buildBaseAttributes( value );
21+
return new DefaultScalarValue( metaModelBaseAttributes, value, new DefaultScalar( value.getURI() ) );
22+
}
23+
}

core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/metamodel/builder/SammBuilder.java

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
import static org.eclipse.esmf.metamodel.DataTypes.dataTypeByUri;
1717
import static org.eclipse.esmf.metamodel.DataTypes.xsd;
18-
import static org.eclipse.esmf.metamodel.Elements.*;
18+
import static org.eclipse.esmf.metamodel.Elements.samm_e;
1919

2020
import java.math.BigInteger;
2121
import java.net.URI;
@@ -1371,25 +1371,54 @@ public static <T extends EntityInstanceBuilder<T>> EntityInstanceBuilder<T> enti
13711371
}
13721372

13731373
public static ScalarValue value( final String stringValue ) {
1374-
return new DefaultScalarValue( stringValue, xsd.string );
1374+
return new DefaultScalarValue( MetaModelBaseAttributes.builder().build(), stringValue, xsd.string );
13751375
}
13761376

13771377
public static ScalarValue value( final boolean booleanValue ) {
1378-
return new DefaultScalarValue( booleanValue, xsd.boolean_ );
1378+
return new DefaultScalarValue( MetaModelBaseAttributes.builder().build(), booleanValue, xsd.boolean_ );
13791379
}
13801380

13811381
public static ScalarValue value( final float floatValue ) {
1382-
return new DefaultScalarValue( floatValue, xsd.float_ );
1382+
return new DefaultScalarValue( MetaModelBaseAttributes.builder().build(), floatValue, xsd.float_ );
13831383
}
13841384

13851385
public static ScalarValue value( final double doubleValue ) {
1386-
return new DefaultScalarValue( doubleValue, xsd.double_ );
1386+
return new DefaultScalarValue( MetaModelBaseAttributes.builder().build(), doubleValue, xsd.double_ );
13871387
}
13881388

13891389
/* Intentionally no value(int) method here, because an int value could imply different XSD types */
13901390

13911391
public static ScalarValue value( final Object value, final Scalar type ) {
1392-
return new DefaultScalarValue( value, dataTypeByUri( type.getUrn() ) );
1392+
MetaModelBaseAttributes metaModelBaseAttributes;
1393+
1394+
if ( value instanceof ModelElement modelElement ) {
1395+
boolean hasUrn = modelElement.urn() != null;
1396+
1397+
MetaModelBaseAttributes.Builder builder = MetaModelBaseAttributes.builder()
1398+
.isAnonymous( !hasUrn );
1399+
1400+
if ( hasUrn ) {
1401+
builder.withUrn( modelElement.urn() );
1402+
} else if ( !builder.build().isAnonymous() ) {
1403+
throw new IllegalStateException( "Non-anonymous ModelElement must have a URN: " + modelElement );
1404+
}
1405+
1406+
if ( modelElement instanceof ScalarValue scalarValue ) {
1407+
builder
1408+
.withPreferredNames( scalarValue.getPreferredNames() )
1409+
.withDescriptions( scalarValue.getDescriptions() )
1410+
.withSee( scalarValue.getSee() )
1411+
.withSourceFile( scalarValue.getSourceFile() );
1412+
}
1413+
1414+
metaModelBaseAttributes = builder.build();
1415+
} else {
1416+
metaModelBaseAttributes = MetaModelBaseAttributes.builder()
1417+
.isAnonymous( true )
1418+
.build();
1419+
}
1420+
1421+
return new DefaultScalarValue( metaModelBaseAttributes, value, dataTypeByUri( type.getUrn() ) );
13931422
}
13941423

13951424
public static <T> java.util.List<ScalarValue> values( final Scalar type, final T... values ) {

0 commit comments

Comments
 (0)