11/* ****************************************************************************
22 * SysML 2 Pilot Implementation
33 * Copyright (c) 2020 California Institute of Technology/Jet Propulsion Laboratory
4- * Copyright (c) 2020-2025 Model Driven Solutions, Inc.
4+ * Copyright (c) 2020-2026 Model Driven Solutions, Inc.
55 *
66 * This program is free software: you can redistribute it and/or modify
77 * it under the terms of the GNU Lesser General Public License as published by
@@ -148,6 +148,10 @@ class SysMLValidator extends KerMLValidator {
148148
149149 public static val INVALID_USAGE_TYPE = " validateUsageType_"
150150 public static val INVALID_USAGE_TYPE_MSG = " A usage must be typed by definitions."
151+ public static val INVALID_USAGE_IS_REFERENTIAL = " validateUsageIsReferential"
152+ public static val INVALID_USAGE_IS_REFERENTIAL_MSG_1 = " A directed usage must be referential."
153+ public static val INVALID_USAGE_IS_REFERENTIAL_MSG_2 = " An end usage must be referential."
154+ public static val INVALID_USAGE_IS_REFERENTIAL_MSG_3 = " A package-lebel usage must be referential."
151155 public static val INVALID_USAGE_VARIATION_IS_ABSTRACT = " validateUsageVariationIsAbstract"
152156 public static val INVALID_USAGE_VARIATION_IS_ABSTRACT_MSG = " A variation must be abstract."
153157 public static val INVALID_USAGE_VARIATION_MEMBERSHIP = " validateUsageVariationMembership"
@@ -158,21 +162,34 @@ class SysMLValidator extends KerMLValidator {
158162 public static val INVALID_VARIANT_MEMBERSHIP_OWNING_NAMESPACE = " validateVariationMembershipOwningNamespace"
159163 public static val INVALID_VARIANT_MEMBERSHIP_OWNING_NAMESPACE_MSG = " A variant must be an owned member of a variation."
160164
165+ public static val INVALID_REFERENCE_USAGE_IS_REFERENCE = " validateReferenceUsageIsReference"
166+ public static val INVALID_REFERENCE_USAGE_IS_REFERENCE_MSG = " An attribute usage must be referential."
167+
161168 public static val INVALID_ATTRIBUTE_DEFINITION_FEATURES = " validateAttributeDefinitionFeatures"
162169 public static val INVALID_ATTRIBUTE_DEFINITION_FEATURES_MSG = " Features of an attribute definition must be referential."
163170 public static val INVALID_ATTRIBUTE_DEFINITION_SPECIALIZATION = " validateDataTypeSpecialization"
164171 public static val INVALID_ATTRIBUTE_DEFINITION_SPECIALIZATION_MSG = " Cannot specialize item definition"
165172
166173 public static val INVALID_ATTRIBUTE_USAGE_FEATURES = " validateAttributeUsageFeatures"
167174 public static val INVALID_ATTRIBUTE_USAGE_FEATURES_MSG = " Features of an attribute usage must be referential."
175+ public static val INVALID_ATTRIBUTE_USAGE_IS_REFERENTIAL = " validateAttributeUsageIsReferential"
176+ public static val INVALID_ATTRIBUTE_USAGE_IS_REFERENTIAL_MSG = " An attribute usage must be referential."
168177 public static val INVALID_ATTRIBUTE_USAGE_TYPE = " validateAttributeUsageType_"
169178 public static val INVALID_ATTRIBUTE_USAGE_MSG = " An attribute must be typed by attribute definitions."
170179 public static val INVALID_ATTRIBUTE_USAGE_ENUMERATION_TYPE = " validateAttributeUsageEnumerationType_"
171180 public static val INVALID_ATTRIBUTE_USAGE_ENUMERATION_TYPE_MSG = " An enumeration attribute cannot have more than one type."
172181
182+ public static val INVALID_ENUMERATION_DEFINITION_IS_VARIATION = " validateEnumerationDefinitionIsVariation"
183+ public static val INVALID_ENUMERATION_DEFINITION_IS_VARIATION_MSG = " An enumeration definition must be a variation."
184+
173185 public static val INVALID_ENUMERATION_USAGE_TYPE = " validateEnumerationUsageType_"
174186 public static val INVALID_ENUMERATION_USAGE_TYPE_MSG = " An enumeration must be typed by one enumeration definition."
175187
188+ public static val INVALID_EVENT_OCCURRENCE_USAGE_IS_REFERENCE = " validateEventOccurrenceUsageIsReference"
189+ public static val INVALID_EVENT_OCCURRENCE_USAGE_IS_REFERENCE_MSG_0 = " An event occurrence usage must be referential."
190+ public static val INVALID_EVENT_OCCURRENCE_USAGE_IS_REFERENCE_MSG_1 = " An exhibit state usage must be referential."
191+ public static val INVALID_EVENT_OCCURRENCE_USAGE_IS_REFERENCE_MSG_2 = " An include use case usage must be referential."
192+ public static val INVALID_EVENT_OCCURRENCE_USAGE_IS_REFERENCE_MSG_3 = " A perform action usage must be referential."
176193 public static val INVALID_EVENT_OCCURRENCE_USAGE_REFERENCE = " validateEventOccurrenceUsageReferent"
177194 public static val INVALID_EVENT_OCCURRENCE_USAGE_REFERENCE_MSG = " Must reference an occurrence."
178195
@@ -210,8 +227,10 @@ class SysMLValidator extends KerMLValidator {
210227
211228 public static val INVALID_PORT_USAGE_TYPE = " validatePortUsageType_"
212229 public static val INVALID_PORT_USAGE_TYPE_MSG = " A port must be typed by port definitions."
230+ public static val INVALID_PORT_USAGE_IS_REFERENCE = " validatePortUsageIsReference"
231+ public static val INVALID_PORT_USAGE_IS_REFERENCE_MSG = " A port usage must be referential."
213232 public static val INVALID_PORT_USAGE_NESTED_USAGES_NOT_COMPOSITE = " validatePortUsageNestedUsagesNotComposite"
214- public static val INVALID_PORT_USAGE_NESTED_USAGES_NOT_COMPOSITE_MSG = " Nested usages of a port usage (other than ports) must be referential."
233+ public static val INVALID_PORT_USAGE_NESTED_USAGES_NOT_COMPOSITE_MSG = " Nested usages in a port usage (other than ports) must be referential."
215234
216235 public static val INVALID_CONNECTION_USAGE_TYPE = " validateConnectionUsageType_"
217236 public static val INVALID_CONNECTION_USAGE_TYPE_MSG = " A connection must be typed by connection definitions."
@@ -420,8 +439,8 @@ class SysMLValidator extends KerMLValidator {
420439
421440 public static val INVALID_EXPOSE_IS_IMPORT_ALL = " validateExposeIsImportAll"
422441 public static val INVALID_EXPOSE_IS_IMPORT_ALL_MSG = " An expose must import all."
423- public static val INVALID_EXPOSE_IS_OWNING_NAMESPACE = " validateExposeIsImportAll "
424- public static val INVALID_EXPOSE_IS_OWNING_NAMESPACE_MSG = " Only view usages can expose elements."
442+ public static val INVALID_EXPOSE_OWNING_NAMESPACE = " validateExposeOwningNamespace "
443+ public static val INVALID_EXPOSE_OWNING_NAMESPACE_MSG = " Only view usages can expose elements."
425444
426445 public static val INVALID_RENDERING_USAGE_TYPE = " validateRenderingUsageType_"
427446 public static val INVALID_RENDERING_USAGE_TYPE_MSG = " A rendering must be typed by one rendering definition."
@@ -467,20 +486,31 @@ class SysMLValidator extends KerMLValidator {
467486 }
468487 }
469488
470- // @Check
471- // def checkReferenceUsage(ReferenceUsage usage) {
472- // // validateReferenceUsageIsReferential is satisfied automatically
473- // }
474-
489+ @Check
490+ def checkReferenceUsage (ReferenceUsage usage ) {
491+ // validateReferenceUsageIsReferential
492+ if (! usage. isReference) {
493+ error(INVALID_ATTRIBUTE_USAGE_IS_REFERENTIAL_MSG , usage, null , INVALID_ATTRIBUTE_USAGE_IS_REFERENTIAL )
494+ }
495+ }
475496
476497 @Check
477498 def checkUsage (Usage usage ) {
478499 // All types must be Classifiers
479500 if (! (usage instanceof AttributeUsage || usage instanceof OccurrenceUsage ))
480501 checkAllTypes(usage, Classifier , INVALID_USAGE_TYPE_MSG , SysMLPackage . eINSTANCE. usage_Definition, INVALID_USAGE_TYPE )
481502
482- // validateUsageIsReferential is satisfied automatically
483-
503+ // validateUsageIsReferential
504+ if (! usage. isReference) {
505+ if (usage. direction !== null ) {
506+ error(INVALID_USAGE_IS_REFERENTIAL_MSG_1 , usage, null , INVALID_USAGE_IS_REFERENTIAL )
507+ } else if (usage. isEnd) {
508+ error(INVALID_USAGE_IS_REFERENTIAL_MSG_2 , usage, null , INVALID_USAGE_IS_REFERENTIAL )
509+ } else if (usage. featuringType. empty) {
510+ error(INVALID_USAGE_IS_REFERENTIAL_MSG_3 , usage, null , INVALID_USAGE_IS_REFERENTIAL )
511+ }
512+ }
513+
484514 if (usage. isVariation) {
485515 // validateUsageVariationIsAbstract
486516 if (! usage. isAbstract) {
@@ -539,7 +569,10 @@ class SysMLValidator extends KerMLValidator {
539569 }
540570 }
541571
542- // validateAttributeUsageIsReference is satisfied automatically
572+ // validateAttributeUsageIsReference
573+ if (! usg. isReference) {
574+ error(INVALID_REFERENCE_USAGE_IS_REFERENCE_MSG , usg, null , INVALID_REFERENCE_USAGE_IS_REFERENCE )
575+ }
543576
544577 // Not implemented for now, until resolution of KerML issues on composite semantics. (See KerML-4.)
545578 // TODO: Check validateAttributeUsageFeatures
@@ -548,10 +581,13 @@ class SysMLValidator extends KerMLValidator {
548581 // checkAllNotComposite(usg.ownedFeature, INVALID_ATTRIBUTE_USAGE_FEATURES_MSG, INVALID_ATTRIBUTE_USAGE_FEATURES)
549582 }
550583
551- // @Check
552- // def checkEnumerationDefinition(EnumerationDefinition defn) {
553- // // validateEnumerationDefinitionIsVariation is satisfied automatically
554- // }
584+ @Check
585+ def checkEnumerationDefinition (EnumerationDefinition defn ) {
586+ // validateEnumerationDefinitionIsVariation
587+ if (! defn. isVariation) {
588+ error(INVALID_ENUMERATION_DEFINITION_IS_VARIATION_MSG , defn, null , INVALID_ENUMERATION_DEFINITION_IS_VARIATION )
589+ }
590+ }
555591
556592 @Check
557593 def checkEnumerationUsage (EnumerationUsage usg ) {
@@ -561,7 +597,18 @@ class SysMLValidator extends KerMLValidator {
561597
562598 @Check
563599 def checkEventOccurrenceUsage (EventOccurrenceUsage usg ) {
564- // validateEventOccurrenceUsageIsReference is satisfied automatically
600+ // validateEventOccurrenceUsageIsReference
601+ if (! usg. isReference) {
602+ if (usg instanceof ExhibitStateUsage ) {
603+ error(INVALID_EVENT_OCCURRENCE_USAGE_IS_REFERENCE_MSG_1 , usg, null , INVALID_EVENT_OCCURRENCE_USAGE_IS_REFERENCE )
604+ } else if (usg instanceof IncludeUseCaseUsage ) {
605+ error(INVALID_EVENT_OCCURRENCE_USAGE_IS_REFERENCE_MSG_2 , usg, null , INVALID_EVENT_OCCURRENCE_USAGE_IS_REFERENCE )
606+ } else if (usg instanceof PerformActionUsage ) {
607+ error(INVALID_EVENT_OCCURRENCE_USAGE_IS_REFERENCE_MSG_3 , usg, null , INVALID_EVENT_OCCURRENCE_USAGE_IS_REFERENCE )
608+ } else {
609+ error(org.omg.sysml.xtext.validation. SysMLValidator . INVALID_EVENT_OCCURRENCE_USAGE_IS_REFERENCE_MSG_0 , usg, null , INVALID_EVENT_OCCURRENCE_USAGE_IS_REFERENCE )
610+ }
611+ }
565612
566613 // validateEventOccurrenceUsageReference
567614 if (! (usg instanceof PerformActionUsage || usg instanceof IncludeUseCaseUsage )) {
@@ -645,7 +692,11 @@ class SysMLValidator extends KerMLValidator {
645692 // All types must be PortDefinitions
646693 checkAllTypes(usg, PortDefinition , INVALID_PORT_USAGE_TYPE_MSG , SysMLPackage . eINSTANCE. portUsage_PortDefinition, INVALID_PORT_USAGE_TYPE )
647694
648- // validatePortUsageIsReference is satisfied automatically
695+ // validatePortUsageIsReference
696+ val owningType = usg. owningType
697+ if (! (owningType instanceof PortDefinition || owningType instanceof PortUsage || usg. isReference)) {
698+ error(INVALID_PORT_USAGE_IS_REFERENCE_MSG , usg, null , INVALID_PORT_USAGE_IS_REFERENCE )
699+ }
649700
650701 // validatePortUsageNestedUsagesNotComposite
651702 val usages = usg. nestedUsage. filter[u | ! (u instanceof PortUsage )]
@@ -1197,7 +1248,10 @@ class SysMLValidator extends KerMLValidator {
11971248
11981249 @Check
11991250 def checkExpose (Expose exp ) {
1200- // validateExposeIsImportAll is automatically satisfied
1251+ // validateExposeIsImportAll
1252+ if (! exp. isImportAll) {
1253+ error(INVALID_EXPOSE_IS_IMPORT_ALL_MSG , exp, null , INVALID_EXPOSE_IS_IMPORT_ALL )
1254+ }
12011255
12021256 // validateExposeOwningNamespace
12031257 if (! (exp. importOwningNamespace instanceof ViewUsage )) {
0 commit comments