org.contextmapper.dsl.refactoring.DeriveFrontendAndBackendSystemsFromFeature Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of context-mapper-dsl Show documentation
Show all versions of context-mapper-dsl Show documentation
Use the ContextMapper DSL in your standalone application.
/*
* 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.refactoring;
import java.util.Optional;
import org.contextmapper.dsl.contextMappingDSL.Aggregate;
import org.contextmapper.dsl.contextMappingDSL.BoundedContext;
import org.contextmapper.dsl.contextMappingDSL.BoundedContextType;
import org.contextmapper.dsl.contextMappingDSL.ContextMap;
import org.contextmapper.dsl.contextMappingDSL.ContextMappingDSLFactory;
import org.contextmapper.dsl.contextMappingDSL.DownstreamRole;
import org.contextmapper.dsl.contextMappingDSL.Relationship;
import org.contextmapper.dsl.contextMappingDSL.UpstreamDownstreamRelationship;
import org.contextmapper.dsl.contextMappingDSL.UpstreamRole;
import org.contextmapper.dsl.refactoring.exception.RefactoringInputException;
import org.eclipse.emf.ecore.util.EcoreUtil;
public class DeriveFrontendAndBackendSystemsFromFeature extends AbstractRefactoring implements SemanticCMLRefactoring {
private String featureBoundedContextName;
private ContextSplittingIntegrationType relationshipType;
private boolean deriveViewModelInFrontend = true;
private String frontendName;
private String backendName;
private String frontendImplTechnology;
private String backendImplTechnology;
private String relationshipImplTechnology;
private RefactoringHelper helper;
public DeriveFrontendAndBackendSystemsFromFeature(String featureBoundedContextName, ContextSplittingIntegrationType relationshipType) {
this.featureBoundedContextName = featureBoundedContextName;
this.relationshipType = relationshipType;
this.frontendName = featureBoundedContextName + "Frontend";
this.backendName = featureBoundedContextName + "Backend";
this.helper = new RefactoringHelper(this);
}
@Override
protected void doRefactor() {
checkPreconditions();
deleteExistingContexts();
BoundedContext featureContext = getAllBoundedContexts().stream().filter(bc -> bc.getName().equals(featureBoundedContextName)).findFirst().get();
BoundedContext backend = EcoreUtil.copy(featureContext);
backend.setType(BoundedContextType.SYSTEM);
backend.setName(backendName);
backend.setImplementationTechnology(backendImplTechnology);
addElementToEList(model.getBoundedContexts(), backend);
helper.adjustAggregateAndModuleNames(backend, "Backend");
BoundedContext frontend = EcoreUtil.copy(featureContext);
frontend.setType(BoundedContextType.SYSTEM);
frontend.setName(frontendName);
frontend.setImplementationTechnology(frontendImplTechnology);
addElementToEList(model.getBoundedContexts(), frontend);
if (!deriveViewModelInFrontend) {
frontend.getAggregates().clear();
frontend.getModules().clear();
addElementToEList(frontend.getAggregates(), createSampleViewModelAggregate());
} else {
helper.adjustAggregateAndModuleNames(frontend, "ViewModel");
}
ContextMap map = createOrGetContextMap();
UpstreamDownstreamRelationship relationship = ContextMappingDSLFactory.eINSTANCE.createUpstreamDownstreamRelationship();
relationship.setDownstream(frontend);
relationship.setUpstream(backend);
relationship.getUpstreamRoles().add(UpstreamRole.PUBLISHED_LANGUAGE);
relationship.getDownstreamRoles().add(getDownstreamRole());
relationship.setImplementationTechnology(relationshipImplTechnology);
addElementsToEList(relationship.getUpstreamExposedAggregates(), helper.collectAggregates(backend));
addElementToEList(map.getBoundedContexts(), frontend);
addElementToEList(map.getBoundedContexts(), backend);
addElementToEList(map.getRelationships(), relationship);
}
private void deleteExistingContexts() {
Optional optFrontend = model.getBoundedContexts().stream().filter(bc -> bc.getName().equals(frontendName)).findFirst();
Optional optBackend = model.getBoundedContexts().stream().filter(bc -> bc.getName().equals(backendName)).findFirst();
if (optFrontend.isPresent())
removeContextFromMap(optFrontend.get());
if (optBackend.isPresent())
removeContextFromMap(optBackend.get());
}
private void removeContextFromMap(BoundedContext bc) {
if (model.getMap() != null) {
ContextMappingModelHelper mappingHelper = new ContextMappingModelHelper(model.getMap());
for (Relationship relationship : mappingHelper.findAnyRelationshipsInvolvingContext(bc)) {
removeElementFromEList(model.getMap().getRelationships(), relationship);
}
if (model.getMap().getBoundedContexts().contains(bc))
removeElementFromEList(model.getMap().getBoundedContexts(), bc);
}
removeElementFromEList(model.getBoundedContexts(), bc);
}
private Aggregate createSampleViewModelAggregate() {
Aggregate aggregate = ContextMappingDSLFactory.eINSTANCE.createAggregate();
aggregate.setName("ViewModel");
aggregate.setComment("/* The view model of this frontend system has not been generated. " + System.lineSeparator()
+ " * TODO: specify the view model now, using Aggregates, Entities, Value Objects, etc. */");
return aggregate;
}
private ContextMap createOrGetContextMap() {
if (model.getMap() != null)
return model.getMap();
ContextMap newContextMap = ContextMappingDSLFactory.eINSTANCE.createContextMap();
model.setMap(newContextMap);
return newContextMap;
}
private DownstreamRole getDownstreamRole() {
if (this.relationshipType == ContextSplittingIntegrationType.ACL)
return DownstreamRole.ANTICORRUPTION_LAYER;
return DownstreamRole.CONFORMIST;
}
private void checkPreconditions() {
Optional optFeatureBC = getAllBoundedContexts().stream().filter(bc -> bc.getName().equals(featureBoundedContextName)).findFirst();
if (!optFeatureBC.isPresent())
throw new RefactoringInputException("A Bounded Context with the name '" + featureBoundedContextName + "' does not exist!");
BoundedContext featureBC = optFeatureBC.get();
if (featureBC.getType() != BoundedContextType.FEATURE && featureBC.getType() != BoundedContextType.APPLICATION)
throw new RefactoringInputException("The Bounded Context '" + featureBoundedContextName + "' is not of the type FEATURE!");
}
public void deriveViewModelInFronted(boolean derive) {
this.deriveViewModelInFrontend = derive;
}
public void setFrontendName(String frontendName) {
this.frontendName = frontendName;
}
public void setBackendName(String backendName) {
this.backendName = backendName;
}
public void setFrontendImplementationTechnology(String technology) {
this.frontendImplTechnology = technology;
}
public void setBackendImplementationTechnology(String technology) {
this.backendImplTechnology = technology;
}
public void setRelationshipImplTechnology(String technology) {
this.relationshipImplTechnology = technology;
}
}