From 98a3a62e42c94cff7c7fa8bee3a5de266d65dd3e Mon Sep 17 00:00:00 2001 From: Stefan Kapferer Date: Wed, 21 Aug 2024 20:04:53 +0200 Subject: [PATCH] Some more transformations (#359) --- ...BackendSystemFromFeatureBCActionTest.xtend | 4 + ...xtractAggregatesByCohesionActionTest.xtend | 4 + ...ractAggregatesByVolatilityActionTest.xtend | 4 + .../MergeBoundedContextsActionTest.xtend | 8 ++ ...itBoundedContextByFeaturesActionTest.xtend | 8 ++ ...SplitBoundedContextByOwnerActionTest.xtend | 8 ++ ...ystemContextIntoSubsystemsActionTest.xtend | 4 + .../tests/actions/UserStoryActionsTest.xtend | 39 +++++++++ ...akeholderForUserStoryRoleCommandTest.xtend | 50 ++++++++++++ ...RegisterForBoundedContextCommandTest.xtend | 48 +++++++++++ .../ExtractIDValueObjectQuickFixTest.xtend | 4 + ...rdinationInBPMNSketchMinerActionTest.xtend | 4 + .../OpenFlowInBPMNSketchMinerActionTest.xtend | 4 + .../SplitStoryByVerbQuickFixTest.xtend | 4 + .../dsl/ide/actions/CMLActionRegistry.java | 6 +- ...eateStakeholderForUserStoryRoleAction.java | 77 ++++++++++++++++++ ...eValueRegisterForBoundedContextAction.java | 78 ++++++++++++++++++ .../dsl/ide/commands/CMLCommandRegistry.java | 6 +- ...ateStakeholderForUserStoryRoleCommand.java | 39 +++++++++ ...ValueRegisterForBoundedContextCommand.java | 39 +++++++++ .../create-stakeholder-for-roleinstory-1.cml | 12 +++ ...e-value-register-for-bounded-context-1.cml | 7 ++ ...reateStakeholderFromUserStoryRoleTest.java | 78 ++++++++++++++++++ ...reateValue4StakeholderRefactoringTest.java | 24 +++++- ...rToNewStakeholderGroupRefactoringTest.java | 15 ++++ ...ateValueRegisterForBoundedContextTest.java | 59 ++++++++++++++ .../WrapValueInClusterRefactoringTest.java | 15 ++++ org.contextmapper.dsl.ui/plugin.xml | 30 +++++++ .../handler/AbstractRefactoringHandler.java | 20 +++-- ...ateStakeholderForUserStoryRoleHandler.java | 56 +++++++++++++ .../CreateValue4StakeholderHandler.java | 3 + .../MoveStakeholderToNewGroupHandler.java | 3 + ...ValueRegisterForBoundedContextHandler.java | 56 +++++++++++++ .../WrapValueInClusterHandler.java | 3 + .../cml/CMLModelObjectsResolvingHelper.java | 62 +++++++++----- .../contextmapper/dsl/cml/XtextIdHelper.java | 38 +++++++++ .../ContextMappingDSLFormatter.xtend | 2 + .../CreateStakeholderForUserStoryRole.java | 81 +++++++++++++++++++ .../CreateValue4StakeholderRefactoring.java | 13 +++ .../CreateValueRegisterForBoundedContext.java | 53 ++++++++++++ 40 files changed, 1038 insertions(+), 30 deletions(-) create mode 100644 org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/commands/refactoring/CreateStakeholderForUserStoryRoleCommandTest.xtend create mode 100644 org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/commands/refactoring/CreateValueRegisterForBoundedContextCommandTest.xtend create mode 100644 org.contextmapper.dsl.ide/src/org/contextmapper/dsl/ide/actions/impl/CreateStakeholderForUserStoryRoleAction.java create mode 100644 org.contextmapper.dsl.ide/src/org/contextmapper/dsl/ide/actions/impl/CreateValueRegisterForBoundedContextAction.java create mode 100644 org.contextmapper.dsl.ide/src/org/contextmapper/dsl/ide/commands/impl/refactoring/CreateStakeholderForUserStoryRoleCommand.java create mode 100644 org.contextmapper.dsl.ide/src/org/contextmapper/dsl/ide/commands/impl/refactoring/CreateValueRegisterForBoundedContextCommand.java create mode 100644 org.contextmapper.dsl.tests/integ-test-files/refactorings/create-stakeholder-for-roleinstory-1.cml create mode 100644 org.contextmapper.dsl.tests/integ-test-files/refactorings/create-value-register-for-bounded-context-1.cml create mode 100644 org.contextmapper.dsl.tests/src/org/contextmapper/dsl/refactoring/stakeholders/CreateStakeholderFromUserStoryRoleTest.java create mode 100644 org.contextmapper.dsl.tests/src/org/contextmapper/dsl/refactoring/value_registers/CreateValueRegisterForBoundedContextTest.java create mode 100644 org.contextmapper.dsl.ui/src/org/contextmapper/dsl/ui/handler/stakeholders/CreateStakeholderForUserStoryRoleHandler.java create mode 100644 org.contextmapper.dsl.ui/src/org/contextmapper/dsl/ui/handler/value_registers/CreateValueRegisterForBoundedContextHandler.java create mode 100644 org.contextmapper.dsl/src/org/contextmapper/dsl/cml/XtextIdHelper.java create mode 100644 org.contextmapper.dsl/src/org/contextmapper/dsl/refactoring/stakeholders/CreateStakeholderForUserStoryRole.java create mode 100644 org.contextmapper.dsl/src/org/contextmapper/dsl/refactoring/value_registers/CreateValueRegisterForBoundedContext.java diff --git a/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/actions/DeriveFrontendAndBackendSystemFromFeatureBCActionTest.xtend b/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/actions/DeriveFrontendAndBackendSystemFromFeatureBCActionTest.xtend index 34e6e480..247d8e14 100644 --- a/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/actions/DeriveFrontendAndBackendSystemFromFeatureBCActionTest.xtend +++ b/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/actions/DeriveFrontendAndBackendSystemFromFeatureBCActionTest.xtend @@ -33,6 +33,10 @@ class DeriveFrontendAndBackendSystemFromFeatureBCActionTest extends AbstractBoun title : Derive Frontend And Backend System From Feature BC args : file://«this.root»/MyModel.cml,TestFeatureContext + command : cml.ar.createValueRegisterForBoundedContext.proxy + title : Create Value Register For Bounded Context + args : + file://«this.root»/MyModel.cml,TestFeatureContext ''' ] } diff --git a/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/actions/ExtractAggregatesByCohesionActionTest.xtend b/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/actions/ExtractAggregatesByCohesionActionTest.xtend index 5c4812c2..ee00b99e 100644 --- a/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/actions/ExtractAggregatesByCohesionActionTest.xtend +++ b/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/actions/ExtractAggregatesByCohesionActionTest.xtend @@ -34,6 +34,10 @@ class ExtractAggregatesByCohesionActionTest extends AbstractBoundedContextCodeAc title : Extract Aggregates By Cohesion args : file://«this.root»/MyModel.cml,TestContext,TestAggregate1,TestAggregate2 + command : cml.ar.createValueRegisterForBoundedContext.proxy + title : Create Value Register For Bounded Context + args : + file://«this.root»/MyModel.cml,TestContext ''' ] } diff --git a/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/actions/ExtractAggregatesByVolatilityActionTest.xtend b/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/actions/ExtractAggregatesByVolatilityActionTest.xtend index 28402fe1..1de87988 100644 --- a/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/actions/ExtractAggregatesByVolatilityActionTest.xtend +++ b/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/actions/ExtractAggregatesByVolatilityActionTest.xtend @@ -42,6 +42,10 @@ class ExtractAggregatesByVolatilityActionTest extends AbstractBoundedContextCode title : Extract Aggregates By Cohesion args : file://«this.root»/MyModel.cml,TestContext,TestAggregate1,TestAggregate2 + command : cml.ar.createValueRegisterForBoundedContext.proxy + title : Create Value Register For Bounded Context + args : + file://«this.root»/MyModel.cml,TestContext ''' ] } diff --git a/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/actions/MergeBoundedContextsActionTest.xtend b/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/actions/MergeBoundedContextsActionTest.xtend index 8edc7c11..660a30ec 100644 --- a/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/actions/MergeBoundedContextsActionTest.xtend +++ b/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/actions/MergeBoundedContextsActionTest.xtend @@ -32,6 +32,10 @@ class MergeBoundedContextsActionTest extends AbstractBoundedContextCodeActionTes title : Merge Bounded Contexts args : file://«this.root»/MyModel.cml,TestContext1,TestContext2 + command : cml.ar.createValueRegisterForBoundedContext.proxy + title : Create Value Register For Bounded Context + args : + file://«this.root»/MyModel.cml,TestContext1 ''' ] } @@ -49,6 +53,10 @@ class MergeBoundedContextsActionTest extends AbstractBoundedContextCodeActionTes line = 1 column = 12 expectedCodeActions = ''' + command : cml.ar.createValueRegisterForBoundedContext.proxy + title : Create Value Register For Bounded Context + args : + file://«this.root»/MyModel.cml, title : Create a Bounded Context named 'SomeContext'. kind : quickfix command : diff --git a/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/actions/SplitBoundedContextByFeaturesActionTest.xtend b/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/actions/SplitBoundedContextByFeaturesActionTest.xtend index a871f72c..87597557 100644 --- a/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/actions/SplitBoundedContextByFeaturesActionTest.xtend +++ b/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/actions/SplitBoundedContextByFeaturesActionTest.xtend @@ -44,6 +44,10 @@ class SplitBoundedContextByFeaturesActionTest extends AbstractBoundedContextCode title : Extract Aggregates By Cohesion args : file://«this.root»/MyModel.cml,TestContext,TestAggregate1,TestAggregate2 + command : cml.ar.createValueRegisterForBoundedContext.proxy + title : Create Value Register For Bounded Context + args : + file://«this.root»/MyModel.cml,TestContext ''' ] } @@ -68,6 +72,10 @@ class SplitBoundedContextByFeaturesActionTest extends AbstractBoundedContextCode title : Extract Aggregates By Cohesion args : file://«this.root»/MyModel.cml,TestContext,TestAggregate1,TestAggregate2 + command : cml.ar.createValueRegisterForBoundedContext.proxy + title : Create Value Register For Bounded Context + args : + file://«this.root»/MyModel.cml,TestContext ''' ] } diff --git a/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/actions/SplitBoundedContextByOwnerActionTest.xtend b/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/actions/SplitBoundedContextByOwnerActionTest.xtend index 466c369b..ca7ab32e 100644 --- a/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/actions/SplitBoundedContextByOwnerActionTest.xtend +++ b/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/actions/SplitBoundedContextByOwnerActionTest.xtend @@ -48,6 +48,10 @@ class SplitBoundedContextByOwnerActionTest extends AbstractBoundedContextCodeAct title : Merge Bounded Contexts args : file://«this.root»/MyModel.cml,TestContext,Team2,Team1 + command : cml.ar.createValueRegisterForBoundedContext.proxy + title : Create Value Register For Bounded Context + args : + file://«this.root»/MyModel.cml,TestContext ''' ] } @@ -76,6 +80,10 @@ class SplitBoundedContextByOwnerActionTest extends AbstractBoundedContextCodeAct title : Merge Bounded Contexts args : file://«this.root»/MyModel.cml,TestContext,Team1 + command : cml.ar.createValueRegisterForBoundedContext.proxy + title : Create Value Register For Bounded Context + args : + file://«this.root»/MyModel.cml,TestContext ''' ] } diff --git a/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/actions/SplitSystemContextIntoSubsystemsActionTest.xtend b/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/actions/SplitSystemContextIntoSubsystemsActionTest.xtend index 5427799b..36dbc52b 100644 --- a/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/actions/SplitSystemContextIntoSubsystemsActionTest.xtend +++ b/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/actions/SplitSystemContextIntoSubsystemsActionTest.xtend @@ -33,6 +33,10 @@ class SplitSystemContextIntoSubsystemsActionTest extends AbstractBoundedContextC title : Split System Context Into Subsystems args : file://«this.root»/MyModel.cml,TestSystemContext + command : cml.ar.createValueRegisterForBoundedContext.proxy + title : Create Value Register For Bounded Context + args : + file://«this.root»/MyModel.cml,TestSystemContext ''' ] } diff --git a/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/actions/UserStoryActionsTest.xtend b/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/actions/UserStoryActionsTest.xtend index 9714b4bc..1b7716cb 100644 --- a/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/actions/UserStoryActionsTest.xtend +++ b/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/actions/UserStoryActionsTest.xtend @@ -38,4 +38,43 @@ class UserStoryActionsTest extends AbstractBoundedContextCodeActionTest { ] } + @Test + def void canOfferAction2CreateStakeholderIfRoleIsDefined() { + testCodeAction [ + model = ''' + UserStory SampleStory1 { + As a "SampleUserOfFutureSystem" + I want to "manipulate" a "BusinessObject" with its "property1", "property2" + so that "I am more efficient" + } + ''' + expectedCodeActions = ''' + command : cml.ar.deriveSubdomainFromURs.proxy + title : Derive Subdomain From User Requirements + args : + file://«this.root»/MyModel.cml,SampleStory1 + command : cml.ar.addEthicalValueAssessment.proxy + title : Add Ethical Value Assessment + args : + file://«this.root»/MyModel.cml,SampleStory1 + command : cml.ar.createStakeholderForUserStoryRole.proxy + title : Create Stakeholder For User Story Role + args : + file://«this.root»/MyModel.cml,SampleStory1 + title : Split Story by Verb/Operation + kind : quickfix + command : Command [ + title = "Split Story by Verb/Operation" + command = "cml.quickfix.command.splitStoryByVerb.proxy" + arguments = LinkedList ( + "file://«this.root»/MyModel.cml", + "SampleStory1" + ) + ] + codes : split-feature-by-verb-suggestion + edit : + ''' + ] + } + } diff --git a/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/commands/refactoring/CreateStakeholderForUserStoryRoleCommandTest.xtend b/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/commands/refactoring/CreateStakeholderForUserStoryRoleCommandTest.xtend new file mode 100644 index 00000000..5c10e331 --- /dev/null +++ b/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/commands/refactoring/CreateStakeholderForUserStoryRoleCommandTest.xtend @@ -0,0 +1,50 @@ +/* + * Copyright 2024 The Context Mapper Project Team + * + * 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. + */ +package org.contextmapper.dsl.ide.tests.commands.refactoring + +import com.google.gson.JsonArray +import com.google.gson.JsonPrimitive +import org.contextmapper.dsl.ide.commands.CMLCommandService +import org.contextmapper.dsl.ide.tests.commands.AbstractCMLCommandTest +import org.eclipse.lsp4j.ExecuteCommandParams +import org.junit.jupiter.api.Test + +class CreateStakeholderForUserStoryRoleCommandTest extends AbstractCMLCommandTest { + + @Test + def void testARCommandExecution() { + // given + initializeCommandsDynamically() + val model = ''' + UserStory TestStory { + As a "Tester" I want to "create" an "Test" so that "" + } + ''' + val fileURI = 'test.cml'.writeFile(model) + + // when + val refactoringParams = new JsonArray + refactoringParams.add("TestStory") + val result = languageServer.executeCommand( + new ExecuteCommandParams("cml.ar.createStakeholderForUserStoryRole", + #[new JsonPrimitive(fileURI), refactoringParams])) + val resultVal = result.get as String + + // then + CMLCommandService.COMMAND_EXECUTED_RETURN_VALUE.assertEquals(resultVal) + } + +} diff --git a/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/commands/refactoring/CreateValueRegisterForBoundedContextCommandTest.xtend b/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/commands/refactoring/CreateValueRegisterForBoundedContextCommandTest.xtend new file mode 100644 index 00000000..a80b9df5 --- /dev/null +++ b/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/commands/refactoring/CreateValueRegisterForBoundedContextCommandTest.xtend @@ -0,0 +1,48 @@ +/* + * Copyright 2024 The Context Mapper Project Team + * + * 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. + */ +package org.contextmapper.dsl.ide.tests.commands.refactoring + +import com.google.gson.JsonArray +import com.google.gson.JsonPrimitive +import org.contextmapper.dsl.ide.commands.CMLCommandService +import org.contextmapper.dsl.ide.tests.commands.AbstractCMLCommandTest +import org.eclipse.lsp4j.ExecuteCommandParams +import org.junit.jupiter.api.Test + +class CreateValueRegisterForBoundedContextCommandTest extends AbstractCMLCommandTest { + + @Test + def void testARCommandExecution() { + // given + initializeCommandsDynamically() + val model = ''' + BoundedContext TestContext + ''' + val fileURI = 'test.cml'.writeFile(model) + + // when + val refactoringParams = new JsonArray + refactoringParams.add("TestContext") + val result = languageServer.executeCommand( + new ExecuteCommandParams("cml.ar.createValueRegisterForBoundedContext", + #[new JsonPrimitive(fileURI), refactoringParams])) + val resultVal = result.get as String + + // then + CMLCommandService.COMMAND_EXECUTED_RETURN_VALUE.assertEquals(resultVal) + } + +} diff --git a/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/quickfixes/ExtractIDValueObjectQuickFixTest.xtend b/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/quickfixes/ExtractIDValueObjectQuickFixTest.xtend index 8a583061..c63cca2f 100644 --- a/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/quickfixes/ExtractIDValueObjectQuickFixTest.xtend +++ b/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/quickfixes/ExtractIDValueObjectQuickFixTest.xtend @@ -35,6 +35,10 @@ class ExtractIDValueObjectQuickFixTest extends AbstractCMLLanguageServerTest { } ''' expectedCodeActions = ''' + command : cml.ar.createValueRegisterForBoundedContext.proxy + title : Create Value Register For Bounded Context + args : + file://«this.root»/MyModel.cml,TestContext title : Extract Value Object kind : quickfix command : diff --git a/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/quickfixes/OpenCoordinationInBPMNSketchMinerActionTest.xtend b/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/quickfixes/OpenCoordinationInBPMNSketchMinerActionTest.xtend index 9920ce2e..64c29b37 100644 --- a/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/quickfixes/OpenCoordinationInBPMNSketchMinerActionTest.xtend +++ b/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/quickfixes/OpenCoordinationInBPMNSketchMinerActionTest.xtend @@ -36,6 +36,10 @@ class OpenCoordinationInBPMNSketchMinerActionTest extends AbstractCMLCommandTest } ''' expectedCodeActions = ''' + command : cml.ar.createValueRegisterForBoundedContext.proxy + title : Create Value Register For Bounded Context + args : + file://«this.root»/MyModel.cml,ContextA title : Open coordination in BPMN Sketch Miner kind : quickfix command : Command [ diff --git a/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/quickfixes/OpenFlowInBPMNSketchMinerActionTest.xtend b/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/quickfixes/OpenFlowInBPMNSketchMinerActionTest.xtend index 85cc1eb8..17703ec2 100644 --- a/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/quickfixes/OpenFlowInBPMNSketchMinerActionTest.xtend +++ b/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/quickfixes/OpenFlowInBPMNSketchMinerActionTest.xtend @@ -38,6 +38,10 @@ class OpenFlowInBPMNSketchMinerActionTest extends AbstractCMLCommandTest { } ''' expectedCodeActions = ''' + command : cml.ar.createValueRegisterForBoundedContext.proxy + title : Create Value Register For Bounded Context + args : + file://«this.root»/MyModel.cml,ContextA title : Open flow in BPMN Sketch Miner kind : quickfix command : Command [ diff --git a/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/quickfixes/SplitStoryByVerbQuickFixTest.xtend b/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/quickfixes/SplitStoryByVerbQuickFixTest.xtend index ac987b4a..fc3b4965 100644 --- a/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/quickfixes/SplitStoryByVerbQuickFixTest.xtend +++ b/org.contextmapper.dsl.ide.tests/src/org/contextmapper/dsl/ide/tests/quickfixes/SplitStoryByVerbQuickFixTest.xtend @@ -43,6 +43,10 @@ class SplitStoryByVerbQuickFixTest extends AbstractCMLCommandTest { file://«this.root»/MyModel.cml,TestStory command : cml.ar.addEthicalValueAssessment.proxy title : Add Ethical Value Assessment + args : + file://«this.root»/MyModel.cml,TestStory + command : cml.ar.createStakeholderForUserStoryRole.proxy + title : Create Stakeholder For User Story Role args : file://«this.root»/MyModel.cml,TestStory title : Split Story by Verb/Operation diff --git a/org.contextmapper.dsl.ide/src/org/contextmapper/dsl/ide/actions/CMLActionRegistry.java b/org.contextmapper.dsl.ide/src/org/contextmapper/dsl/ide/actions/CMLActionRegistry.java index d566d4f6..0ac9c765 100644 --- a/org.contextmapper.dsl.ide/src/org/contextmapper/dsl/ide/actions/CMLActionRegistry.java +++ b/org.contextmapper.dsl.ide/src/org/contextmapper/dsl/ide/actions/CMLActionRegistry.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 The Context Mapper Project Team + * Copyright 2020-2024 The Context Mapper Project Team * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,9 @@ import org.contextmapper.dsl.cml.CMLResource; import org.contextmapper.dsl.exception.ContextMapperApplicationException; import org.contextmapper.dsl.ide.actions.impl.AddEthicalValueAssessmentAction; +import org.contextmapper.dsl.ide.actions.impl.CreateStakeholderForUserStoryRoleAction; import org.contextmapper.dsl.ide.actions.impl.CreateValue4StakeholderAction; +import org.contextmapper.dsl.ide.actions.impl.CreateValueRegisterForBoundedContextAction; import org.contextmapper.dsl.ide.actions.impl.DeriveBoundedContextFromSubdomainsAction; import org.contextmapper.dsl.ide.actions.impl.DeriveFrontendAndBackendFromFeatureBCAction; import org.contextmapper.dsl.ide.actions.impl.DeriveSubdomainFromUserRequirementsAction; @@ -118,6 +120,8 @@ private List getAllActions(CMLResource resource, List se codeActions.add(new CreateValue4StakeholderAction(resource, selectedObjects)); codeActions.add(new AddEthicalValueAssessmentAction(resource, selectedObjects)); codeActions.add(new WrapValueInClusterAction(resource, selectedObjects)); + codeActions.add(new CreateStakeholderForUserStoryRoleAction(resource, selectedObjects)); + codeActions.add(new CreateValueRegisterForBoundedContextAction(resource, selectedObjects)); return Lists.newLinkedList(codeActions); } diff --git a/org.contextmapper.dsl.ide/src/org/contextmapper/dsl/ide/actions/impl/CreateStakeholderForUserStoryRoleAction.java b/org.contextmapper.dsl.ide/src/org/contextmapper/dsl/ide/actions/impl/CreateStakeholderForUserStoryRoleAction.java new file mode 100644 index 00000000..89d53d31 --- /dev/null +++ b/org.contextmapper.dsl.ide/src/org/contextmapper/dsl/ide/actions/impl/CreateStakeholderForUserStoryRoleAction.java @@ -0,0 +1,77 @@ +/* + * Copyright 2024 The Context Mapper Project Team + * + * 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. + */ +package org.contextmapper.dsl.ide.actions.impl; + +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import org.contextmapper.dsl.cml.CMLResource; +import org.contextmapper.dsl.contextMappingDSL.UserStory; +import org.contextmapper.dsl.ide.actions.CMLCodeAction; +import org.contextmapper.dsl.refactoring.stakeholders.CreateStakeholderForUserStoryRole; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.lsp4j.Command; + +import com.google.common.collect.Lists; + +/** + * Action that calls the "Create Stakeholder for User Story Role" refactoring. + * + * @author Stefan Kapferer + * + */ +public class CreateStakeholderForUserStoryRoleAction implements CMLCodeAction { + + private CMLResource cmlResource; + private List editorSelection; + + public CreateStakeholderForUserStoryRoleAction(CMLResource cmlResource, List editorSelection) { + this.cmlResource = cmlResource; + this.editorSelection = editorSelection; + } + + @Override + public boolean isApplicable() { + Set userStories = getSelectedUserStories(); + if (userStories.isEmpty() || userStories.size() > 1) + return false; + UserStory story = userStories.iterator().next(); + if (story.getRole() == null || "".equals(story.getRole())) + return false; + return !(new CreateStakeholderForUserStoryRole(story.getName()).stakeholderForRoleAlreadyExists(story)); + } + + @Override + public Command getCommand() { + UserStory story = getSelectedUserStory(); + List commandArguments = Lists.newLinkedList(); + commandArguments.add(cmlResource.getURI().toString()); + commandArguments.add(story.getName()); + return new Command("Create Stakeholder For User Story Role", "cml.ar.createStakeholderForUserStoryRole.proxy", + commandArguments); + } + + private UserStory getSelectedUserStory() { + return getSelectedUserStories().iterator().next(); + } + + private Set getSelectedUserStories() { + return editorSelection.stream().filter(o -> o instanceof UserStory).map(o -> (UserStory) o) + .collect(Collectors.toSet()); + } + +} diff --git a/org.contextmapper.dsl.ide/src/org/contextmapper/dsl/ide/actions/impl/CreateValueRegisterForBoundedContextAction.java b/org.contextmapper.dsl.ide/src/org/contextmapper/dsl/ide/actions/impl/CreateValueRegisterForBoundedContextAction.java new file mode 100644 index 00000000..50718e5c --- /dev/null +++ b/org.contextmapper.dsl.ide/src/org/contextmapper/dsl/ide/actions/impl/CreateValueRegisterForBoundedContextAction.java @@ -0,0 +1,78 @@ +/* + * Copyright 2024 The Context Mapper Project Team + * + * 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. + */ +package org.contextmapper.dsl.ide.actions.impl; + +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import org.contextmapper.dsl.cml.CMLModelObjectsResolvingHelper; +import org.contextmapper.dsl.cml.CMLResource; +import org.contextmapper.dsl.contextMappingDSL.BoundedContext; +import org.contextmapper.dsl.contextMappingDSL.ContextMappingModel; +import org.contextmapper.dsl.ide.actions.CMLCodeAction; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.lsp4j.Command; + +import com.google.common.collect.Lists; + +/** + * Action that calls the "Create Value Register for Bounded Context" + * refactoring. + * + * @author Stefan Kapferer + * + */ +public class CreateValueRegisterForBoundedContextAction implements CMLCodeAction { + + private CMLResource cmlResource; + private List editorSelection; + + public CreateValueRegisterForBoundedContextAction(CMLResource cmlResource, List editorSelection) { + this.cmlResource = cmlResource; + this.editorSelection = editorSelection; + } + + @Override + public boolean isApplicable() { + Set contexts = getSelectedBoundedContexts(); + if (contexts.isEmpty() || contexts.size() > 1) + return false; + BoundedContext context = contexts.iterator().next(); + return !(new CMLModelObjectsResolvingHelper((ContextMappingModel) context.eContainer()) + .isReferencedInAValueRegister(context)); + } + + @Override + public Command getCommand() { + BoundedContext context = getSelectedBoundedContext(); + List commandArguments = Lists.newLinkedList(); + commandArguments.add(cmlResource.getURI().toString()); + commandArguments.add(context.getName()); + return new Command("Create Value Register For Bounded Context", + "cml.ar.createValueRegisterForBoundedContext.proxy", commandArguments); + } + + private BoundedContext getSelectedBoundedContext() { + return getSelectedBoundedContexts().iterator().next(); + } + + private Set getSelectedBoundedContexts() { + return editorSelection.stream().filter(o -> o instanceof BoundedContext).map(o -> (BoundedContext) o) + .collect(Collectors.toSet()); + } + +} diff --git a/org.contextmapper.dsl.ide/src/org/contextmapper/dsl/ide/commands/CMLCommandRegistry.java b/org.contextmapper.dsl.ide/src/org/contextmapper/dsl/ide/commands/CMLCommandRegistry.java index d1105c2f..1a6fb29b 100644 --- a/org.contextmapper.dsl.ide/src/org/contextmapper/dsl/ide/commands/CMLCommandRegistry.java +++ b/org.contextmapper.dsl.ide/src/org/contextmapper/dsl/ide/commands/CMLCommandRegistry.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 The Context Mapper Project Team + * Copyright 2020-2024 The Context Mapper Project Team * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,9 @@ import org.contextmapper.dsl.ide.commands.impl.generation.SketchMinerGenerationCommand; import org.contextmapper.dsl.ide.commands.impl.quickfix.SplitStoryByVerbCommand; import org.contextmapper.dsl.ide.commands.impl.refactoring.AddEthicalValueAssessmentCommand; +import org.contextmapper.dsl.ide.commands.impl.refactoring.CreateStakeholderForUserStoryRoleCommand; import org.contextmapper.dsl.ide.commands.impl.refactoring.CreateValue4StakeholderCommand; +import org.contextmapper.dsl.ide.commands.impl.refactoring.CreateValueRegisterForBoundedContextCommand; import org.contextmapper.dsl.ide.commands.impl.refactoring.DeriveBoundedContextFromSubdomainsCommand; import org.contextmapper.dsl.ide.commands.impl.refactoring.DeriveFrontendAndBackendFromFeatureBCCommand; import org.contextmapper.dsl.ide.commands.impl.refactoring.DeriveSubdomainFromUserRequirementsCommand; @@ -93,6 +95,8 @@ private void registerCommands() { commandMap.put("cml.ar.createValueForStakeholder", new CreateValue4StakeholderCommand(editRecorder)); commandMap.put("cml.ar.addEthicalValueAssessment", new AddEthicalValueAssessmentCommand(editRecorder)); commandMap.put("cml.ar.wrapValueInCluster", new WrapValueInClusterCommand(editRecorder)); + commandMap.put("cml.ar.createStakeholderForUserStoryRole", new CreateStakeholderForUserStoryRoleCommand(editRecorder)); + commandMap.put("cml.ar.createValueRegisterForBoundedContext", new CreateValueRegisterForBoundedContextCommand(editRecorder)); } public CMLResourceCommand getCommand(String commandId) { diff --git a/org.contextmapper.dsl.ide/src/org/contextmapper/dsl/ide/commands/impl/refactoring/CreateStakeholderForUserStoryRoleCommand.java b/org.contextmapper.dsl.ide/src/org/contextmapper/dsl/ide/commands/impl/refactoring/CreateStakeholderForUserStoryRoleCommand.java new file mode 100644 index 00000000..7a32fda6 --- /dev/null +++ b/org.contextmapper.dsl.ide/src/org/contextmapper/dsl/ide/commands/impl/refactoring/CreateStakeholderForUserStoryRoleCommand.java @@ -0,0 +1,39 @@ +/* + * Copyright 2024 The Context Mapper Project Team + * + * 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. + */ +package org.contextmapper.dsl.ide.commands.impl.refactoring; + +import org.contextmapper.dsl.ide.edit.WorkspaceEditRecorder; +import org.contextmapper.dsl.refactoring.SemanticCMLRefactoring; +import org.contextmapper.dsl.refactoring.stakeholders.CreateStakeholderForUserStoryRole; +import org.eclipse.lsp4j.ExecuteCommandParams; + +import com.google.gson.JsonArray; +import com.google.gson.JsonPrimitive; + +public class CreateStakeholderForUserStoryRoleCommand extends AbstractRefactoringCommand { + + public CreateStakeholderForUserStoryRoleCommand(WorkspaceEditRecorder editRecorder) { + super(editRecorder); + } + + @Override + protected SemanticCMLRefactoring getRefactoring(ExecuteCommandParams params) { + JsonArray refactoringParams = (JsonArray) params.getArguments().get(1); + JsonPrimitive userStoryName = (JsonPrimitive) refactoringParams.get(0); + return new CreateStakeholderForUserStoryRole(userStoryName.getAsString()); + } + +} diff --git a/org.contextmapper.dsl.ide/src/org/contextmapper/dsl/ide/commands/impl/refactoring/CreateValueRegisterForBoundedContextCommand.java b/org.contextmapper.dsl.ide/src/org/contextmapper/dsl/ide/commands/impl/refactoring/CreateValueRegisterForBoundedContextCommand.java new file mode 100644 index 00000000..10422eaf --- /dev/null +++ b/org.contextmapper.dsl.ide/src/org/contextmapper/dsl/ide/commands/impl/refactoring/CreateValueRegisterForBoundedContextCommand.java @@ -0,0 +1,39 @@ +/* + * Copyright 2024 The Context Mapper Project Team + * + * 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. + */ +package org.contextmapper.dsl.ide.commands.impl.refactoring; + +import org.contextmapper.dsl.ide.edit.WorkspaceEditRecorder; +import org.contextmapper.dsl.refactoring.SemanticCMLRefactoring; +import org.contextmapper.dsl.refactoring.value_registers.CreateValueRegisterForBoundedContext; +import org.eclipse.lsp4j.ExecuteCommandParams; + +import com.google.gson.JsonArray; +import com.google.gson.JsonPrimitive; + +public class CreateValueRegisterForBoundedContextCommand extends AbstractRefactoringCommand { + + public CreateValueRegisterForBoundedContextCommand(WorkspaceEditRecorder editRecorder) { + super(editRecorder); + } + + @Override + protected SemanticCMLRefactoring getRefactoring(ExecuteCommandParams params) { + JsonArray refactoringParams = (JsonArray) params.getArguments().get(1); + JsonPrimitive boundedContextName = (JsonPrimitive) refactoringParams.get(0); + return new CreateValueRegisterForBoundedContext(boundedContextName.getAsString()); + } + +} diff --git a/org.contextmapper.dsl.tests/integ-test-files/refactorings/create-stakeholder-for-roleinstory-1.cml b/org.contextmapper.dsl.tests/integ-test-files/refactorings/create-stakeholder-for-roleinstory-1.cml new file mode 100644 index 00000000..c6042aed --- /dev/null +++ b/org.contextmapper.dsl.tests/integ-test-files/refactorings/create-stakeholder-for-roleinstory-1.cml @@ -0,0 +1,12 @@ + +UserStory SampleStory1 { + As a "SampleUserOfFutureSystem" + I want to "manipulate" a "BusinessObject" with its "property1", "property2" + so that "I am more efficient" +} + +UserStory SampleStory2 { + As a "Sample User Of Future System" + I want to "manipulate" a "BusinessObject" with its "property1", "property2" + so that "I am more efficient" +} \ No newline at end of file diff --git a/org.contextmapper.dsl.tests/integ-test-files/refactorings/create-value-register-for-bounded-context-1.cml b/org.contextmapper.dsl.tests/integ-test-files/refactorings/create-value-register-for-bounded-context-1.cml new file mode 100644 index 00000000..fac9e1da --- /dev/null +++ b/org.contextmapper.dsl.tests/integ-test-files/refactorings/create-value-register-for-bounded-context-1.cml @@ -0,0 +1,7 @@ + +BoundedContext TestContextWithRegister + +BoundedContext TestContextWithoutRegister {} + +ValueRegister ExistingRegister for TestContextWithRegister { +} diff --git a/org.contextmapper.dsl.tests/src/org/contextmapper/dsl/refactoring/stakeholders/CreateStakeholderFromUserStoryRoleTest.java b/org.contextmapper.dsl.tests/src/org/contextmapper/dsl/refactoring/stakeholders/CreateStakeholderFromUserStoryRoleTest.java new file mode 100644 index 00000000..87262998 --- /dev/null +++ b/org.contextmapper.dsl.tests/src/org/contextmapper/dsl/refactoring/stakeholders/CreateStakeholderFromUserStoryRoleTest.java @@ -0,0 +1,78 @@ +/* + * Copyright 2024 The Context Mapper Project Team + * + * 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. + */ +package org.contextmapper.dsl.refactoring.stakeholders; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.io.IOException; + +import org.contextmapper.dsl.cml.CMLResource; +import org.contextmapper.dsl.contextMappingDSL.ContextMappingModel; +import org.contextmapper.dsl.refactoring.AbstractRefactoringTest; +import org.junit.jupiter.api.Test; + +public class CreateStakeholderFromUserStoryRoleTest extends AbstractRefactoringTest { + + @Test + void canCreateValueIfNameIsOK() throws IOException { + // given + String inputModelName = "create-stakeholder-for-roleinstory-1.cml"; + CMLResource input = getResourceCopyOfTestCML(inputModelName); + + // when + new CreateStakeholderForUserStoryRole("SampleStory1").refactor(input); + + // then + ContextMappingModel model = input.getContextMappingModel(); + assertEquals(1, model.getStakeholders().size()); + assertEquals(1, model.getStakeholders().get(0).getStakeholders().size()); + assertEquals("SampleUserOfFutureSystem", model.getStakeholders().get(0).getStakeholders().get(0).getName()); + } + + @Test + void canCreateValueIfNameContainsBlanksOrOtherSpecialCharacters() throws IOException { + // given + String inputModelName = "create-stakeholder-for-roleinstory-1.cml"; + CMLResource input = getResourceCopyOfTestCML(inputModelName); + + // when + new CreateStakeholderForUserStoryRole("SampleStory2").refactor(input); + + // then + ContextMappingModel model = input.getContextMappingModel(); + assertEquals(1, model.getStakeholders().size()); + assertEquals(1, model.getStakeholders().get(0).getStakeholders().size()); + assertEquals("Sample_User_Of_Future_System", model.getStakeholders().get(0).getStakeholders().get(0).getName()); + } + + @Test + void createOnlyOneStakeholderEvenIfRefactoringIsExecutedTwice() throws IOException { + // given + String inputModelName = "create-stakeholder-for-roleinstory-1.cml"; + CMLResource input = getResourceCopyOfTestCML(inputModelName); + + // when + CreateStakeholderForUserStoryRole ar = new CreateStakeholderForUserStoryRole("SampleStory1"); + ar.refactor(input); + ar.refactor(input); + + // then + ContextMappingModel model = input.getContextMappingModel(); + assertEquals(1, model.getStakeholders().size()); + assertEquals(1, model.getStakeholders().get(0).getStakeholders().size()); + assertEquals("SampleUserOfFutureSystem", model.getStakeholders().get(0).getStakeholders().get(0).getName()); + } +} diff --git a/org.contextmapper.dsl.tests/src/org/contextmapper/dsl/refactoring/stakeholders/CreateValue4StakeholderRefactoringTest.java b/org.contextmapper.dsl.tests/src/org/contextmapper/dsl/refactoring/stakeholders/CreateValue4StakeholderRefactoringTest.java index e2eeeeba..56b7801d 100644 --- a/org.contextmapper.dsl.tests/src/org/contextmapper/dsl/refactoring/stakeholders/CreateValue4StakeholderRefactoringTest.java +++ b/org.contextmapper.dsl.tests/src/org/contextmapper/dsl/refactoring/stakeholders/CreateValue4StakeholderRefactoringTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2024 The Context Mapper Project Team + * + * 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. + */ package org.contextmapper.dsl.refactoring.stakeholders; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -25,8 +40,15 @@ void canCreateValueIfARegisterAlreadyExists() throws IOException { assertEquals(1, model.getValueRegisters().size()); assertEquals(1, model.getValueRegisters().get(0).getValues().size()); assertEquals("To_Be_Defined", model.getValueRegisters().get(0).getValues().get(0).getName()); + assertEquals(1, model.getValueRegisters().get(0).getValues().get(0).getDemonstrators().size()); + assertEquals("Tester", model.getValueRegisters().get(0).getValues().get(0).getElicitations().get(0) + .getStakeholder().getName()); + assertEquals("MEDIUM", model.getValueRegisters().get(0).getValues().get(0).getElicitations().get(0) + .getPriority().getLiteral()); + assertEquals(1, + model.getValueRegisters().get(0).getValues().get(0).getElicitations().get(0).getConsequences().size()); } - + @Test void canCreateValueIfNoRegisterExistsYet() throws IOException { // given diff --git a/org.contextmapper.dsl.tests/src/org/contextmapper/dsl/refactoring/stakeholders/MoveStakeholderToNewStakeholderGroupRefactoringTest.java b/org.contextmapper.dsl.tests/src/org/contextmapper/dsl/refactoring/stakeholders/MoveStakeholderToNewStakeholderGroupRefactoringTest.java index cd9366e8..fa2dfb5b 100644 --- a/org.contextmapper.dsl.tests/src/org/contextmapper/dsl/refactoring/stakeholders/MoveStakeholderToNewStakeholderGroupRefactoringTest.java +++ b/org.contextmapper.dsl.tests/src/org/contextmapper/dsl/refactoring/stakeholders/MoveStakeholderToNewStakeholderGroupRefactoringTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2024 The Context Mapper Project Team + * + * 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. + */ package org.contextmapper.dsl.refactoring.stakeholders; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/org.contextmapper.dsl.tests/src/org/contextmapper/dsl/refactoring/value_registers/CreateValueRegisterForBoundedContextTest.java b/org.contextmapper.dsl.tests/src/org/contextmapper/dsl/refactoring/value_registers/CreateValueRegisterForBoundedContextTest.java new file mode 100644 index 00000000..9fb47a65 --- /dev/null +++ b/org.contextmapper.dsl.tests/src/org/contextmapper/dsl/refactoring/value_registers/CreateValueRegisterForBoundedContextTest.java @@ -0,0 +1,59 @@ +/* + * Copyright 2024 The Context Mapper Project Team + * + * 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. + */ +package org.contextmapper.dsl.refactoring.value_registers; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.io.IOException; + +import org.contextmapper.dsl.cml.CMLResource; +import org.contextmapper.dsl.contextMappingDSL.ContextMappingModel; +import org.contextmapper.dsl.refactoring.AbstractRefactoringTest; +import org.junit.jupiter.api.Test; + +public class CreateValueRegisterForBoundedContextTest extends AbstractRefactoringTest { + + @Test + void doesNotCreateValueRegisterForBoundedContextIfAlreadyPresent() throws IOException { + // given + String inputModelName = "create-value-register-for-bounded-context-1.cml"; + CMLResource input = getResourceCopyOfTestCML(inputModelName); + + // when + new CreateValueRegisterForBoundedContext("TestContextWithRegister").refactor(input); + + // then + ContextMappingModel model = input.getContextMappingModel(); + assertEquals(1, model.getValueRegisters().size()); + } + + @Test + void canCreateValueRegisterForBoundedContext() throws IOException { + // given + String inputModelName = "create-value-register-for-bounded-context-1.cml"; + CMLResource input = getResourceCopyOfTestCML(inputModelName); + + // when + new CreateValueRegisterForBoundedContext("TestContextWithoutRegister").refactor(input); + + // then + ContextMappingModel model = input.getContextMappingModel(); + assertEquals(2, model.getValueRegisters().size()); + assertEquals("ValueRegisterFor_TestContextWithoutRegister", model.getValueRegisters().get(1).getName()); + assertEquals("Compliance with values in value register", + model.getBoundedContexts().get(1).getResponsibilities().get(0)); + } +} diff --git a/org.contextmapper.dsl.tests/src/org/contextmapper/dsl/refactoring/value_registers/WrapValueInClusterRefactoringTest.java b/org.contextmapper.dsl.tests/src/org/contextmapper/dsl/refactoring/value_registers/WrapValueInClusterRefactoringTest.java index 4a641a83..563562ee 100644 --- a/org.contextmapper.dsl.tests/src/org/contextmapper/dsl/refactoring/value_registers/WrapValueInClusterRefactoringTest.java +++ b/org.contextmapper.dsl.tests/src/org/contextmapper/dsl/refactoring/value_registers/WrapValueInClusterRefactoringTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2024 The Context Mapper Project Team + * + * 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. + */ package org.contextmapper.dsl.refactoring.value_registers; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/org.contextmapper.dsl.ui/plugin.xml b/org.contextmapper.dsl.ui/plugin.xml index 5b7bc1b9..53360c41 100644 --- a/org.contextmapper.dsl.ui/plugin.xml +++ b/org.contextmapper.dsl.ui/plugin.xml @@ -589,6 +589,15 @@ + + + + + + @@ -598,6 +607,15 @@ + + + + + + @@ -713,6 +731,12 @@ id="org.contextmapper.dsl.ui.handler.stakeholders.CreateValue4StakeholderRefactoringCommand"> + + + + + + + + diff --git a/org.contextmapper.dsl.ui/src/org/contextmapper/dsl/ui/handler/AbstractRefactoringHandler.java b/org.contextmapper.dsl.ui/src/org/contextmapper/dsl/ui/handler/AbstractRefactoringHandler.java index 505e4e16..5514bed0 100644 --- a/org.contextmapper.dsl.ui/src/org/contextmapper/dsl/ui/handler/AbstractRefactoringHandler.java +++ b/org.contextmapper.dsl.ui/src/org/contextmapper/dsl/ui/handler/AbstractRefactoringHandler.java @@ -64,17 +64,20 @@ public Object execute(ExecutionEvent event) throws ExecutionException { currentResource = getCurrentResource(); executeRefactoring(new CMLResource(currentResource), event); } catch (RefactoringSerializationException e) { - String message = e.getMessage() != null && !"".equals(e.getMessage()) ? e.getMessage() : e.getClass().getName() + " occurred in " + this.getClass().getName(); + String message = e.getMessage() != null && !"".equals(e.getMessage()) ? e.getMessage() + : e.getClass().getName() + " occurred in " + this.getClass().getName(); Status status = new Status(IStatus.ERROR, DslActivator.PLUGIN_ID, message, e); StatusManager.getManager().handle(status); MessageDialog.openInformation(HandlerUtil.getActiveShell(event), "Model Input", e.getMessage()); } catch (ContextMapperApplicationException e) { MessageDialog.openInformation(HandlerUtil.getActiveShell(event), "Model Input", e.getMessage()); } catch (Exception e) { - String message = e.getMessage() != null && !"".equals(e.getMessage()) ? e.getMessage() : e.getClass().getName() + " occurred in " + this.getClass().getName(); + String message = e.getMessage() != null && !"".equals(e.getMessage()) ? e.getMessage() + : e.getClass().getName() + " occurred in " + this.getClass().getName(); Status status = new Status(IStatus.ERROR, DslActivator.PLUGIN_ID, message, e); StatusManager.getManager().handle(status); - ErrorDialog.openError(HandlerUtil.getActiveShell(event), "Error", "Exception occured during execution of command!", status); + ErrorDialog.openError(HandlerUtil.getActiveShell(event), "Error", + "Exception occured during execution of command!", status); } return null; } @@ -91,7 +94,8 @@ protected Resource getCurrentResource() { protected ContextMappingModel getCurrentContextMappingModel() { Resource resource = currentResource == null ? getCurrentResource() : currentResource; - List contextMappingModels = IteratorExtensions.toList(Iterators.filter(resource.getAllContents(), ContextMappingModel.class)); + List contextMappingModels = IteratorExtensions.toList( + Iterators.filter(resource.getAllContents(), ContextMappingModel.class)); if (contextMappingModels.size() > 0) { return contextMappingModels.get(0); @@ -117,8 +121,8 @@ protected Set getReferencedContextMappingModels(ContextMapp URI importURI = URI.createURI(cmlImport.getImportURI()); Resource resource = rs.getResource(importURI.resolve(currentResource.getURI()), true); if (resource != null) { - List contextMappingModels = IteratorExtensions - .toList(Iterators.filter(resource.getAllContents(), ContextMappingModel.class)); + List contextMappingModels = IteratorExtensions.toList( + Iterators.filter(resource.getAllContents(), ContextMappingModel.class)); models.addAll(contextMappingModels); } } @@ -149,6 +153,10 @@ protected Set getAllSelectedElements() { return xtextEditorHelper.getAllSelectedElements(EditorUtils.getActiveXtextEditor()); } + protected boolean moreThenOneElementSelected() { + return getAllSelectedElements().size() > 1; + } + private boolean editorHasChanges() { final XtextEditor editor = EditorUtils.getActiveXtextEditor(); if (editor != null) { diff --git a/org.contextmapper.dsl.ui/src/org/contextmapper/dsl/ui/handler/stakeholders/CreateStakeholderForUserStoryRoleHandler.java b/org.contextmapper.dsl.ui/src/org/contextmapper/dsl/ui/handler/stakeholders/CreateStakeholderForUserStoryRoleHandler.java new file mode 100644 index 00000000..2234f02e --- /dev/null +++ b/org.contextmapper.dsl.ui/src/org/contextmapper/dsl/ui/handler/stakeholders/CreateStakeholderForUserStoryRoleHandler.java @@ -0,0 +1,56 @@ +/* + * Copyright 2024 The Context Mapper Project Team + * + * 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. + */ +package org.contextmapper.dsl.ui.handler.stakeholders; + +import org.contextmapper.dsl.cml.CMLResource; +import org.contextmapper.dsl.contextMappingDSL.UserStory; +import org.contextmapper.dsl.refactoring.SemanticCMLRefactoring; +import org.contextmapper.dsl.refactoring.stakeholders.CreateStakeholderForUserStoryRole; +import org.contextmapper.dsl.ui.handler.AbstractRefactoringHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.emf.ecore.EObject; + +public class CreateStakeholderForUserStoryRoleHandler extends AbstractRefactoringHandler { + + @Override + protected void executeRefactoring(CMLResource resource, ExecutionEvent event) { + UserStory userStory = (UserStory) this.getSelectedElement(); + SemanticCMLRefactoring ar = new CreateStakeholderForUserStoryRole(userStory.getName()); + ar.refactor(resource, getAllResources()); + ar.persistChanges(serializer); + } + + @Override + public boolean isEnabled() { + if (moreThenOneElementSelected()) + return false; + + EObject obj = this.getSelectedElement(); + + if (obj == null || !super.isEnabled()) + return false; + + if (!(obj instanceof UserStory)) + return false; + + UserStory story = (UserStory) obj; + if (story.getRole() == null || story.getRole().equals("")) + return false; + + // check whether Stakeholder of this name already exists + return !(new CreateStakeholderForUserStoryRole(story.getName()).stakeholderForRoleAlreadyExists(story)); + } +} diff --git a/org.contextmapper.dsl.ui/src/org/contextmapper/dsl/ui/handler/stakeholders/CreateValue4StakeholderHandler.java b/org.contextmapper.dsl.ui/src/org/contextmapper/dsl/ui/handler/stakeholders/CreateValue4StakeholderHandler.java index 285b1232..995fa84e 100644 --- a/org.contextmapper.dsl.ui/src/org/contextmapper/dsl/ui/handler/stakeholders/CreateValue4StakeholderHandler.java +++ b/org.contextmapper.dsl.ui/src/org/contextmapper/dsl/ui/handler/stakeholders/CreateValue4StakeholderHandler.java @@ -35,6 +35,9 @@ protected void executeRefactoring(CMLResource resource, ExecutionEvent event) { @Override public boolean isEnabled() { + if (moreThenOneElementSelected()) + return false; + EObject obj = getSelectedElement(); if (obj == null || !super.isEnabled()) diff --git a/org.contextmapper.dsl.ui/src/org/contextmapper/dsl/ui/handler/stakeholders/MoveStakeholderToNewGroupHandler.java b/org.contextmapper.dsl.ui/src/org/contextmapper/dsl/ui/handler/stakeholders/MoveStakeholderToNewGroupHandler.java index cc9adf3f..fa85af8b 100644 --- a/org.contextmapper.dsl.ui/src/org/contextmapper/dsl/ui/handler/stakeholders/MoveStakeholderToNewGroupHandler.java +++ b/org.contextmapper.dsl.ui/src/org/contextmapper/dsl/ui/handler/stakeholders/MoveStakeholderToNewGroupHandler.java @@ -35,6 +35,9 @@ protected void executeRefactoring(CMLResource resource, ExecutionEvent event) { @Override public boolean isEnabled() { + if (moreThenOneElementSelected()) + return false; + EObject obj = getSelectedElement(); if (obj == null || !super.isEnabled()) diff --git a/org.contextmapper.dsl.ui/src/org/contextmapper/dsl/ui/handler/value_registers/CreateValueRegisterForBoundedContextHandler.java b/org.contextmapper.dsl.ui/src/org/contextmapper/dsl/ui/handler/value_registers/CreateValueRegisterForBoundedContextHandler.java new file mode 100644 index 00000000..47d90d58 --- /dev/null +++ b/org.contextmapper.dsl.ui/src/org/contextmapper/dsl/ui/handler/value_registers/CreateValueRegisterForBoundedContextHandler.java @@ -0,0 +1,56 @@ +/* + * Copyright 2024 The Context Mapper Project Team + * + * 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. + */ +package org.contextmapper.dsl.ui.handler.value_registers; + +import org.contextmapper.dsl.cml.CMLModelObjectsResolvingHelper; +import org.contextmapper.dsl.cml.CMLResource; +import org.contextmapper.dsl.contextMappingDSL.BoundedContext; +import org.contextmapper.dsl.contextMappingDSL.ContextMappingModel; +import org.contextmapper.dsl.refactoring.SemanticCMLRefactoring; +import org.contextmapper.dsl.refactoring.value_registers.CreateValueRegisterForBoundedContext; +import org.contextmapper.dsl.ui.handler.AbstractRefactoringHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.emf.ecore.EObject; + +public class CreateValueRegisterForBoundedContextHandler extends AbstractRefactoringHandler { + + @Override + protected void executeRefactoring(CMLResource resource, ExecutionEvent event) { + BoundedContext context = (BoundedContext) this.getSelectedElement(); + SemanticCMLRefactoring ar = new CreateValueRegisterForBoundedContext(context.getName()); + ar.refactor(resource, getAllResources()); + ar.persistChanges(serializer); + } + + @Override + public boolean isEnabled() { + if (moreThenOneElementSelected()) + return false; + + EObject obj = getSelectedElement(); + + if (obj == null || !super.isEnabled()) + return false; + + if (!(obj instanceof BoundedContext)) + return false; + + BoundedContext bc = (BoundedContext) obj; + return !(new CMLModelObjectsResolvingHelper((ContextMappingModel) bc.eContainer()) + .isReferencedInAValueRegister(bc)); + } + +} diff --git a/org.contextmapper.dsl.ui/src/org/contextmapper/dsl/ui/handler/value_registers/WrapValueInClusterHandler.java b/org.contextmapper.dsl.ui/src/org/contextmapper/dsl/ui/handler/value_registers/WrapValueInClusterHandler.java index aa207987..24c71eb4 100644 --- a/org.contextmapper.dsl.ui/src/org/contextmapper/dsl/ui/handler/value_registers/WrapValueInClusterHandler.java +++ b/org.contextmapper.dsl.ui/src/org/contextmapper/dsl/ui/handler/value_registers/WrapValueInClusterHandler.java @@ -36,6 +36,9 @@ protected void executeRefactoring(CMLResource resource, ExecutionEvent event) { @Override public boolean isEnabled() { + if (moreThenOneElementSelected()) + return false; + EObject obj = getSelectedElement(); if (obj == null || !super.isEnabled()) diff --git a/org.contextmapper.dsl/src/org/contextmapper/dsl/cml/CMLModelObjectsResolvingHelper.java b/org.contextmapper.dsl/src/org/contextmapper/dsl/cml/CMLModelObjectsResolvingHelper.java index a2f290a6..b32ba37d 100644 --- a/org.contextmapper.dsl/src/org/contextmapper/dsl/cml/CMLModelObjectsResolvingHelper.java +++ b/org.contextmapper.dsl/src/org/contextmapper/dsl/cml/CMLModelObjectsResolvingHelper.java @@ -34,6 +34,7 @@ import org.contextmapper.dsl.contextMappingDSL.SymmetricRelationship; import org.contextmapper.dsl.contextMappingDSL.UpstreamDownstreamRelationship; import org.contextmapper.dsl.contextMappingDSL.UserRequirement; +import org.contextmapper.dsl.contextMappingDSL.ValueRegister; import org.contextmapper.tactic.dsl.tacticdsl.Enum; import org.contextmapper.tactic.dsl.tacticdsl.Service; import org.contextmapper.tactic.dsl.tacticdsl.ServiceOperation; @@ -54,7 +55,8 @@ public CMLModelObjectsResolvingHelper(ContextMappingModel rootModel) { } private Set resolveImportedModels() { - Set importedResources = new CMLImportResolver().resolveImportedResources(new CMLResource(rootModel.eResource())); + Set importedResources = new CMLImportResolver() + .resolveImportedResources(new CMLResource(rootModel.eResource())); return importedResources.stream().map(r -> r.getContextMappingModel()).collect(Collectors.toSet()); } @@ -163,18 +165,20 @@ public List resolveAllAggregates() { public Set resolveAggregateStates(Aggregate aggregate) { Set aggregateStates = Sets.newHashSet(); - Optional optStatesEnum = aggregate.getDomainObjects().stream().filter(o -> o instanceof Enum).map(o -> (Enum) o) - .filter(o -> o.isDefinesAggregateLifecycle()).findFirst(); + Optional optStatesEnum = aggregate.getDomainObjects().stream() + .filter(o -> o instanceof Enum).map(o -> (Enum) o).filter(o -> o.isDefinesAggregateLifecycle()) + .findFirst(); if (optStatesEnum.isPresent()) - aggregateStates.addAll(optStatesEnum.get().getValues().stream().map(v -> v.getName()).collect(Collectors.toSet())); + aggregateStates + .addAll(optStatesEnum.get().getValues().stream().map(v -> v.getName()).collect(Collectors.toSet())); return aggregateStates; } - + public Set resolveAllUpstreamContexts(BoundedContext boundedContext) { Set allUpstreamContexts = new HashSet<>(); allUpstreamContexts.add(boundedContext); - + ContextMap contextMap = getContextMap(boundedContext); if (contextMap != null) { for (Relationship relationship : contextMap.getRelationships()) { @@ -184,27 +188,40 @@ public Set resolveAllUpstreamContexts(BoundedContext boundedCont } } } - + return allUpstreamContexts; } - + public Service resolveApplicationServiceByName(Application application, String serviceName) { - return application == null ? null : application.getServices().stream() - .filter(service -> service.getName().equals(serviceName)) - .findAny() - .orElse(null); + return application == null ? null + : application.getServices().stream().filter(service -> service.getName().equals(serviceName)).findAny() + .orElse(null); } - + public List resolveServiceOperationsByName(Service service, String operationName) { - return service == null ? null : service.getOperations().stream() - .filter(operation -> operation.getName().equals(operationName)) - .collect(Collectors.toList()); + return service == null ? null + : service.getOperations().stream().filter(operation -> operation.getName().equals(operationName)) + .collect(Collectors.toList()); + } + + public boolean isReferencedInAValueRegister(BoundedContext bc) { + if (rootModel == null) + return false; + List allValueRegisters = EcoreUtil2.getAllContentsOfType(rootModel, + ValueRegister.class); + for (ValueRegister nextRegister : allValueRegisters) { + if (nextRegister.getContext() != null && nextRegister.getContext() == bc) { + return true; + } + } + return false; } private boolean isBCDownstreamInRelationship(Relationship relationship, BoundedContext bc) { if (relationship instanceof SymmetricRelationship) { SymmetricRelationship symRel = (SymmetricRelationship) relationship; - return symRel.getParticipant1().getName().equals(bc.getName()) || symRel.getParticipant2().getName().equals(bc.getName()); + return symRel.getParticipant1().getName().equals(bc.getName()) + || symRel.getParticipant2().getName().equals(bc.getName()); } else if (relationship instanceof UpstreamDownstreamRelationship) { UpstreamDownstreamRelationship upDownRel = (UpstreamDownstreamRelationship) relationship; return upDownRel.getDownstream().getName().equals(bc.getName()); @@ -215,11 +232,14 @@ private boolean isBCDownstreamInRelationship(Relationship relationship, BoundedC private List getExposedAggregates(Relationship relationship) { List aggregates = Lists.newLinkedList(); if (relationship instanceof SymmetricRelationship) { - aggregates.addAll(EcoreUtil2.eAllOfType(((SymmetricRelationship) relationship).getParticipant1(), Aggregate.class)); - aggregates.addAll(EcoreUtil2.eAllOfType(((SymmetricRelationship) relationship).getParticipant2(), Aggregate.class)); + aggregates.addAll( + EcoreUtil2.eAllOfType(((SymmetricRelationship) relationship).getParticipant1(), Aggregate.class)); + aggregates.addAll( + EcoreUtil2.eAllOfType(((SymmetricRelationship) relationship).getParticipant2(), Aggregate.class)); } else if (relationship instanceof UpstreamDownstreamRelationship) { UpstreamDownstreamRelationship upDownRel = (UpstreamDownstreamRelationship) relationship; - if (upDownRel.getUpstreamExposedAggregates() != null && !upDownRel.getUpstreamExposedAggregates().isEmpty()) { + if (upDownRel.getUpstreamExposedAggregates() != null + && !upDownRel.getUpstreamExposedAggregates().isEmpty()) { aggregates.addAll(upDownRel.getUpstreamExposedAggregates()); } else { aggregates.addAll(EcoreUtil2.eAllOfType(upDownRel.getUpstream(), Aggregate.class)); @@ -227,7 +247,7 @@ private List getExposedAggregates(Relationship relationship) { } return aggregates; } - + private BoundedContext getUpstreamContext(Relationship relationship, BoundedContext boundedContext) { if (relationship instanceof SymmetricRelationship) { SymmetricRelationship symmetricRelationship = (SymmetricRelationship) relationship; diff --git a/org.contextmapper.dsl/src/org/contextmapper/dsl/cml/XtextIdHelper.java b/org.contextmapper.dsl/src/org/contextmapper/dsl/cml/XtextIdHelper.java new file mode 100644 index 00000000..370a9f2d --- /dev/null +++ b/org.contextmapper.dsl/src/org/contextmapper/dsl/cml/XtextIdHelper.java @@ -0,0 +1,38 @@ +/* + * Copyright 2020 The Context Mapper Project Team + * + * 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. + */ +package org.contextmapper.dsl.cml; + +public class XtextIdHelper { + + public String convertStringToXtextID(String text) { + StringBuilder result = new StringBuilder(text); + + // ID is not supposed to contain non-letters, non-digits: + for (int i = 0; i < text.length(); i++) { + if (!Character.isLetterOrDigit(text.charAt(i))) { + result.setCharAt(i, '_'); + } + } + + // ID must not start with a number/digit: + if (Character.isDigit(result.charAt(0))) { + result.insert(0, "s_"); + } + + return result.toString(); + } + +} diff --git a/org.contextmapper.dsl/src/org/contextmapper/dsl/formatting2/ContextMappingDSLFormatter.xtend b/org.contextmapper.dsl/src/org/contextmapper/dsl/formatting2/ContextMappingDSLFormatter.xtend index 295c2ca3..b7265896 100644 --- a/org.contextmapper.dsl/src/org/contextmapper/dsl/formatting2/ContextMappingDSLFormatter.xtend +++ b/org.contextmapper.dsl/src/org/contextmapper/dsl/formatting2/ContextMappingDSLFormatter.xtend @@ -392,6 +392,7 @@ class ContextMappingDSLFormatter extends TacticDDDLanguageFormatter { for (valueWeighting : valueRegister.valueWeightings) { valueWeighting.format } + valueRegister.regionFor.keyword('ValueRegister').prepend[newLine] } def dispatch void format(ValueEpic valueEpic, extension IFormattableDocument document) { @@ -453,6 +454,7 @@ class ContextMappingDSLFormatter extends TacticDDDLanguageFormatter { elicitation.regionFor.ruleCallTo(OPENRule).append[newLine], elicitation.regionFor.ruleCallTo(CLOSERule).prepend[newLine].append[newLine] )[indent] + elicitation.regionFor.keyword('Stakeholder').prepend[newLine] elicitation.regionFor.keyword('priority').prepend[newLine] elicitation.regionFor.keyword('impact').prepend[newLine] elicitation.regionFor.keyword('consequences').prepend[newLine] diff --git a/org.contextmapper.dsl/src/org/contextmapper/dsl/refactoring/stakeholders/CreateStakeholderForUserStoryRole.java b/org.contextmapper.dsl/src/org/contextmapper/dsl/refactoring/stakeholders/CreateStakeholderForUserStoryRole.java new file mode 100644 index 00000000..8650e1d1 --- /dev/null +++ b/org.contextmapper.dsl/src/org/contextmapper/dsl/refactoring/stakeholders/CreateStakeholderForUserStoryRole.java @@ -0,0 +1,81 @@ +/* + * Copyright 2024 The Context Mapper Project Team + * + * 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. + */ +package org.contextmapper.dsl.refactoring.stakeholders; + +import java.util.List; + +import org.contextmapper.dsl.cml.XtextIdHelper; +import org.contextmapper.dsl.contextMappingDSL.ContextMappingDSLFactory; +import org.contextmapper.dsl.contextMappingDSL.ContextMappingModel; +import org.contextmapper.dsl.contextMappingDSL.INFLUENCE; +import org.contextmapper.dsl.contextMappingDSL.INTEREST; +import org.contextmapper.dsl.contextMappingDSL.Stakeholder; +import org.contextmapper.dsl.contextMappingDSL.Stakeholders; +import org.contextmapper.dsl.contextMappingDSL.UserStory; +import org.contextmapper.dsl.refactoring.AbstractRefactoring; +import org.contextmapper.dsl.refactoring.SemanticCMLRefactoring; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.xtext.EcoreUtil2; + +public class CreateStakeholderForUserStoryRole extends AbstractRefactoring implements SemanticCMLRefactoring { + + private String userStoryName; + private XtextIdHelper idHelper; + + public CreateStakeholderForUserStoryRole(String userStoryName) { + this.userStoryName = userStoryName; + this.idHelper = new XtextIdHelper(); + } + + protected void doRefactor() { + UserStory story = this.getSelectedUserStory(); + if (!stakeholderForRoleAlreadyExists(story)) { + EObject parentObject = story.eContainer(); + if (parentObject instanceof ContextMappingModel) { + ContextMappingModel modelRoot = (ContextMappingModel) story.eContainer(); + Stakeholders stakeholders = createStakeholderForStoryRole(story); + modelRoot.getStakeholders().add(stakeholders); + } + } + } + + private Stakeholders createStakeholderForStoryRole(UserStory story) { + Stakeholder stakeholderForRole = ContextMappingDSLFactory.eINSTANCE.createStakeholder(); + stakeholderForRole.setName(idHelper.convertStringToXtextID(story.getRole())); + stakeholderForRole.setDescription("Role of/in " + userStoryName); + stakeholderForRole.setInfluence(INFLUENCE.MEDIUM); + stakeholderForRole.setInterest(INTEREST.MEDIUM); + Stakeholders stakeholders = ContextMappingDSLFactory.eINSTANCE.createStakeholders(); + stakeholders.getStakeholders().add(stakeholderForRole); + return stakeholders; + } + + private UserStory getSelectedUserStory() { + return EcoreUtil2.getAllContentsOfType(model, UserStory.class).stream() + .filter(s -> s.getName().equals(userStoryName)).findFirst().get(); + } + + public boolean stakeholderForRoleAlreadyExists(UserStory story) { + ContextMappingModel model = (ContextMappingModel) story.eContainer(); + List allStakeholders = EcoreUtil2.getAllContentsOfType(model, Stakeholder.class); + for (Stakeholder stakeholder : allStakeholders) { + if (stakeholder.getName().equals(idHelper.convertStringToXtextID(story.getRole()))) { + return true; + } + } + return false; + } +} diff --git a/org.contextmapper.dsl/src/org/contextmapper/dsl/refactoring/stakeholders/CreateValue4StakeholderRefactoring.java b/org.contextmapper.dsl/src/org/contextmapper/dsl/refactoring/stakeholders/CreateValue4StakeholderRefactoring.java index c5fbda92..cf5d6428 100644 --- a/org.contextmapper.dsl/src/org/contextmapper/dsl/refactoring/stakeholders/CreateValue4StakeholderRefactoring.java +++ b/org.contextmapper.dsl/src/org/contextmapper/dsl/refactoring/stakeholders/CreateValue4StakeholderRefactoring.java @@ -15,11 +15,15 @@ */ package org.contextmapper.dsl.refactoring.stakeholders; +import org.contextmapper.dsl.contextMappingDSL.Consequence; import org.contextmapper.dsl.contextMappingDSL.ContextMappingDSLFactory; +import org.contextmapper.dsl.contextMappingDSL.IMPACT; +import org.contextmapper.dsl.contextMappingDSL.PRIORITY; import org.contextmapper.dsl.contextMappingDSL.Stakeholder; import org.contextmapper.dsl.contextMappingDSL.Value; import org.contextmapper.dsl.contextMappingDSL.ValueElicitation; import org.contextmapper.dsl.contextMappingDSL.ValueRegister; + import org.contextmapper.dsl.refactoring.AbstractRefactoring; import org.contextmapper.dsl.refactoring.SemanticCMLRefactoring; import org.eclipse.xtext.EcoreUtil2; @@ -39,9 +43,18 @@ protected void doRefactor() { ValueRegister valueRegister = getOrCreateValueRegister(); Value value = ContextMappingDSLFactory.eINSTANCE.createValue(); value.setName("To_Be_Defined"); + value.getDemonstrators().add("Example where and how this value can be observed."); + ValueElicitation elicitation = ContextMappingDSLFactory.eINSTANCE.createValueElicitation(); elicitation.setStakeholder(s); + elicitation.setImpact(IMPACT.MEDIUM); + elicitation.setPriority(PRIORITY.MEDIUM); + Consequence consequence = ContextMappingDSLFactory.eINSTANCE.createConsequence(); + consequence.setConsequence("Sample consequence for/of [value] for [stakeholder], can be good, bad or neutral."); + consequence.setType("neutral"); + elicitation.getConsequences().add(consequence); value.getElicitations().add(elicitation); + valueRegister.getValues().add(value); } diff --git a/org.contextmapper.dsl/src/org/contextmapper/dsl/refactoring/value_registers/CreateValueRegisterForBoundedContext.java b/org.contextmapper.dsl/src/org/contextmapper/dsl/refactoring/value_registers/CreateValueRegisterForBoundedContext.java new file mode 100644 index 00000000..1d61c823 --- /dev/null +++ b/org.contextmapper.dsl/src/org/contextmapper/dsl/refactoring/value_registers/CreateValueRegisterForBoundedContext.java @@ -0,0 +1,53 @@ +package org.contextmapper.dsl.refactoring.value_registers; + +import org.contextmapper.dsl.contextMappingDSL.BoundedContext; +import org.contextmapper.dsl.contextMappingDSL.ContextMappingDSLFactory; +import org.contextmapper.dsl.contextMappingDSL.ValueRegister; +import org.contextmapper.dsl.refactoring.AbstractRefactoring; +import org.eclipse.emf.common.util.EList; +import org.eclipse.xtext.EcoreUtil2; + +public class CreateValueRegisterForBoundedContext extends AbstractRefactoring { + + private String contextName; + + public CreateValueRegisterForBoundedContext(String contextName) { + this.contextName = contextName; + } + + @Override + protected void doRefactor() { + if (!boundedContextAlreadyHasAValueRegister()) { + BoundedContext selectedBC = getSelectedBoundedContext(); + if (selectedBC != null) { + ValueRegister newVR = ContextMappingDSLFactory.eINSTANCE.createValueRegister(); + newVR.setName("ValueRegisterFor_" + contextName); + newVR.setContext(selectedBC); + model.getValueRegisters().add(newVR); + addComment(selectedBC); + } else { + System.err.println("Did not find bounded context " + this.contextName); + } + } + } + + private void addComment(BoundedContext boundedContext) { + boundedContext.getResponsibilities().add("Compliance with values in value register"); // TODO improve formatter + } + + private boolean boundedContextAlreadyHasAValueRegister() { + EList vrs = this.model.getValueRegisters(); + for (ValueRegister vr : vrs) { + if (vr.getContext() != null && vr.getContext().getName().equals(contextName)) { + return true; + } + } + return false; + } + + private BoundedContext getSelectedBoundedContext() { + return EcoreUtil2.getAllContentsOfType(model, BoundedContext.class).stream() + .filter(s -> s.getName().equals(contextName)).findFirst().get(); + } + +}