Repository navigation
Expand file tree
/
Copy pathTutorial.java
More file actions
113 lines (103 loc) · 6.35 KB
/
Copy pathTutorial.java
File metadata and controls
113 lines (103 loc) · 6.35 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
// SysML v2 SDK, Java: a first walk through a model.
//
// Compile and run from the repository root (JDK 21 or newer, no build tool needed):
//
// javac --enable-preview --release 21 -d java/out $(find java/src -name '*.java')
// javac --enable-preview --release 21 -cp java/out -d examples/java/out examples/java/Tutorial.java
// java --enable-preview -cp java/out:examples/java/out Tutorial (; instead of : on Windows)
// java --enable-preview -cp java/out:examples/java/out Tutorial --toolkit reads vehicle.sysml through the SysML Toolkit
//
// Without --toolkit this reads examples/vehicle.full.json, a full-form interchange payload, whose
// references into the standard library resolve against the library as JSON, published with each
// SDK release. In this repository both are generated by
// `python tools/export_example.py --library <sysml.library>`. With --toolkit, the SysML Toolkit
// answers directly through the binding library (build abi/ first). The preview flags are for
// JDK 21; on JDK 22 or newer the foreign function API is final and they go away.
//
// Everything is named as in the OMG specification. Properties are read through getters, `get` +
// the specification name: getOwnedMember(), getQualifiedName(), getIsAbstract(). Operations keep
// their specification names: effectiveName(), specializes(...). The generated interfaces form the
// real metaclass hierarchy, so instanceof works.
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import org.openmbee.sysml.Element;
import org.openmbee.sysml.ToolkitBackend;
import org.openmbee.sysml.Model;
import org.openmbee.sysml.NotImplementedInToolkitException;
import org.openmbee.sysml.PayloadLibrary;
import org.openmbee.sysml.classes.Definition;
import org.openmbee.sysml.classes.Documentation;
import org.openmbee.sysml.classes.Feature;
import org.openmbee.sysml.classes.Namespace;
import org.openmbee.sysml.classes.PartDefinition;
import org.openmbee.sysml.classes.PartUsage;
import org.openmbee.sysml.classes.Type;
public class Tutorial {
public static void main(String[] args) throws Exception {
boolean toolkit = args.length > 0 && args[0].equals("--toolkit");
Model model = toolkit
? new Model(ToolkitBackend.open(List.of(Path.of("examples", "vehicle.sysml").toString())))
: Model.fromFullJson(Files.readString(Path.of("examples", "vehicle.full.json")),
PayloadLibrary.fromJson(Files.readString(Path.of("examples", "sysml.library.full.json"))));
// 1. Find an element by its qualified name, and confirm what it is.
PartDefinition vehicle = (PartDefinition) model.resolve("Vehicles::Vehicle");
System.out.println(vehicle.getQualifiedName() + " is a " + vehicle.$metaclass());
// 2. The generated interfaces are the metaclass hierarchy.
Namespace vehicles = (Namespace) model.resolve("Vehicles");
StringBuilder defs = new StringBuilder();
for (Element m : vehicles.getOwnedMember()) {
if (m instanceof Definition d) defs.append(defs.length() == 0 ? "" : ", ").append(d.getDeclaredName());
}
System.out.println("definitions: " + defs);
// 3. Walk a definition's features and their declared types.
System.out.println("\nfeatures of " + vehicle.getDeclaredName() + ":");
for (Feature f : vehicle.getOwnedFeature()) {
String types;
try {
StringBuilder names = new StringBuilder();
for (Type t : f.getType()) names.append(names.length() == 0 ? "" : ", ").append(t.getDeclaredName());
types = names.length() == 0 ? "untyped" : names.toString();
} catch (NotImplementedInToolkitException e) { // the SysML Toolkit cannot vouch for this value yet
types = "(" + e.getMessage() + ")";
}
String name = f.getDeclaredName() == null ? "(unnamed)" : f.getDeclaredName();
System.out.printf(" %-16s %-10s : %s%n", f.$metaclass(), name, types);
}
// 4. Documentation is a member like any other.
for (Documentation doc : vehicle.getDocumentation()) System.out.println("\ndoc: " + doc.getBody().trim());
// 5. A usage and the definition it is typed by.
PartUsage myCar = (PartUsage) model.resolve("Vehicles::myCar");
try {
List<Type> typedBy = myCar.getType();
System.out.println("\n" + myCar.getQualifiedName() + " is typed by " + typedBy.get(0).getQualifiedName());
} catch (NotImplementedInToolkitException e) {
System.out.println("\n" + myCar.getQualifiedName() + ": " + e.getMessage());
}
// 6. Inheritance. Through the SysML Toolkit, inherited features are computed. A payload
// holds what the exporting tool wrote: this file was exported at the closure level, so
// it has them too; an export by the SysML Toolkit's command-line tool would list the
// owned side only. With the standard library, every part also inherits the library's
// features (`self`, `start`, ...); getIsLibraryElement() tells them apart.
PartDefinition sports = (PartDefinition) model.resolve("Vehicles::SportsCar");
String inherited;
try {
inherited = String.valueOf(sports.getInheritedFeature().stream()
.filter(f -> !Boolean.TRUE.equals(f.getIsLibraryElement())).count());
} catch (NotImplementedInToolkitException e) {
inherited = "(" + e.getMessage() + ")";
}
System.out.println("\n" + sports.getDeclaredName() + " owns " + sports.getOwnedFeature().size()
+ " features; inherited: " + inherited);
// 7. Honest refusal. Through the SysML Toolkit, a member it cannot vouch for yet says so
// instead of answering, as the reads above show where it does. Through a payload there
// is nobody to say so: the file holds what the exporting tool wrote.
try {
StringBuilder defs7 = new StringBuilder();
for (Element d : myCar.getPartDefinition()) defs7.append(defs7.length() == 0 ? "" : ", ").append(d.getQualifiedName());
System.out.println("\npartDefinition of myCar: " + defs7);
} catch (NotImplementedInToolkitException e) {
System.out.println("\nnot answered by the SysML Toolkit, and it says so: " + e.getMessage());
}
}
}