Skip to content

Commit 7d6e991

Browse files
Merge branch 'main' into feature/695-extend-code-generator-setters
2 parents 1a4b53b + 5102355 commit 7d6e991

File tree

10 files changed

+456
-4
lines changed

10 files changed

+456
-4
lines changed

core/esmf-aspect-model-aas-generator/src/main/java/org/eclipse/esmf/aspectmodel/aas/AspectModelAasVisitor.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,10 @@ private Optional<SubmodelElement> mapText( final Property property, final Contex
285285
final SubmodelElement element = context.getPropertyResult();
286286
element.setSupplementalSemanticIds( updateGlobalReferenceWithSeeReferences( element, property ) );
287287

288+
if ( !property.getPayloadName().isEmpty() ) {
289+
element.setIdShort( property.getPayloadName() );
290+
}
291+
288292
recursiveProperty.remove( property );
289293

290294
return Optional.of( element );

core/esmf-aspect-model-aas-generator/src/test/java/org/eclipse/esmf/aspectmodel/aas/AspectModelAasGeneratorTest.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ void testGenerateAasxFromAspectModelWithEnumeration() throws DeserializationExce
360360
@EnumSource( value = TestAspect.class )
361361
// anonymous enumeration in test has no urn for enum values but is required for Concept
362362
// Description referencing
363-
public void testGeneration( final TestAspect testAspect ) throws DeserializationException {
363+
void testGeneration( final TestAspect testAspect ) throws DeserializationException {
364364
final String aasXmlString = aspectToAasXml( testAspect );
365365
final byte[] aasXmlInput = aasXmlString.getBytes();
366366

@@ -424,6 +424,15 @@ void testGeneratedAasxFromAspectModelSemanticIdsAreGlobalReferences() throws Des
424424
assertThat( property.getSemanticId().getKeys().get( 0 ).getType() ).isEqualTo( KeyTypes.GLOBAL_REFERENCE );
425425
}
426426

427+
@Test
428+
void testAspectWithPayloadName() throws DeserializationException {
429+
final Environment environment = getAssetAdministrationShellFromAspect( TestAspect.ASPECT_WITH_PROPERTY_WITH_PAYLOAD_NAME );
430+
431+
final Property property = (Property) environment.getSubmodels().get( 0 ).getSubmodelElements().get( 0 );
432+
assertThat( environment.getSubmodels().get( 0 ).getSubmodelElements() ).hasSize( 1 );
433+
assertThat( environment.getSubmodels().get( 0 ).getSubmodelElements().get( 0 ).getIdShort() ).isEqualTo( property.getIdShort() );
434+
}
435+
427436
private void checkDataSpecificationIec61360( final Set<String> semanticIds, final Environment env ) {
428437
semanticIds.forEach( semanticId -> getDataSpecificationIec61360( semanticId, env ) );
429438
}

core/esmf-aspect-model-validator/src/main/java/org/eclipse/esmf/aspectmodel/validation/services/DetailedViolationFormatter.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,9 @@ private String formatViolation( final Violation violation, final Supplier<String
141141
builder.append( String.format( " - %s%n", fix.description() ) );
142142
}
143143
}
144+
// Add documentation link
145+
builder.append( " documentation: https://eclipse-esmf.github.io/esmf-developer-guide/tooling-guide/error-codes.html"
146+
+ violation.errorCode().toLowerCase().replace( "_", "-" ) );
144147
builder.append( indent( additionalAttributesSupplier.get(), 2 ) );
145148
if ( violation.context() != null ) {
146149
builder.append( String.format( " caused-by-shape:%n" ) );

core/esmf-aspect-model-validator/src/main/java/org/eclipse/esmf/aspectmodel/validation/services/ViolationFormatter.java

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ public class ViolationFormatter implements Function<List<Violation>, String>, Vi
4242
protected final String additionalHints;
4343
protected final RustLikeFormatter formatter;
4444

45+
private static final String ERROR_CODES_DOC_LINK = "https://eclipse-esmf.github.io/esmf-developer-guide/tooling-guide/error-codes.html";
46+
private static final String ERROR_CODES_DOC_STRING = "For more information, see: documentation: " + ERROR_CODES_DOC_LINK;
47+
4548
public ViolationFormatter( final String additionalHints ) {
4649
this( new PlainTextFormatter(), additionalHints );
4750
}
@@ -84,11 +87,17 @@ public String apply( final List<Violation> violations ) {
8487
final List<Violation> elementViolations = entry.getValue();
8588
builder.append( String.format( "> %s :%n", textFormatter.formatName( elementName ) ) );
8689
for ( final Violation violation : elementViolations ) {
90+
// Include error code in the violation message
91+
final String errorCode = violation.errorCode();
92+
final String enhancedMessage = String.format( "[%s] %s", errorCode, violation.message() );
8793
builder.append( indent( violation.accept( this ), 2 ) ).append( System.lineSeparator() );
8894
for ( final Fix possibleFix : violation.fixes() ) {
8995
builder.append( " > Possible fix: " )
9096
.append( possibleFix.description() );
9197
}
98+
// Add documentation link
99+
builder.append( String.format( ERROR_CODES_DOC_STRING + "#%s%n",
100+
errorCode.toLowerCase().replace( "_", "-" ) ) );
92101
builder.append( System.lineSeparator() );
93102
}
94103
builder.append( System.lineSeparator() );
@@ -98,10 +107,20 @@ public String apply( final List<Violation> violations ) {
98107
if ( violation instanceof final ProcessingViolation processingViolation ) {
99108
builder.append( processingViolation.accept( this ) );
100109
} else if ( violation.violationSpecificMessage() == null || violation.violationSpecificMessage().equals( violation.message() ) ) {
101-
builder.append( String.format( "> %s%n", violation.message() ) );
110+
final String errorCode = violation.errorCode();
111+
final String enhancedMessage = String.format( "[%s] %s", errorCode, violation.message() );
112+
builder.append( String.format( "> %s%n", enhancedMessage ) );
113+
// Add documentation link for context-free violations
114+
builder.append( ERROR_CODES_DOC_STRING
115+
+ errorCode.toLowerCase().replace( "_", "-" ) );
102116
} else {
103-
builder.append( String.format( "> %s: %n", violation.message() ) );
117+
final String errorCode = violation.errorCode();
118+
final String enhancedMessage = String.format( "[%s] %s", errorCode, violation.message() );
119+
builder.append( String.format( "> %s: %n", enhancedMessage ) );
104120
builder.append( indent( violation.accept( this ), 2 ) ).append( System.lineSeparator() );
121+
// Add documentation link
122+
builder.append( ERROR_CODES_DOC_STRING
123+
+ errorCode.toLowerCase().replace( "_", "-" ) );
105124
}
106125
builder.append( System.lineSeparator() );
107126
}
@@ -111,7 +130,9 @@ public String apply( final List<Violation> violations ) {
111130

112131
@Override
113132
public String visit( final Violation violation ) {
114-
return formatter.constructDetailedMessage( violation.highlight(), violation.message(), violation.context().element().getModel() );
133+
final String errorCode = violation.errorCode();
134+
final String enhancedMessage = String.format( "[%s] %s", errorCode, violation.message() );
135+
return formatter.constructDetailedMessage( violation.highlight(), enhancedMessage, violation.context().element().getModel() );
115136
}
116137

117138
@Override
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright (c) 2025 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 examples;
15+
16+
// tag::imports[]
17+
import java.util.List;
18+
import java.util.Map;
19+
import java.util.stream.Collectors;
20+
21+
import org.eclipse.esmf.aspectmodel.shacl.violation.DatatypeViolation;
22+
import org.eclipse.esmf.aspectmodel.shacl.violation.MaxCountViolation;
23+
import org.eclipse.esmf.aspectmodel.shacl.violation.Violation;
24+
// end::imports[]
25+
26+
public class CustomViolationFormatter implements Violation.Visitor<String> {
27+
28+
// tag::custom-formatter[]
29+
// Implement other visitor methods for different violation types
30+
@Override
31+
public String visit(Violation violation) {
32+
// Generic fallback for unhandled violation types
33+
return String.format("Validation error: %s", violation.message());
34+
}
35+
// end::custom-formatter[]
36+
37+
// tag::error-aggregation[]
38+
public void aggregateErrors(List<Violation> violations) {
39+
// Group violations by error code for batch processing
40+
Map<String, List<Violation>> errorsByCode = violations.stream()
41+
.collect(Collectors.groupingBy(Violation::errorCode));
42+
43+
// Handle each error type separately
44+
List<Violation> dataTypeErrors = errorsByCode.get("ERR_TYPE");
45+
List<Violation> cardinalityErrors = errorsByCode.get("ERR_MAX_COUNT");
46+
47+
// Process each error type with specific handling logic
48+
if (dataTypeErrors != null && !dataTypeErrors.isEmpty()) {
49+
System.out.println("Found " + dataTypeErrors.size() + " data type errors");
50+
// Handle data type errors...
51+
}
52+
53+
if (cardinalityErrors != null && !cardinalityErrors.isEmpty()) {
54+
System.out.println("Found " + cardinalityErrors.size() + " cardinality errors");
55+
// Handle cardinality errors...
56+
}
57+
}
58+
// end::error-aggregation[]
59+
}

documentation/developer-guide/modules/tooling-guide/examples/ValidateAspectModel.java

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

2020
import org.eclipse.esmf.aspectmodel.loader.AspectModelLoader;
21+
import org.eclipse.esmf.aspectmodel.shacl.fix.Fix;
22+
import org.eclipse.esmf.aspectmodel.shacl.violation.EvaluationContext;
2123
import org.eclipse.esmf.aspectmodel.shacl.violation.Violation;
2224
import org.eclipse.esmf.aspectmodel.validation.services.AspectModelValidator;
2325
import org.eclipse.esmf.aspectmodel.validation.services.DetailedViolationFormatter;
@@ -38,11 +40,20 @@ public void validate() {
3840
new File( "aspect-models/org.eclipse.esmf.examples.movement/1.0.0/Movement.ttl" ) );
3941
// tag::validate[]
4042

43+
// tag::violations[]
4144
final List<Violation> violations = new AspectModelValidator().validateModel( aspectModel );
4245
if ( violations.isEmpty() ) {
4346
// Aspect Model is valid!
4447
return;
48+
} else {
49+
for (Violation violation : violations) {
50+
String errorCode = violation.errorCode();
51+
String message = violation.message();
52+
EvaluationContext context = violation.context();
53+
List<Fix> fixes = violation.fixes();
54+
}
4555
}
56+
// end::violations[]
4657

4758
final String validationReport = new ViolationFormatter().apply( violations ); // <1>
4859
final String detailedReport = new DetailedViolationFormatter().apply( violations );
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
* xref:samm-cli.adoc[SAMM CLI]
22
* xref:java-aspect-tooling.adoc[Java APIs for Aspect Models]
33
* xref:maven-plugin.adoc[Maven Plugin]
4+
* xref:error-codes.adoc[Error Codes and Validation Results]
5+
* xref:best-practices.adoc[Best Practices]
46
* xref:bamm-migration.adoc[Migration from BAMM]
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
:page-partial:
2+
3+
[[best-practices]]
4+
= Best Practices
5+
6+
This guide provides best practices for developing Aspect Models and handling validation errors effectively.
7+
8+
[[analyzing-modeling-errors]]
9+
== Analyzing Modeling Errors
10+
11+
When working with ESMF SDK validation results, follow these practices to efficiently identify and resolve modeling issues.
12+
13+
=== Model Development
14+
15+
1. **Validate Early**: Run validation frequently during model development
16+
2. **Use Detailed Output**: Enable detailed error reporting for comprehensive feedback
17+
3. **Address Errors Systematically**: Start with meta-violations before fixing constraint violations
18+
4. **Test Edge Cases**: Verify models with boundary values and optional properties
19+
20+
=== Error Handling
21+
22+
1. **Programmatic Handling**: Use the visitor pattern for type-safe error handling
23+
2. **User-Friendly Messages**: Transform technical errors into user-friendly guidance
24+
3. **Logging**: Log error codes and context for troubleshooting
25+
4. **Documentation**: Link to error code documentation in error messages where appropriate
26+
27+

0 commit comments

Comments
 (0)