11/*****************************************************************************
22 * SysML 2 Pilot Implementation
3- * Copyright (c) 2019-2022, 2024 Model Driven Solutions, Inc.
3+ * Copyright (c) 2019-2022, 2024, 2025 Model Driven Solutions, Inc.
44 * Copyright (c) 2020 Mgnite Inc.
55 * Copyright (c) 2021 Twingineer LLC
66 *
3232import java .io .IOException ;
3333import java .util .ArrayList ;
3434import java .util .Collections ;
35- import java .util .Date ;
35+ import java .util .Comparator ;
3636import java .util .List ;
37+ import java .util .Map ;
3738import java .util .Scanner ;
3839import java .util .UUID ;
3940import java .util .stream .Collectors ;
5455import org .eclipse .xtext .validation .CheckMode ;
5556import org .eclipse .xtext .validation .IResourceValidator ;
5657import org .eclipse .xtext .validation .Issue ;
57- import org .omg .kerml .xmi .KerMLxStandaloneSetup ;
5858import org .omg .kerml .xtext .KerMLStandaloneSetup ;
59+ import org .omg .kerml .xtext .xmi .KerMLxStandaloneSetup ;
5960import org .omg .kerml .xtext .library .ILibraryIndexProvider ;
6061import org .omg .kerml .xtext .naming .KerMLQualifiedNameConverter ;
6162import org .omg .sysml .execution .expressions .ExpressionEvaluator ;
7273import org .omg .sysml .lang .sysml .util .SysMLLibraryUtil ;
7374import org .omg .sysml .plantuml .SysML2PlantUMLLinkProvider ;
7475import org .omg .sysml .plantuml .SysML2PlantUMLSvc ;
75- import org .omg .sysml .util .NamespaceUtil ;
7676import org .omg .sysml .util .SysMLUtil ;
7777import org .omg .sysml .util .TypeUtil ;
7878import org .omg .sysml .util .repository .EObjectUUIDTracker ;
8686import org .omg .sysml .util .traversal .Traversal ;
8787import org .omg .sysml .util .traversal .facade .impl .ApiElementProcessingFacade ;
8888import org .omg .sysml .util .traversal .facade .impl .JsonElementProcessingFacade ;
89- import org .omg .sysml .xmi .SysMLxStandaloneSetup ;
89+ import org .omg .sysml .xtext . xmi .SysMLxStandaloneSetup ;
9090import org .omg .sysml .xtext .SysMLStandaloneSetup ;
9191
9292import com .google .common .base .Predicates ;
9696
9797public class SysMLInteractive extends SysMLUtil {
9898
99+ public static final String HELP_KEY = "help" ;
100+ public static final String PROJECT_ID_KEY = "id" ;
101+ public static final String PROJECT_NAME_KEY = "name" ;
102+ public static final String BRANCH_ID_KEY = "branch-id" ;
103+ public static final String BRANCH_NAME_KEY = "branch" ;
104+
99105 public static final String KERNEL_LIBRARIES_DIRECTORY = "Kernel Libraries" ;
100106 public static final String SYSTEMS_LIBRARY_DIRECTORY = "Systems Library" ;
101107 public static final String DOMAIN_LIBRARIES_DIRECTORY = "Domain Libraries" ;
@@ -384,7 +390,7 @@ else if (matchStyle(styles, "JSON")) {
384390 else if (styles .isEmpty () || matchStyle (styles , "TREE" )){
385391 return SysMLInteractiveUtil .formatTree (element );
386392 } else {
387- return "ERROR:Invalid style. Possible styles: TREE and JSON" ;
393+ return "ERROR:Invalid style. Possible styles: TREE and JSON\n " ;
388394 }
389395 } catch (Exception e ) {
390396 return SysMLInteractiveUtil .formatException (e );
@@ -454,67 +460,83 @@ protected String publish(String name) {
454460 publish (name , null , null , false , Collections .emptyList ());
455461 }
456462
457- public String loadByName (String projectName , String branchName , List <String > help ) {
458- if (Strings .isNullOrEmpty (projectName )) {
459- return help .isEmpty ()? "" : SysMLInteractiveHelp .getLoadHelp ();
460- }
463+ /**
464+ * Loads using the supplied parameters<br>
465+ * Possible parameters are:
466+ * <li> {@value SysMLInteractive#PROJECT_NAME_KEY}: name of the project</li>
467+ * <li> {@value SysMLInteractive#PROJECT_ID_KEY}: id of the project</li>
468+ * <li> {@value SysMLInteractive#BRANCH_NAME_KEY}: name of the project's branch</li>
469+ * <li> {@value SysMLInteractive#BRANCH_ID_KEY}: id of the project's branch </li>
470+ * <li>{@value SysMLInteractive#HELP_KEY}: request help string for the operation</li>
471+ *
472+ * <br>
473+ * {@value SysMLInteractive#PROJECT_NAME_KEY} and {@value SysMLInteractive#PROJECT_ID_KEY} are mutually exclusive. It is mandatory to specify one of them.
474+ * <br>
475+ * {@value SysMLInteractive#BRANCH_NAME_KEY} and {@value SysMLInteractive#BRANCH_ID_KEY} are mutually exclusive. If neither is given the project's default branch is used.
476+ * <br>
477+ * If help {@value SysMLInteractive#HELP_KEY} is passed as a parameter (with any value) the help string is printed. Every other parameters are ignored.
478+ *
479+ * <br>
480+ * <br>
481+ * @param parameters map containing the parameters and their values
482+ * @return output of the command
483+ */
484+ public String load (Map <String , String > parameters ) {
485+ counter ++;
461486
462- ProjectRepository repository = new ProjectRepository (apiBasePath );
463- RemoteProject repositoryProject = repository .getProjectByName (projectName );
487+ if (parameters .containsKey (HELP_KEY )) {
488+ return SysMLInteractiveHelp .getLoadHelp ();
489+ }
464490
465- if (repositoryProject == null ) {
466- return "ERROR:Project doesn't exist. " ;
491+ if (parameters . containsKey ( PROJECT_ID_KEY ) && parameters . containsKey ( PROJECT_NAME_KEY ) ) {
492+ return "ERROR:Project name and id cannot be provided at the same time \n " ;
467493 }
468494
469- return load (repositoryProject , branchName );
470- }
471-
472- public String loadById (String projectId , String branchId , List <String > help ) {
473- if (Strings .isNullOrEmpty (projectId )) {
474- return help .isEmpty ()? "" : SysMLInteractiveHelp .getLoadHelp ();
495+ if (parameters .containsKey (BRANCH_ID_KEY ) && parameters .containsKey (BRANCH_NAME_KEY )) {
496+ return "ERROR:Branch name and id cannot be provided at the same time\n " ;
475497 }
476498
477- ProjectRepository repository = new ProjectRepository (apiBasePath );
478- RemoteProject remoteProject = repository . getPRojectById ( UUID . fromString ( projectId )) ;
499+ final ProjectRepository repository = new ProjectRepository (apiBasePath );
500+ final RemoteProject project ;
479501
480- if (remoteProject == null ) {
481- return "ERROR:Project doesn't exist." ;
502+ if (parameters .containsKey (PROJECT_ID_KEY )) {
503+ String projectId = parameters .get (PROJECT_ID_KEY );
504+ project = repository .getProjectById (projectId );
505+ } else if (parameters .containsKey (PROJECT_NAME_KEY )) {
506+ String projectName = parameters .get (PROJECT_NAME_KEY );
507+ project = repository .getProjectByName (projectName );
508+ } else {
509+ return SysMLInteractiveHelp .getLoadHelp ();
482510 }
483511
484- if (branchId == null ) {
485- return load (remoteProject , (UUID ) null );
486- } else {
487- UUID branchUUID = UUID .fromString (branchId );
488- return load (remoteProject , branchUUID );
512+ if (project == null ) {
513+ return "ERROR:Project doesn't exist\n " ;
489514 }
490- }
491-
492- private String load (RemoteProject remoteProject , String branchName ) {
515+
493516 final RemoteBranch branch ;
494- if (branchName == null ) {
495- branch = remoteProject .getDefaultBranch ();
517+
518+ if (parameters .containsKey (BRANCH_NAME_KEY )) {
519+ String branchName = parameters .get (BRANCH_NAME_KEY );
520+ branch = project .getBranch (branchName );
521+ } else if (parameters .containsKey (BRANCH_ID_KEY )) {
522+ String branchIdString = parameters .get (BRANCH_ID_KEY );
523+ UUID branchId = UUID .fromString (branchIdString );
524+ branch = project .getBranch (branchId );
496525 } else {
497- branch = remoteProject . getBranch ( branchName );
526+ branch = project . getDefaultBranch ( );
498527 }
528+
499529 return load (branch );
500530 }
501531
502- private String load (RemoteProject remoteProject , UUID branchId ) {
503- final RemoteBranch branch ;
504- if (branchId == null ) {
505- branch = remoteProject .getDefaultBranch ();
506- } else {
507- branch = remoteProject .getBranch (branchId );
508- }
509- return load (branch );
510- }
511-
512532 private String load (RemoteBranch branch ) {
513533 if (branch == null ) {
514- return "ERROR:Branch doesn't exist" ;
534+ return "ERROR:Branch doesn't exist\n " ;
515535 }
516536
517- System .out .println ("Selected branch " + branch .getName ());
537+ System .out .println ("API base path: " + apiBasePath );
538+ System .out .println ();
539+ System .out .println ("Selected branch " + branch .getName () + " (" + branch .getRemoteId ().toString () + ")" );
518540
519541 if (!tracker .isLibraryTracked ()) {
520542 System .out .println ("Caching library UUIDs..." );
@@ -536,39 +558,44 @@ private String load(RemoteBranch branch) {
536558 EMFModelDelta delta = modelRefresher .create ();
537559 modelRefresher .getIssues ().forEach (System .out ::println );
538560
539- delta .getProjectRoots ().forEach ((eObject , dto ) -> {
540- next (SYSMLX_EXTENSION );
541- Resource xmiResource = getResource ();
542- if (eObject instanceof Namespace ) {
543- xmiResource .getContents ().add (eObject );
544- } else {
545- Namespace root = SysMLFactory .eINSTANCE .createNamespace ();
546- NamespaceUtil .addOwnedMemberTo (root , (Element ) eObject );
547- xmiResource .getContents ().add (root );
548- }
549- addResourceToIndex (xmiResource );
561+ delta .getProjectRootsAsNamespaces ().forEach (rootNs -> {
562+ Resource resource = this .createResource (rootNs .toString () + SYSML_EXTENSION );
563+ resource .getContents ().add (rootNs );
564+ this .addInputResource (resource );
565+ addResourceToIndex (resource );
550566 });
551567
552- return "Loaded Project " + remoteProject .getProjectName () + " (" + remoteProject .getRemoteId ().toString () + ")" ;
568+ return "Loaded Project " + remoteProject .getProjectName () + " (" + remoteProject .getRemoteId ().toString () + ")\n " ;
553569 }
554570
555- protected String download (String name ) {
571+ protected String load (String name ) {
556572 return "-h" .equals (name )?
557- loadByName ( null , null , Collections . singletonList ( "true" )):
558- loadByName ( name , null , Collections . emptyList ( ));
573+ load ( Map . of ( HELP_KEY , "true" )):
574+ load ( Map . of ( PROJECT_NAME_KEY , name ));
559575 }
560576
561577 public String projects (List <String > help ) {
578+ this .counter ++;
562579 if (help != null && !help .isEmpty ()) {
563580 return SysMLInteractiveHelp .getProjectsHelp ();
564581 }
565582 ProjectRepository projectRepository = new ProjectRepository (apiBasePath );
566583
584+ Comparator <String > projectNameComparator = Comparator .nullsFirst (Comparator .naturalOrder ());
585+
567586 String apiBasePathString = "API base path: " + apiBasePath ;
568587 List <RemoteProject > repositoryProjects = projectRepository .getProjects ();
569- String projectsListString = repositoryProjects .stream ().map (p -> String .format ("Project %s (%s)" , p .getProjectName (), p .getRemoteId ()))
588+ String projectsListString = repositoryProjects .stream ()
589+ .sorted ((p1 , p2 ) -> projectNameComparator .compare (p1 .getProjectName (), p2 .getProjectName ()))
590+ .map (p -> String .format ("Project %s (%s)" , p .getProjectName (), p .getRemoteId ()))
570591 .collect (Collectors .joining ("\n " ));
571- return apiBasePathString + "\n \n " + projectsListString ;
592+ return apiBasePathString + "\n \n " + projectsListString + "\n " ;
593+ }
594+
595+ protected String projects (String arg ) {
596+ return "-h" .equals (arg )?
597+ projects (Collections .singletonList ("true" )):
598+ projects (Collections .emptyList ());
572599 }
573600
574601 protected ApiElementProcessingFacade getApiElementProcessingFacade (String modelName , String branchName , boolean includeDerived ) {
@@ -751,10 +778,16 @@ public void run() {
751778 if (!"" .equals (argument )) {
752779 System .out .print (this .show (argument ));
753780 }
781+ } else if ("%projects" .equals (command )) {
782+ System .out .print (this .projects (argument ));
754783 } else if ("%publish" .equals (command )) {
755784 if (!"" .equals (argument )) {
756785 System .out .print (this .publish (argument ));
757786 }
787+ } else if ("%load" .equals (command )) {
788+ if (!"" .equals (argument )) {
789+ System .out .print (this .load (argument ));
790+ }
758791 } else if ("%viz" .equals (command )) {
759792 if (!"" .equals (argument )) {
760793 System .out .print (this .viz (argument ));
0 commit comments