-
Notifications
You must be signed in to change notification settings - Fork 33
Expand file tree
/
Copy pathEMFExporter.java
More file actions
614 lines (582 loc) · 30.3 KB
/
EMFExporter.java
File metadata and controls
614 lines (582 loc) · 30.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
package org.openmbee.mdk.emf;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.*;
import com.nomagic.ci.persistence.IAttachedProject;
import com.nomagic.ci.persistence.IProject;
import com.nomagic.magicdraw.core.Project;
import com.nomagic.magicdraw.core.ProjectUtilities;
import com.nomagic.magicdraw.core.ProjectUtilitiesInternal;
import com.nomagic.magicdraw.esi.EsiUtils;
import com.nomagic.magicdraw.sysml.util.SysMLProfile;
import com.nomagic.uml2.ext.jmi.helpers.StereotypesHelper;
import com.nomagic.uml2.ext.magicdraw.auxiliaryconstructs.mdmodels.Model;
import com.nomagic.uml2.ext.magicdraw.classes.mdkernel.Package;
import com.nomagic.uml2.ext.magicdraw.classes.mdkernel.*;
import com.nomagic.uml2.ext.magicdraw.compositestructures.mdinternalstructures.Connector;
import com.nomagic.uml2.ext.magicdraw.mdprofiles.Stereotype;
import com.nomagic.uml2.ext.magicdraw.metadata.UMLPackage;
import com.nomagic.magicdraw.hyperlinks.ElementHyperlink;
import org.openmbee.mdk.SysMLExtensions;
import org.openmbee.mdk.api.function.TriFunction;
import org.openmbee.mdk.api.incubating.MDKConstants;
import org.openmbee.mdk.api.incubating.convert.Converters;
import org.openmbee.mdk.api.stream.MDKCollectors;
import org.openmbee.mdk.json.JacksonUtils;
import org.openmbee.mdk.util.MDUtils;
import org.openmbee.mdk.util.Utils;
import org.w3c.dom.html.HTMLDocument;
import org.eclipse.emf.ecore.EDataType;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;
import java.util.function.BiFunction;
import java.util.stream.Collectors;
import java.io.Reader;
import java.io.StringReader;
public class EMFExporter implements BiFunction<Element, Project, ObjectNode> {
@Override
public ObjectNode apply(Element element, Project project) {
return convert(element, project);
}
private static ObjectNode convert(Element element, Project project) {
return convert(element, project, false);
}
private static ObjectNode convert(Element element, Project project, boolean nestedValueSpecification) {
if (element == null) {
return null;
}
ObjectNode objectNode = JacksonUtils.getObjectMapper().createObjectNode();
for (Processor processor : Arrays.stream(Processor.values()).filter(processor -> processor.getType() == Processor.Type.PRE).collect(Collectors.toList())) {
if (nestedValueSpecification && processor == Processor.VALUE_SPECIFICATION) {
continue;
}
try {
objectNode = processor.getFunction().apply(element, project, objectNode);
} catch (RuntimeException e) {
e.printStackTrace();
System.out.println("EXCEPTION: " + element.getHumanName() + " | " + element.getLocalID() + " in " + project.getName());
}
if (objectNode == null) {
return null;
}
}
for (EStructuralFeature eStructuralFeature : element.eClass().getEAllStructuralFeatures()) {
final ObjectNode finalObjectNode = objectNode;
ExportFunction function = Arrays.stream(EStructuralFeatureOverride.values())
.filter(override -> override.getPredicate().test(element, project, eStructuralFeature, finalObjectNode)).map(EStructuralFeatureOverride::getFunction)
.findAny().orElse(DEFAULT_E_STRUCTURAL_FEATURE_FUNCTION);
try {
objectNode = function.apply(element, project, eStructuralFeature, objectNode);
} catch (RuntimeException e) {
e.printStackTrace();
System.err.println(element);
}
if (objectNode == null) {
return null;
}
}
for (Processor processor : Arrays.stream(Processor.values()).filter(processor -> processor.getType() == Processor.Type.POST).collect(Collectors.toList())) {
try {
objectNode = processor.getFunction().apply(element, project, objectNode);
} catch (RuntimeException e) {
e.printStackTrace();
System.out.println("EXCEPTION: " + element.getHumanName() + " | " + element.getLocalID() + " in " + project.getName());
}
if (objectNode == null) {
return null;
}
}
return objectNode;
}
/*
* @deprecated
* As of MDK 6.1.1 this function has been moved to make it more widely available to other processes. This link is subject to remvoal in a future version. Please refactor accordingly
* @see org.openmbee.mdk.util.MDUtils#getEID()
*/
@Deprecated(since="6.1.1")
public static String getEID(EObject eObject) {
return MDUtils.getEID(eObject);
}
private static void dumpUMLPackageLiterals() {
for (Field field : UMLPackage.Literals.class.getDeclaredFields()) {
if (Modifier.isStatic(field.getModifiers())) {
try {
field.setAccessible(true);
Object o = field.get(null);
System.out.println(field.getName() + ": " + o);
if (o instanceof EReference) {
EReference eReference = (EReference) o;
System.out.println(" --- " + eReference.getEReferenceType() + " : " + eReference.getEReferenceType().getInstanceClass());
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
private enum Processor {
/*APPLIED_STEREOTYPE(
(element, project, objectNode) -> {
ArrayNode applied = StereotypesHelper.getStereotypes(element).stream().map(stereotype -> TextNode.valueOf(MDUtils.getEID(stereotype))).collect(MDKCollectors.toArrayNode());
objectNode.set(MDKConstants.APPLIED_STEREOTYPE_IDS_KEY, applied);
return objectNode;
},
Type.PRE
),*/
ATTACHED_PROJECT(
(element, project, objectNode) -> ProjectUtilities.isElementInAttachedProject(element) && ProjectUtilities.getAttachedProjects(project.getPrimaryProject()).stream().noneMatch(iAttachedProject -> ProjectUtilitiesInternal.distanceFromProject(iAttachedProject) == 1 && ProjectUtilities.isAttachedProjectRoot(element, iAttachedProject)) ? null : objectNode,
Type.PRE
),
COMMENT(
(element, project, objectNode) -> {
if (!(element instanceof Comment)) {
return objectNode;
}
Comment comment = (Comment) element;
return comment.getAnnotatedElement().size() == 1 && comment.getAnnotatedElement().iterator().next() == comment.getOwner() ? null : objectNode;
},
Type.PRE
),
DIAGRAM_TYPE(
(element, project, objectNode) -> {
if (element instanceof Diagram) {
objectNode.put(MDKConstants.DIAGRAM_TYPE_KEY, ((Diagram) element).get_representation() != null ? ((Diagram) element).get_representation().getType() : null);
}
return objectNode;
},
Type.PRE
),
DOCUMENTATION_PRE(
(element, project, objectNode) -> {
//Todo: FIgure out how to read this stuff and parse the <a tags from MD
String doc_text = (String) Utils.getElementAttribute(element, Utils.AvailableAttribute.Documentation);
Document doc = Jsoup.parse(doc_text);
Elements crossReferences = doc.select("a[href^=mdel:]");
if (!crossReferences.isEmpty()) {
crossReferences.tagName("mms-cf");
}
// Reader reader = new StringReader(doc_text);
// HTMLDocument html = new HTMLDocument(doc_text);
objectNode.put(MDKConstants.DOCUMENTATION_KEY, (String) Utils.getElementAttribute(element, Utils.AvailableAttribute.Documentation));
return objectNode;
},
Type.PRE
),
MOUNT_PRE(
(element, project, objectNode) -> {
if (!ProjectUtilities.isAttachedProjectRoot(element)) {
return objectNode;
}
IProject iProject = ProjectUtilities.getProjectFor(element);
if (!(iProject instanceof IAttachedProject)) {
return objectNode;
}
IAttachedProject attachedProject = (IAttachedProject) iProject;
boolean isRemote = ProjectUtilities.isRemote(attachedProject) && !attachedProject.getLocationURI().isFile();
objectNode.put(MDKConstants.TYPE_KEY, "Mount");
objectNode.put(MDKConstants.MOUNTED_ELEMENT_ID_KEY, Converters.getIProjectToIdConverter().apply(attachedProject) + MDKConstants.PRIMARY_MODEL_ID_SUFFIX);
objectNode.put(MDKConstants.MOUNTED_ELEMENT_PROJECT_ID_KEY, Converters.getIProjectToIdConverter().apply(attachedProject));
EsiUtils.EsiBranchInfo branchInfo = EsiUtils.getCurrentBranch(attachedProject);
if (isRemote && branchInfo == null) {
return null;
}
String branchName;
if (!isRemote || (branchName = branchInfo.getName()) == null || "trunk".equals(branchName)) {
branchName = "master";
}
String branchId = "master".equals(branchName) ? "master" : branchInfo.getID().toString();
objectNode.put(MDKConstants.MOUNTED_REF_ID_KEY, branchId);
objectNode.put(MDKConstants.TWC_VERSION_KEY, isRemote ? ProjectUtilities.versionToInt(ProjectUtilities.getVersion(attachedProject).getName()) : -1);
return objectNode;
},
Type.PRE
),
IS_GROUP(
(element, project, objectNode) -> {
if (element instanceof Package) {
objectNode.put(MDKConstants.IS_GROUP_KEY, SysMLExtensions.getInstance(element).group().is(element));
}
return objectNode;
},
Type.PRE
),
SYNC(
(element, project, objectNode) -> element == null || Converters.getElementToIdConverter().apply(element).endsWith(MDKConstants.SYNC_SYSML_ID_SUFFIX) ||
element.getOwner() != null && Converters.getElementToIdConverter().apply(element.getOwner()).endsWith(MDKConstants.SYNC_SYSML_ID_SUFFIX) ? null : objectNode,
Type.PRE
),
//TWC_ID is disabled indefinitely, due to our inability to update the ID and associated issues
// TWC_ID(
// (element, project, objectNode) -> {
// if (project.isRemote() && element.getID() != element.getLocalID()) {
// objectNode.put(MDKConstants.TWC_ID_KEY, element.getID());
// }
// return objectNode;
// },
// Type.PRE
// ),
TYPE(
(element, project, objectNode) -> {
if (!objectNode.has(MDKConstants.TYPE_KEY)) {
objectNode.put(MDKConstants.TYPE_KEY, element.eClass().getName());
}
return objectNode;
},
Type.PRE
),
VALUE_SPECIFICATION(
(element, project, objectNode) -> {
Element e = element;
do {
if (e instanceof ValueSpecification) {
return null;
}
} while ((e = e.getOwner()) != null);
return objectNode;
},
Type.PRE
),
VIEW(
(element, project, objectNode) -> {
Stereotype viewStereotype = SysMLProfile.getInstance(element).view().getStereotype();
if (viewStereotype == null || !StereotypesHelper.hasStereotypeOrDerived(element, viewStereotype)) {
return objectNode;
}
Constraint viewConstraint = Utils.getViewConstraint(element);
if (viewConstraint == null) {
return objectNode;
}
objectNode.set(MDKConstants.CONTENTS_KEY, DEFAULT_SERIALIZATION_FUNCTION.apply(viewConstraint.getSpecification(), project, null));
return objectNode;
},
Type.PRE
),
VIEW_POST(
(element, project, objectNode) -> {
Stereotype viewStereotype = SysMLProfile.getInstance(element).view().getStereotype();
JsonNode node = objectNode.get(MDKConstants.OWNED_RULE_IDS);
if (viewStereotype == null || !StereotypesHelper.hasStereotypeOrDerived(element, viewStereotype) ||
node == null || !node.isArray() || node.size() == 0) {
return objectNode;
}
((ArrayNode)node).removeAll();
return objectNode;
},
Type.POST
),
MOUNT_POST(
(element, project, objectNode) -> {
if (!objectNode.get(MDKConstants.TYPE_KEY).asText().equals("Mount")) {
return objectNode;
}
Iterator<String> iterator = objectNode.fieldNames();
while (iterator.hasNext()) {
String key = iterator.next();
if (key.equals(MDKConstants.MOUNTED_ELEMENT_ID_KEY)
|| key.equals(MDKConstants.MOUNTED_ELEMENT_PROJECT_ID_KEY)
|| key.equals(MDKConstants.MOUNTED_REF_ID_KEY)
|| key.equals(MDKConstants.TWC_VERSION_KEY)
|| key.equals(MDKConstants.TYPE_KEY)
|| key.equals(MDKConstants.ID_KEY)
|| key.equals(MDKConstants.OWNER_ID_KEY)) {
continue;
}
iterator.remove();
}
return objectNode;
},
Type.POST
),
DOCUMENTATION_POST(
(element, project, objectNode) -> {
if (element != null) {
Element docEl = Utils.getDocumentationElement(element);
if (docEl != null) {
ArrayNode ownedCommentIds = ((ArrayNode) objectNode.get(MDKConstants.OWNED_COMMENT_IDS_KEY));
for (int i = 0; i < ownedCommentIds.size(); i++) {
if (ownedCommentIds.get(i).asText().equals(MDUtils.getEID(docEl)))
ownedCommentIds.remove(i);
}
if (ownedCommentIds.size() == 0) {
objectNode.remove(MDKConstants.OWNED_COMMENT_IDS_KEY);
} else {
objectNode.replace(MDKConstants.OWNED_COMMENT_IDS_KEY, ownedCommentIds);
}
}
}
return objectNode;
},
Type.POST
),
TAGGEDVALUE_POST(
(element, project, objectNode) -> {
if (!(element instanceof TaggedValue) || element instanceof ElementTaggedValue) {
return objectNode;
}
TaggedValue v = (TaggedValue)element;
ArrayNode l = (ArrayNode)objectNode.get("value");
if (l == null) {
l = JacksonUtils.getObjectMapper().createArrayNode();
objectNode.set("value", l);
}
l.removeAll();
// for continuity with 19.x mdk export, value is a list of objects with value key or elementId
for (Object o: v.getValue()) {
ObjectNode n = JacksonUtils.getObjectMapper().createObjectNode();
JsonNode node = null;
if (o instanceof String) {
node = TextNode.valueOf((String) o);
}
else if (o instanceof Boolean) {
node = BooleanNode.valueOf((boolean) o);
}
else if (o instanceof Integer) {
node = IntNode.valueOf((Integer) o);
}
else if (o instanceof Double) {
node = DoubleNode.valueOf((Double) o);
}
else if (o instanceof Long) {
node = LongNode.valueOf((Long) o);
}
else if (o instanceof Short) {
node = ShortNode.valueOf((Short) o);
}
else if (o instanceof Float) {
node = FloatNode.valueOf((Float) o);
}
else if (o instanceof BigInteger) {
node = BigIntegerNode.valueOf((BigInteger) o);
}
else if (o instanceof BigDecimal) {
node = DecimalNode.valueOf((BigDecimal) o);
}
n.set("value", node);
if (o instanceof Element) {
node = TextNode.valueOf(MDUtils.getEID((Element)o));
n.set("elementId", node);
n.remove("value");
}
l.add(n);
}
return objectNode;
},
Type.POST
);
private TriFunction<Element, Project, ObjectNode, ObjectNode> function;
private Type type;
Processor(TriFunction<Element, Project, ObjectNode, ObjectNode> function, Type type) {
this.function = function;
this.type = type;
}
public TriFunction<Element, Project, ObjectNode, ObjectNode> getFunction() {
return function;
}
public Type getType() {
return type;
}
public enum Type {
PRE,
POST
}
}
private static final SerializationFunction DEFAULT_SERIALIZATION_FUNCTION = (object, project, eStructuralFeature) -> {
if (object == null) {
return NullNode.getInstance();
}
else if (object instanceof Collection) {
ArrayNode arrayNode = JacksonUtils.getObjectMapper().createArrayNode();
try {
for (Object o : ((Collection<?>) object)) {
JsonNode serialized = EMFExporter.DEFAULT_SERIALIZATION_FUNCTION.apply(o, project, eStructuralFeature);
if (serialized == null && o != null) {
// failed to serialize; taking the conservative approach and returning entire thing as null
return NullNode.getInstance();
}
arrayNode.add(serialized);
}
} catch (UnsupportedOperationException e) {
e.printStackTrace();
System.err.println("Object: " + object.getClass());
}
return arrayNode;
}
else if (object instanceof ValueSpecification) {
return convert((ValueSpecification) object, project, true);
//return fillValueSpecification((ValueSpecification) object);
}
else if (eStructuralFeature instanceof EReference && object instanceof EObject) {
return EMFExporter.DEFAULT_SERIALIZATION_FUNCTION.apply(MDUtils.getEID(((EObject) object)), project, eStructuralFeature);
}
else if (object instanceof String) {
return TextNode.valueOf((String) object);
}
else if (object instanceof Boolean) {
return BooleanNode.valueOf((boolean) object);
}
else if (object instanceof Integer) {
return IntNode.valueOf((Integer) object);
}
else if (object instanceof Double) {
return DoubleNode.valueOf((Double) object);
}
else if (object instanceof Long) {
return LongNode.valueOf((Long) object);
}
else if (object instanceof Short) {
return ShortNode.valueOf((Short) object);
}
else if (object instanceof Float) {
return FloatNode.valueOf((Float) object);
}
else if (object instanceof BigInteger) {
return BigIntegerNode.valueOf((BigInteger) object);
}
else if (object instanceof BigDecimal) {
return DecimalNode.valueOf((BigDecimal) object);
}
else if (object instanceof byte[]) {
return BinaryNode.valueOf((byte[]) object);
}
else if (eStructuralFeature.getEType() instanceof EDataType) {
return TextNode.valueOf(EcoreUtil.convertToString((EDataType) eStructuralFeature.getEType(), object));
//return ((Enumerator) object).getLiteral();
}
// if we get here we have no idea what to do with this object
return NullNode.getInstance();
};
private static final ExportFunction DEFAULT_E_STRUCTURAL_FEATURE_FUNCTION = (element, project, eStructuralFeature, objectNode) -> {
if (!eStructuralFeature.isChangeable() || eStructuralFeature.isVolatile() || eStructuralFeature.isTransient() || eStructuralFeature.isUnsettable() || eStructuralFeature.isDerived() || eStructuralFeature.getName().startsWith("_")) {
return EMFExporter.EMPTY_E_STRUCTURAL_FEATURE_FUNCTION.apply(element, project, eStructuralFeature, objectNode);
}
return EMFExporter.UNCHECKED_E_STRUCTURAL_FEATURE_FUNCTION.apply(element, project, eStructuralFeature, objectNode);
};
private static final ExportFunction UNCHECKED_E_STRUCTURAL_FEATURE_FUNCTION = (element, project, eStructuralFeature, objectNode) -> {
Object value = element.eGet(eStructuralFeature);
JsonNode serializedValue = DEFAULT_SERIALIZATION_FUNCTION.apply(value, project, eStructuralFeature);
if (value != null && serializedValue == null) {
System.err.println("[EMF] Failed to serialize " + eStructuralFeature + " for " + element + ": " + value + " - " + value.getClass());
return objectNode;
}
String key = eStructuralFeature.getName();
if (eStructuralFeature instanceof EReference && EObject.class.isAssignableFrom(((EReference) eStructuralFeature).getEReferenceType().getInstanceClass())
&& !ValueSpecification.class.isAssignableFrom(((EReference) eStructuralFeature).getEReferenceType().getInstanceClass())) {
key += "Id" + (eStructuralFeature.isMany() ? "s" : "");
}
objectNode.put(key, serializedValue);
return objectNode;
};
private static final ExportFunction EMPTY_E_STRUCTURAL_FEATURE_FUNCTION = (element, project, eStructuralFeature, objectNode) -> objectNode;
private enum EStructuralFeatureOverride {
ID(
(element, project, eStructuralFeature, objectNode) -> eStructuralFeature == element.eClass().getEIDAttribute(),
(element, project, eStructuralFeature, objectNode) -> {
/*if (element instanceof ValueSpecification && !(element instanceof TimeExpression)) {
return objectNode;
}*/
objectNode.put(MDKConstants.ID_KEY, MDUtils.getEID(element));
return objectNode;
}
),
OWNER(
(element, project, eStructuralFeature, objectNode) -> UMLPackage.Literals.ELEMENT__OWNER == eStructuralFeature,
(element, project, eStructuralFeature, objectNode) -> {
Element owner = element.getOwner();
/*if (element instanceof ValueSpecification || owner instanceof ValueSpecification) {
return objectNode;
}*/
//UNCHECKED_E_STRUCTURAL_FEATURE_FUNCTION.apply(element, project, UMLPackage.Literals.ELEMENT__OWNER, objectNode);
// safest way to prevent circular references, like with ValueSpecifications
objectNode.put(MDKConstants.OWNER_ID_KEY, element instanceof Model && project.getModels().stream().anyMatch(model -> element == model) ? Converters.getIProjectToIdConverter().apply(project.getPrimaryProject()) : MDUtils.getEID(owner));
return objectNode;
}
),
DIRECTED_RELATIONSHIP__SOURCE(
(element, project, eStructuralFeature, objectNode) -> UMLPackage.Literals.DIRECTED_RELATIONSHIP__SOURCE == eStructuralFeature,
(element, project, eStructuralFeature, objectNode) -> {
objectNode.set(MDKConstants.DERIVED_KEY_PREFIX + eStructuralFeature.getName() + MDKConstants.IDS_KEY_SUFFIX, DEFAULT_SERIALIZATION_FUNCTION.apply(element.eGet(eStructuralFeature), project, eStructuralFeature));
return objectNode;
}
),
DIRECTED_RELATIONSHIP__TARGET(
(element, project, eStructuralFeature, objectNode) -> UMLPackage.Literals.DIRECTED_RELATIONSHIP__TARGET == eStructuralFeature,
(element, project, eStructuralFeature, objectNode) -> {
objectNode.set(MDKConstants.DERIVED_KEY_PREFIX + eStructuralFeature.getName() + MDKConstants.IDS_KEY_SUFFIX, DEFAULT_SERIALIZATION_FUNCTION.apply(element.eGet(eStructuralFeature), project, eStructuralFeature));
return objectNode;
}
),
CONNECTOR__END(
(element, project, eStructuralFeature, objectNode) -> eStructuralFeature == UMLPackage.Literals.CONNECTOR__END,
(element, project, eStructuralFeature, objectNode) -> {
Connector connector = (Connector) element;
List<List<Object>> propertyPaths = connector.getEnd().stream()
.map(connectorEnd -> SysMLProfile.NestedConnectorEndStereotype.isInstance(connectorEnd) ? SysMLProfile.getInstance(connector).nestedConnectorEnd().getPropertyPath(connector) : null)
.map(elements -> {
if (elements == null) {
return new ArrayList<>(1);
}
List<Object> list = new ArrayList<>(elements.size() + 1);
for (Object o : elements) {
list.add(o instanceof ElementValue ? ((ElementValue) o).getElement() : o);
}
return list;
}).collect(Collectors.toList());
for (int i = 0; i < propertyPaths.size(); i++) {
propertyPaths.get(i).add(connector.getEnd().get(i).getRole());
}
objectNode.set(MDKConstants.PROPERTY_PATH_IDS_KEY, DEFAULT_SERIALIZATION_FUNCTION.apply(propertyPaths, project, eStructuralFeature));
return DEFAULT_E_STRUCTURAL_FEATURE_FUNCTION.apply(element, project, eStructuralFeature, objectNode);
}
),
VALUE_SPECIFICATION__EXPRESSION(
(element, project, eStructuralFeature, objectNode) -> eStructuralFeature == UMLPackage.Literals.VALUE_SPECIFICATION__EXPRESSION,
/*(element, project, eStructuralFeature, objectNode) -> {
Expression expression = null;
Object object = element.eGet(UMLPackage.Literals.VALUE_SPECIFICATION__EXPRESSION);
if (object instanceof Expression) {
expression = (Expression) object;
}
objectNode.put(UMLPackage.Literals.VALUE_SPECIFICATION__EXPRESSION.getName() + MDKConstants.ID_KEY_SUFFIX, expression != null ? expression.getID() : null);
return objectNode;
}*/
EMPTY_E_STRUCTURAL_FEATURE_FUNCTION
),
UML_CLASS(
(element, project, eStructuralFeature, objectNode) -> eStructuralFeature == UMLPackage.Literals.CLASSIFIER__UML_CLASS || eStructuralFeature == UMLPackage.Literals.PROPERTY__UML_CLASS || eStructuralFeature == UMLPackage.Literals.OPERATION__UML_CLASS,
EMPTY_E_STRUCTURAL_FEATURE_FUNCTION
);
private ExportPredicate predicate;
private ExportFunction function;
EStructuralFeatureOverride(ExportPredicate predicate, ExportFunction function) {
this.predicate = predicate;
this.function = function;
}
public ExportPredicate getPredicate() {
return predicate;
}
public ExportFunction getFunction() {
return function;
}
}
@FunctionalInterface
interface SerializationFunction {
JsonNode apply(Object object, Project project, EStructuralFeature eStructuralFeature);
}
@FunctionalInterface
interface ExportPredicate {
boolean test(Element element, Project project, EStructuralFeature structuralFeature, ObjectNode objectNode);
}
@FunctionalInterface
interface ExportFunction {
ObjectNode apply(Element element, Project project, EStructuralFeature eStructuralFeature, ObjectNode objectNode);
}
}