diff --git a/.java-version b/.java-version new file mode 100644 index 00000000..2dbc24b3 --- /dev/null +++ b/.java-version @@ -0,0 +1 @@ +11.0 diff --git a/org.contextmapper.dsl.tests/src/org/contextmapper/dsl/BoundedContextDSLParsingTest.xtend b/org.contextmapper.dsl.tests/src/org/contextmapper/dsl/BoundedContextDSLParsingTest.xtend index 75b9cf27..7ec9b6ca 100644 --- a/org.contextmapper.dsl.tests/src/org/contextmapper/dsl/BoundedContextDSLParsingTest.xtend +++ b/org.contextmapper.dsl.tests/src/org/contextmapper/dsl/BoundedContextDSLParsingTest.xtend @@ -21,6 +21,7 @@ import org.contextmapper.dsl.contextMappingDSL.BoundedContext import org.contextmapper.dsl.contextMappingDSL.BoundedContextType import org.contextmapper.dsl.contextMappingDSL.ContextMappingDSLPackage import org.contextmapper.dsl.contextMappingDSL.ContextMappingModel +import org.contextmapper.dsl.contextMappingDSL.Evolution import org.contextmapper.dsl.contextMappingDSL.KnowledgeLevel import org.eclipse.xtext.testing.InjectWith import org.eclipse.xtext.testing.extensions.InjectionExtension @@ -158,6 +159,38 @@ class BoundedContextDSLParsingTest { assertEquals("Java / Spring Boot App", result.boundedContexts.get(0).implementationTechnology); } + @Test + def void canDefineBusinessModel() { + // given + val String dslSnippet = ''' + BoundedContext testContext { + businessModel = "ENGAGEMENT" + } + '''; + // when + val ContextMappingModel result = parseHelper.parse(dslSnippet); + // then + assertThatNoParsingErrorsOccurred(result); + assertThatNoValidationErrorsOccurred(result); + assertEquals("ENGAGEMENT", result.boundedContexts.get(0).businessModel); + } + + @Test + def void canDefineEvolution() { + // given + val String dslSnippet = ''' + BoundedContext testContext { + evolution = CUSTOM_BUILT + } + '''; + // when + val ContextMappingModel result = parseHelper.parse(dslSnippet); + // then + assertThatNoParsingErrorsOccurred(result); + assertThatNoValidationErrorsOccurred(result); + assertEquals(Evolution.CUSTOM_BUILT, result.boundedContexts.get(0).evolution); + } + @Test def void canDefineTeamRealizesContext() { // given @@ -174,7 +207,7 @@ class BoundedContextDSLParsingTest { // then assertThatNoParsingErrorsOccurred(result); assertThatNoValidationErrorsOccurred(result); - + val BoundedContext team = result.boundedContexts.findFirst[it.type == BoundedContextType.TEAM]; assertEquals("ContextA", team.realizedBoundedContexts.get(0).name); } @@ -199,7 +232,7 @@ class BoundedContextDSLParsingTest { // then assertThatNoParsingErrorsOccurred(result); assertThatNoValidationErrorsOccurred(result); - + val BoundedContext team = result.boundedContexts.findFirst[it.type == BoundedContextType.TEAM]; val realizedBCNames = team.realizedBoundedContexts.stream.map[name].collect(Collectors.toList); assertTrue(realizedBCNames.contains("ContextA")); @@ -223,8 +256,8 @@ class BoundedContextDSLParsingTest { assertThatNoParsingErrorsOccurred(result); validationTestHelper.assertError(result, ContextMappingDSLPackage.Literals.BOUNDED_CONTEXT, "", String.format(ONLY_TEAMS_CAN_REALIZE_OTHER_BOUNDED_CONTEXT, "NotATeam")); - } - + } + @Test def void canDefineAttributesWithoutEqualSign() { // given @@ -239,20 +272,20 @@ class BoundedContextDSLParsingTest { '''; // when val ContextMappingModel result = parseHelper.parse(dslSnippet); - + // then assertThatNoParsingErrorsOccurred(result); assertThatNoValidationErrorsOccurred(result); assertEquals("Java / Spring Boot App", result.boundedContexts.get(0).implementationTechnology); assertEquals(KnowledgeLevel.META, result.boundedContexts.get(0).knowledgeLevel); assertEquals("this is my vision", result.boundedContexts.get(0).domainVisionStatement); - + val responsibilities = result.boundedContexts.get(0).responsibilities; assertTrue(responsibilities.contains("a responsibility description...")); assertTrue(responsibilities.contains("another responsibility")); assertEquals(BoundedContextType.FEATURE, result.boundedContexts.get(0).type); } - + @Test def void canRefineOtherBoundedContext() { // given @@ -262,11 +295,11 @@ class BoundedContextDSLParsingTest { '''; // when val ContextMappingModel result = parseHelper.parse(dslSnippet); - + // then assertThatNoParsingErrorsOccurred(result); assertThatNoValidationErrorsOccurred(result); - + val contextMapperContext = result.boundedContexts.get(1); assertEquals("ContextMapper", contextMapperContext.name); assertEquals("StrategicDDD", contextMapperContext.refinedBoundedContext.name); diff --git a/org.contextmapper.dsl/src/org/contextmapper/dsl/ContextMappingDSL.xtext b/org.contextmapper.dsl/src/org/contextmapper/dsl/ContextMappingDSL.xtext index e2aa2b9b..b97b81a8 100644 --- a/org.contextmapper.dsl/src/org/contextmapper/dsl/ContextMappingDSL.xtext +++ b/org.contextmapper.dsl/src/org/contextmapper/dsl/ContextMappingDSL.xtext @@ -27,7 +27,7 @@ ContextMappingModel: (map = ContextMap)? & (boundedContexts += BoundedContext)* & (domains += Domain)* & - (userRequirements += UserRequirement)* + (userRequirements += UserRequirement)* ) ; @@ -47,8 +47,8 @@ ContextMap: BoundedContext: (comment=ML_COMMENT | comment=SL_COMMENT)? - 'BoundedContext' name=ID (('implements' (implementedDomainParts+=[DomainPart]) ("," implementedDomainParts+=[DomainPart])*)? & - ('realizes' (realizedBoundedContexts+=[BoundedContext]) ("," realizedBoundedContexts+=[BoundedContext])*)? & + 'BoundedContext' name=ID (('implements' (implementedDomainParts+=[DomainPart]) ("," implementedDomainParts+=[DomainPart])*)? & + ('realizes' (realizedBoundedContexts+=[BoundedContext]) ("," realizedBoundedContexts+=[BoundedContext])*)? & ('refines' refinedBoundedContext=[BoundedContext])? ) ( @@ -58,6 +58,8 @@ BoundedContext: (('responsibilities' ('=')? responsibilities+=STRING) ("," responsibilities+=STRING)*)? & ('implementationTechnology' ('=')? implementationTechnology=STRING)? & ('knowledgeLevel' ('=')? knowledgeLevel=KnowledgeLevel)?) + ('businessModel' ('=')? businessModel=STRING)? & + ('evolution' ('=')? evolution=Evolution)? & ((application = Application)? & (modules += SculptorModule)* & (aggregates += Aggregate)*) @@ -101,13 +103,13 @@ SymmetricRelationship: Partnership: ( - (participant1 = [BoundedContext] '[''P'']' '<->' '[''P'']' participant2 = [BoundedContext]) | - ('[''P'']' participant1 = [BoundedContext] '<->' '[''P'']' participant2 = [BoundedContext]) | + (participant1 = [BoundedContext] '[''P'']' '<->' '[''P'']' participant2 = [BoundedContext]) | + ('[''P'']' participant1 = [BoundedContext] '<->' '[''P'']' participant2 = [BoundedContext]) | (participant1 = [BoundedContext] '[''P'']' '<->' participant2 = [BoundedContext] '[''P'']') | ('[''P'']' participant1 = [BoundedContext] '<->' participant2 = [BoundedContext] '[''P'']') | (participant1 = [BoundedContext] 'Partnership' participant2 = [BoundedContext]) ) - (':' name=ID)? + (':' name=ID)? (OPEN ('implementationTechnology' ('=')? implementationTechnology=STRING)? CLOSE)? @@ -122,17 +124,17 @@ SharedKernel: (participant1 = [BoundedContext] 'Shared-Kernel' participant2 = [BoundedContext]) | (participant1 = [BoundedContext] '<->' participant2 = [BoundedContext]) ) - (':' name=ID)? + (':' name=ID)? (OPEN ('implementationTechnology' ('=')? implementationTechnology=STRING)? CLOSE)? ; UpstreamDownstreamRelationship: - CustomerSupplierRelationship | + CustomerSupplierRelationship | ( ( - (upstream = [BoundedContext] (('[''U'']') | ('['('U'',')?(upstreamRoles+=UpstreamRole) ("," upstreamRoles+=UpstreamRole)*)']')? '->' (('[''D'']') | ('['('D'',')?(downstreamRoles+=DownstreamRole) ("," downstreamRoles+=DownstreamRole)*)']')? downstream = [BoundedContext]) | + (upstream = [BoundedContext] (('[''U'']') | ('['('U'',')?(upstreamRoles+=UpstreamRole) ("," upstreamRoles+=UpstreamRole)*)']')? '->' (('[''D'']') | ('['('D'',')?(downstreamRoles+=DownstreamRole) ("," downstreamRoles+=DownstreamRole)*)']')? downstream = [BoundedContext]) | (downstream = [BoundedContext] (('[''D'']') | ('['('D'',')?(downstreamRoles+=DownstreamRole) ("," downstreamRoles+=DownstreamRole)*)']')? '<-' (('[''U'']') | ('['('U'',')?(upstreamRoles+=UpstreamRole) ("," upstreamRoles+=UpstreamRole)*)']')? upstream = [BoundedContext]) | (upstream = [BoundedContext] ('['((upstreamRoles+=UpstreamRole) ("," upstreamRoles+=UpstreamRole)*)?']')?'Upstream-Downstream'('['((downstreamRoles+=DownstreamRole) ("," downstreamRoles+=DownstreamRole)*)?']')? downstream = [BoundedContext]) | (downstream = [BoundedContext] ('['((downstreamRoles+=DownstreamRole) ("," downstreamRoles+=DownstreamRole)*)?']')?'Downstream-Upstream'('['((upstreamRoles+=UpstreamRole) ("," upstreamRoles+=UpstreamRole)*)?']')? upstream = [BoundedContext]) @@ -176,9 +178,9 @@ Aggregate : (('userStories' ('=')? userRequirements += [UserStory]) ("," userRequirements += [UserStory])*) | ((('features' | 'userRequirements') ('=')? userRequirements += [UserRequirement]) ("," userRequirements += [UserRequirement])*) )? & - ('owner' ('=')? owner=[BoundedContext])? & + ('owner' ('=')? owner=[BoundedContext])? & ('knowledgeLevel' ('=')? knowledgeLevel=KnowledgeLevel)? & - (('likelihoodForChange' | 'structuralVolatility') ('=')? likelihoodForChange=Volatility)? & + (('likelihoodForChange' | 'structuralVolatility') ('=')? likelihoodForChange=Volatility)? & ('contentVolatility' ('=')? contentVolatility=Volatility)? & ('availabilityCriticality' ('=')? availabilityCriticality=Criticality)? & ('consistencyCriticality' ('=')? consistencyCriticality=Criticality)? & @@ -191,7 +193,8 @@ Aggregate : (resources+=Resource) | (consumers+=Consumer) | (domainObjects+=SimpleDomainObject))* - CLOSE)?; + CLOSE)? +; Application: "Application" (name=ID)? (OPEN @@ -199,12 +202,14 @@ Application: (events+=DomainEvent)* & (services+=Service)* & (flows+=Flow)*) -CLOSE)?; +CLOSE)? +; Flow: - "Flow" name=ID (OPEN + "Flow" name=ID (OPEN (steps+=FlowStep)* - CLOSE)?; + CLOSE)? +; FlowStep: DomainEventProductionStep | CommandInvokationStep @@ -291,7 +296,7 @@ UserRequirement: ; UseCase: - 'UseCase' name=ID + 'UseCase' name=ID (OPEN (('actor' ('=')? role=STRING)? & ('interactions' ('=')? features+=Feature ("," features+=Feature)*)? & @@ -335,7 +340,8 @@ SculptorModule : (consumers+=Consumer) | (domainObjects+=SimpleDomainObject) | (aggregates+=Aggregate))* - CLOSE)?; + CLOSE)? +; enum UpstreamRole: PUBLISHED_LANGUAGE = 'PL' | OPEN_HOST_SERVICE = 'OHS' @@ -369,18 +375,22 @@ enum KnowledgeLevel : META="META" | CONCRETE="CONCRETE" ; -enum Volatility : +enum Volatility : UNDEFINED | NORMAL | RARELY | OFTEN ; -enum Criticality : +enum Criticality : UNDEFINED | NORMAL | HIGH | LOW ; -enum Similarity : +enum Similarity : UNDEFINED | NORMAL | HUGE | TINY ; +enum Evolution : + UNDEFINED | GENESIS | CUSTOM_BUILT | PRODUCT | COMMODITY +; + // define terminals terminal OPEN: '{'; terminal CLOSE: '}';