diff --git a/resources/Decision Model and Notation/dtc-23-02-13.xmi.xml b/resources/Decision Model and Notation/dtc-23-02-13.xmi similarity index 100% rename from resources/Decision Model and Notation/dtc-23-02-13.xmi.xml rename to resources/Decision Model and Notation/dtc-23-02-13.xmi diff --git a/resources/Decision Model and Notation/dtc-23-02-16.xmi.xml b/resources/Decision Model and Notation/dtc-23-02-16.xmi similarity index 100% rename from resources/Decision Model and Notation/dtc-23-02-16.xmi.xml rename to resources/Decision Model and Notation/dtc-23-02-16.xmi diff --git a/resources/UML/PrimitiveTypes.xmi.xml b/resources/UML/PrimitiveTypes.xmi similarity index 100% rename from resources/UML/PrimitiveTypes.xmi.xml rename to resources/UML/PrimitiveTypes.xmi diff --git a/resources/UML/StandardProfile.xmi.xml b/resources/UML/StandardProfile.xmi similarity index 100% rename from resources/UML/StandardProfile.xmi.xml rename to resources/UML/StandardProfile.xmi diff --git a/resources/UML/UML.xmi.xml b/resources/UML/UML.xmi similarity index 100% rename from resources/UML/UML.xmi.xml rename to resources/UML/UML.xmi diff --git a/resources/UML/UMLDI.xmi.xml b/resources/UML/UMLDI.xmi similarity index 100% rename from resources/UML/UMLDI.xmi.xml rename to resources/UML/UMLDI.xmi diff --git a/uml4net.CodeGenerator.Tests/uml4net.CodeGenerator.Tests.csproj b/uml4net.CodeGenerator.Tests/uml4net.CodeGenerator.Tests.csproj index 24698d1b..54782e53 100644 --- a/uml4net.CodeGenerator.Tests/uml4net.CodeGenerator.Tests.csproj +++ b/uml4net.CodeGenerator.Tests/uml4net.CodeGenerator.Tests.csproj @@ -233,10 +233,10 @@ - + Always - + Always diff --git a/uml4net.Extensions.Tests/uml4net.Extensions.Tests.csproj b/uml4net.Extensions.Tests/uml4net.Extensions.Tests.csproj index eb82a92e..7383c231 100644 --- a/uml4net.Extensions.Tests/uml4net.Extensions.Tests.csproj +++ b/uml4net.Extensions.Tests/uml4net.Extensions.Tests.csproj @@ -43,10 +43,10 @@ - + Always - + Always diff --git a/uml4net.HandleBars.Tests/uml4net.HandleBars.Tests.csproj b/uml4net.HandleBars.Tests/uml4net.HandleBars.Tests.csproj index 297c64d1..ff6c0063 100644 --- a/uml4net.HandleBars.Tests/uml4net.HandleBars.Tests.csproj +++ b/uml4net.HandleBars.Tests/uml4net.HandleBars.Tests.csproj @@ -44,10 +44,10 @@ - + Always - + Always diff --git a/uml4net.Reporting.Tests/uml4net.Reporting.Tests.csproj b/uml4net.Reporting.Tests/uml4net.Reporting.Tests.csproj index cebce85d..23d792ec 100644 --- a/uml4net.Reporting.Tests/uml4net.Reporting.Tests.csproj +++ b/uml4net.Reporting.Tests/uml4net.Reporting.Tests.csproj @@ -43,10 +43,10 @@ - + Always - + Always diff --git a/uml4net.Tools.Tests/uml4net.Tools.Tests.csproj b/uml4net.Tools.Tests/uml4net.Tools.Tests.csproj index ad9f22ad..b6fb5b03 100644 --- a/uml4net.Tools.Tests/uml4net.Tools.Tests.csproj +++ b/uml4net.Tools.Tests/uml4net.Tools.Tests.csproj @@ -49,10 +49,10 @@ - + Always - + Always diff --git a/uml4net.xmi.Tests/DecisionModelNotationReaderTestFixture.cs b/uml4net.xmi.Tests/DecisionModelNotationReaderTestFixture.cs index 481f2476..a18ece40 100644 --- a/uml4net.xmi.Tests/DecisionModelNotationReaderTestFixture.cs +++ b/uml4net.xmi.Tests/DecisionModelNotationReaderTestFixture.cs @@ -60,7 +60,7 @@ public void Verify_that_DMN_XMI_can_be_read() .WithLogger(this.loggerFactory) .Build(); - var xmiReaderResult = reader.Read(Path.Combine(TestContext.CurrentContext.TestDirectory, "TestData", "dtc-23-02-13.xmi.xml")); + var xmiReaderResult = reader.Read(Path.Combine(TestContext.CurrentContext.TestDirectory, "TestData", "dtc-23-02-13.xmi")); Assert.That(xmiReaderResult.Packages.Count, Is.EqualTo(2)); diff --git a/uml4net.xmi.Tests/ReferenceResolver/ExternalReferenceResolverTestFixture.cs b/uml4net.xmi.Tests/ReferenceResolver/ExternalReferenceResolverTestFixture.cs new file mode 100644 index 00000000..f2e4ecaa --- /dev/null +++ b/uml4net.xmi.Tests/ReferenceResolver/ExternalReferenceResolverTestFixture.cs @@ -0,0 +1,201 @@ +// ------------------------------------------------------------------------------------------------- +// +// +// Copyright 2019-2025 Starion Group S.A. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +// ------------------------------------------------------------------------------------------------ + +namespace uml4net.xmi.Tests.ReferenceResolver +{ + using System.Collections.Generic; + using System.IO; + using System.Linq; + using Classification; + using Microsoft.Extensions.Logging; + using Moq; + using NUnit.Framework; + using Resources; + using Serilog; + using Settings; + using uml4net.xmi.ReferenceResolver; + + [TestFixture] + public class ExternalReferenceResolverTestFixture + { + private ILoggerFactory loggerFactory; + + private ExternalReferenceResolver referenceResolver; + + private ResourceLoader resourceLoader; + + private XmiElementCache xmiElementCache; + + private IXmiReaderSettings settings; + + [OneTimeSetUp] + public void OneTimeSetUp() + { + Log.Logger = new LoggerConfiguration() + .MinimumLevel.Debug() + .WriteTo.Console() + .CreateLogger(); + + loggerFactory = LoggerFactory.Create(builder => + { + builder.AddSerilog(); + }); + } + + [SetUp] + public void SetUp() + { + this.resourceLoader = new ResourceLoader(); + + this.xmiElementCache = new XmiElementCache(); + + this.settings = new Settings.DefaultSettings(); + + this.referenceResolver = new ExternalReferenceResolver(this.resourceLoader, + this.xmiElementCache, settings, this.loggerFactory.CreateLogger()); + } + + [Test] + public void Verify_that_resolving_external_resources_that_are_known_returns_expected_result() + { + var property_1 = new Property + { + XmiId = "property_1", + Name = "IsValid", + DocumentName = "test", + }; + property_1.SingleValueReferencePropertyIdentifiers.Add("type", "http://www.omg.org/spec/UML/20131001/PrimitiveTypes.xmi#Boolean"); + property_1.MultiValueReferencePropertyIdentifiers.Add("subsettedProperty", ["https://www.omg.org/spec/UML/20131001/PrimitiveTypes.xmi#Boolean"]); + + var property_2 = new Property + { + XmiId = "property_2", + Name = "IsComposite", + DocumentName = "test", + }; + property_2.SingleValueReferencePropertyIdentifiers.Add("type", "PrimitiveTypes.xmi#Boolean"); + property_2.MultiValueReferencePropertyIdentifiers.Add("subsettedProperty", ["PrimitiveTypes#Boolean"]); + + this.xmiElementCache.TryAdd(property_1); + this.xmiElementCache.TryAdd(property_2); + + var resolvedKnowReferences = this.referenceResolver.TryResolve("test"); + + Assert.That(resolvedKnowReferences.Count, Is.EqualTo(4)); + + Assert.That(resolvedKnowReferences[0].Context, Is.EqualTo("http://www.omg.org/spec/UML/20131001/PrimitiveTypes.xmi")); + Assert.That(resolvedKnowReferences[1].Context, Is.EqualTo("PrimitiveTypes.xmi")); + Assert.That(resolvedKnowReferences[2].Context, Is.EqualTo("https://www.omg.org/spec/UML/20131001/PrimitiveTypes.xmi")); + Assert.That(resolvedKnowReferences[3].Context, Is.EqualTo("PrimitiveTypes")); + } + + [Test] + public void Verify_that_duplicate_use_of_known_resource_returns_only_once() + { + var property_1 = new Property + { + XmiId = "property_1", + Name = "IsValid", + DocumentName = "test", + }; + property_1.SingleValueReferencePropertyIdentifiers.Add("type", "https://www.omg.org/spec/UML/20131001/PrimitiveTypes.xmi#Boolean"); + property_1.MultiValueReferencePropertyIdentifiers.Add("subsettedProperty", ["https://www.omg.org/spec/UML/20131001/PrimitiveTypes.xmi#Integer"]); + + this.xmiElementCache.TryAdd(property_1); + + var resolvedKnowReferences = this.referenceResolver.TryResolve("test"); + + Assert.That(resolvedKnowReferences.Count, Is.EqualTo(1)); + + Assert.That(resolvedKnowReferences[0].Context, Is.EqualTo("https://www.omg.org/spec/UML/20131001/PrimitiveTypes.xmi")); + } + + [Test] + public void verify_that_http_or_https_resolve_to_local_file() + { + var rootPath = Path.Combine(TestContext.CurrentContext.TestDirectory, "TestData"); + + this.settings.LocalReferenceBasePath = rootPath; + + var property_1 = new Property + { + XmiId = "property_1", + Name = "IsValid", + DocumentName = "test", + }; + property_1.SingleValueReferencePropertyIdentifiers.Add("type", "https://www.omg.org/spec/UML/PrimitiveTypes.xmi#Boolean"); + property_1.SingleValueReferencePropertyIdentifiers.Add("count", "http://www.omg.org/spec/UML/PrimitiveTypes.xmi#Integer"); + property_1.SingleValueReferencePropertyIdentifiers.Add("unlimitedCount", "ftp://www.omg.org/spec/UML/PrimitiveTypes.xmi#LiteralUnlimitedNatural"); + + this.xmiElementCache.TryAdd(property_1); + + var resolvedKnowReferences = this.referenceResolver.TryResolve("test"); + + Assert.That(resolvedKnowReferences.Count, Is.EqualTo(3)); + + Assert.That(resolvedKnowReferences[0].Context, Is.EqualTo("https://www.omg.org/spec/UML/PrimitiveTypes.xmi")); + Assert.That(resolvedKnowReferences[1].Context, Is.EqualTo("http://www.omg.org/spec/UML/PrimitiveTypes.xmi")); + Assert.That(resolvedKnowReferences[2].Context, Is.EqualTo("ftp://www.omg.org/spec/UML/PrimitiveTypes.xmi")); + } + + [Test] + public void Verity_that_file_references_can_be_processed() + { + var rootPath = Path.Combine(TestContext.CurrentContext.TestDirectory, "TestData"); + + var fileSchemePath = $"file://{rootPath}//PrimitiveTypes.xmi#Boolean"; + var resoureceName = $"file://{rootPath}//PrimitiveTypes.xmi"; + + var property_1 = new Property + { + XmiId = "property_1", + Name = "IsValid", + DocumentName = "test", + }; + property_1.SingleValueReferencePropertyIdentifiers.Add("type", fileSchemePath); + + this.xmiElementCache.TryAdd(property_1); + + var resolvedKnowReferences = this.referenceResolver.TryResolve("test"); + + Assert.That(resolvedKnowReferences.Count, Is.EqualTo(1)); + + Assert.That(resolvedKnowReferences[0].Context, Is.EqualTo(resoureceName)); + } + + [Test] + public void Verify_that_non_external_references_are_not_processed() + { + var property_1 = new Property + { + XmiId = "property_1", + Name = "IsValid", + DocumentName = "test", + }; + property_1.SingleValueReferencePropertyIdentifiers.Add("type", "Boolean"); + + this.xmiElementCache.TryAdd(property_1); + + var resolvedKnowReferences = this.referenceResolver.TryResolve("test"); + + Assert.That(resolvedKnowReferences.Count, Is.EqualTo(0)); + } + } +} diff --git a/uml4net.xmi.Tests/StandardProfileReaderTestFixture.cs b/uml4net.xmi.Tests/StandardProfileReaderTestFixture.cs index b6538e36..ac6d994d 100644 --- a/uml4net.xmi.Tests/StandardProfileReaderTestFixture.cs +++ b/uml4net.xmi.Tests/StandardProfileReaderTestFixture.cs @@ -64,7 +64,7 @@ public void Verify_that_StandardProfile_XMI_can_be_read() .WithLogger(this.loggerFactory) .Build(); - var xmiReaderResult = reader.Read(Path.Combine(TestContext.CurrentContext.TestDirectory, "TestData", "StandardProfile.xmi.xml")); + var xmiReaderResult = reader.Read(Path.Combine(TestContext.CurrentContext.TestDirectory, "TestData", "StandardProfile.xmi")); Assert.That(xmiReaderResult.Packages.Count, Is.EqualTo(3)); diff --git a/uml4net.xmi.Tests/TestData/doc1.xml b/uml4net.xmi.Tests/TestData/doc1.xml new file mode 100644 index 00000000..04751b7e --- /dev/null +++ b/uml4net.xmi.Tests/TestData/doc1.xml @@ -0,0 +1,23 @@ + + + + demo for crossreferencing between doc1 and doc2 + + + + + + + First Constraint definition + + + + + + + + + + + + \ No newline at end of file diff --git a/uml4net.xmi.Tests/TestData/doc2.xml b/uml4net.xmi.Tests/TestData/doc2.xml new file mode 100644 index 00000000..839ea69e --- /dev/null +++ b/uml4net.xmi.Tests/TestData/doc2.xml @@ -0,0 +1,16 @@ + + + + demo for crossreferencing between doc1 and doc2 + + + + + + Fourth Constraint definition + + + + + + \ No newline at end of file diff --git a/uml4net.xmi.Tests/XmiReaderCrossReferenceTwoModels.cs b/uml4net.xmi.Tests/XmiReaderCrossReferenceTwoModels.cs new file mode 100644 index 00000000..17410152 --- /dev/null +++ b/uml4net.xmi.Tests/XmiReaderCrossReferenceTwoModels.cs @@ -0,0 +1,77 @@ +// ------------------------------------------------------------------------------------------------- +// +// +// Copyright 2019-2025 Starion Group S.A. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +// ------------------------------------------------------------------------------------------------ + +namespace uml4net.xmi.Tests +{ + using System.IO; + using System.Linq; + using Classification; + using Microsoft.Extensions.Logging; + + using NUnit.Framework; + + using Serilog; + + using uml4net.StructuredClassifiers; + using uml4net.xmi; + + [TestFixture] + public class XmiReaderCrossReferenceTwoModels + { + private ILoggerFactory loggerFactory; + + [OneTimeSetUp] + public void OneTimeSetUp() + { + Log.Logger = new LoggerConfiguration() + .MinimumLevel.Debug() + .WriteTo.Console() + .CreateLogger(); + + this.loggerFactory = LoggerFactory.Create(builder => + { + builder.AddSerilog(); + }); + } + + [Test] + public void Verify_that_doc1_and_doc2_can_be_read_where_the_contents_references_each_other() + { + var rootPath = Path.Combine(TestContext.CurrentContext.TestDirectory, "TestData"); + + var reader = XmiReaderBuilder.Create() + .UsingSettings(x => x.LocalReferenceBasePath = rootPath) + .WithLogger(this.loggerFactory) + .Build(); + + var xmiReaderResult = reader.Read(Path.Combine(TestContext.CurrentContext.TestDirectory, "TestData", "doc1.xml")); + + Assert.That(xmiReaderResult.Packages.Count, Is.EqualTo(2)); + + var class_2 = xmiReaderResult.Root.PackagedElement.OfType().Single(x => x.FullyQualifiedIdentifier == "doc1.xml#class02"); + Assert.That(class_2.DocumentName, Is.EqualTo("doc1.xml")); + + var class_1 = xmiReaderResult.Packages[1].PackagedElement.OfType().Single(x => x.FullyQualifiedIdentifier == "doc2.xml#class01"); + Assert.That(class_1.DocumentName, Is.EqualTo("doc2.xml")); + + Assert.That(class_2.OwnedAttribute.OfType().Single().Type, Is.EqualTo(class_1) ); + } + } +} diff --git a/uml4net.xmi.Tests/uml4net.xmi.Tests.csproj b/uml4net.xmi.Tests/uml4net.xmi.Tests.csproj index 9b44d34f..c8682433 100644 --- a/uml4net.xmi.Tests/uml4net.xmi.Tests.csproj +++ b/uml4net.xmi.Tests/uml4net.xmi.Tests.csproj @@ -19,6 +19,7 @@ + @@ -43,19 +44,28 @@ - + Always - + Always - + Always - + Always - + + Always + + + + + + Always + + Always diff --git a/uml4net.xmi/Readers/XmiReader.cs b/uml4net.xmi/Readers/XmiReader.cs index 04dfa7ae..c0f0c8c0 100644 --- a/uml4net.xmi/Readers/XmiReader.cs +++ b/uml4net.xmi/Readers/XmiReader.cs @@ -256,7 +256,7 @@ private void Read(Stream stream, string documentName, XmiReaderResult xmiReaderR this.logger.LogTrace("xml read in {Time}", currentlyElapsedMilliseconds); sw.Stop(); - this.TryResolveExternalReferences(xmiReaderResult); + this.TryResolveExternalReferences(xmiReaderResult, documentName); if (isRoot) { @@ -270,13 +270,13 @@ private void Read(Stream stream, string documentName, XmiReaderResult xmiReaderR /// /// The to which the read s are added /// - private void TryResolveExternalReferences(XmiReaderResult xmiReaderResult) + private void TryResolveExternalReferences(XmiReaderResult xmiReaderResult, string documentName) { var stopwatch = Stopwatch.StartNew(); this.logger.LogTrace("resolving the external references"); - var x = this.externalReferenceResolver.TryResolve().ToList(); + var x = this.externalReferenceResolver.TryResolve(documentName).ToList(); foreach (var (context, externalResource) in x) { diff --git a/uml4net.xmi/ReferenceResolver/ExternalReferenceResolver.cs b/uml4net.xmi/ReferenceResolver/ExternalReferenceResolver.cs index d0e95c4d..5a7bd3a2 100644 --- a/uml4net.xmi/ReferenceResolver/ExternalReferenceResolver.cs +++ b/uml4net.xmi/ReferenceResolver/ExternalReferenceResolver.cs @@ -27,16 +27,22 @@ namespace uml4net.xmi.ReferenceResolver using Microsoft.Extensions.Logging; + using uml4net.xmi.Resources; using uml4net.xmi.Settings; - /// /// Resolves external references for XMI elements using provided settings and cache. /// - /// The cache containing XMI reader information. - /// The settings for the XMI reader configuration. - /// The logger for logging information and errors. - public class ExternalReferenceResolver(IXmiElementCache cache, IXmiReaderSettings settings, ILogger logger) + /// + /// The (injected) cache containing XMI reader information. + /// + /// + /// The (injected) settings for the XMI reader configuration. + /// + /// + /// The (injected) logger used for logging. + /// + public class ExternalReferenceResolver(IResourceLoader resourceLoader, IXmiElementCache cache, IXmiReaderSettings settings, ILogger logger) : IExternalReferenceResolver { /// @@ -47,35 +53,46 @@ public class ExternalReferenceResolver(IXmiElementCache cache, IXmiReaderSetting /// /// Asynchronously attempts to resolve external references and yields their context and stream. /// - /// - /// The current directory of the main resource + /// + /// the name of the XMI document for which the external references are being resolved. /// /// /// An IEnumerable of tuples containing the context and stream of resolved references. /// - public IEnumerable<(string Context, Stream Stream)> TryResolve() + public IReadOnlyList<(string Context, Stream Stream)> TryResolve(string documentName) { - foreach (var identifier in cache.Values - .SelectMany(cacheEntry => cacheEntry.SingleValueReferencePropertyIdentifiers.Values)) + this.externalReferencesCache.Add(documentName); + + var result = new List<(string Context, Stream Stream)>(); + + var singleValueReferencePropertyIdentifiers = cache.Values + .SelectMany(cacheEntry => cacheEntry.SingleValueReferencePropertyIdentifiers.Values).ToList(); + + foreach (var identifier in singleValueReferencePropertyIdentifiers) { if(this.TryResolve(identifier, out var reference)) { - yield return reference; + result.Add(reference); } } - foreach (var identifiers in cache.Values - .SelectMany(cacheEntry => cacheEntry.MultiValueReferencePropertyIdentifiers.Values)) + var multiValueReferencePropertyIdentifiers = cache.Values + .SelectMany(cacheEntry => cacheEntry.MultiValueReferencePropertyIdentifiers.Values).ToList(); + + foreach (var identifiers in multiValueReferencePropertyIdentifiers) { foreach (var identifier in identifiers) { if (this.TryResolve(identifier, out var reference)) { - yield return reference; + result.Add(reference); } } } + + return result; } + /// /// Attempts to resolve an external reference identified by the specified key. /// @@ -93,32 +110,32 @@ private bool TryResolve(string key, out (string Context, Stream Stream) result) { result = default; - if (this.IsInvalidKey(key) || !this.TryResolveContext(key, out var resource)) + if (this.IsInvalidExternalResourceKey(key) || !this.TryResolveContext(key, out var externalResource)) { logger.LogTrace("Resource key [{Key}] is not referencing an external resource", key); return false; } - if (this.externalReferencesCache.Contains(resource.Context)) + if (this.externalReferencesCache.Contains(externalResource.Context)) { - logger.LogDebug("The resource {Resource} was already parsed", resource.Context); + logger.LogDebug("The external resource {Resource} was already parsed", externalResource.Context); return false; } try { - var resolveResult = this.ResolveStream(key, resource.Context); + var resolvedStreamResult = this.ResolveStream(key, externalResource.Context); - if (resolveResult == null) + if (resolvedStreamResult == null) { - logger.LogWarning("The resolving key '{Key}' from context '{Context}' could not be resolved", key, resource.Context); + logger.LogWarning("The resolving key '{Key}' from context '{Context}' could not be resolved", key, externalResource.Context); return false; } - result.Stream = resolveResult.Item1; - result.Context = resource.Context; + result.Stream = resolvedStreamResult.Item1; + result.Context = externalResource.Context; - this.externalReferencesCache.Add(resource.Context); + this.externalReferencesCache.Add(externalResource.Context); return result.Stream?.Length > 0; } @@ -146,61 +163,118 @@ private bool TryResolve(string key, out (string Context, Stream Stream) result) private bool TryResolveContext(string resourceKey, out (string Context, string ResourceId) resolvedContextAndResource) { var referenceString = resourceKey.Split(['#'], StringSplitOptions.RemoveEmptyEntries); + + resolvedContextAndResource = new ValueTuple(referenceString[0], referenceString[1]); + + return true; + } - if (referenceString.Length == 2) + /// + /// Checks if the key is invalid for resolving from an external resource + /// + /// + /// The key to check. + /// + /// + /// true if the key is invalid; otherwise, false. + /// + /// + /// an invalid key is a key that: + /// starts with # + /// does not contain 1 # + /// contains more than 1 # + /// contains the # sign at most once + /// + private bool IsInvalidExternalResourceKey(string key) + { + if (string.IsNullOrEmpty(key)) { - resolvedContextAndResource = new ValueTuple(referenceString[0], referenceString[1]); + return true; } - else + + var firstIndex = key.IndexOf('#'); + + // check if starts with # + if (firstIndex == 0) { - resolvedContextAndResource = new ValueTuple("_", resourceKey); + return true; } - return true; - } + int lastIndex = key.LastIndexOf('#'); - /// - /// Checks if the key is invalid for resolving. - /// - /// The key to check. - /// true if the key is invalid; otherwise, false. - private bool IsInvalidKey(string key) => - string.IsNullOrEmpty(key) || key.StartsWith("#") || !key.Contains("#"); + // check if at most 1 # + return !(firstIndex != -1 && firstIndex == lastIndex); + } /// /// Resolves the appropriate stream based on the key and context. /// - /// The key representing the resource location. - /// The resource context path. - /// The resolved if found; otherwise, null. + /// + /// The key representing the resource location. + /// + /// + /// The resource context path. + /// + /// + /// The resolved if found; otherwise, null. + /// + /// + /// The following kinds of context are supported: + /// - http: or https: - either resolves to a known resource that is embedded + /// or tries to load from a local file that has the same name as the last part of the uri + /// + /// - file: a file on the filesystem + /// - pathmap: a mapping to a local file + /// - resource-name#referfence-name: the resource-name is a name of file in the same directory + /// as the current xmi file + /// private Tuple ResolveStream(string key, string context) { + if (resourceLoader.TryLoadKnownResource(key, out var knownResourceStream)) + { + return new Tuple(knownResourceStream, context); + } + if (Uri.TryCreate(key, UriKind.Absolute, out var uri)) { - if (uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps) + if (uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps || uri.Scheme == Uri.UriSchemeFtp) { - return this.ResolveRemoteResource(uri, context); + return this.ResolveRemoteResource(uri); } - else if (uri.Scheme == Uri.UriSchemeFile && File.Exists(uri.LocalPath)) + + if (uri.Scheme == Uri.UriSchemeFile && File.Exists(uri.LocalPath)) { return new Tuple(File.OpenRead(uri.LocalPath), uri.LocalPath) ; } } - return key.StartsWith("pathmap://") ? this.ResolvePathmapResource(key) : - File.Exists(context) ? new Tuple(File.OpenRead(context), context) : - null; + if (key.StartsWith("pathmap://")) + { + return this.ResolvePathmapResource(key); + } + + var localPath = Path.Combine(settings.LocalReferenceBasePath, context); + if (File.Exists(localPath)) + { + return new Tuple(File.OpenRead(localPath), context); + } + + return null; } /// /// Attempts to resolve a remote resource by treating it as a local file. /// - /// The URI of the remote resource. - /// The resource context. - /// The if the file exists locally; otherwise, null. - private Tuple ResolveRemoteResource(Uri uri, string context) + /// + /// The URI of the remote resource. + /// + /// + /// The if the file exists locally; otherwise, null. + /// + private Tuple ResolveRemoteResource(Uri uri) { - logger.LogWarning("The resource {Resource} is a reference to a remote resource which is unsupported by the Uml4Net library. An attempt to load the resource locally will be made", context); + logger.LogWarning("The resource {Resource} is a reference to a remote resource which is unsupported by the Uml4Net library. " + + "An attempt to load the resource locally from {LocalReferenceBasePath} will be made", uri.AbsoluteUri, settings.LocalReferenceBasePath); var fileName = Path.GetFileName(uri.AbsolutePath); @@ -212,8 +286,12 @@ private Tuple ResolveRemoteResource(Uri uri, string context) /// /// Resolves the file path of a resource identified by the specified key and returns a stream for it. /// - /// The key representing the resource path to resolve. - /// A stream of the resource if the file exists; otherwise, null. + /// + /// The key representing the resource path to resolve. + /// + /// + /// A stream of the resource if the file exists; otherwise, null. + /// private Tuple ResolvePathmapResource(string key) { if (key.IndexOf('#') is var index && index <= 0) @@ -223,12 +301,18 @@ private Tuple ResolvePathmapResource(string key) var substring = key.Substring(0, index); - if (settings.PathMaps.TryGetValue(substring, out var resolvedPathmap) - && File.Exists(resolvedPathmap)) + if (settings.PathMaps.TryGetValue(substring, out var resolvedPath)) { - return new Tuple(File.OpenRead(resolvedPathmap), resolvedPathmap); + if (File.Exists(resolvedPath)) + { + return new Tuple(File.OpenRead(resolvedPath), resolvedPath); + } + + logger.LogWarning("The Pathmap {Pathmap} is registered but the file cannot not be found {ResolvedPath}", substring, resolvedPath); } + logger.LogWarning("A Pathmap was encountered that was not registered: {Pathmap}", substring); + return default; } } diff --git a/uml4net.xmi/ReferenceResolver/IExternalReferenceResolver.cs b/uml4net.xmi/ReferenceResolver/IExternalReferenceResolver.cs index 24cc0cc8..006bf893 100644 --- a/uml4net.xmi/ReferenceResolver/IExternalReferenceResolver.cs +++ b/uml4net.xmi/ReferenceResolver/IExternalReferenceResolver.cs @@ -31,7 +31,12 @@ public interface IExternalReferenceResolver /// /// Asynchronously attempts to resolve external references and yields their context and stream. /// - /// An enumerable of tuples containing the context and stream of resolved references. - IEnumerable<(string Context, Stream Stream)> TryResolve(); + /// + /// the name of the XMI document for which the external references are being resolved. + /// + /// + /// A read-only List of tuples containing the context and stream of resolved references + /// + IReadOnlyList<(string Context, Stream Stream)> TryResolve(string documentName); } } diff --git a/uml4net.xmi/Resources/IResourceLoader.cs b/uml4net.xmi/Resources/IResourceLoader.cs new file mode 100644 index 00000000..7f5bc158 --- /dev/null +++ b/uml4net.xmi/Resources/IResourceLoader.cs @@ -0,0 +1,55 @@ +// ------------------------------------------------------------------------------------------------- +// +// +// Copyright 2019-2025 Starion Group S.A. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +// ------------------------------------------------------------------------------------------------ + +namespace uml4net.xmi.Resources +{ + using System.IO; + + /// + /// The isresponsible for loading embedded resources. + /// + public interface IResourceLoader + { + /// + /// Tries to load a know resource by its name and returns it as a + /// + /// + /// the name of the know resource + /// + /// + /// The resulting that contains the content of the know resource + /// + /// + /// true if the know resource could be loaded, false if not + /// + bool TryLoadKnownResource(string resourceName, out Stream resourceStream); + + /// + /// Load an embedded resource + /// + /// + /// The path of the embedded resource + /// + /// + /// a string containing the contents of the embedded resource + /// + string LoadEmbeddedResource(string path); + } +} diff --git a/uml4net.xmi/Resources/ResourceLoader.cs b/uml4net.xmi/Resources/ResourceLoader.cs new file mode 100644 index 00000000..3ee3b52a --- /dev/null +++ b/uml4net.xmi/Resources/ResourceLoader.cs @@ -0,0 +1,144 @@ +// ------------------------------------------------------------------------------------------------- +// +// +// Copyright 2019-2025 Starion Group S.A. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// +// ------------------------------------------------------------------------------------------------ + +namespace uml4net.xmi.Resources +{ + using System; + using System.Collections.Generic; + using System.IO; + using System.Reflection; + using System.Resources; + + /// + /// The isresponsible for loading embedded resources. + /// + public class ResourceLoader : IResourceLoader + { + /// + /// A dictionary of known (embedded) resources + /// + private readonly Dictionary knownExternalReferences = new Dictionary + { + { "http://www.omg.org/spec/UML/20161101/StandardProfile.xmi", "uml4net.xmi.Resources.StandardProfile.xmi" }, + { "https://www.omg.org/spec/UML/20161101/StandardProfile.xmi", "uml4net.xmi.Resources.StandardProfile.xmi" }, + { "StandardProfile.xmi", "uml4net.xmi.Resources.StandardProfile.xmi" }, + { "StandardProfile", "uml4net.xmi.Resources.StandardProfile.xmi" }, + + { "http://www.omg.org/spec/UML/20161101/UML.xmi", "uml4net.xmi.Resources.UML.xmi" }, + { "https://www.omg.org/spec/UML/20161101/UML.xmi", "uml4net.xmi.Resources.UML.xmi" }, + { "UML.xmi", "uml4net.xmi.Resources.UML.xmi" }, + { "UML", "uml4net.xmi.Resources.UML.xmi" }, + + { "http://www.omg.org/spec/UML/20131001/PrimitiveTypes.xmi", "uml4net.xmi.Resources.PrimitiveTypes.xmi" }, + { "https://www.omg.org/spec/UML/20131001/PrimitiveTypes.xmi", "uml4net.xmi.Resources.PrimitiveTypes.xmi" }, + { "PrimitiveTypes.xmi", "uml4net.xmi.Resources.UML.xmi" }, + { "PrimitiveTypes", "uml4net.xmi.Resources.UML.xmi" }, + }; + + /// + /// Try to load a know resource by its name and returns it as a + /// + /// + /// the name of the know resource + /// + /// + /// The resulting that contains the content of the know resource + /// + /// + /// true if the know resource could be loaded, false if not + /// + public bool TryLoadKnownResource(string resourceName, out Stream resourceStream) + { + if (string.IsNullOrEmpty(resourceName)) + { + throw new ArgumentNullException(nameof(resourceName)); + } + + if (Uri.TryCreate(resourceName, UriKind.Absolute, out var uri)) + { + resourceName = uri.GetLeftPart(UriPartial.Path); + + return this.TryLoadKnownEmbeddedResource(resourceName, out resourceStream); + } + + if (resourceName.IndexOf('#') is var index && index > 0) + { + resourceName = resourceName.Substring(0, index); + + return this.TryLoadKnownEmbeddedResource(resourceName, out resourceStream); + } + + resourceStream = null; + return false; + } + + /// + /// Try to load a know resource by its name and returns it as a + /// + /// + /// The name of the resource + /// + /// + /// The resulting that contains the content of the know resource + /// + /// + /// true if the know resource could be loaded, false if not + /// + private bool TryLoadKnownEmbeddedResource(string resourceName, out Stream resourceStream) + { + if (this.knownExternalReferences.TryGetValue(resourceName, out var resourcePath)) + { + var assembly = Assembly.GetExecutingAssembly(); + + resourceStream = assembly.GetManifestResourceStream(resourcePath); + + return true; + } + + resourceStream = null; + return false; + } + + /// + /// Load an embedded resource + /// + /// + /// The path of the embedded resource + /// + /// + /// a string containing the contents of the embedded resource + /// + public string LoadEmbeddedResource(string path) + { + if (string.IsNullOrEmpty(path)) + { + throw new ArgumentNullException(path); + } + + var assembly = Assembly.GetExecutingAssembly(); + + using var stream = assembly.GetManifestResourceStream(path); + + using var reader = new StreamReader(stream ?? throw new MissingManifestResourceException()); + + return reader.ReadToEnd(); + } + } +} diff --git a/uml4net.xmi/Resources/UML.xmi b/uml4net.xmi/Resources/UML.xmi new file mode 100644 index 00000000..cdb53736 --- /dev/null +++ b/uml4net.xmi/Resources/UML.xmi @@ -0,0 +1,18093 @@ + + + + UML.xmi: XMI representation of the metamodel for UML 2.5.1. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ownedParameter->forAll(p | + p.direction <> ParameterDirectionKind::inout implies node->select( + oclIsKindOf(ActivityParameterNode) and oclAsType(ActivityParameterNode).parameter = p)->size()= 1) + OCL + + + + + + + + + ownedParameter->forAll(p | +p.direction = ParameterDirectionKind::inout implies +let associatedNodes : Set(ActivityNode) = node->select( + oclIsKindOf(ActivityParameterNode) and oclAsType(ActivityParameterNode).parameter = p) in + associatedNodes->size()=2 and + associatedNodes->select(incoming->notEmpty())->size()<=1 and + associatedNodes->select(outgoing->notEmpty())->size()<=1 +) + + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + activity<>null implies source.containingActivity() = activity and target.containingActivity() = activity + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (redefiningElement.oclIsKindOf(ActivityEdge)) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + containedNode->forAll(activity = self.containingActivity()) and +containedEdge->forAll(activity = self.containingActivity()) + OCL + + + + + + + + + subgroup->closure(subgroup).containedNode->excludesAll(containedNode) and +superGroup->closure(superGroup).containedNode->excludesAll(containedNode) and +subgroup->closure(subgroup).containedEdge->excludesAll(containedEdge) and +superGroup->closure(superGroup).containedEdge->excludesAll(containedEdge) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (if superGroup<>null then superGroup.containingActivity() +else inActivity +endif) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (if inStructuredNode<>null then inStructuredNode.containingActivity() +else activity +endif) + OCL + + + + + + + + + + + + result = (redefiningElement.oclIsKindOf(ActivityNode)) + OCL + + + + + + + + + + + + + + + + + + + (incoming->notEmpty() and outgoing->isEmpty()) implies + (parameter.direction = ParameterDirectionKind::out or + parameter.direction = ParameterDirectionKind::inout or + parameter.direction = ParameterDirectionKind::return) + OCL + + + + + + + + + activity.ownedParameter->includes(parameter) + OCL + + + + + + + + + type = parameter.type + OCL + + + + + + + + + (outgoing->notEmpty() and incoming->isEmpty()) implies + (parameter.direction = ParameterDirectionKind::_'in' or + parameter.direction = ParameterDirectionKind::inout) + OCL + + + + + + + + + incoming->isEmpty() or outgoing->isEmpty() + OCL + + + + + + + + + + + + + + + + + + + + (not isExternal and represents.oclIsKindOf(Classifier) and superPartition->notEmpty()) implies +( + let representedClassifier : Classifier = represents.oclAsType(Classifier) in + superPartition.represents.oclIsKindOf(Classifier) and + let representedSuperClassifier : Classifier = superPartition.represents.oclAsType(Classifier) in + (representedSuperClassifier.oclIsKindOf(BehavioredClassifier) and representedClassifier.oclIsKindOf(Behavior) and + representedSuperClassifier.oclAsType(BehavioredClassifier).ownedBehavior->includes(representedClassifier.oclAsType(Behavior))) + or + (representedSuperClassifier.oclIsKindOf(Class) and representedSuperClassifier.oclAsType(Class).nestedClassifier->includes(representedClassifier)) + or + (Association.allInstances()->exists(a | a.memberEnd->exists(end1 | end1.isComposite and end1.type = representedClassifier and + a.memberEnd->exists(end2 | end1<>end2 and end2.type = representedSuperClassifier)))) +) + OCL + + + + + + + + + (represents.oclIsKindOf(Property) and superPartition->notEmpty()) implies +( + (superPartition.represents.oclIsKindOf(Classifier) and represents.owner = superPartition.represents) or + (superPartition.represents.oclIsKindOf(Property) and represents.owner = superPartition.represents.oclAsType(Property).type) +) + OCL + + + + + + + + + (represents.oclIsKindOf(Property) and superPartition->notEmpty() and superPartition.represents.oclIsKindOf(Classifier)) implies +( + let representedClassifier : Classifier = superPartition.represents.oclAsType(Classifier) + in + superPartition.subpartition->reject(isExternal)->forAll(p | + p.represents.oclIsKindOf(Property) and p.owner=representedClassifier) +) + OCL + + + + + + + + + isDimension implies superPartition->isEmpty() + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + (source.oclIsKindOf(ObjectNode) implies source.oclAsType(ObjectNode).isControlType) and +(target.oclIsKindOf(ObjectNode) implies target.oclAsType(ObjectNode).isControlType) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + (decisionInput<>null and decisionInputFlow=null and incoming->exists(oclIsKindOf(ControlFlow))) implies + decisionInput.inputParameters()->isEmpty() + OCL + + + + + + + + + let allEdges: Set(ActivityEdge) = incoming->union(outgoing) in +let allRelevantEdges: Set(ActivityEdge) = if decisionInputFlow->notEmpty() then allEdges->excluding(decisionInputFlow) else allEdges endif in +allRelevantEdges->forAll(oclIsKindOf(ControlFlow)) or allRelevantEdges->forAll(oclIsKindOf(ObjectFlow)) + + OCL + + + + + + + + + incoming->includes(decisionInputFlow) + OCL + + + + + + + + + (decisionInput<>null and decisionInputFlow<>null and incoming->forAll(oclIsKindOf(ObjectFlow))) implies + decisionInput.inputParameters()->size()=2 + OCL + + + + + + + + + (incoming->size() = 1 or incoming->size() = 2) and outgoing->size() > 0 + OCL + + + + + + + + + (decisionInput<>null and decisionInputFlow<>null and incoming->exists(oclIsKindOf(ControlFlow))) implies + decisionInput.inputParameters()->size()=1 + OCL + + + + + + + + + decisionInput<>null implies + (decisionInput.ownedParameter->forAll(par | + par.direction <> ParameterDirectionKind::out and + par.direction <> ParameterDirectionKind::inout ) and + decisionInput.ownedParameter->one(par | + par.direction <> ParameterDirectionKind::return)) + + OCL + + + + + + + + + (decisionInput<>null and decisionInputFlow=null and incoming->forAll(oclIsKindOf(ObjectFlow))) implies + decisionInput.inputParameters()->size()=1 + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + handlerBody.incoming->isEmpty() and handlerBody.outgoing->isEmpty() and exceptionInput.incoming->isEmpty() + OCL + + + + + + + + + (protectedNode.oclIsKindOf(Action) and protectedNode.oclAsType(Action).output->notEmpty()) implies +( + handlerBody.oclIsKindOf(Action) and + let protectedNodeOutput : OrderedSet(OutputPin) = protectedNode.oclAsType(Action).output, + handlerBodyOutput : OrderedSet(OutputPin) = handlerBody.oclAsType(Action).output in + protectedNodeOutput->size() = handlerBodyOutput->size() and + Sequence{1..protectedNodeOutput->size()}->forAll(i | + handlerBodyOutput->at(i).type.conformsTo(protectedNodeOutput->at(i).type) and + handlerBodyOutput->at(i).isOrdered=protectedNodeOutput->at(i).isOrdered and + handlerBodyOutput->at(i).compatibleWith(protectedNodeOutput->at(i))) +) + OCL + + + + + + + + + handlerBody.oclIsKindOf(Action) and +let inputs: OrderedSet(InputPin) = handlerBody.oclAsType(Action).input in +inputs->size()=1 and inputs->first()=exceptionInput + OCL + + + + + + + + + let nodes:Set(ActivityNode) = handlerBody.oclAsType(Action).allOwnedNodes() in +nodes.outgoing->forAll(nodes->includes(target)) and +nodes.incoming->forAll(nodes->includes(source)) + OCL + + + + + + + + + handlerBody.owner=protectedNode.owner + OCL + + + + + + + + + exceptionInput.type=null or +exceptionType->forAll(conformsTo(exceptionInput.type.oclAsType(Classifier))) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + outgoing->isEmpty() + OCL + + + + + + + + + + + + + + + + + + + + + let allEdges : Set(ActivityEdge) = incoming->union(outgoing) in +allEdges->forAll(oclIsKindOf(ControlFlow)) or allEdges->forAll(oclIsKindOf(ObjectFlow)) + + OCL + + + + + + + + + incoming->size()=1 + OCL + + + + + + + + + + + + + + + incoming->isEmpty() + OCL + + + + + + + + + outgoing->forAll(oclIsKindOf(ControlFlow)) + OCL + + + + + + + + + + + + + + + interruptingEdge->forAll(edge | + node->includes(edge.source) and node->excludes(edge.target) and edge.target.containingActivity() = inActivity) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + outgoing->size() = 1 + OCL + + + + + + + + + if incoming->exists(oclIsKindOf(ObjectFlow)) then outgoing->forAll(oclIsKindOf(ObjectFlow)) +else outgoing->forAll(oclIsKindOf(ControlFlow)) +endif + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + outgoing->size()=1 + OCL + + + + + + + + + let allEdges : Set(ActivityEdge) = incoming->union(outgoing) in +allEdges->forAll(oclIsKindOf(ControlFlow)) or allEdges->forAll(oclIsKindOf(ObjectFlow)) + + OCL + + + + + + + + + + + + + + + selection<>null implies + selection.inputParameters()->size()=1 and + selection.inputParameters()->forAll(not isUnique and is(0,*)) and + selection.outputParameters()->size()=1 + OCL + + + + + + + + + not (source.oclIsKindOf(ExecutableNode) or target.oclIsKindOf(ExecutableNode)) + OCL + + + + + + + + + transformation<>null implies + transformation.inputParameters()->size()=1 and + transformation.outputParameters()->size()=1 + OCL + + + + + + + + + selection<>null implies source.oclIsKindOf(ObjectNode) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + not (isMulticast and isMultireceive) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + selection<>null implies + selection.inputParameters()->size()=1 and + selection.inputParameters()->forAll(p | not p.isUnique and p.is(0,*) and self.type.conformsTo(p.type)) and + selection.outputParameters()->size()=1 and + selection.inputParameters()->forAll(p | self.type.conformsTo(p.type)) + + OCL + + + + + + + + + (selection<>null) = (ordering=ObjectNodeOrderingKind::ordered) + OCL + + + + + + + + + (not isControlType) implies incoming->union(outgoing)->forAll(oclIsKindOf(ObjectFlow)) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (if scope<>null then scope.allOwnedNodes()->includes(a) +else a.containingActivity()=activityScope +endif) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + expr = null implies (observation->size() = 1 and observation->forAll(oclIsKindOf(DurationObservation))) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + if (constrainedElement->size() = 2) + then (firstEvent->size() = 2) else (firstEvent->size() = 0) +endif + OCL + + + + + + + + + constrainedElement->size() = 1 or constrainedElement->size()=2 + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + if (event->size() = 2) + then (firstEvent->size() = 2) else (firstEvent->size() = 0) +endif + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (value) + OCL + + + + + + + + + + + + + + + result = (true) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (value) + OCL + + + + + + + + + + + + + + + result = (true) + OCL + + + + + + + + + + + + + + + + + + + + + result = (true) + OCL + + + + + + + + + + + + + + + result = (true) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (true) + OCL + + + + + + + + + + + + + + + result = (value) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (true) + OCL + + + + + + + + + + + + + + + result = (value) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (true) + OCL + + + + + + + + + + + + + + + result = (value) + OCL + + + + + + + + + + + + + + + + + + + + + + + + language->notEmpty() implies (_'body'->size() = language->size()) + OCL + + + + + + + + + behavior <> null implies + behavior.ownedParameter->select(direction=ParameterDirectionKind::return)->size() = 1 + OCL + + + + + + + + + behavior <> null implies behavior.ownedParameter->forAll(not isStream and +(direction=ParameterDirectionKind::in or direction=ParameterDirectionKind::return)) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (false) + OCL + + + + + + + + + + + + + + + self.isIntegral() + OCL + + + + + + result = (false) + OCL + + + + + + + + + + + + + + + result = (false) + OCL + + + + + + self.isIntegral() + OCL + + + + + + + + + + + + + + + result = (if behavior = null then + null +else + behavior.ownedParameter->first() +endif) + OCL + + + + + + + + + + + + + + + self.isIntegral() + OCL + + + + + + result = (0) + OCL + + + + + + + + + + + + + + + + + + operand->forAll (oclIsKindOf (LiteralString)) + OCL + + + + + + + + + if subExpression->notEmpty() then operand->isEmpty() else operand->notEmpty() endif + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (if subExpression->notEmpty() +then subExpression->iterate(se; stringValue: String = '' | stringValue.concat(se.stringValue())) +else operand->iterate(op; stringValue: String = '' | stringValue.concat(op.stringValue())) +endif) + OCL + + + + + + + + + + + + + + + + + + constrainedElement->size() = 1 + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + expr = null implies (observation->size() = 1 and observation->forAll(oclIsKindOf(TimeObservation))) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (null) + OCL + + + + + + + + + + + + + + + result = (null) + OCL + + + + + + + + + + + + + + + + result = (self.oclIsKindOf(p.oclType()) and (p.oclIsKindOf(TypedElement) implies +self.type.conformsTo(p.oclAsType(TypedElement).type))) + OCL + + + + + + + + + + + + + + + result = (false) + OCL + + + + + + + + + + + + + + result = (false) + OCL + + + + + + + + + + + + + + result = (null) + OCL + + + + + + + + + + + + + + + result = (null) + OCL + + + + + + + + + + + + + + + result = (null) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Association.allInstances()->forAll( a | + a.memberEnd->collect(type)->includes(self) implies + ( + a.memberEnd->size() = 2 and + let actorEnd : Property = a.memberEnd->any(type = self) in + actorEnd.opposite.class.oclIsKindOf(UseCase) or + ( actorEnd.opposite.class.oclIsKindOf(Class) and not + actorEnd.opposite.class.oclIsKindOf(Behavior)) + ) + ) + OCL + + + + + + + + + name->notEmpty() + OCL + + + + + + + + + + + + + + + extensionLocation->forAll (xp | extendedCase.extensionPoint->includes(xp)) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + name->notEmpty () + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Association.allInstances()->forAll(a | a.memberEnd.type->includes(self) implies a.memberEnd->size() = 2) + OCL + + + + + + + + + Association.allInstances()->forAll(a | a.memberEnd.type->includes(self) implies + ( + let usecases: Set(UseCase) = a.memberEnd.type->select(oclIsKindOf(UseCase))->collect(oclAsType(UseCase))->asSet() in + usecases->size() > 1 implies usecases->collect(subject)->size() > 1 + ) +) + OCL + + + + + + + + + not allIncludedUseCases()->includes(self) + OCL + + + + + + + + + name -> notEmpty () + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (self.include.addition->union(self.include.addition->collect(uc | uc.allIncludedUseCases()))->asSet()) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + parents()->select(oclIsKindOf(Association)).oclAsType(Association)->forAll(p | p.memberEnd->size() = self.memberEnd->size()) + OCL + + + + + + + + + Sequence{1..memberEnd->size()}-> + forAll(i | general->select(oclIsKindOf(Association)).oclAsType(Association)-> + forAll(ga | self.memberEnd->at(i).type.conformsTo(ga.memberEnd->at(i).type))) + OCL + + + + + + + + + memberEnd->exists(aggregation <> AggregationKind::none) implies (memberEnd->size() = 2 and memberEnd->exists(aggregation = AggregationKind::none)) + OCL + + + + + + + + + memberEnd->size() > 2 implies ownedEnd->includesAll(memberEnd) + OCL + + + + + + memberEnd->forAll(type->notEmpty()) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (memberEnd->collect(type)->asSet()) + OCL + + + + + + + + + + + + + + + + + + self.endType()->excludes(self) and self.endType()->collect(et|et.oclAsType(Classifier).allParents())->flatten()->excludes(self) + OCL + + + + + + + + + ownedAttribute->intersection(ownedEnd)->isEmpty() + OCL + + + + + + + + + + + + + + + + not isActive implies (ownedReception->isEmpty() and classifierBehavior = null) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (Extension.allInstances()->select(ext | + let endTypes : Sequence(Classifier) = ext.memberEnd->collect(type.oclAsType(Classifier)) in + endTypes->includes(self) or endTypes.allParents()->includes(self) )) + OCL + + + + + + + + + + + + + + + + result = (self.general()->select(oclIsKindOf(Class))->collect(oclAsType(Class))->asSet()) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + roleBinding->collect(client)->forAll(ne1, ne2 | + ne1.oclIsKindOf(ConnectableElement) and ne2.oclIsKindOf(ConnectableElement) and + let ce1 : ConnectableElement = ne1.oclAsType(ConnectableElement), ce2 : ConnectableElement = ne2.oclAsType(ConnectableElement) in + ce1.structuredClassifier = ce2.structuredClassifier) +and + roleBinding->collect(supplier)->forAll(ne1, ne2 | + ne1.oclIsKindOf(ConnectableElement) and ne2.oclIsKindOf(ConnectableElement) and + let ce1 : ConnectableElement = ne1.oclAsType(ConnectableElement), ce2 : ConnectableElement = ne2.oclAsType(ConnectableElement) in + ce1.collaboration = ce2.collaboration) + OCL + + + + + + + + + type.collaborationRole->forAll(role | roleBinding->exists(rb | rb.supplier->includes(role))) + OCL + + + + + + + + + type.ownedConnector->forAll(connector | + let rolesConnectedInCollab : Set(ConnectableElement) = connector.end.role->asSet(), + relevantBindings : Set(Dependency) = roleBinding->select(rb | rb.supplier->intersection(rolesConnectedInCollab)->notEmpty()), + boundRoles : Set(ConnectableElement) = relevantBindings->collect(client.oclAsType(ConnectableElement))->asSet(), + contextClassifier : StructuredClassifier = boundRoles->any(true).structuredClassifier->any(true) in + contextClassifier.ownedConnector->exists( correspondingConnector | + correspondingConnector.end.role->forAll( role | boundRoles->includes(role) ) + and (connector.type->notEmpty() and correspondingConnector.type->notEmpty()) implies connector.type->forAll(conformsTo(correspondingConnector.type)) ) +) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + nestedClassifier->isEmpty() + OCL + + + + + + + + + nestingClass <> null implies packagedElement->isEmpty() + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (let ris : Set(Interface) = allRealizedInterfaces(), + realizingClassifiers : Set(Classifier) = self.realization.realizingClassifier->union(self.allParents()->collect(realization.realizingClassifier))->asSet(), + allRealizingClassifiers : Set(Classifier) = realizingClassifiers->union(realizingClassifiers.allParents())->asSet(), + realizingClassifierInterfaces : Set(Interface) = allRealizingClassifiers->iterate(c; rci : Set(Interface) = Set{} | rci->union(c.allRealizedInterfaces())), + ports : Set(Port) = self.ownedPort->union(allParents()->collect(ownedPort))->asSet(), + providedByPorts : Set(Interface) = ports.provided->asSet() +in ris->union(realizingClassifierInterfaces) ->union(providedByPorts)->asSet()) + OCL + + + + + + + + + + + + + + + + result = (let uis : Set(Interface) = allUsedInterfaces(), + realizingClassifiers : Set(Classifier) = self.realization.realizingClassifier->union(self.allParents()->collect(realization.realizingClassifier))->asSet(), + allRealizingClassifiers : Set(Classifier) = realizingClassifiers->union(realizingClassifiers.allParents())->asSet(), + realizingClassifierInterfaces : Set(Interface) = allRealizingClassifiers->iterate(c; rci : Set(Interface) = Set{} | rci->union(c.allUsedInterfaces())), + ports : Set(Port) = self.ownedPort->union(allParents()->collect(ownedPort))->asSet(), + usedByPorts : Set(Interface) = ports.required->asSet() +in uis->union(realizingClassifierInterfaces)->union(usedByPorts)->asSet() +) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (ConnectorEnd.allInstances()->select(role = self)) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + type<>null implies + let noOfEnds : Integer = end->size() in + (type.memberEnd->size() = noOfEnds) and Sequence{1..noOfEnds}->forAll(i | end->at(i).role.type.conformsTo(type.memberEnd->at(i).type)) + OCL + + + + + + + + + structuredClassifier <> null +and + end->forAll( e | structuredClassifier.allRoles()->includes(e.role) +or + e.role.oclIsKindOf(Port) and structuredClassifier.allRoles()->includes(e.partWithPort)) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (if end->exists( + role.oclIsKindOf(Port) + and partWithPort->isEmpty() + and not role.oclAsType(Port).isBehavior) +then ConnectorKind::delegation +else ConnectorKind::assembly +endif) + OCL + + + + + + + + + + + + + + + + partWithPort->notEmpty() implies + (role.oclIsKindOf(Port) and partWithPort.type.oclAsType(Namespace).member->includes(role)) + OCL + + + + + + + + + (role.oclIsKindOf(Port) and role.owner = connector.owner) implies partWithPort->isEmpty() + OCL + + + + + + + + + self.compatibleWith(definingEnd) + OCL + + + + + + + + + partWithPort->notEmpty() implies not partWithPort.oclIsKindOf(Port) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (if connector.type = null +then + null +else + let index : Integer = connector.end->indexOf(self) in + connector.type.memberEnd->at(index) +endif) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (ownedAttribute->select(oclIsKindOf(Port))->collect(oclAsType(Port))->asOrderedSet()) + OCL + + + + + + + + + + + + + + + + + + + aggregation = AggregationKind::composite + OCL + + + + + + + + + type.oclIsKindOf(Interface) implies defaultValue->isEmpty() + OCL + + + + + + + + + owner = encapsulatedClassifier + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (if isConjugated then basicRequired() else basicProvided() endif) + OCL + + + + + + + + + + + + + + + + result = (if isConjugated then basicProvided() else basicRequired() endif) + OCL + + + + + + + + + + + + + + + result = (if type.oclIsKindOf(Interface) +then type.oclAsType(Interface)->asSet() +else type.oclAsType(Classifier).allRealizedInterfaces() +endif) + OCL + + + + + + + + + + + + + + + result = ( type.oclAsType(Classifier).allUsedInterfaces() ) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (ownedAttribute->select(isComposite)) + OCL + + + + + + + + + + + + + + + result = (allFeatures()->select(oclIsKindOf(ConnectableElement))->collect(oclAsType(ConnectableElement))->asSet()) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + exit->forAll(kind = PseudostateKind::exitPoint) + OCL + + + + + + + + + entry->forAll(kind = PseudostateKind::entryPoint) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + redefiningElement.isRedefinitionContextValid(self) + OCL + + + + + + result = redefiningElement.oclIsKindOf(ConnectionPointReference) + OCL + + + + + + + + + + + + + + + + + + + exit->isEmpty() + OCL + + + + + + + + + outgoing->size() = 0 + OCL + + + + + + + + + region->size() = 0 + OCL + + + + + + + + + submachine->isEmpty() + OCL + + + + + + + + + entry->isEmpty() + OCL + + + + + + + + + doActivity->isEmpty() + OCL + + + + + + + + + + + + + redefiningElement.isRedefinitionContextValid(self) + OCL + + + + + + result = redefiningElement.oclIsKindOf(FinalState) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + _'context' <> null and specification = null + OCL + + + + + + + + + region->forAll (r | r.subvertex->forAll (v | v.oclIsKindOf(Pseudostate) implies +((v.oclAsType(Pseudostate).kind <> PseudostateKind::deepHistory) and (v.oclAsType(Pseudostate).kind <> PseudostateKind::shallowHistory)))) + + OCL + + + + + + + + + region->forAll(r | r.subvertex->forAll(v | v.oclIsKindOf(State) implies +(v.oclAsType(State).entry->isEmpty() and v.oclAsType(State).exit->isEmpty() and v.oclAsType(State).doActivity->isEmpty()))) + + OCL + + + + + + + + + region->forAll(r | r.transition->forAll(t | t.oclIsTypeOf(ProtocolTransition))) + OCL + + + + + + + + + + + + + + + + + + + + + + + + if (referred()->notEmpty() and containingStateMachine()._'context'->notEmpty()) then + containingStateMachine()._'context'.oclAsType(BehavioredClassifier).allFeatures()->includesAll(referred()) +else true endif + OCL + + + + + + + + + effect = null + OCL + + + + + + + + + container.belongsToPSM() + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (trigger->collect(event)->select(oclIsKindOf(CallEvent))->collect(oclAsType(CallEvent).operation)->asSet()) + OCL + + + + + + + + + + + + + + + + + + + (kind = PseudostateKind::fork) implies + +-- for any pair of outgoing transitions there exists an orthogonal state which contains the targets of these transitions +-- such that these targets belong to different regions of that orthogonal state + +outgoing->forAll(t1:Transition, t2:Transition | let contState:State = containingStateMachine().LCAState(t1.target, t2.target) in + ((contState <> null) and (contState.region + ->exists(r1:Region, r2: Region | (r1 <> r2) and t1.target.isContainedInRegion(r1) and t2.target.isContainedInRegion(r2))))) + + OCL + + + + + + + + + (kind = PseudostateKind::choice) implies (incoming->size() >= 1 and outgoing->size() >= 1) + + OCL + + + + + + + + + (kind = PseudostateKind::initial) implies (outgoing.guard = null and outgoing.trigger->isEmpty()) + OCL + + + + + + + + + (kind = PseudostateKind::join) implies (outgoing->size() = 1 and incoming->size() >= 2) + + OCL + + + + + + + + + (kind = PseudostateKind::junction) implies (incoming->size() >= 1 and outgoing->size() >= 1) + + OCL + + + + + + + + + ((kind = PseudostateKind::deepHistory) or (kind = PseudostateKind::shallowHistory)) implies (outgoing->size() <= 1) + + OCL + + + + + + + + + (kind = PseudostateKind::initial) implies (outgoing->size() <= 1) + OCL + + + + + + + + + (kind = PseudostateKind::fork) implies (incoming->size() = 1 and outgoing->size() >= 2) + + OCL + + + + + + + + + (kind = PseudostateKind::join) implies + +-- for any pair of incoming transitions there exists an orthogonal state which contains the source vetices of these transitions +-- such that these source vertices belong to different regions of that orthogonal state + +incoming->forAll(t1:Transition, t2:Transition | let contState:State = containingStateMachine().LCAState(t1.source, t2.source) in + ((contState <> null) and (contState.region + ->exists(r1:Region, r2: Region | (r1 <> r2) and t1.source.isContainedInRegion(r1) and t2.source.isContainedInRegion(r2))))) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + redefiningElement.isRedefinitionContextValid(self) + OCL + + + + + + result = (redefiningElement.oclIsKindOf(Pseudostate) and +redefiningElement.oclAsType(Pseudostate).kind = kind) + OCL + + + + + + + + + + + + + + + + + + + self.subvertex->select (oclIsKindOf(Pseudostate))->collect(oclAsType(Pseudostate))-> + select(kind = PseudostateKind::deepHistory)->size() <= 1 + + OCL + + + + + + + + + subvertex->select(oclIsKindOf(Pseudostate))->collect(oclAsType(Pseudostate))-> + select(kind = PseudostateKind::shallowHistory)->size() <= 1 + + OCL + + + + + + + + + (stateMachine <> null implies state = null) and (state <> null implies stateMachine = null) + OCL + + + + + + + + + self.subvertex->select (oclIsKindOf(Pseudostate))->collect(oclAsType(Pseudostate))-> + select(kind = PseudostateKind::initial)->size() <= 1 + + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (if stateMachine <> null +then + stateMachine.oclIsKindOf(ProtocolStateMachine) +else + state <> null implies state.container.belongsToPSM() +endif ) + OCL + + + + + + + + + + + + + + result = (if stateMachine = null +then + state.containingStateMachine() +else + stateMachine +endif) + OCL + + + + + + + + + + + + + + result = true + OCL + + + + + + redefiningElement.isRedefinitionContextValid(self) + OCL + + + + + + + + + + + + + + + + result = (if redefinedElement.oclIsKindOf(Region) then + let redefinedRegion : Region = redefinedElement.oclAsType(Region) in + if stateMachine->isEmpty() then + -- the Region is owned by a State + (state.redefinedState->notEmpty() and state.redefinedState.region->includes(redefinedRegion)) + else -- the region is owned by a StateMachine + (stateMachine.extendedStateMachine->notEmpty() and + stateMachine.extendedStateMachine->exists(sm : StateMachine | + sm.region->includes(redefinedRegion))) + endif +else + false +endif) + OCL + + + + + + + + + + + + + + + + result = containingStateMachine() + OCL + + + + + + + + + + + + + + + + connectionPoint->forAll(kind = PseudostateKind::entryPoint or kind = PseudostateKind::exitPoint) + OCL + + + + + + + + + isSubmachineState implies connection->notEmpty( ) + OCL + + + + + + + + + connectionPoint->notEmpty() implies isComposite + OCL + + + + + + + + + self.isSubmachineState implies (self.connection->forAll (cp | + cp.entry->forAll (ps | ps.stateMachine = self.submachine) and + cp.exit->forAll (ps | ps.stateMachine = self.submachine))) + OCL + + + + + + + + + isComposite implies not isSubmachineState + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (container.containingStateMachine()) + OCL + + + + + + + + + + + + + result = (region->notEmpty()) + OCL + + + + + + + + + + + + + + + + result = (redefiningElement.oclIsTypeOf(State) and + let redefiningState : State = redefiningElement.oclAsType(State) in + submachine <> null implies (redefiningState.submachine <> null and + redefiningState.submachine.extendedStateMachine->includes(submachine))) + OCL + + + + + + redefiningElement.isRedefinitionContextValid(self) + OCL + + + + + + + + + + + + + + + + result = (region->size () > 1) + OCL + + + + + + + + + + + + + + + result = ((region->isEmpty()) and not isSubmachineState()) + OCL + + + + + + + + + + + + + + + result = (submachine <> null) + OCL + + + + + + + + + + + + + + + + + + connectionPoint->forAll (kind = PseudostateKind::entryPoint or kind = PseudostateKind::exitPoint) + OCL + + + + + + + + + _'context' <> null implies not _'context'.oclIsKindOf(Interface) + OCL + + + + + + + + + specification <> null implies connectionPoint->isEmpty() + OCL + + + + + + + + + specification <> null implies ( _'context' <> null and specification.featuringClassifier->exists(c | c = _'context')) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (if ancestor(s1, s2) then + s2.container +else + if ancestor(s2, s1) then + s1.container + else + LCA(s1.container.state, s2.container.state) + endif +endif) + OCL + + + + + + + + + + + + + + result = (if (s2 = s1) then + true +else + if s1.container.stateMachine->notEmpty() then + true + else + if s2.container.stateMachine->notEmpty() then + false + else + ancestor(s1, s2.container.state) + endif + endif +endif ) + OCL + + + + + + + + + + + + + + + + + result = true + OCL + + + + + + + + + + + + + + + + result = (redefinedElement.oclIsKindOf(StateMachine) and + let parentContext : BehavioredClassifier = + redefinedElement.oclAsType(StateMachine).context in + if context = null then + parentContext = null and self.allParents()→includes(redefinedElement) + else + parentContext <> null and context.allParents()->includes(parentContext) + endif) + OCL + + + + + + + + + + + + + + + result = (if v2.oclIsTypeOf(State) and ancestor(v1, v2) then + v2.oclAsType(State) +else if v1.oclIsTypeOf(State) and ancestor(v2, v1) then + v1.oclAsType(State) +else if (v1.container.state->isEmpty() or v2.container.state->isEmpty()) then + null.oclAsType(State) +else LCAState(v1.container.state, v2.container.state) +endif endif endif) + OCL + + + + + + + + + + + + + + + + + + (kind = TransitionKind::external) implies + not (source.oclIsKindOf(Pseudostate) and source.oclAsType(Pseudostate).kind = PseudostateKind::entryPoint) + OCL + + + + + + + + + (target.oclIsKindOf(Pseudostate) and target.oclAsType(Pseudostate).kind = PseudostateKind::join) implies (guard = null and trigger->isEmpty()) + OCL + + + + + + + + + (kind = TransitionKind::internal) implies + (source.oclIsKindOf (State) and source = target) + OCL + + + + + + + + + source.oclIsKindOf(Pseudostate) and (source.oclAsType(Pseudostate).kind <> PseudostateKind::initial) implies trigger->isEmpty() + OCL + + + + + + + + + (target.oclIsKindOf(Pseudostate) and target.oclAsType(Pseudostate).kind = PseudostateKind::join) implies (source.oclIsKindOf(State)) + OCL + + + + + + + + + (source.oclIsKindOf(Pseudostate) and source.oclAsType(Pseudostate).kind = PseudostateKind::fork) implies (target.oclIsKindOf(State)) + OCL + + + + + + + + + (kind = TransitionKind::local) implies + ((source.oclIsKindOf (State) and source.oclAsType(State).isComposite) or + (source.oclIsKindOf (Pseudostate) and source.oclAsType(Pseudostate).kind = PseudostateKind::entryPoint)) + OCL + + + + + + + + + (source.oclIsKindOf(Pseudostate) and container.stateMachine->notEmpty()) implies + trigger->isEmpty() + + OCL + + + + + + + + + (source.oclIsKindOf(Pseudostate) and source.oclAsType(Pseudostate).kind = PseudostateKind::fork) implies (guard = null and trigger->isEmpty()) + OCL + + + + + + + + + let stateMachine = self.containingStateMachine() in +source.containingStateMachine() = stateMachine and +target.containingStateMachine() = stateMachine + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (container.containingStateMachine()) + OCL + + + + + + + + + + + + + + result = (redefiningElement.oclIsKindOf(Transition) and + redefiningElement.oclAsType(Transition).source.redefinedTransition = source) + OCL + + + + + + redefiningElement.isRedefinitionContextValid(self) + OCL + + + + + + + + + + + + + + + + result = containingStateMachine() + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (if container <> null +then +-- the container is a region + container.containingStateMachine() +else + if (self.oclIsKindOf(Pseudostate)) and ((self.oclAsType(Pseudostate).kind = PseudostateKind::entryPoint) or (self.oclAsType(Pseudostate).kind = PseudostateKind::exitPoint)) then + self.oclAsType(Pseudostate).stateMachine + else + if (self.oclIsKindOf(ConnectionPointReference)) then + self.oclAsType(ConnectionPointReference).state.containingStateMachine() -- no other valid cases possible + else + null + endif + endif +endif + +) + OCL + + + + + + + + + + + + + result = (Transition.allInstances()->select(target=self)) + OCL + + + + + + + + + + + + + + + + result = (Transition.allInstances()->select(source=self)) + OCL + + + + + + + + + + + + + + + result = (if not s.isComposite() or container->isEmpty() then + false +else + if container.state = s then + true + else + container.state.isContainedInState(s) + endif +endif) + OCL + + + + + + + + + + + + + + + result = (if (container = r) then + true +else + if (r.state->isEmpty()) then + false + else + container.state.isContainedInRegion(r) + endif +endif) + OCL + + + + + + + + + + + + + + + + result = containingStateMachine() + OCL + + + + + + + + + + + + + + redefiningElement.isRedefinitionContextValid(self) + OCL + + + + + + result = (redefinedElement.oclIsKindOf(Vertex) and + owner.oclAsType(RedefinableElement).redefinedElement->includes(redefinedElement.owner)) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + classifierBehavior->notEmpty() implies classifierBehavior.specification->isEmpty() + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ownedAttribute->forAll(isReadOnly) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (enumeration) + OCL + + + + + + + + + + + + + + + + feature->forAll(visibility = VisibilityKind::public) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + name = signal.name + OCL + + + + + + + + + signal.ownedAttribute->size() = ownedParameter->size() and +Sequence{1..signal.ownedAttribute->size()}->forAll( i | + ownedParameter->at(i).direction = ParameterDirectionKind::_'in' and + ownedParameter->at(i).name = signal.ownedAttribute->at(i).name and + ownedParameter->at(i).type = signal.ownedAttribute->at(i).type and + ownedParameter->at(i).lowerBound() = signal.ownedAttribute->at(i).lowerBound() and + ownedParameter->at(i).upperBound() = signal.ownedAttribute->at(i).upperBound() +) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + metaclassEnd()->notEmpty() and metaclassEnd().type.oclIsKindOf(Class) + OCL + + + + + + + + + memberEnd->size() = 2 + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (ownedEnd.lowerBound() = 1) + OCL + + + + + + + + + + + + + + + result = (metaclassEnd().type.oclAsType(Class)) + OCL + + + + + + + + + + + + result = (memberEnd->reject(p | ownedEnd->includes(p.oclAsType(ExtensionEnd)))->any(true)) + OCL + + + + + + + + + + + + + + + + (lowerBound() = 0 or lowerBound() = 1) and upperBound() = 1 + OCL + + + + + + + + + self.aggregation = AggregationKind::composite + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + result = (if lowerValue=null then 0 else lowerValue.integerValue() endif) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + packagedElement->forAll(e | e.visibility<> null implies e.visibility = VisibilityKind::public or e.visibility = VisibilityKind::private) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (let ownedPackages : Bag(Package) = ownedMember->select(oclIsKindOf(Package))->collect(oclAsType(Package)) in + ownedStereotype->union(ownedPackages.allApplicableStereotypes())->flatten()->asSet() +) + OCL + + + + + + + + + + + + + + + result = (if self.oclIsKindOf(Profile) then + self.oclAsType(Profile) +else + self.namespace.oclAsType(Package).containingProfile() +endif) + OCL + + + + + + + + + + + + + + + member->includes(el) + OCL + + + + + + result = (ownedMember->includes(el) or +(elementImport->select(ei|ei.importedElement = VisibilityKind::public)->collect(importedElement.oclAsType(NamedElement))->includes(el)) or +(packageImport->select(visibility = VisibilityKind::public)->collect(importedPackage.member->includes(el))->notEmpty())) + OCL + + + + + + + + + + + + + + + + result = (false) + OCL + + + + + + + + + + + + + + + result = (packagedElement->select(oclIsKindOf(Package))->collect(oclAsType(Package))->asSet()) + OCL + + + + + + + + + + + + + + + + result = (packagedElement->select(oclIsKindOf(Stereotype))->collect(oclAsType(Stereotype))->asSet()) + OCL + + + + + + + + + + + + + + + + result = (packagedElement->select(oclIsKindOf(Type))->collect(oclAsType(Type))->asSet()) + OCL + + + + + + + + + + + + + + + result = (member->select( m | m.oclIsKindOf(PackageableElement) and self.makesVisible(m))->collect(oclAsType(PackageableElement))->asSet()) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + metaclassReference.importedElement-> + select(c | c.oclIsKindOf(Classifier) and + (c.oclAsType(Classifier).allParents()->collect(namespace)->includes(self)))->isEmpty() +and +packagedElement-> + select(oclIsKindOf(Classifier))->collect(oclAsType(Classifier).allParents())-> + intersection(metaclassReference.importedElement->select(oclIsKindOf(Classifier))->collect(oclAsType(Classifier)))->isEmpty() + OCL + + + + + + + + + metamodelReference.importedPackage.elementImport.importedElement.allOwningPackages()-> + union(metaclassReference.importedElement.allOwningPackages() )->notEmpty() + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ownedAttribute.association->forAll(memberEnd->size()=2) + OCL + + + + + + + + + allParents()->forAll(oclIsKindOf(Stereotype)) +and Classifier.allInstances()->forAll(c | c.allParents()->exists(oclIsKindOf(Stereotype)) implies c.oclIsKindOf(Stereotype)) + + OCL + + + + + + + + + + + + + + + + ownedAttribute +->select(association->notEmpty() and not association.oclIsKindOf(Extension) and not type.oclIsKindOf(Stereotype)) +->forAll(opposite.owner = association) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (self.namespace.oclAsType(Package).containingProfile()) + OCL + + + + + + + + + + + + + result = (self.containingProfile()) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + (enclosingInteraction->notEmpty() or enclosingOperand.combinedFragment->notEmpty()) and +let parentInteraction : Set(Interaction) = enclosingInteraction.oclAsType(Interaction)->asSet()->union( +enclosingOperand.combinedFragment->closure(enclosingOperand.combinedFragment)-> +collect(enclosingInteraction).oclAsType(Interaction)->asSet()) in +(parentInteraction->size() = 1) and self.action.interaction->asSet() = parentInteraction + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + interactionOperator=InteractionOperatorKind::break implies +enclosingInteraction.oclAsType(InteractionFragment)->asSet()->union( + enclosingOperand.oclAsType(InteractionFragment)->asSet()).covered->asSet() = self.covered->asSet() + OCL + + + + + + + + + ((interactionOperator = InteractionOperatorKind::consider) or (interactionOperator = InteractionOperatorKind::ignore)) implies oclIsKindOf(ConsiderIgnoreFragment) + OCL + + + + + + + + + (interactionOperator = InteractionOperatorKind::opt or interactionOperator = InteractionOperatorKind::loop or +interactionOperator = InteractionOperatorKind::break or interactionOperator = InteractionOperatorKind::assert or +interactionOperator = InteractionOperatorKind::neg) +implies operand->size()=1 + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + (interactionOperator = InteractionOperatorKind::consider) or (interactionOperator = InteractionOperatorKind::ignore) + OCL + + + + + + + + + message->forAll(m | m.oclIsKindOf(Operation) or m.oclIsKindOf(Signal)) + OCL + + + + + + + + + + + + + + + + + + + + + + enclosingOperand->notEmpty() and + let peerFragments : OrderedSet(InteractionFragment) = enclosingOperand.fragment in + ( peerFragments->notEmpty() and + ((peerFragments->first() = self) or (peerFragments->last() = self))) + OCL + + + + + + + + + enclosingOperand.combinedFragment->notEmpty() and +let parentInteraction : Set(Interaction) = +enclosingOperand.combinedFragment->closure(enclosingOperand.combinedFragment)-> +collect(enclosingInteraction).oclAsType(Interaction)->asSet() +in +(parentInteraction->size() = 1) +and let peerInteractions : Set(Interaction) = + (parentInteraction->union(parentInteraction->collect(_'context')->collect(behavior)-> + select(oclIsKindOf(Interaction)).oclAsType(Interaction)->asSet())->asSet()) in + (peerInteractions->notEmpty()) and + let combinedFragments1 : Set(CombinedFragment) = peerInteractions.fragment-> + select(oclIsKindOf(CombinedFragment)).oclAsType(CombinedFragment)->asSet() in + combinedFragments1->notEmpty() and combinedFragments1->closure(operand.fragment-> + select(oclIsKindOf(CombinedFragment)).oclAsType(CombinedFragment))->asSet().operand.fragment-> + select(oclIsKindOf(Continuation)).oclAsType(Continuation)->asSet()-> + forAll(c : Continuation | (c.name = self.name) implies + (c.covered->asSet()->forAll(cl : Lifeline | -- cl must be common to one lifeline covered by self + self.covered->asSet()-> + select(represents = cl.represents and selector = cl.selector)->asSet()->size()=1)) + and + (self.covered->asSet()->forAll(cl : Lifeline | -- cl must be common to one lifeline covered by c + c.covered->asSet()-> + select(represents = cl.represents and selector = cl.selector)->asSet()->size()=1)) + ) + OCL + + + + + + + + + enclosingOperand->notEmpty() and + let operandLifelines : Set(Lifeline) = enclosingOperand.covered in + (operandLifelines->notEmpty() and + operandLifelines->forAll(ol :Lifeline |self.covered->includes(ol))) + OCL + + + + + + + + + + + + + + + + + + + + + + let o : InteractionOperand = enclosingOperand in o->notEmpty() and +let peerEvents : OrderedSet(OccurrenceSpecification) = covered.events->select(enclosingOperand = o) +in peerEvents->last() = self + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + start.covered = finish.covered + OCL + + + + + + + + + + + + + + + + + + + + + + + + + interactionUse->notEmpty() implies interactionUse.refersTo.formalGate->select(matches(self))->size()=1 + OCL + + + + + + + + + isInsideCF() implies combinedFragment.cfragmentGate->select(isOutsideCF() and matches(self))->size()=1 + OCL + + + + + + + + + isOutsideCF() implies + if self.combinedFragment.interactionOperator->asOrderedSet()->first() = InteractionOperatorKind::alt + then self.combinedFragment.operand->forAll(op : InteractionOperand | + self.combinedFragment.cfragmentGate->select(isInsideCF() and + oppositeEnd().enclosingFragment()->includes(self.combinedFragment) and matches(self))->size()=1) + else self.combinedFragment.cfragmentGate->select(isInsideCF() and matches(self))->size()=1 + endif + OCL + + + + + + + + + isFormal() implies interaction.formalGate->select(getName() = self.getName())->size()=1 + OCL + + + + + + + + + isActual() implies interactionUse.actualGate->select(getName() = self.getName())->size()=1 + OCL + + + + + + + + + isOutsideCF() implies combinedFragment.cfragmentGate->select(getName() = self.getName())->size()=1 + OCL + + + + + + + + + isInsideCF() implies +let selfOperand : InteractionOperand = self.getOperand() in + combinedFragment.cfragmentGate->select(isInsideCF() and getName() = self.getName())->select(getOperand() = selfOperand)->size()=1 + OCL + + + + + + + + + + + result = (self.oppositeEnd()-> notEmpty() and combinedFragment->notEmpty() implies +let oppEnd : MessageEnd = self.oppositeEnd()->asOrderedSet()->first() in +if oppEnd.oclIsKindOf(MessageOccurrenceSpecification) +then let oppMOS : MessageOccurrenceSpecification = oppEnd.oclAsType(MessageOccurrenceSpecification) +in self.combinedFragment.enclosingInteraction.oclAsType(InteractionFragment)->asSet()-> + union(self.combinedFragment.enclosingOperand.oclAsType(InteractionFragment)->asSet()) = + oppMOS.enclosingInteraction.oclAsType(InteractionFragment)->asSet()-> + union(oppMOS.enclosingOperand.oclAsType(InteractionFragment)->asSet()) +else let oppGate : Gate = oppEnd.oclAsType(Gate) +in self.combinedFragment.enclosingInteraction.oclAsType(InteractionFragment)->asSet()-> + union(self.combinedFragment.enclosingOperand.oclAsType(InteractionFragment)->asSet()) = + oppGate.combinedFragment.enclosingInteraction.oclAsType(InteractionFragment)->asSet()-> + union(oppGate.combinedFragment.enclosingOperand.oclAsType(InteractionFragment)->asSet()) +endif) + OCL + + + + + + + + + + + + + + result = (self.oppositeEnd()-> notEmpty() and combinedFragment->notEmpty() implies +let oppEnd : MessageEnd = self.oppositeEnd()->asOrderedSet()->first() in +if oppEnd.oclIsKindOf(MessageOccurrenceSpecification) +then let oppMOS : MessageOccurrenceSpecification += oppEnd.oclAsType(MessageOccurrenceSpecification) +in combinedFragment = oppMOS.enclosingOperand.combinedFragment +else let oppGate : Gate = oppEnd.oclAsType(Gate) +in combinedFragment = oppGate.combinedFragment.enclosingOperand.combinedFragment +endif) + OCL + + + + + + + + + + + + + + result = (interactionUse->notEmpty()) + OCL + + + + + + + + + + + + + + + + + result = (interaction->notEmpty()) + OCL + + + + + + + + + + + + + + result = (if name->notEmpty() then name->asOrderedSet()->first() +else if isActual() or isOutsideCF() + then if isSend() + then 'out_'.concat(self.message.name->asOrderedSet()->first()) + else 'in_'.concat(self.message.name->asOrderedSet()->first()) + endif + else if isSend() + then 'in_'.concat(self.message.name->asOrderedSet()->first()) + else 'out_'.concat(self.message.name->asOrderedSet()->first()) + endif + endif +endif) + OCL + + + + + + + + + + + + + + result = (self.getName() = gateToMatch.getName() and +self.message.messageSort = gateToMatch.message.messageSort and +self.message.name = gateToMatch.message.name and +self.message.sendEvent->includes(self) implies gateToMatch.message.receiveEvent->includes(gateToMatch) and +self.message.receiveEvent->includes(self) implies gateToMatch.message.sendEvent->includes(gateToMatch) and +self.message.signature = gateToMatch.message.signature) + OCL + + + + + + + + + + + + + + + + result = (true) + OCL + + + + + + + + + + + + + + + + result = (if isInsideCF() then + let oppEnd : MessageEnd = self.oppositeEnd()->asOrderedSet()->first() in + if oppEnd.oclIsKindOf(MessageOccurrenceSpecification) + then let oppMOS : MessageOccurrenceSpecification = oppEnd.oclAsType(MessageOccurrenceSpecification) + in oppMOS.enclosingOperand->asOrderedSet()->first() + else let oppGate : Gate = oppEnd.oclAsType(Gate) + in oppGate.combinedFragment.enclosingOperand->asOrderedSet()->first() + endif + else null +endif) + OCL + + + + + + + + + + + + + + + + after->closure(toAfter.after)->excludes(before) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + enclosingInteraction->isEmpty() + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maxint->notEmpty() or minint->notEmpty() implies +interactionOperand.combinedFragment.interactionOperator = +InteractionOperatorKind::loop + OCL + + + + + + + + + minint->notEmpty() implies +minint->asSequence()->first().integerValue() >= 0 + OCL + + + + + + + + + maxint->notEmpty() implies +maxint->asSequence()->first().integerValue() > 0 + OCL + + + + + + + + + + + + + + + + + + + + + + + maxint->notEmpty() implies (minint->notEmpty() and +maxint->asSequence()->first().integerValue() >= +minint->asSequence()->first().integerValue() ) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + actualGate->notEmpty() implies +refersTo.formalGate->forAll( fg : Gate | self.actualGate->select(matches(fg))->size()=1) and +self.actualGate->forAll(ag : Gate | refersTo.formalGate->select(matches(ag))->size()=1) + OCL + + + + + + + + + + + + + + + + returnValueRecipient->asSet()->notEmpty() implies +let covCE : Set(ConnectableElement) = covered.represents->asSet() in +covCE->notEmpty() and let classes:Set(Classifier) = covCE.type.oclIsKindOf(Classifier).oclAsType(Classifier)->asSet() in +let allProps : Set(Property) = classes.attribute->union(classes.allParents().attribute)->asSet() in +allProps->includes(returnValueRecipient) + OCL + + + + + + + + + + + + + + + + returnValue.type->asSequence()->notEmpty() implies returnValue.type->asSequence()->first() = returnValueRecipient.type->asSequence()->first() + + OCL + + + + + + + + + let parentInteraction : Set(Interaction) = enclosingInteraction->asSet()-> +union(enclosingOperand.combinedFragment->closure(enclosingOperand.combinedFragment)-> +collect(enclosingInteraction).oclAsType(Interaction)->asSet()) in +parentInteraction->size()=1 and let refInteraction : Interaction = refersTo in +parentInteraction.covered-> forAll(intLifeline : Lifeline | refInteraction.covered-> +forAll( refLifeline : Lifeline | refLifeline.represents = intLifeline.represents and +( +( refLifeline.selector.oclIsKindOf(LiteralString) implies + intLifeline.selector.oclIsKindOf(LiteralString) and + refLifeline.selector.oclAsType(LiteralString).value = intLifeline.selector.oclAsType(LiteralString).value ) and +( refLifeline.selector.oclIsKindOf(LiteralInteger) implies + intLifeline.selector.oclIsKindOf(LiteralInteger) and + refLifeline.selector.oclAsType(LiteralInteger).value = intLifeline.selector.oclAsType(LiteralInteger).value ) +) + implies self.covered->asSet()->includes(intLifeline))) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + self.selector->notEmpty() = (self.represents.oclIsKindOf(MultiplicityElement) and self.represents.oclAsType(MultiplicityElement).isMultivalued()) + OCL + + + + + + + + + let intUses : Set(InteractionUse) = interaction.interactionUse in +intUses->forAll +( iuse : InteractionUse | +let usingInteraction : Set(Interaction) = iuse.enclosingInteraction->asSet() +->union( +iuse.enclosingOperand.combinedFragment->asSet()->closure(enclosingOperand.combinedFragment).enclosingInteraction->asSet() + ) +in +let peerUses : Set(InteractionUse) = usingInteraction.fragment->select(oclIsKindOf(InteractionUse)).oclAsType(InteractionUse)->asSet() +->union( +usingInteraction.fragment->select(oclIsKindOf(CombinedFragment)).oclAsType(CombinedFragment)->asSet() +->closure(operand.fragment->select(oclIsKindOf(CombinedFragment)).oclAsType(CombinedFragment)).operand.fragment-> +select(oclIsKindOf(InteractionUse)).oclAsType(InteractionUse)->asSet() + )->excluding(iuse) + in +peerUses->forAll( peerUse : InteractionUse | + peerUse.refersTo.lifeline->forAll( l : Lifeline | (l.represents = self.represents and + ( self.selector.oclIsKindOf(LiteralString) implies + l.selector.oclIsKindOf(LiteralString) and + self.selector.oclAsType(LiteralString).value = l.selector.oclAsType(LiteralString).value ) + and +( self.selector.oclIsKindOf(LiteralInteger) implies + l.selector.oclIsKindOf(LiteralInteger) and + self.selector.oclAsType(LiteralInteger).value = l.selector.oclAsType(LiteralInteger).value ) +) +implies + usingInteraction.lifeline->select(represents = self.represents and + ( self.selector.oclIsKindOf(LiteralString) implies + l.selector.oclIsKindOf(LiteralString) and + self.selector.oclAsType(LiteralString).value = l.selector.oclAsType(LiteralString).value ) +and +( self.selector.oclIsKindOf(LiteralInteger) implies + l.selector.oclIsKindOf(LiteralInteger) and + self.selector.oclAsType(LiteralInteger).value = l.selector.oclAsType(LiteralInteger).value ) +) + ) + ) +) + OCL + + + + + + + + + represents.namespace->closure(namespace)->includes(interaction._'context') + OCL + + + + + + + + + self.selector->notEmpty() implies +self.selector.oclIsKindOf(LiteralInteger) or +self.selector.oclIsKindOf(LiteralString) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + receiveEvent.oclIsKindOf(MessageOccurrenceSpecification) +implies +let f : Lifeline = sendEvent->select(oclIsKindOf(MessageOccurrenceSpecification)).oclAsType(MessageOccurrenceSpecification)->asOrderedSet()->first().covered in +f = receiveEvent->select(oclIsKindOf(MessageOccurrenceSpecification)).oclAsType(MessageOccurrenceSpecification)->asOrderedSet()->first().covered implies +f.events->indexOf(sendEvent.oclAsType(MessageOccurrenceSpecification)->asOrderedSet()->first() ) < +f.events->indexOf(receiveEvent.oclAsType(MessageOccurrenceSpecification)->asOrderedSet()->first() ) + OCL + + + + + + + + + + + + + + + + sendEvent->notEmpty() and receiveEvent->notEmpty() implies +let sendEnclosingFrag : Set(InteractionFragment) = +sendEvent->asOrderedSet()->first().enclosingFragment() +in +let receiveEnclosingFrag : Set(InteractionFragment) = +receiveEvent->asOrderedSet()->first().enclosingFragment() +in sendEnclosingFrag = receiveEnclosingFrag + OCL + + + + + + + + + (messageSort = MessageSort::asynchSignal ) and signature.oclIsKindOf(Signal) implies + let signalAttributes : OrderedSet(Property) = signature.oclAsType(Signal).inheritedMember()-> + select(n:NamedElement | n.oclIsTypeOf(Property))->collect(oclAsType(Property))->asOrderedSet() + in signalAttributes->size() = self.argument->size() + and self.argument->forAll( o: ValueSpecification | + not (o.oclIsKindOf(Expression) + and o.oclAsType(Expression).symbol->size()=0 + and o.oclAsType(Expression).operand->isEmpty() ) implies + let p : Property = signalAttributes->at(self.argument->indexOf(o)) + in o.type.oclAsType(Classifier).conformsTo(p.type.oclAsType(Classifier))) + + OCL + + + + + + + + + + + + + + + + signature->notEmpty() implies +((signature.oclIsKindOf(Operation) and +(messageSort = MessageSort::asynchCall or messageSort = MessageSort::synchCall or messageSort = MessageSort::reply) +) or (signature.oclIsKindOf(Signal) and messageSort = MessageSort::asynchSignal ) + ) and name = signature.name + OCL + + + + + + + + + (messageSort = MessageSort::asynchCall or messageSort = MessageSort::synchCall) and signature.oclIsKindOf(Operation) implies + let requestParms : OrderedSet(Parameter) = signature.oclAsType(Operation).ownedParameter-> + select(direction = ParameterDirectionKind::inout or direction = ParameterDirectionKind::_'in' ) +in requestParms->size() = self.argument->size() and +self.argument->forAll( o: ValueSpecification | +not (o.oclIsKindOf(Expression) and o.oclAsType(Expression).symbol->size()=0 and o.oclAsType(Expression).operand->isEmpty() ) implies +let p : Parameter = requestParms->at(self.argument->indexOf(o)) in +o.type.oclAsType(Classifier).conformsTo(p.type.oclAsType(Classifier)) +) + OCL + + + + + + + + + (messageSort = MessageSort::reply) and signature.oclIsKindOf(Operation) implies + let replyParms : OrderedSet(Parameter) = signature.oclAsType(Operation).ownedParameter-> +select(direction = ParameterDirectionKind::inout or direction = ParameterDirectionKind::out or direction = ParameterDirectionKind::return) +in replyParms->size() = self.argument->size() and +self.argument->forAll( o: ValueSpecification | o.oclIsKindOf(Expression) and let e : Expression = o.oclAsType(Expression) in +e.operand->notEmpty() implies +let p : Parameter = replyParms->at(self.argument->indexOf(o)) in +e.operand->asSequence()->first().type.oclAsType(Classifier).conformsTo(p.type.oclAsType(Classifier)) +) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (messageKind) + OCL + + + + + + + + + + + + + result = (true) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (message->asSet().messageEnd->asSet()->excluding(self)) + OCL + + + + + + message->notEmpty() + + OCL + + + + + + + + + + + + + + + + message->notEmpty() + + OCL + + + + + + result = (message.sendEvent->asSet()->includes(self)) + OCL + + + + + + + + + + + + + + + + + + message->notEmpty() + + OCL + + + + + + result = (message.receiveEvent->asSet()->includes(self)) + OCL + + + + + + + + + + + + + + result = (if self->select(oclIsKindOf(Gate))->notEmpty() +then -- it is a Gate +let endGate : Gate = + self->select(oclIsKindOf(Gate)).oclAsType(Gate)->asOrderedSet()->first() + in + if endGate.isOutsideCF() + then endGate.combinedFragment.enclosingInteraction.oclAsType(InteractionFragment)->asSet()-> + union(endGate.combinedFragment.enclosingOperand.oclAsType(InteractionFragment)->asSet()) + else if endGate.isInsideCF() + then endGate.combinedFragment.oclAsType(InteractionFragment)->asSet() + else if endGate.isFormal() + then endGate.interaction.oclAsType(InteractionFragment)->asSet() + else if endGate.isActual() + then endGate.interactionUse.enclosingInteraction.oclAsType(InteractionFragment)->asSet()-> + union(endGate.interactionUse.enclosingOperand.oclAsType(InteractionFragment)->asSet()) + else null + endif + endif + endif + endif +else -- it is a MessageOccurrenceSpecification +let endMOS : MessageOccurrenceSpecification = + self->select(oclIsKindOf(MessageOccurrenceSpecification)).oclAsType(MessageOccurrenceSpecification)->asOrderedSet()->first() + in + if endMOS.enclosingInteraction->notEmpty() + then endMOS.enclosingInteraction.oclAsType(InteractionFragment)->asSet() + else endMOS.enclosingOperand.oclAsType(InteractionFragment)->asSet() + endif +endif) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + (self.informationSource->forAll( sis | + oclIsKindOf(Actor) or oclIsKindOf(Node) or oclIsKindOf(UseCase) or oclIsKindOf(Artifact) or + oclIsKindOf(Class) or oclIsKindOf(Component) or oclIsKindOf(Port) or oclIsKindOf(Property) or + oclIsKindOf(Interface) or oclIsKindOf(Package) or oclIsKindOf(ActivityNode) or oclIsKindOf(ActivityPartition) or + (oclIsKindOf(InstanceSpecification) and not sis.oclAsType(InstanceSpecification).classifier->exists(oclIsKindOf(Relationship))))) + +and + +(self.informationTarget->forAll( sit | + oclIsKindOf(Actor) or oclIsKindOf(Node) or oclIsKindOf(UseCase) or oclIsKindOf(Artifact) or + oclIsKindOf(Class) or oclIsKindOf(Component) or oclIsKindOf(Port) or oclIsKindOf(Property) or + oclIsKindOf(Interface) or oclIsKindOf(Package) or oclIsKindOf(ActivityNode) or oclIsKindOf(ActivityPartition) or +(oclIsKindOf(InstanceSpecification) and not sit.oclAsType(InstanceSpecification).classifier->exists(oclIsKindOf(Relationship))))) + OCL + + + + + + + + + self.conveyed->forAll(oclIsKindOf(Class) or oclIsKindOf(Interface) + or oclIsKindOf(InformationItem) or oclIsKindOf(Signal) or oclIsKindOf(Component)) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + (self.represented->select(oclIsKindOf(InformationItem))->forAll(p | + p.conveyingFlow.source->forAll(q | self.conveyingFlow.source->includes(q)) and + p.conveyingFlow.target->forAll(q | self.conveyingFlow.target->includes(q)))) and + (self.represented->forAll(oclIsKindOf(Class) or oclIsKindOf(Interface) or + oclIsKindOf(InformationItem) or oclIsKindOf(Signal) or oclIsKindOf(Component))) + OCL + + + + + + + + + self.generalization->isEmpty() and self.feature->isEmpty() + OCL + + + + + + + + + isAbstract + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + endType->forAll (oclIsKindOf(DeploymentTarget)) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + deployment->forAll (location.oclIsKindOf(ExecutionEnvironment)) + OCL + + + + + + + + + deployment->forAll (location.deployedElement->forAll (oclIsKindOf(Component))) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (deployment.deployedArtifact->select(oclIsKindOf(Artifact))->collect(oclAsType(Artifact).manifestation)->collect(utilizedElement)->asSet()) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + part->forAll(oclIsKindOf(Node)) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + not constrainedElement->includes(self) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + mustBeOwned() implies owner->notEmpty() + OCL + + + + + + + + + not allOwnedElements()->includes(self) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (ownedElement->union(ownedElement->collect(e | e.allOwnedElements()))->asSet()) + OCL + + + + + + + + + + + + + + + result = (true) + OCL + + + + + + + + + + + + + + + + + + importedElement.visibility <> null implies importedElement.visibility = VisibilityKind::public + OCL + + + + + + + + + visibility = VisibilityKind::public or visibility = VisibilityKind::private + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (if alias->notEmpty() then + alias +else + importedElement.name +endif) + OCL + + + + + + + + + + + + + + + + + + upperBound() >= lowerBound() + OCL + + + + + + + + + lowerBound() >= 0 + OCL + + + + + + + + + + + + + + + + + + + + + + + lowerValue <> null implies lowerValue.integerValue() <> null + OCL + + + + + + + + + upperValue <> null implies upperValue.unlimitedValue() <> null + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = ((other.lowerBound() <= self.lowerBound()) and ((other.upperBound() = *) or (self.upperBound() <= other.upperBound()))) + OCL + + + + + + + + + + + + + + + + self.upperBound()->notEmpty() and self.lowerBound()->notEmpty() and M.upperBound()->notEmpty() and M.lowerBound()->notEmpty() + OCL + + + + + + result = ((self.lowerBound() <= M.lowerBound()) and (self.upperBound() >= M.upperBound())) + OCL + + + + + + + + + + + + + + + result = (lowerbound = self.lowerBound() and upperbound = self.upperBound()) + OCL + + + + + + + + + + + + + + + + + + + + + upperBound()->notEmpty() + OCL + + + + + + result = (upperBound() > 1) + OCL + + + + + + + + + + + + + + + result = (lowerBound()) + OCL + + + + + + + + + + + + + + + result = (if (lowerValue=null or lowerValue.integerValue()=null) then 1 else lowerValue.integerValue() endif) + OCL + + + + + + + + + + + + + + + result = (upperBound()) + OCL + + + + + + + + + + + + + + + result = (if (upperValue=null or upperValue.unlimitedValue()=null) then 1 else upperValue.unlimitedValue() endif) + OCL + + + + + + + + + + + + + + + + + + (namespace = null and owner <> null) implies visibility = null + OCL + + + + + + + + + (name <> null and allNamespaces()->select(ns | ns.name = null)->isEmpty()) implies + qualifiedName = allNamespaces()->iterate( ns : Namespace; agg: String = name | ns.name.concat(self.separator()).concat(agg)) + OCL + + + + + + + + + name=null or allNamespaces()->select( ns | ns.name=null )->notEmpty() implies qualifiedName = null + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (if owner.oclIsKindOf(TemplateParameter) and + owner.oclAsType(TemplateParameter).signature.template.oclIsKindOf(Namespace) then + let enclosingNamespace : Namespace = + owner.oclAsType(TemplateParameter).signature.template.oclAsType(Namespace) in + enclosingNamespace.allNamespaces()->prepend(enclosingNamespace) +else + if namespace->isEmpty() + then OrderedSet{} + else + namespace.allNamespaces()->prepend(namespace) + endif +endif) + OCL + + + + + + + + + + + + + + + result = (if namespace.oclIsKindOf(Package) +then + let owningPackage : Package = namespace.oclAsType(Package) in + owningPackage->union(owningPackage.allOwningPackages()) +else + null +endif) + OCL + + + + + + + + + + + + + + + result = ((self.oclIsKindOf(n.oclType()) or n.oclIsKindOf(self.oclType())) implies + ns.getNamesOfMember(self)->intersection(ns.getNamesOfMember(n))->isEmpty() +) + OCL + + + + + + + + + + + + + + + + + result = (if self.name <> null and self.allNamespaces()->select( ns | ns.name=null )->isEmpty() +then + self.allNamespaces()->iterate( ns : Namespace; agg: String = self.name | ns.name.concat(self.separator()).concat(agg)) +else + null +endif) + OCL + + + + + + + + + + + + + + result = ('::') + OCL + + + + + + + + + + + + result = (Dependency.allInstances()->select(d | d.client->includes(self))) + OCL + + + + + + + + + + + + + + + + + + + membersAreDistinguishable() + OCL + + + + + + + + + packageImport.importedPackage.oclAsType(Namespace)->excludes(self) + OCL + + + + + + + + + elementImport.importedElement.oclAsType(Element)->excludesAll(ownedMember) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (imps->reject(imp1 | imps->exists(imp2 | not imp1.isDistinguishableFrom(imp2, self)))) + OCL + + + + + + + + + + + + + + + + + + + result = (if self.ownedMember ->includes(element) +then Set{element.name} +else let elementImports : Set(ElementImport) = self.elementImport->select(ei | ei.importedElement = element) in + if elementImports->notEmpty() + then + elementImports->collect(el | el.getName())->asSet() + else + self.packageImport->select(pi | pi.importedPackage.visibleMembers().oclAsType(NamedElement)->includes(element))-> collect(pi | pi.importedPackage.getNamesOfMember(element))->asSet() + endif +endif) + OCL + + + + + + + + + + + + + + + + + result = (self.excludeCollisions(imps)->select(imp | self.ownedMember->forAll(mem | imp.isDistinguishableFrom(mem, self)))) + OCL + + + + + + + + + + + + + + + + + + + + result = (self.importMembers(elementImport.importedElement->asSet()->union(packageImport.importedPackage->collect(p | p.visibleMembers()))->asSet())) + OCL + + + + + + + + + + + + + + + result = (member->forAll( memb | + member->excluding(memb)->forAll(other | + memb.isDistinguishableFrom(other, self)))) + OCL + + + + + + + + + + + + + + + + + + visibility = null implies namespace = null + OCL + + + + + + + + + + + + + + + + + + + + + + + + visibility = VisibilityKind::public or visibility = VisibilityKind::private + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (self.oclIsKindOf(p.oclType())) + OCL + + + + + + + + + + + + + + + result = (templateParameter->notEmpty()) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (ownedTemplateSignature <> null) + OCL + + + + + + + + + + + + + + result = (self.allOwnedElements()->select(oclIsKindOf(ParameterableElement)).oclAsType(ParameterableElement)->asSet()) + OCL + + + + + + + + + + + + + + + + + + + parameterSubstitution->forAll(b | signature.parameter->includes(b.formal)) + OCL + + + + + + + + + signature.parameter->forAll(p | parameterSubstitution->select(b | b.formal = p)->size() <= 1) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + default <> null implies default.isCompatibleWith(parameteredElement) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + actual->forAll(a | a.isCompatibleWith(formal.parameteredElement)) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + template.ownedElement->includesAll(parameter.parameteredElement->asSet() - parameter.ownedParameteredElement->asSet()) + OCL + + + + + + + + + parameter->forAll( p1, p2 | (p1 <> p2 and p1.parameteredElement.oclIsKindOf(NamedElement) and p2.parameteredElement.oclIsKindOf(NamedElement) ) implies + p1.parameteredElement.oclAsType(NamedElement).name <> p2.parameteredElement.oclAsType(NamedElement).name) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (false) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + specification <> null implies _'context'.ownedBehavior->select(specification=self.specification)->size() = 1 + OCL + + + + + + + + + specification <> null implies ownedParameter->size() = specification.ownedParameter->size() + OCL + + + + + + + + + _'context'.feature->includes(specification) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (if nestingClass <> null then + null +else + let b:BehavioredClassifier = self.behavioredClassifier(self.owner) in + if b.oclIsKindOf(Behavior) and b.oclAsType(Behavior)._'context' <> null then + b.oclAsType(Behavior)._'context' + else + b + endif +endif + ) + OCL + + + + + + + + + + + + + + + if from.oclIsKindOf(BehavioredClassifier) then + from.oclAsType(BehavioredClassifier) +else if from.owner = null then + null +else + self.behavioredClassifier(from.owner) +endif +endif + + OCL + + + + + + + + + + + + + + + result = (ownedParameter->select(direction=ParameterDirectionKind::_'in' or direction=ParameterDirectionKind::inout)) + OCL + + + + + + + + + + + + + + + result = (ownedParameter->select(direction=ParameterDirectionKind::out or direction=ParameterDirectionKind::inout or direction=ParameterDirectionKind::return)) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + self.ownedParameter-> + select(p | p.direction = ParameterDirectionKind::out or p.direction= ParameterDirectionKind::inout or p.direction= ParameterDirectionKind::return)->size() >= 1 + OCL + + + + + + + + + ownedParameter->forAll(p | p.type <> null and + p.type.oclIsTypeOf(DataType) and hasAllDataTypeAttributes(p.type.oclAsType(DataType))) + OCL + + + + + + + + + + + result = (d.ownedAttribute->forAll(a | + a.type.oclIsKindOf(DataType) and + hasAllDataTypeAttributes(a.type.oclAsType(DataType)))) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + when.integerValue() >= 0 + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + port->notEmpty() implies event.oclIsKindOf(MessageEvent) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + isAbstract implies method->isEmpty() + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = ((n.oclIsKindOf(BehavioralFeature) and ns.getNamesOfMember(self)->intersection(ns.getNamesOfMember(n))->notEmpty()) implies + Set{self}->including(n.oclAsType(BehavioralFeature))->isUnique(ownedParameter->collect(p| + Tuple { name=p.name, type=p.type,effect=p.effect,direction=p.direction,isException=p.isException, + isStream=p.isStream,isOrdered=p.isOrdered,isUnique=p.isUnique,lower=p.lower, upper=p.upper })) + ) + OCL + + + + + + + + + + + + + + + + result = (ownedParameter->select(direction=ParameterDirectionKind::_'in' or direction=ParameterDirectionKind::inout)) + OCL + + + + + + + + + + + + + + + result = (ownedParameter->select(direction=ParameterDirectionKind::out or direction=ParameterDirectionKind::inout or direction=ParameterDirectionKind::return)) + OCL + + + + + + + + + + + + + + + + + + + parents()->forAll(c | self.maySpecializeType(c)) + OCL + + + + + + + + + powertypeExtent->forAll( gs | + gs.generalization->forAll( gen | + not (gen.general = self) and not gen.general.allParents()->includes(self) and not (gen.specific = self) and not self.allParents()->includes(gen.specific) + )) + OCL + + + + + + + + + parents()->forAll(not isFinalSpecialization) + OCL + + + + + + + + + not allParents()->includes(self) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (member->select(oclIsKindOf(Feature))->collect(oclAsType(Feature))->asSet()) + OCL + + + + + + + + + + + + + + + result = (parents()->union(parents()->collect(allParents())->asSet())) + OCL + + + + + + + + + + + + + + + + result = (if other.oclIsKindOf(Classifier) then + let otherClassifier : Classifier = other.oclAsType(Classifier) in + self = otherClassifier or allParents()->includes(otherClassifier) +else + false +endif) + OCL + + + + + + + + + + + + + + + + result = (parents()) + OCL + + + + + + + + + + + + + + + + allParents()->including(self)->collect(member)->includes(n) + OCL + + + + + + result = (n.visibility <> VisibilityKind::private) + OCL + + + + + + + + + + + + + + + result = (inhs->reject(inh | + inh.oclIsKindOf(RedefinableElement) and + ownedMember->select(oclIsKindOf(RedefinableElement))-> + select(redefinedElement->includes(inh.oclAsType(RedefinableElement))) + ->notEmpty())) + OCL + + + + + + + + + + + + + + + + + + + + c.allParents()->includes(self) + OCL + + + + + + result = (member->select(m | c.hasVisibilityOf(m))) + OCL + + + + + + + + + + + + + + + + + result = (inherit(parents()->collect(inheritableMembers(self))->asSet())) + OCL + + + + + + + + + + + + + + + + result = (ownedTemplateSignature <> null or general->exists(g | g.isTemplate())) + OCL + + + + + + + + + + + + + + result = (self.oclIsKindOf(c.oclType())) + OCL + + + + + + + + + + + + + + + result = (generalization.general->asSet()) + OCL + + + + + + + + + + + + + + + result = ((clientDependency-> + select(oclIsKindOf(Realization) and supplier->forAll(oclIsKindOf(Interface))))-> + collect(supplier.oclAsType(Interface))->asSet()) + OCL + + + + + + + + + + + + + + + result = ((supplierDependency-> + select(oclIsKindOf(Usage) and client->forAll(oclIsKindOf(Interface))))-> + collect(client.oclAsType(Interface))->asSet()) + OCL + + + + + + + + + + + + + + + result = (directlyRealizedInterfaces()->union(self.allParents()->collect(directlyRealizedInterfaces()))->asSet()) + OCL + + + + + + + + + + + + + + + result = (directlyUsedInterfaces()->union(self.allParents()->collect(directlyUsedInterfaces()))->asSet()) + OCL + + + + + + + + + + + + result = (substitution.contract->includes(contract)) + OCL + + + + + + + + + + + + + + + result = (attribute->asSequence()->union(parents()->asSequence().allAttributes())->select(p | member->includes(p))->asOrderedSet()) + OCL + + + + + + + + + + + + + + + result = (member->select(oclIsKindOf(StructuralFeature))-> + collect(oclAsType(StructuralFeature))-> + union(self.inherit(self.allParents()->collect(p | p.attribute)->asSet())-> + collect(oclAsType(StructuralFeature)))->asSet()) + OCL + + + + + + + + + + + + + + + + + + + allowSubstitutable implies constrainingClassifier->notEmpty() + OCL + + + + + + + + + parameteredElement.feature->isEmpty() and (constrainingClassifier->isEmpty() implies parameteredElement.allParents()->isEmpty()) + OCL + + + + + + + + + (not parameteredElement.isAbstract) implies templateParameterSubstitution.actual->forAll(a | not a.oclAsType(Classifier).isAbstract) + OCL + + + + + + + + + templateParameterSubstitution.actual->forAll(a | a.oclIsKindOf(Classifier)) + OCL + + + + + + + + + templateParameterSubstitution.actual->forAll( a | + let arg : Classifier = a.oclAsType(Classifier) in + constrainingClassifier->forAll( + cc | + arg = cc or arg.conformsTo(cc) or (allowSubstitutable and arg.isSubstitutableFor(cc)) + ) +) + OCL + + + + + + + + + constrainingClassifier->forAll( + cc | parameteredElement = cc or parameteredElement.conformsTo(cc) or (allowSubstitutable and parameteredElement.isSubstitutableFor(cc)) +) + + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + generalization->collect(general)->asSet()->size() <= 1 + OCL + + + + + + + + + powertype <> null implies generalization->forAll( gen | + not (gen.general = powertype) and not gen.general.allParents()->includes(powertype) and not (gen.specific = powertype) and not powertype.allParents()->includes(gen.specific) + ) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + deploymentForArtifact->notEmpty() implies classifier->exists(oclIsKindOf(Artifact)) + OCL + + + + + + + + + classifier->forAll(c | (c.allSlottableFeatures()->forAll(f | slot->select(s | s.definingFeature = f)->size() <= 1))) + OCL + + + + + + + + + slot->forAll(s | classifier->exists (c | c.allSlottableFeatures()->includes (s.definingFeature))) + OCL + + + + + + + + + deployment->notEmpty() implies classifier->exists(node | node.oclIsKindOf(Node) and Node.allInstances()->exists(n | n.part->exists(p | p.type = node))) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + self.ownedParameter->select(direction = ParameterDirectionKind::return)->size() <= 1 + OCL + + + + + + + + + bodyCondition <> null implies isQuery + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (redefiningElement.oclIsKindOf(Operation) and +let op : Operation = redefiningElement.oclAsType(Operation) in + self.ownedParameter->size() = op.ownedParameter->size() and + Sequence{1..self.ownedParameter->size()}-> + forAll(i | + let redefiningParam : Parameter = op.ownedParameter->at(i), + redefinedParam : Parameter = self.ownedParameter->at(i) in + (redefiningParam.isUnique = redefinedParam.isUnique) and + (redefiningParam.isOrdered = redefinedParam. isOrdered) and + (redefiningParam.direction = redefinedParam.direction) and + (redefiningParam.type.conformsTo(redefinedParam.type) or + redefinedParam.type.conformsTo(redefiningParam.type)) and + (redefiningParam.direction = ParameterDirectionKind::inout implies + (redefinedParam.compatibleWith(redefiningParam) and + redefiningParam.compatibleWith(redefinedParam))) and + (redefiningParam.direction = ParameterDirectionKind::_'in' implies + redefinedParam.compatibleWith(redefiningParam)) and + ((redefiningParam.direction = ParameterDirectionKind::out or + redefiningParam.direction = ParameterDirectionKind::return) implies + redefiningParam.compatibleWith(redefinedParam)) + )) + OCL + + + + + + redefiningElement.isRedefinitionContextValid(self) + OCL + + + + + + + + + + + + + + + + result = (if returnResult()->notEmpty() then returnResult()-> exists(isOrdered) else false endif) + OCL + + + + + + + + + + + + + + + result = (if returnResult()->notEmpty() then returnResult()->exists(isUnique) else true endif) + OCL + + + + + + + + + + + + + + + result = (if returnResult()->notEmpty() then returnResult()->any(true).lower else null endif) + OCL + + + + + + + + + + + + + + result = (ownedParameter->select (direction = ParameterDirectionKind::return)) + OCL + + + + + + + + + + + + + + + + result = (if returnResult()->notEmpty() then returnResult()->any(true).type else null endif) + OCL + + + + + + + + + + + + + result = (if returnResult()->notEmpty() then returnResult()->any(true).upper else null endif) + OCL + + + + + + + + + + + + + + + default->notEmpty() implies (default.oclIsKindOf(Operation) and (let defaultOp : Operation = default.oclAsType(Operation) in + defaultOp.ownedParameter->size() = parameteredElement.ownedParameter->size() and + Sequence{1.. defaultOp.ownedParameter->size()}->forAll( ix | + let p1: Parameter = defaultOp.ownedParameter->at(ix), p2 : Parameter = parameteredElement.ownedParameter->at(ix) in + p1.type = p2.type and p1.upper = p2.upper and p1.lower = p2.lower and p1.direction = p2.direction and p1.isOrdered = p2.isOrdered and p1.isUnique = p2.isUnique))) + OCL + + + + + + + + + + + + + + + + + + + + + + + + (effect = ParameterEffectKind::delete implies (direction = ParameterDirectionKind::_'in' or direction = ParameterDirectionKind::inout)) +and +(effect = ParameterEffectKind::create implies (direction = ParameterDirectionKind::out or direction = ParameterDirectionKind::inout or direction = ParameterDirectionKind::return)) + OCL + + + + + + + + + isException implies (direction <> ParameterDirectionKind::_'in' and direction <> ParameterDirectionKind::inout) + OCL + + + + + + + + + end->notEmpty() implies collaboration->notEmpty() + OCL + + + + + + + + + (isStream and behavior <> null) implies not behavior.isReentrant + OCL + + + + + + + + + not (isException and isStream) + OCL + + + + + + + + + (type.oclIsKindOf(DataType)) implies (effect = null) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (if self.type = String then defaultValue.stringValue() else null endif) + OCL + + + + + + + + + + + + + + + + + + + parameter->forAll(p1, p2 | self.owner = p1.owner and self.owner = p2.owner and p1.direction = p2.direction) + OCL + + + + + + + + + ((parameter->exists(direction = ParameterDirectionKind::_'in')) implies + behavioralFeature.ownedParameter->select(p | p.direction = ParameterDirectionKind::_'in' and p.parameterSet->isEmpty())->forAll(isStream)) + and +((parameter->exists(direction = ParameterDirectionKind::out)) implies + behavioralFeature.ownedParameter->select(p | p.direction = ParameterDirectionKind::out and p.parameterSet->isEmpty())->forAll(isStream)) + + OCL + + + + + + + + + parameter->forAll(parameterSet->forAll(s1, s2 | s1->size() = s2->size() implies s1.parameter->exists(p | not s2.parameter->includes(p)))) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + subsettedProperty->notEmpty() implies + (subsettingContext()->notEmpty() and subsettingContext()->forAll (sc | + subsettedProperty->forAll(sp | + sp.subsettingContext()->exists(c | sc.conformsTo(c))))) + OCL + + + + + + + + + isDerivedUnion implies isReadOnly + OCL + + + + + + + + + isComposite and association <> null implies opposite.upperBound() <= 1 + + + OCL + + + + + + + + + (redefinedProperty->notEmpty()) implies + (redefinitionContext->notEmpty() and + redefinedProperty->forAll(rp| + ((redefinitionContext->collect(fc| + fc.allParents()))->asSet())->collect(c| c.allFeatures())->asSet()->includes(rp))) + OCL + + + + + + + + + subsettedProperty->forAll(sp | + self.type.conformsTo(sp.type) and + ((self.upperBound()->notEmpty() and sp.upperBound()->notEmpty()) implies + self.upperBound() <= sp.upperBound() )) + OCL + + + + + + + + + (self.isAttribute() +and (templateParameterSubstitution->notEmpty()) +implies (templateParameterSubstitution->forAll(ts | + ts.formal.oclIsKindOf(Property) + and ts.formal.oclAsType(Property).isAttribute()))) + OCL + + + + + + + + + isDerivedUnion implies isDerived + OCL + + + + + + + + + deployment->notEmpty() implies owner.oclIsKindOf(Node) and Node.allInstances()->exists(n | n.part->exists(p | p = self)) + OCL + + + + + + + + + subsettedProperty->forAll(sp | sp.name <> name) + OCL + + + + + + + + + (opposite->notEmpty() and owningAssociation->isEmpty()) implies classifier = opposite.type + OCL + + + + + + + + + qualifier->notEmpty() implies association->notEmpty() + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (not classifier->isEmpty()) + OCL + + + + + + + + + + + + + + + result = (self.oclIsKindOf(p.oclType()) and (p.oclIsKindOf(TypeElement) implies +self.type.conformsTo(p.oclAsType(TypedElement).type))) + OCL + + + + + + + + + + + + + + + + result = (aggregation = AggregationKind::composite) + OCL + + + + + + + + + + + + + + + + redefiningElement.isRedefinitionContextValid(self) + OCL + + + + + + result = (redefiningElement.oclIsKindOf(Property) and + let prop : Property = redefiningElement.oclAsType(Property) in + (prop.type.conformsTo(self.type) and + ((prop.lowerBound()->notEmpty() and self.lowerBound()->notEmpty()) implies prop.lowerBound() >= self.lowerBound()) and + ((prop.upperBound()->notEmpty() and self.upperBound()->notEmpty()) implies prop.lowerBound() <= self.lowerBound()) and + (self.isComposite implies prop.isComposite))) + OCL + + + + + + + + + + + + + + + result = (not classifier->isEmpty() or association.navigableOwnedEnd->includes(self)) + OCL + + + + + + + + + + + + + + + result = (if association <> null and association.memberEnd->size() = 2 +then + association.memberEnd->any(e | e <> self) +else + null +endif) + OCL + + + + + + + + + + + + result = (if association <> null +then association.memberEnd->excluding(self)->collect(type)->asSet() +else + if classifier<>null + then classifier->asSet() + else Set{} + endif +endif) + OCL + + + + + + + + + + + + + + + + + + + redefinedElement->forAll(re | re.isConsistentWith(self)) + OCL + + + + + + + + + redefinedElement->forAll(re | not re.isLeaf) + OCL + + + + + + + + + redefinedElement->forAll(re | self.isRedefinitionContextValid(re)) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (false) + OCL + + + + + + redefiningElement.isRedefinitionContextValid(self) + OCL + + + + + + + + + + + + + + + result = (redefinitionContext->exists(c | c.allParents()->includesAll(redefinedElement.redefinitionContext))) + OCL + + + + + + + + + + + + + + + + + + + classifier.allParents()->forAll(c | c.ownedTemplateSignature->notEmpty() implies self->closure(extendedSignature)->includes(c.ownedTemplateSignature)) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (if extendedSignature->isEmpty() then Set{} else extendedSignature.parameter->asSet() endif) + OCL + + + + + + + + + + + + + + + + + result = (redefiningElement.oclIsKindOf(RedefinableTemplateSignature)) + OCL + + + + + + redefiningElement.isRedefinitionContextValid(self) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result.is(1,1) + OCL + + + + + + + + + value.type.conformsTo(result.type) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + variable.isAccessibleBy(self) + OCL + + + + + + + + + + + + + + + + + + + + endData.end->exists(end | + end.type=_'context' or + end.visibility=VisibilityKind::public or + end.visibility=VisibilityKind::protected and + endData.end->exists(other | + other<>end and _'context'.conformsTo(other.type.oclAsType(Classifier)))) + + OCL + + + + + + + + + + + + + + + result <> null implies result.is(1,1) + OCL + + + + + + + + + value <> null implies value.type.conformsTo(structuralFeature.type) + OCL + + + + + + + + + value<>null implies value.is(1,1) + OCL + + + + + + + + + result <> null implies result.type = object.type + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + value <> null implies value.type.conformsTo(variable.type) + OCL + + + + + + + + + value<>null implies value.is(1,1) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + let parameter: OrderedSet(Parameter) = trigger.event->asSequence()->first().oclAsType(CallEvent).operation.inputParameters() in +result->size() = parameter->size() and +Sequence{1..result->size()}->forAll(i | + parameter->at(i).type.conformsTo(result->at(i).type) and + parameter->at(i).isOrdered = result->at(i).isOrdered and + parameter->at(i).compatibleWith(result->at(i))) + OCL + + + + + + + + + trigger->size()=1 and +trigger->asSequence()->first().event.oclIsKindOf(CallEvent) + + OCL + + + + + + + + + isUnmarshall = true + OCL + + + + + + + + + + + + + + + + + + + + + not isUnmarshall and trigger->exists(event.oclIsKindOf(SignalEvent) or event.oclIsKindOf(TimeEvent)) implies + output->size() = 1 and output->first().is(1,1) + OCL + + + + + + + + + input->size() = 0 + OCL + + + + + + + + + (self.oclIsTypeOf(AcceptEventAction) and + (trigger->forAll(event.oclIsKindOf(ChangeEvent) or + event.oclIsKindOf(CallEvent)))) +implies output->size() = 0 + OCL + + + + + + + + + isUnmarshall and self.oclIsTypeOf(AcceptEventAction) implies + trigger->size()=1 and + trigger->asSequence()->first().event.oclIsKindOf(SignalEvent) and + let attribute: OrderedSet(Property) = trigger->asSequence()->first().event.oclAsType(SignalEvent).signal.allAttributes() in + attribute->size()>0 and result->size() = attribute->size() and + Sequence{1..result->size()}->forAll(i | + result->at(i).type = attribute->at(i).type and + result->at(i).isOrdered = attribute->at(i).isOrdered and + result->at(i).includesMultiplicity(attribute->at(i))) + OCL + + + + + + + + + not isUnmarshall implies + result->isEmpty() or + let type: Type = result->first().type in type=null or + (trigger->forAll(event.oclIsKindOf(SignalEvent)) and + trigger.event.oclAsType(SignalEvent).signal->forAll(s | s.conformsTo(type))) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (let behavior: Behavior = self.containingBehavior() in +if behavior=null then null +else if behavior._'context' = null then behavior +else behavior._'context' +endif +endif) + OCL + + + + + + + + + + + + + + result = (self->asSet()) + OCL + + + + + + + + + + + + + + + result = (input.oclAsType(Pin)->asSet()->union(output->asSet())) + OCL + + + + + + + + + + + + result = (if inStructuredNode<>null then inStructuredNode.containingBehavior() +else if activity<>null then activity +else interaction +endif +endif +) + OCL + + + + + + + + + + + + + + + + + + fromAction.input->forAll(oclIsKindOf(ActionInputPin)) + OCL + + + + + + + + + fromAction.output->size() = 1 + OCL + + + + + + + + + fromAction.incoming->union(outgoing)->isEmpty() and +fromAction.input.incoming->isEmpty() and +fromAction.output.outgoing->isEmpty() + OCL + + + + + + + + + + + + + + + + + + + + + value<>null + OCL + + + + + + + + + if not structuralFeature.isOrdered then insertAt = null +else + not isReplaceAll implies + insertAt<>null and + insertAt->forAll(type=UnlimitedNatural and is(1,1.oclAsType(UnlimitedNatural))) +endif + + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + value <> null + OCL + + + + + + + + + if not variable.isOrdered then insertAt = null +else + not isReplaceAll implies + insertAt<>null and + insertAt->forAll(type=UnlimitedNatural and is(1,1.oclAsType(UnlimitedNatural))) +endif + + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + argument->size() = signal.allAttributes()->size() + OCL + + + + + + + + + let attribute: OrderedSet(Property) = signal.allAttributes() in +Sequence{1..argument->size()}->forAll(i | + argument->at(i).type.conformsTo(attribute->at(i).type) and + argument->at(i).isOrdered = attribute->at(i).isOrdered and + argument->at(i).compatibleWith(attribute->at(i))) + OCL + + + + + + + + + onPort=null + OCL + + + + + + + + + + + + + + + + + + + + let parameter: OrderedSet(Parameter) = self.inputParameters() in +argument->size() = parameter->size() and +Sequence{1..argument->size()}->forAll(i | + argument->at(i).type.conformsTo(parameter->at(i).type) and + argument->at(i).isOrdered = parameter->at(i).isOrdered and + argument->at(i).compatibleWith(parameter->at(i))) + OCL + + + + + + + + + let parameter: OrderedSet(Parameter) = self.outputParameters() in +result->size() = parameter->size() and +Sequence{1..result->size()}->forAll(i | + parameter->at(i).type.conformsTo(result->at(i).type) and + parameter->at(i).isOrdered = result->at(i).isOrdered and + parameter->at(i).compatibleWith(result->at(i))) + OCL + + + + + + + + + result->notEmpty() implies isSynchronous + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + onPort=null + OCL + + + + + + + + + + + + + + + + + result = (behavior.outputParameters()) + OCL + + + + + + + + + + + + + + + + result = (behavior.inputParameters()) + OCL + + + + + + + + + + + + + + + + + + + if onPort=null then target.type.oclAsType(Classifier).allFeatures()->includes(operation) +else target.type.oclAsType(Classifier).allFeatures()->includes(onPort) and onPort.provided->union(onPort.required).allFeatures()->includes(operation) +endif + OCL + + + + + + + + + + + + + + + + + + + + + + + result = (operation.outputParameters()) + OCL + + + + + + + + + + + + + + + + result = (operation.inputParameters()) + OCL + + + + + + + + + + + + + + + + + + + _'body'.oclAsType(Action).allActions().output->includesAll(bodyOutput) + OCL + + + + + + + + + test.oclAsType(Action).allActions().output->includes(decider) and +decider.type = Boolean and +decider.is(1,1) + OCL + + + + + + + + + test->intersection(_'body')->isEmpty() + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + object.is(1,1) + OCL + + + + + + + + + association.memberEnd->exists(self.object.type.conformsTo(type)) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + result<>null implies result.type = object.type + OCL + + + + + + + + + result<>null implies result.is(1,1) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + result.incoming->isEmpty() + OCL + + + + + + + + + input->isEmpty() + OCL + + + + + + + + + node->select(oclIsKindOf(ExecutableNode)).oclAsType(ExecutableNode)->forAll(n | + self.clause->select(test->union(_'body')->includes(n))->size()=1) + OCL + + + + + + + + + clause->forAll( + bodyOutput->size()=self.result->size() and + Sequence{1..self.result->size()}->forAll(i | + bodyOutput->at(i).type.conformsTo(result->at(i).type) and + bodyOutput->at(i).isOrdered = result->at(i).isOrdered and + bodyOutput->at(i).isUnique = result->at(i).isUnique and + bodyOutput->at(i).compatibleWith(result->at(i)))) + OCL + + + + + + + + + clause.test->union(clause._'body') = node->select(oclIsKindOf(ExecutableNode)).oclAsType(ExecutableNode) + OCL + + + + + + + + + clause->closure(predecessorClause)->intersection(clause)->isEmpty() + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (self->asSet()) + OCL + + + + + + + + + + + + + + + + + + + not self.association().isAbstract + OCL + + + + + + + + + + + + + + + + + + + + + + + result.is(1,1) + OCL + + + + + + + + + result.type = association() + OCL + + + + + + + + + self.association().oclIsKindOf(AssociationClass) + OCL + + + + + + + + + + + + + + + + + + + + + not classifier.isAbstract + OCL + + + + + + + + + result.is(1,1) + OCL + + + + + + + + + not classifier.oclIsKindOf(AssociationClass) + OCL + + + + + + + + + result.type = classifier + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + target.is(1,1) + OCL + + + + + + + + + target.type= null + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + regionAsInput->notEmpty() xor regionAsOutput->notEmpty() + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + outgoing->notEmpty() implies + action<>null and + action.oclIsKindOf(StructuredActivityNode) and + action.oclAsType(StructuredActivityNode).allOwnedNodes()->includesAll(outgoing.target) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + inputValue->asBag()=endData.allPins() + OCL + + + + + + + + + endData.end = self.association().memberEnd->asBag() + OCL + + + + + + + + + endData->forAll(not end.isStatic) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + result = (endData->asSequence()->first().end.association) + OCL + + + + + + + + + + + + + + + + if not end.isOrdered +then insertAt = null +else + not isReplaceAll=false implies + insertAt <> null and insertAt->forAll(type=UnlimitedNatural and is(1,1)) +endif + + OCL + + + + + + + + + + + + + + + + + + + + + + + + + result = (self.LinkEndData::allPins()->including(insertAt)) + OCL + + + + + + + + + + + + + + + + + + + value<>null implies value.type.conformsTo(end.type) + OCL + + + + + + + + + value<>null implies value.is(1,1) + OCL + + + + + + + + + value->excludesAll(qualifier.value) + OCL + + + + + + + + + end.association <> null + OCL + + + + + + + + + end.qualifier->includesAll(qualifier.qualifier) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (value->asBag()->union(qualifier.value)) + OCL + + + + + + + + + + + + + + + + + + + if not end.isOrdered or end.isUnique or isDestroyDuplicates +then destroyAt = null +else + destroyAt <> null and + destroyAt->forAll(type=UnlimitedNatural and is(1,1)) +endif + + OCL + + + + + + + + + + + + + + + + + + + + + + + + + result = (self.LinkEndData::allPins()->including(destroyAt)) + OCL + + + + + + + + + + + + + + + + + + + result.incoming->isEmpty() + OCL + + + + + + + + + loopVariableInput.outgoing->isEmpty() + OCL + + + + + + + + + setupPart->union(test)->union(bodyPart)=node->select(oclIsKindOf(ExecutableNode)).oclAsType(ExecutableNode)->asSet() + OCL + + + + + + + + + bodyPart.oclAsType(Action).allActions().output->includesAll(bodyOutput) + OCL + + + + + + + + + setupPart->intersection(test)->isEmpty() and +setupPart->intersection(bodyPart)->isEmpty() and +test->intersection(bodyPart)->isEmpty() + OCL + + + + + + + + + bodyOutput->size()=loopVariable->size() and +Sequence{1..loopVariable->size()}->forAll(i | + bodyOutput->at(i).type.conformsTo(loopVariable->at(i).type) and + bodyOutput->at(i).isOrdered = loopVariable->at(i).isOrdered and + bodyOutput->at(i).isUnique = loopVariable->at(i).isUnique and + loopVariable->at(i).includesMultiplicity(bodyOutput->at(i))) + OCL + + + + + + + + + loopVariableInput->size()=loopVariable->size() and +loopVariableInput.type=loopVariable.type and +loopVariableInput.isUnique=loopVariable.isUnique and +loopVariableInput.lower=loopVariable.lower and +loopVariableInput.upper=loopVariable.upper + OCL + + + + + + + + + result->size()=loopVariable->size() and +result.type=loopVariable.type and +result.isUnique=loopVariable.isUnique and +result.lower=loopVariable.lower and +result.upper=loopVariable.upper + OCL + + + + + + + + + allOwnedNodes()->includesAll(loopVariable.outgoing.target) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (self->asSet()) + OCL + + + + + + + + + + + + + + + + result = (self.StructuredActivityNode::sourceNodes()->union(loopVariable)) + OCL + + + + + + + + + + + + + + + + + + + language->notEmpty() implies (_'body'->size() = language->size()) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + incoming->notEmpty() implies + action<>null and + action.oclIsKindOf(StructuredActivityNode) and + action.oclAsType(StructuredActivityNode).allOwnedNodes()->includesAll(incoming.source) + OCL + + + + + + + + + + + + + + + isControl implies isControlType + OCL + + + + + + + + + not isUnique + OCL + + + + + + + + + + + + + + + + + + + + + + + value.is(1,1) + OCL + + + + + + + + + value.type.conformsTo(qualifier.type) + OCL + + + + + + + + + linkEndData.end.qualifier->includes(qualifier) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result.type = classifier + OCL + + + + + + + + + result.is(0,*) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + object.type = null + OCL + + + + + + + + + result.is(1,1) + OCL + + + + + + + + + result.type = Boolean + OCL + + + + + + + + + object.is(1,1) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + self.openEnd()->forAll(type=result.type and isOrdered=result.isOrdered) + + OCL + + + + + + + + + self.openEnd()->first().compatibleWith(result) + + OCL + + + + + + + + + let openEnd : Property = self.openEnd()->first() in + openEnd.visibility = VisibilityKind::public or + endData->exists(oed | + oed.end<>openEnd and + (_'context' = oed.end.type or + (openEnd.visibility = VisibilityKind::protected and + _'context'.conformsTo(oed.end.type.oclAsType(Classifier))))) + + OCL + + + + + + + + + self.openEnd()->size() = 1 + OCL + + + + + + + + + self.openEnd()->first().isNavigable() + + OCL + + + + + + + + + + + + + + + + + result = (endData->select(value=null).end->asOrderedSet()) + OCL + + + + + + + + + + + + + + + + + + + end.association <> null + OCL + + + + + + + + + object.is(1,1) + OCL + + + + + + + + + end.association.memberEnd->forAll(e | not e.isStatic) + OCL + + + + + + + + + result.type = end.type + OCL + + + + + + + + + result.is(1,1) + OCL + + + + + + + + + object.type = end.association + OCL + + + + + + + + + end.association.oclIsKindOf(AssociationClass) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + object.is(1,1) + OCL + + + + + + + + + object.type = qualifier.associationEnd.association + OCL + + + + + + + + + qualifier.is(1,1) + OCL + + + + + + + + + qualifier.associationEnd.association.memberEnd->forAll(e | not e.isStatic) + OCL + + + + + + + + + result.is(1,1) + OCL + + + + + + + + + result.type = qualifier.type + OCL + + + + + + + + + qualifier.associationEnd.association.oclIsKindOf(AssociationClass) + OCL + + + + + + + + + qualifier.associationEnd <> null + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + _'context' <> null + OCL + + + + + + + + + result.is(1,1) + OCL + + + + + + + + + let behavior: Behavior = self.containingBehavior() in +behavior.specification<>null implies not behavior.specification.isStatic + OCL + + + + + + + + + result.type = _'context' + OCL + + + + + + + + + + + + + + + + + + + + + structuralFeature.compatibleWith(result) + OCL + + + + + + + + + result.type =structuralFeature.type and +result.isOrdered = structuralFeature.isOrdered + + OCL + + + + + + + + + + + + + + + + + + + + + result.type =variable.type and +result.isOrdered = variable.isOrdered + + OCL + + + + + + + + + variable.compatibleWith(result) + OCL + + + + + + + + + + + + + + + + + + + + + object.type = null + OCL + + + + + + + + + not newClassifier->exists(isAbstract) + OCL + + + + + + + + + object.is(1,1) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + let inputs: OrderedSet(Parameter) = reducer.inputParameters() in +let outputs: OrderedSet(Parameter) = reducer.outputParameters() in +inputs->size()=2 and outputs->size()=1 and +inputs.type->forAll(t | + outputs.type->forAll(conformsTo(t)) and + -- Note that the following only checks the case when the collection is via multiple tokens. + collection.upperBound()>1 implies collection.type.conformsTo(t)) + OCL + + + + + + + + + + + + + + + + reducer.outputParameters().type->forAll(conformsTo(result.type)) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + if structuralFeature.isOrdered and not structuralFeature.isUnique and not isRemoveDuplicates then + value = null and + removeAt <> null and + removeAt.type = UnlimitedNatural and + removeAt.is(1,1) +else + removeAt = null and value <> null +endif + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + if variable.isOrdered and not variable.isUnique and not isRemoveDuplicates then + value = null and + removeAt <> null and + removeAt.type = UnlimitedNatural and + removeAt.is(1,1) +else + removeAt = null and value <> null +endif + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + let parameter:OrderedSet(Parameter) = replyToCall.event.oclAsType(CallEvent).operation.outputParameters() in +replyValue->size()=parameter->size() and +Sequence{1..replyValue->size()}->forAll(i | + replyValue->at(i).type.conformsTo(parameter->at(i).type) and + replyValue->at(i).isOrdered=parameter->at(i).isOrdered and + replyValue->at(i).compatibleWith(parameter->at(i))) + OCL + + + + + + + + + replyToCall.event.oclIsKindOf(CallEvent) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + onPort<>null implies target.type.oclAsType(Classifier).allFeatures()->includes(onPort) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + let attribute: OrderedSet(Property) = signal.allAttributes() in +Sequence{1..argument->size()}->forAll(i | + argument->at(i).type.conformsTo(attribute->at(i).type) and + argument->at(i).isOrdered = attribute->at(i).isOrdered and + argument->at(i).compatibleWith(attribute->at(i))) + OCL + + + + + + + + + argument->size()=signal.allAttributes()->size() + OCL + + + + + + + + + not onPort->isEmpty() implies target.type.oclAsType(Classifier).allFeatures()->includes(onPort) + + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + object.is(1,1) + OCL + + + + + + + + + object.type->notEmpty() implies + (object.type.oclIsKindOf(BehavioredClassifier) and object.type.oclAsType(BehavioredClassifier).classifierBehavior<>null) + OCL + + + + + + + + + + + + + + + + + + + + + object.is(1,1) + OCL + + + + + + + + + self.behavior()<>null + OCL + + + + + + + + + onPort->isEmpty() + OCL + + + + + + + + + + + + + + + + + + result = (self.behavior().outputParameters()) + OCL + + + + + + + + + + + + + + + + result = (self.behavior().inputParameters()) + OCL + + + + + + + + + + + + + + + result = (if object.type.oclIsKindOf(Behavior) then + object.type.oclAsType(Behavior) +else if object.type.oclIsKindOf(BehavioredClassifier) then + object.type.oclAsType(BehavioredClassifier).classifierBehavior +else + null +endif +endif) + OCL + + + + + + + + + + + + + + + + + + object.is(1,1) + OCL + + + + + + + + + object.type.oclAsType(Classifier).allFeatures()->includes(structuralFeature) or + object.type.conformsTo(structuralFeature.oclAsType(Property).opposite.type) + OCL + + + + + + + + + structuralFeature.visibility = VisibilityKind::public or +_'context'.allFeatures()->includes(structuralFeature) or +structuralFeature.visibility=VisibilityKind::protected and +_'context'.conformsTo(structuralFeature.oclAsType(Property).opposite.type.oclAsType(Classifier)) + + OCL + + + + + + + + + not structuralFeature.isStatic + OCL + + + + + + + + + structuralFeature.featuringClassifier->size() = 1 + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + output.outgoing.target->excludesAll(allOwnedNodes()-input) + OCL + + + + + + + + + edge=self.sourceNodes().outgoing->intersection(self.allOwnedNodes().incoming)-> + union(self.targetNodes().incoming->intersection(self.allOwnedNodes().outgoing))->asSet() + OCL + + + + + + + + + input.incoming.source->excludesAll(allOwnedNodes()-output) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + result = (node->select(oclIsKindOf(Action)).oclAsType(Action).allActions()->including(self)->asSet()) + OCL + + + + + + + + + + + + + + + + result = (self.Action::allOwnedNodes()->union(node)->union(node->select(oclIsKindOf(Action)).oclAsType(Action).allOwnedNodes())->asSet()) + OCL + + + + + + + + + + + + + + + result = (node->union(input.oclAsType(ActivityNode)->asSet())-> + union(node->select(oclIsKindOf(Action)).oclAsType(Action).output)->asSet()) + OCL + + + + + + + + + + + + + + + result = (node->union(output.oclAsType(ActivityNode)->asSet())-> + union(node->select(oclIsKindOf(Action)).oclAsType(Action).input)->asSet()) + OCL + + + + + + + + + + + + + + + + + result = (self.Action::containingActivity()) + OCL + + + + + + + + + + + + + + + + + + first.is(1,1) and second.is(1,1) + + OCL + + + + + + + + + first.type= null and second.type = null + + OCL + + + + + + + + + result.type=Boolean + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + unmarshallType.allAttributes()->size() >= 1 + OCL + + + + + + + + + unmarshallType.allAttributes()->size() = result->size() + OCL + + + + + + + + + let attribute:OrderedSet(Property) = unmarshallType.allAttributes() in +Sequence{1..result->size()}->forAll(i | + attribute->at(i).type.conformsTo(result->at(i).type) and + attribute->at(i).isOrdered=result->at(i).isOrdered and + attribute->at(i).compatibleWith(result->at(i))) + OCL + + + + + + + + + object.is(1,1) + OCL + + + + + + + + + object.type.conformsTo(unmarshallType) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + incoming->isEmpty() + OCL + + + + + + + + + value.type.conformsTo(type) + OCL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/uml4net.xmi/XmiReaderScope.cs b/uml4net.xmi/XmiReaderScope.cs index 301815fe..2ba2f67c 100644 --- a/uml4net.xmi/XmiReaderScope.cs +++ b/uml4net.xmi/XmiReaderScope.cs @@ -23,7 +23,7 @@ namespace uml4net.xmi using Autofac; using Microsoft.Extensions.Logging; - + using Resources; using uml4net.xmi.Readers; using uml4net.xmi.ReferenceResolver; using uml4net.xmi.Settings; @@ -68,9 +68,11 @@ internal XmiReaderScope() // Required services this.ContainerBuilder.RegisterGeneric(typeof(Logger<>)).As(typeof(ILogger<>)).PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies); this.ContainerBuilder.RegisterInstance(this).As().SingleInstance(); + this.ContainerBuilder.RegisterType().As(); this.ContainerBuilder.RegisterType().As().SingleInstance(); - this.ContainerBuilder.RegisterType().As(); + this.ContainerBuilder.RegisterType().As().SingleInstance(); + this.ContainerBuilder.RegisterType().As().SingleInstance(); // Readers this.ContainerBuilder.RegisterType().As().SingleInstance(); diff --git a/uml4net.xmi/uml4net.xmi.csproj b/uml4net.xmi/uml4net.xmi.csproj index f4854a23..a04da57a 100644 --- a/uml4net.xmi/uml4net.xmi.csproj +++ b/uml4net.xmi/uml4net.xmi.csproj @@ -31,9 +31,16 @@ + + + + + + +