use of org.eclipse.winery.model.tosca.RelationshipSourceOrTarget in project winery by eclipse.
the class BackendUtils method mergeTopologyTemplateAinTopologyTemplateB.
/**
* Merges two Topology Templates and returns the mapping between the topology elements from the original Topology
* Template and their respective clones inside the merged topology. Hereby, the staying elements must not be
* merged.
*
* @param topologyTemplateA the topology to merged into <code>topologyTemplateB</code>
* @param topologyTemplateB the target topology in which <dode>topologyTemplateA</dode> should be merged in
* @param stayingElementIds the TEntityTemplates that must not be merged from A to B.
* @return A mapping between the ids in the <code>topologyTemplateA</code> and their corresponding ids in
* <code>topologyTemplateB</code>
*/
public static Map<String, String> mergeTopologyTemplateAinTopologyTemplateB(TTopologyTemplate topologyTemplateA, TTopologyTemplate topologyTemplateB, List<String> stayingElementIds) {
Objects.requireNonNull(topologyTemplateA);
Objects.requireNonNull(topologyTemplateB);
TTopologyTemplate topologyTemplateToBeMerged = new TTopologyTemplate.Builder().build();
Map<String, String> idMapping = new HashMap<>();
Optional<Integer> shiftLeft = topologyTemplateB.getNodeTemplateOrRelationshipTemplate().stream().filter(x -> x instanceof TNodeTemplate).map(x -> (TNodeTemplate) x).max(Comparator.comparingInt(n -> ModelUtilities.getLeft(n).orElse(0))).map(n -> ModelUtilities.getLeft(n).orElse(0));
if (Objects.nonNull(stayingElementIds)) {
topologyTemplateA.getNodeTemplateOrRelationshipTemplate().forEach(entity -> {
if (!stayingElementIds.contains(entity.getId())) {
if (entity instanceof TNodeTemplate) {
topologyTemplateToBeMerged.addNodeTemplate((TNodeTemplate) entity);
} else if (entity instanceof TRelationshipTemplate) {
topologyTemplateToBeMerged.addRelationshipTemplate((TRelationshipTemplate) entity);
}
}
});
} else {
topologyTemplateToBeMerged.getNodeTemplateOrRelationshipTemplate().addAll(topologyTemplateA.getNodeTemplateOrRelationshipTemplate());
}
if (shiftLeft.isPresent()) {
ModelUtilities.collectIdsOfExistingTopologyElements(topologyTemplateB, idMapping);
// patch ids of reqs change them if required
topologyTemplateToBeMerged.getNodeTemplates().stream().filter(nt -> nt.getRequirements() != null).forEach(nt -> nt.getRequirements().forEach(oldReq -> {
TRequirement req = SerializationUtils.clone(oldReq);
ModelUtilities.generateNewIdOfTemplate(req, idMapping);
topologyTemplateToBeMerged.getRelationshipTemplates().stream().filter(rt -> rt.getSourceElement().getRef() instanceof TRequirement).forEach(rt -> {
TRequirement sourceElement = (TRequirement) rt.getSourceElement().getRef();
if (sourceElement.getId().equalsIgnoreCase(oldReq.getId())) {
sourceElement.setId(req.getId());
}
});
}));
// patch ids of caps change them if required
topologyTemplateToBeMerged.getNodeTemplates().stream().filter(nt -> nt.getCapabilities() != null).forEach(nt -> nt.getCapabilities().forEach(oldCap -> {
TCapability cap = SerializationUtils.clone(oldCap);
ModelUtilities.generateNewIdOfTemplate(cap, idMapping);
topologyTemplateToBeMerged.getRelationshipTemplates().stream().filter(rt -> rt.getTargetElement().getRef() instanceof TCapability).forEach(rt -> {
TCapability targetElement = (TCapability) rt.getTargetElement().getRef();
if (targetElement.getId().equalsIgnoreCase(oldCap.getId())) {
targetElement.setId(cap.getId());
}
});
}));
ArrayList<TRelationshipTemplate> newRelationships = new ArrayList<>();
// patch the ids of templates and add them
topologyTemplateToBeMerged.getNodeTemplateOrRelationshipTemplate().forEach(element -> {
TEntityTemplate rtOrNt = SerializationUtils.clone(element);
ModelUtilities.generateNewIdOfTemplate(rtOrNt, idMapping);
if (rtOrNt instanceof TNodeTemplate) {
int newLeft = ModelUtilities.getLeft((TNodeTemplate) rtOrNt).orElse(0) + shiftLeft.get();
((TNodeTemplate) rtOrNt).setX(Integer.toString(newLeft));
} else if (rtOrNt instanceof TRelationshipTemplate) {
newRelationships.add((TRelationshipTemplate) rtOrNt);
}
topologyTemplateB.getNodeTemplateOrRelationshipTemplate().add(rtOrNt);
});
// update references to the new elements
newRelationships.forEach(rel -> {
RelationshipSourceOrTarget source = rel.getSourceElement().getRef();
RelationshipSourceOrTarget target = rel.getTargetElement().getRef();
if (source instanceof TNodeTemplate && (stayingElementIds == null || stayingElementIds.stream().noneMatch(elementId -> elementId.equals(source.getId())))) {
TNodeTemplate newSource = topologyTemplateB.getNodeTemplate(idMapping.get(source.getId()));
rel.setSourceNodeTemplate(newSource);
}
if (target instanceof TNodeTemplate && (stayingElementIds == null || stayingElementIds.stream().noneMatch(elementId -> elementId.equals(target.getId())))) {
TNodeTemplate newTarget = topologyTemplateB.getNodeTemplate(idMapping.get(target.getId()));
rel.setTargetNodeTemplate(newTarget);
}
});
} else {
topologyTemplateB.getNodeTemplateOrRelationshipTemplate().addAll(topologyTemplateToBeMerged.getNodeTemplateOrRelationshipTemplate());
}
return idMapping;
}
Aggregations