add metamodel and api classes after latest run#3
Conversation
* copyconstructor * default values
|
Still open:
|
|
There's an issue with the way copy constructors are generated. Currently, for a SMEC, that looks like this: public DefaultSubmodelElementCollection(SubmodelElementCollection x) {
this.embeddedDataSpecifications = x.getEmbeddedDataSpecifications();
this.extensions = x.getExtensions();
this.semanticId = x.getSemanticId();
this.supplementalSemanticIds = x.getSupplementalSemanticIds();
this.qualifiers = x.getQualifiers();
this.category = x.getCategory();
this.description = x.getDescription();
this.displayName = x.getDisplayName();
this.idShort = x.getIdShort();
this.value = x.getValue();
}The copy is populated via getting the respective field from the original object. This creates only shallow copies! If a field requires something that's not either immutable or primitive, there will NOT be a new sub-object created. Meaning that Why this can lead to unexpected behavior as in the test below. package org.eclipse.digitaltwin.aas4j.v3.model;
import org.eclipse.digitaltwin.aas4j.v3.model.builder.LangStringTextTypeBuilder;
import org.eclipse.digitaltwin.aas4j.v3.model.builder.PropertyBuilder;
import org.eclipse.digitaltwin.aas4j.v3.model.impl.DefaultLangStringTextType;
import org.eclipse.digitaltwin.aas4j.v3.model.impl.DefaultProperty;
import org.eclipse.digitaltwin.aas4j.v3.model.impl.DefaultSubmodelElementCollection;
import org.junit.Test;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
public class CopyConstructorTest {
@Test
public void onProperty() {
DefaultSubmodelElementCollection original = new DefaultSubmodelElementCollection.Builder()
.value(new DefaultProperty.Builder()
.description(new DefaultLangStringTextType.Builder()
.language("en")
.text("MyDescription")
.build())
.build())
.build();
DefaultSubmodelElementCollection copy = new DefaultSubmodelElementCollection(original); // make copy
assertEquals(getPropertyDescriptionTextFromSmec(original), getPropertyDescriptionTextFromSmec(copy)); // true
copy.getValue().get(0).getDescription().get(0).setText("DifferentDescription"); // change value in copy
assertNotEquals(
getPropertyDescriptionTextFromSmec(original),
getPropertyDescriptionTextFromSmec(copy)
);
// Objects should be different. Copy was changed, the original was not. However, both hold "DifferentDescription".
}
private String getPropertyDescriptionTextFromSmec(SubmodelElementCollection smec) {
String text = smec.getValue().get(0).getDescription().get(0).getText();
System.out.println(text);
return text;
}
} |
|
I need more time to design a deep copy pattern. Will keep this PR open as a reminder. |
| return new DefaultEndpoint.Builder() | ||
| .protocolInformation(createProtocolInformationBuilder().build()) | ||
| .withInterface(DEFAULT_INTERFACE_VALUE); | ||
| ._interface(DEFAULT_INTERFACE_VALUE); |
There was a problem hiding this comment.
The old version seems better to me.
emildinchev
left a comment
There was a problem hiding this comment.
Most of the Metadata interfaces simply extends the SubmodelElementAttributes interface without any new definition. Are these new interfaces really needed?
Including these extensions: