Skip to content

Commit cf9b05c

Browse files
authored
Merge pull request #649 from Systems-Modeling/ST6RI-823
ST6RI-823 Support extending Jupyter integration with additional magic commands
2 parents 7808b57 + 5409133 commit cf9b05c

7 files changed

Lines changed: 156 additions & 82 deletions

File tree

org.omg.sysml.interactive/src/org/omg/sysml/interactive/SysMLInteractive.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ public String help(String command) {
282282
public String repo(String apiBasePath, List<String> help) {
283283
this.counter++;
284284
if (!help.isEmpty()) {
285-
return SysMLInteractiveHelp.getApiBasePathHelp();
285+
return SysMLInteractiveHelp.getRepoPathHelp();
286286
}
287287

288288
if (!Strings.isNullOrEmpty(apiBasePath)) {

org.omg.sysml.interactive/src/org/omg/sysml/interactive/SysMLInteractiveHelp.java

Lines changed: 84 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -21,46 +21,42 @@
2121
*
2222
* Contributors:
2323
* Ed Seidewitz, MDS
24-
* Ivan Gomes
25-
* Hisashi Miyashita
24+
* Zoltan Ujhelyi, MDS
25+
* Ivan Gomes, Twingineer
26+
* Hisashi Miyashita, Mgnite
2627
*
2728
*******************************************************************************/
2829

2930
package org.omg.sysml.interactive;
3031

3132
import java.util.HashMap;
3233
import java.util.Map;
34+
import java.util.TreeMap;
3335

3436
import org.omg.sysml.plantuml.SysML2PlantUMLStyle;
3537

38+
import com.google.common.base.Preconditions;
39+
3640
public class SysMLInteractiveHelp {
3741

38-
private static final String GENERAL_HELP_STRING =
42+
private static final String GENERAL_HELP_STRING_PREFIX =
3943
"The following SysML v2 magic commands are available.\n"
4044
+ "For help on a specific command, use \"%help <COMMAND>\" or \"%<cmd> -h\".\n\n"
41-
+ "%eval\t\tEvaluate a given expression.\n"
42-
+ "%export\t\tSave a file of the JSON representation of the abstract syntax tree rooted in the named element.\n"
43-
+ "%help\t\tGet a list of available commands or help on a specific command\n"
44-
+ "%list\t\tList loaded library packages or the results of a given query\n"
45-
+ "%load\t\tLoad a model from the repository\n"
46-
+ "%repo\t Set the api base path for the repository\n"
47-
+ "%show\t\tPrint the abstract syntax tree rooted in a named element\n"
48-
+ "%projects\tList projects in the repository\n"
49-
+ "%publish\tPublish to the repository the modele elements rooted in a named element\n"
50-
+ "%view\t\tRender the view specified by the named view usage\n"
51-
+ "%viz\t\tVisualize the name model elements\n"
5245
;
5346

47+
private static final String HELP_HELP_SHORT_STRING = "%help\t\tGet a list of available commands or help on a specific command";
5448
private static final String HELP_HELP_STRING =
5549
"Usage: %help [<COMMAND>]\n\n"
5650
+ "Print help information on the named SysML v2 magic <COMMAND>.\n"
5751
+ "If no <COMMAND> is given, then list the available commands.\n";
5852

53+
private static final String EVAL_HELP_SHORT_STRING = "%eval\t\tEvaluate a given expression.";
5954
private static final String EVAL_HELP_STRING =
6055
"Usage: %eval [--target=<NAME>] <EXPR>\n\n"
6156
+ "Print the results of evaluating <EXPR> on the target given by <NAME>, which must be fully qualified.\n"
6257
+ "If a target is not given, then evaluate <EXPR> in global scope.\n";
6358

59+
private static final String LIST_HELP_SHORT_STRING = "%list\t\tList loaded library packages or the results of a given query";
6460
private static final String LIST_HELP_STRING =
6561
"Usage: %list [<QUERY>]\n\n"
6662
+ "If <QUERY> is not given, then list all loaded library packages.\n"
@@ -72,13 +68,17 @@ public class SysMLInteractiveHelp {
7268
+ " <NAME>::**\t\tall members of the namespace <NAME> and, recursively, members of owned namespaces.\n"
7369
+ "The last two forms may be optionally followed by a filter expression in square brackets.\n";
7470

71+
private static final String SHOW_HELP_SHORT_STRING =
72+
"%show\t\tPrint the abstract syntax tree rooted in a named element";
7573
private static final String SHOW_HELP_STRING =
7674
"Usage: %show [--style=<STYLE>] <NAME>\n\n"
7775
+ "Print the abstract syntax tree rooted in <NAME>. <NAME> must be fully qualified.\n\n"
7876
+ "<STYLE> is also case insensitive. The possible style names are:\n"
7977
+ " TREE\t\tHierarchically indented representation with only identifying information\n"
8078
+ " JSON\t\tComplete JSON representation of the tree\n";
8179

80+
private static final String PUBLISH_HELP_SHORT_STRING =
81+
"%publish\tPublish to the repository the model elements rooted in a named element";
8282
private static final String PUBLISH_HELP_STRING =
8383
"Usage: %publish [-d] [--project=<PROJECT NAME>] [--branch=<BRANCH NAME>] <NAME>\n\n"
8484
+ "Publish the model elements rooted in <NAME> to the repository. <NAME> must be fully qualified.\n"
@@ -90,6 +90,9 @@ public class SysMLInteractiveHelp {
9090
+ "If <BRANCH NAME> is given, then the model is written to this branch of the project.\n"
9191
+ "If <BRANCH NAME> is not given, the default branch is used.\n";
9292

93+
94+
private static final String VIZ_HELP_SHORT_STRING =
95+
"%viz\t\tVisualize the named model elements";
9396
private static final String VIZ_HELP_STRING =
9497
"Usage: %viz [--view=<VIEW>] [--style=<STYLE>...] <NAME> [<NAME>...]\n\n"
9598
+ "Visualize model elements of <NAME>(s). <NAME>s must be fully qualified.\n\n"
@@ -107,6 +110,8 @@ public class SysMLInteractiveHelp {
107110
+ "\t%viz --view Tree --style LR --style ortholine Pkg1::PartDef Pkg1::Pkg2::partUsage\n"
108111
+ "should visualize Pkg1::PartDef and Pkg1::Pkg2::partUsage with a tree view ordered in the left-to-right direction with orthogonal lines.\n";
109112

113+
private static final String VIEW_HELP_SHORT_STRING =
114+
"%view\t\tRender the view specified by the named view usage";
110115
private static final String VIEW_HELP_STRING =
111116
"Usage: %view [--render=<RENDERING>] [--style=<STYLE>...] <NAME>\n\n"
112117
+ "Render the view specified by the view usage <NAME>. <NAME> must be fully qualified.\n"
@@ -122,34 +127,51 @@ public class SysMLInteractiveHelp {
122127
+ SysML2PlantUMLStyle.getStyleHelp();
123128

124129

130+
private static final String EXPORT_HELP_SHORT_STRING =
131+
"%export\t\tSave a file of the JSON representation of the abstract syntax tree rooted in the named element.";
125132
private static final String EXPORT_HELP_STRING =
126133
"Usage: %export <NAME>\n\n"
127134
+ "Save a file containing the complete JSON representation of the abstract syntax tree rooted in <NAME>.\n"
128135
+ "<NAME> must be fully qualified.\n";
129136

137+
private static final String LOAD_HELP_SHORT_STRING = "%load\t\tLoad models from the repository";
130138
private static final String LOAD_HELP_STRING =
131-
"Usage: %load [--id=<PROJECT ID] [--name=<NAME>] [--branch=<BRANCH_NAME>] [<NAME>]\n\n"
132-
+ "Download previously published models from a project in the repository. <NAME> is the full name of the project.\n"
133-
+ "Named elements of the downloaded models may then be referenced models in the notebook."
134-
+ "(Use %projects to view repository contents.)\n"
139+
"Usage: %load [--id=<PROJECT ID>] [--name=<NAME>] [--branch=<BRANCH_NAME>] [<NAME>]\n\n"
140+
+ "Download previously published models from a project in the repository. (Use %projects to view repository contents.)\n"
141+
+ "Named elements of the downloaded models may then be referenced by models in the notebook.\n"
142+
+ "<NAME> is the full name of the project.\n"
135143
+ "If <PROJECT ID> is given, then the project with that UUID is loaded. In this case, the <NAME> must not be given.\n"
136-
+ "If <BRANCH NAME> is given, then the model is loaded from this branch of the project.\n"
137-
+ "If <BRANCH NAME> is not given, the default branch is used.\n";
144+
+ "If <BRANCH NAME> or <BRANCH ID> is given, then the model is loaded from this branch of the project.\n"
145+
+ "If no <BRANCH NAME> or <BRANCH ID> is given, the default branch is used.\n"
146+
+ "If <BRANCH ID> is given, then a <BRANCH NAME> must not be given.\n";
138147

148+
private static final String PROJECTS_HELP_SHORT_STRING = "%projects\tList projects in the repository";
139149
private static final String PROJECTS_HELP_STRING =
140150
"Usage: %projects\n\n"
141151
+ "Print the name and identifier of all projects in the repository.\n";
142152

143-
private static final String API_BASE_PATH_HELP_STRING =
153+
private static final String REPO_HELP_SHORT_STRING ="%repo\t\tSet the API base path for the repository";
154+
private static final String REPO_HELP_STRING =
144155
"Usage: %repo [<BASE PATH>]\n\n"
145-
+ "If <BASE PATH> is not given, print the current repository base path.\r\n"
146-
+ "If <BASE PATH> is given, set the repository base path.\r\n"
147-
+ "\r\n"
148-
+ "<BASE PATH> is a URL giving the API base path for the repository access by the %projects, %publish and %load commands. \r\n"
149-
+ "For example: https://my.domain.com/sysml_repo";
150-
156+
+ "Set the API base path for the repository accessed by the %projects, %publish and %load commands.\n"
157+
+ "<BASE PATH> is a URL (possibly including port number), such as: https://my.domain.com/sysml_repo:9000.\n"
158+
+ "If <BASE PATH> is not given, the current repository base path is printed.\n"
159+
+ "If <BASE PATH> is given, the repository base path is set to this.\n"
160+
;
161+
162+
private static String generalHelpCached;
163+
151164
public static String getGeneralHelp() {
152-
return GENERAL_HELP_STRING;
165+
if (generalHelpCached == null) {
166+
StringBuilder sb = new StringBuilder();
167+
sb.append(GENERAL_HELP_STRING_PREFIX);
168+
for (var entry: commandShortHelpMap.entrySet()) {
169+
sb.append(entry.getValue());
170+
sb.append(System.lineSeparator());
171+
}
172+
generalHelpCached = sb.toString();
173+
}
174+
return generalHelpCached;
153175
}
154176

155177
public static String getHelpHelp() {
@@ -192,27 +214,42 @@ public static String getLoadHelp() {
192214
return LOAD_HELP_STRING;
193215
}
194216

195-
public static String getApiBasePathHelp() {
196-
return API_BASE_PATH_HELP_STRING;
217+
public static String getRepoPathHelp() {
218+
return REPO_HELP_STRING;
197219
}
198220

199-
private static Map<String, String> commandHelpMap = createCommandHelpMap();
200-
201-
private static Map<String, String> createCommandHelpMap() {
202-
Map<String, String> map = new HashMap<>();
203-
map.put("%help", HELP_HELP_STRING);
204-
map.put("%eval", EVAL_HELP_STRING);
205-
map.put("%list", LIST_HELP_STRING);
206-
map.put("%show", SHOW_HELP_STRING);
207-
map.put("%publish", PUBLISH_HELP_STRING);
208-
map.put("%viz", VIZ_HELP_STRING);
209-
map.put("%view", VIEW_HELP_STRING);
210-
map.put("%export", EXPORT_HELP_STRING);
211-
map.put("%load", LOAD_HELP_STRING);
212-
map.put("%projects", PROJECTS_HELP_STRING);
213-
map.put("%repo", API_BASE_PATH_HELP_STRING);
214-
215-
return map;
221+
private static Map<String, String> commandShortHelpMap = new TreeMap<>();
222+
private static Map<String, String> commandHelpMap = new HashMap<>();
223+
static {
224+
registerHelpString("%help", HELP_HELP_SHORT_STRING, HELP_HELP_STRING);
225+
registerHelpString("%eval", EVAL_HELP_SHORT_STRING, EVAL_HELP_STRING);
226+
registerHelpString("%list", LIST_HELP_SHORT_STRING, LIST_HELP_STRING);
227+
registerHelpString("%show", SHOW_HELP_SHORT_STRING, SHOW_HELP_STRING);
228+
registerHelpString("%publish", PUBLISH_HELP_SHORT_STRING, PUBLISH_HELP_STRING);
229+
registerHelpString("%viz", VIZ_HELP_SHORT_STRING, VIZ_HELP_STRING);
230+
registerHelpString("%view", VIEW_HELP_SHORT_STRING, VIEW_HELP_STRING);
231+
registerHelpString("%export", EXPORT_HELP_SHORT_STRING, EXPORT_HELP_STRING);
232+
registerHelpString("%load", LOAD_HELP_SHORT_STRING, LOAD_HELP_STRING);
233+
registerHelpString("%projects", PROJECTS_HELP_SHORT_STRING, PROJECTS_HELP_STRING);
234+
registerHelpString("%repo", REPO_HELP_SHORT_STRING, REPO_HELP_STRING);
235+
}
236+
237+
/**
238+
* Adds command helps to the centralized store.
239+
* @param command The name of the magic command, including the '%' prefix
240+
* @param shortDescription
241+
* A one-line description of a command, including the command name with the '%' prefix
242+
* one or two tabs to make the output of the %help command nicely formatted.
243+
* @param detailedHelp
244+
* A multi-line help for a given command, expected to also detail the parameter formatting
245+
*
246+
* @throws IllegalStateException when help for a command is being re-registered
247+
*/
248+
public static void registerHelpString(String command, String shortDescription, String detailedHelp) {
249+
Preconditions.checkState(!commandHelpMap.containsKey(command), "Help is already registered for command %s", command);
250+
commandShortHelpMap.put(command, shortDescription);
251+
commandHelpMap.put(command, detailedHelp);
252+
generalHelpCached = null;
216253
}
217254

218255
public static String getHelpString(String command) {

org.omg.sysml.jupyter.kernel/.classpath

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
</classpathentry>
2222
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17">
2323
<attributes>
24-
<attribute name="module" value="true"/>
2524
<attribute name="maven.pomderived" value="true"/>
2625
</attributes>
2726
</classpathentry>
@@ -37,12 +36,6 @@
3736
<attribute name="maven.pomderived" value="true"/>
3837
</attributes>
3938
</classpathentry>
40-
<classpathentry kind="src" output="target/classes" path="target/kernel">
41-
<attributes>
42-
<attribute name="optional" value="true"/>
43-
<attribute name="maven.pomderived" value="true"/>
44-
</attributes>
45-
</classpathentry>
4639
<classpathentry combineaccessrules="false" kind="src" path="/org.omg.sysml.interactive"/>
4740
<classpathentry combineaccessrules="false" kind="src" path="/org.omg.sysml"/>
4841
<classpathentry kind="output" path="target/classes"/>

org.omg.sysml.jupyter.kernel/pom.xml

Lines changed: 9 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<version>${revision}</version>
99
</parent>
1010
<artifactId>jupyter-sysml-kernel</artifactId>
11-
11+
1212
<dependencies>
1313
<dependency>
1414
<groupId>org.omg.sysml</groupId>
@@ -35,8 +35,8 @@
3535
</exclusion>
3636
</exclusions>
3737
</dependency>
38-
<!--
39-
Dependencies needed for m2e
38+
<!--
39+
Dependencies needed for m2e
4040
we need to add these manually so the Eclipse IDE can see the classpath
4141
-->
4242
<dependency>
@@ -119,7 +119,7 @@
119119
</execution>
120120
</executions>
121121
</plugin>
122-
122+
123123
<plugin>
124124
<groupId>org.apache.maven.plugins</groupId>
125125
<artifactId>maven-jar-plugin</artifactId>
@@ -138,7 +138,7 @@
138138
</execution>
139139
</executions>
140140
</plugin>
141-
141+
142142
<plugin>
143143
<groupId>org.apache.maven.plugins</groupId>
144144
<artifactId>maven-shade-plugin</artifactId>
@@ -201,25 +201,6 @@
201201
</executions>
202202
</plugin>
203203

204-
<!-- Needed for updating the version number in the kernel.json. This is used to copy the resources to the unzipped kernel.-->
205-
<plugin>
206-
<groupId>org.codehaus.mojo</groupId>
207-
<artifactId>templating-maven-plugin</artifactId>
208-
<version>3.0.0</version>
209-
<executions>
210-
<execution>
211-
<phase>prepare-package</phase>
212-
<goals>
213-
<goal>filter-sources</goal>
214-
</goals>
215-
</execution>
216-
</executions>
217-
<configuration>
218-
<sourceDirectory>src/main/resources</sourceDirectory>
219-
<outputDirectory>target/kernel</outputDirectory>
220-
</configuration>
221-
</plugin>
222-
223204
<plugin>
224205
<groupId>org.apache.maven.plugins</groupId>
225206
<artifactId>maven-resources-plugin</artifactId>
@@ -241,6 +222,9 @@
241222
<include>${project.artifactId}-${project.version}-all.jar</include>
242223
</includes>
243224
</resource>
225+
<resource>
226+
<directory>${basedir}/src/main/resources</directory>
227+
</resource>
244228
<resource>
245229
<directory>..</directory>
246230
<targetPath>sysml</targetPath>
@@ -255,7 +239,7 @@
255239
</execution>
256240
</executions>
257241
</plugin>
258-
242+
259243
<plugin>
260244
<groupId>org.apache.maven.plugins</groupId>
261245
<artifactId>maven-assembly-plugin</artifactId>
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*****************************************************************************
2+
* SysML 2 Pilot Implementation
3+
* Copyright (c) 2025 Model Driven Solutions, Inc.
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU Lesser General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of theGNU Lesser General Public License
16+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
17+
*
18+
* @license LGPL-3.0-or-later <http://spdx.org/licenses/LGPL-3.0-or-later>
19+
*
20+
* Contributors:
21+
* Zoltan Ujhelyi, MDS
22+
*
23+
*****************************************************************************/
24+
package org.omg.sysml.jupyter.kernel;
25+
26+
import org.omg.sysml.interactive.SysMLInteractiveHelp;
27+
28+
import io.github.spencerpark.jupyter.kernel.magic.registry.Magics;
29+
30+
public interface IMagicCommandRegistrator {
31+
32+
/**
33+
* Implementors of this method are free to register their extra commands to the
34+
* Jupyter kernel. This method is called when the Jupyter environment is
35+
* initialized and it assumed the registration code will run quickly and without
36+
* exceptions. If the registrator cannot run successfully, it should not
37+
* register anything instead of throwing an exception.
38+
* </p>
39+
* Implementors are recommended to use the register methods of the {@link Magics}
40+
* class. Help is managed by the {@link SysMLInteractiveHelp} class.
41+
*
42+
* @see Magics#registerMagics(Class)
43+
* @see SysMLInteractiveHelp#registerHelpString(String, String, String)
44+
*/
45+
void registerMagicCommand(Magics magics);
46+
}

0 commit comments

Comments
 (0)