2525
2626import java .util .Collection ;
2727import java .util .HashMap ;
28+ import java .util .LinkedList ;
2829import java .util .List ;
2930import java .util .Map ;
3031import java .util .Objects ;
32+ import java .util .Optional ;
3133import java .util .Set ;
3234import java .util .UUID ;
3335import java .util .stream .Collectors ;
@@ -57,6 +59,9 @@ public class EMFModelRefresher {
5759
5860 private static Set <String > disabledStructuralFeatures = Set .of ("importedMembership" );
5961
62+
63+ private final List <Issue > issues = new LinkedList <>();
64+
6065 /**
6166 * @param model to propagate into EMF
6267 * @param tracker index based on element UUIDs
@@ -87,8 +92,8 @@ public EMFModelDelta create() {
8792 tracker .forEachTrackedLocalElement ((id , langElement ) -> {
8893 Element element = model .getElement (id );
8994 if (element != null && isNotStandardLibraryElement (langElement )) {
90- tranformCrossreferences (langElement , element );
91- tranformAttributes (langElement , element );
95+ transformCrossreferences (langElement , element );
96+ transformAttributes (langElement , element );
9297 //set importedMemberships for MembershipImports
9398 setImportedMembership (langElement , element );
9499 }
@@ -127,10 +132,9 @@ private void setImportedMembership(EObject langElement, Element dto) {
127132 //this is a workaround to address library element proxies where UUIDs of referenced Memberships aren't stable,
128133 //so the importedElement UUID is used instead.
129134 Object importedMembers = dto .get ("importedElement" );
130- EObject resolvedReference = resolveReference (importedMembers , false );
131- if (resolvedReference != null ) {
135+ resolveReference (importedMembers , false ).ifPresent (resolvedReference -> {
132136 membershipImport .setImportedMembership (((org .omg .sysml .lang .sysml .Element ) resolvedReference ).getOwningMembership ());
133- }
137+ });
134138 }
135139 }
136140
@@ -150,7 +154,7 @@ private boolean isNotStandardLibraryElement(EObject langElement) {
150154 }
151155
152156 private void transformContainmentReferences (EObject langElement , Element remoteElement ) {
153- for (EStructuralFeature feature : getStructuralFeatuers (langElement ))
157+ for (EStructuralFeature feature : getStructuralFeatures (langElement ))
154158 {
155159 if (!feature .isDerived () && remoteElement .get (feature .getName ()) != null ) {
156160 if (feature instanceof EReference reference && reference .isContainment ()) {
@@ -160,8 +164,8 @@ private void transformContainmentReferences(EObject langElement, Element remoteE
160164 }
161165 }
162166
163- private void tranformCrossreferences (EObject langElement , Element remoteElement ) {
164- for (EStructuralFeature feature : getStructuralFeatuers (langElement ))
167+ private void transformCrossreferences (EObject langElement , Element remoteElement ) {
168+ for (EStructuralFeature feature : getStructuralFeatures (langElement ))
165169 {
166170 if (!feature .isDerived () && remoteElement .containsKey (feature .getName ())) {
167171 if (feature instanceof EReference reference ) {
@@ -175,8 +179,8 @@ private void tranformCrossreferences(EObject langElement, Element remoteElement)
175179 }
176180 }
177181
178- private void tranformAttributes (EObject langElement , Element remoteElement ) {
179- for (EStructuralFeature feature : getStructuralFeatuers (langElement ))
182+ private void transformAttributes (EObject langElement , Element remoteElement ) {
183+ for (EStructuralFeature feature : getStructuralFeatures (langElement ))
180184 {
181185 if (!feature .isDerived () && remoteElement .containsKey (feature .getName ())) {
182186 if (feature instanceof EAttribute reference ) {
@@ -186,7 +190,7 @@ private void tranformAttributes(EObject langElement, Element remoteElement) {
186190 }
187191 }
188192
189- private static Collection <EStructuralFeature > getStructuralFeatuers (EObject langElement ){
193+ private static Collection <EStructuralFeature > getStructuralFeatures (EObject langElement ){
190194 EClass eClass = langElement .eClass ();
191195
192196 Set <EObject > allRedefined = eClass .getEAllStructuralFeatures ().stream ()
@@ -196,42 +200,54 @@ private static Collection<EStructuralFeature> getStructuralFeatuers(EObject lang
196200 return eClass .getEAllStructuralFeatures ().stream ().filter (f -> !allRedefined .contains (f )).collect (Collectors .toList ());
197201 }
198202
199- @ SuppressWarnings ("unchecked" )
200203 private void transformStructuralFeature (EObject langElement , Element remoteElement , EStructuralFeature feature , boolean isReference , boolean isContainment ) {
201- if (!disabledStructuralFeatures .contains (feature .getName ())) {
202- try {
203- if (feature .isMany ()) {
204- var referenceList = (List <EObject >) langElement .eGet (feature , false );
205- Object value = remoteElement .get (feature .getName ());
206- if (value instanceof Collection valueCollection ) {
207- for (Object referenceValue : valueCollection ) {
208- EObject referencedLangElement = resolveReference (referenceValue , isContainment );
209- if (referencedLangElement != null ) {
210- referenceList .add (referencedLangElement );
211- }
212- }
213- }
214- } else {
215- Object value = remoteElement .get (feature .getName ());
216- if (value != null ) {
217- langElement .eSet (feature , isReference ? resolveReference (value , isContainment ) : transformAttributeValue (value , feature ));
218- }
219- }
204+
205+ if (disabledStructuralFeatures .contains (feature .getName ())) {
206+ return ;
207+ }
208+
209+ try {
210+ if (feature .isMany ()) {
211+ Object value = remoteElement .get (feature .getName ());
212+ transformAndAddFeatureValues (langElement , feature , isReference , isContainment , value );
213+ } else {
214+ Object value = remoteElement .get (feature .getName ());
215+ transformAndSetFeatureValue (langElement , feature , isReference , isContainment , value );
220216 }
221- catch (Exception e ) {
222- System .out .printf ("Unable to set structural feature %s::%s %n" , feature .getEContainingClass ().getName (), feature .getName ());
217+ } catch (IllegalArgumentException e ) {
218+ // handle EObject.eGet, eSet errors
219+ issues .add (new Issue (String .format ("Unable to set structural feature %s because %s ha no such feature or feature is not changable." ,
220+ feature .getName (), feature .getEType ().getName ())));
221+ }
222+ }
223+
224+ private void transformAndSetFeatureValue (EObject langElement , EStructuralFeature feature , boolean isReference , boolean isContainment , Object valueToTransform ) {
225+ if (valueToTransform != null ) {
226+ langElement .eSet (feature , isReference ? resolveReference (valueToTransform , isContainment ).orElse (null )
227+ : transformAttributeValue (valueToTransform , feature ));
228+ }
229+ }
230+
231+ @ SuppressWarnings ("unchecked" )
232+ private void transformAndAddFeatureValues (EObject langElement , EStructuralFeature feature , boolean isReference , boolean isContainment , Object valueToTransform ) {
233+ var referenceList = (List <EObject >) langElement .eGet (feature , false );
234+ if (valueToTransform instanceof Collection valueCollection ) {
235+ for (Object referenceValue : valueCollection ) {
236+ resolveReference (referenceValue , isContainment ).ifPresentOrElse (referenceList ::add , () -> {
237+ issues .add (new Issue ("Could not resolve reference: " + feature .getName ()));
238+ });
223239 }
224240 }
225241 }
226242
227- private EObject resolveReference (Object referenceValue , boolean isContainment ) {
243+ private Optional < EObject > resolveReference (Object referenceValue , boolean isContainment ) {
228244 if (referenceValue instanceof Map referenceObjectMap ) {
229245 Object refUUID = referenceObjectMap .get ("@id" );
230246 Element referencedElement = model .getElement (UUID .fromString (refUUID .toString ()));
231247 EObject referencedLangElement = isContainment ? transform (referencedElement ) : tracker .get (UUID .fromString (refUUID .toString ()));
232- return referencedLangElement ;
248+ return Optional . ofNullable ( referencedLangElement ) ;
233249 }
234- return null ;
250+ return Optional . empty () ;
235251 }
236252
237253
@@ -254,4 +270,20 @@ private Object transformAttributeValue(Object attributeValue, EStructuralFeature
254270
255271 return null ;
256272 }
273+
274+ public List <Issue > getIssues () {
275+ return issues ;
276+ }
277+
278+ public static class Issue {
279+ private final String message ;
280+
281+ public Issue (String message ) {
282+ this .message = message ;
283+ }
284+
285+ public String getMessage () {
286+ return message ;
287+ }
288+ }
257289}
0 commit comments