Search in sources :

Example 11 with Relationship

use of com.structurizr.model.Relationship in project dsl by structurizr.

the class DynamicViewContentParserTests method test_parseRelationship_AddsTheRelationshipWithTheSpecifiedTechnologyToTheView_WhenItAlreadyExistsInTheModel.

@Test
void test_parseRelationship_AddsTheRelationshipWithTheSpecifiedTechnologyToTheView_WhenItAlreadyExistsInTheModel() {
    Person user = model.addPerson("User", "Description");
    SoftwareSystem softwareSystem = model.addSoftwareSystem("Software System", "Description");
    Relationship r1 = user.uses(softwareSystem, "Uses 1", "Tech 1");
    Relationship r2 = user.uses(softwareSystem, "Uses 2", "Tech 2");
    DynamicView view = views.createDynamicView("key", "Description");
    DynamicViewDslContext context = new DynamicViewDslContext(view);
    IdentifiersRegister elements = new IdentifiersRegister();
    elements.register("source", user);
    elements.register("destination", softwareSystem);
    context.setIdentifierRegister(elements);
    parser.parseRelationship(context, tokens("source", "->", "destination", "Description", "Tech 2"));
    assertEquals(1, view.getRelationships().size());
    RelationshipView rv = view.getRelationships().iterator().next();
    assertSame(r2, rv.getRelationship());
    assertSame(user, rv.getRelationship().getSource());
    assertSame(softwareSystem, rv.getRelationship().getDestination());
    assertEquals("Description", rv.getDescription());
    assertEquals("1", rv.getOrder());
}
Also used : RelationshipView(com.structurizr.view.RelationshipView) Relationship(com.structurizr.model.Relationship) SoftwareSystem(com.structurizr.model.SoftwareSystem) DynamicView(com.structurizr.view.DynamicView) Person(com.structurizr.model.Person) Test(org.junit.jupiter.api.Test)

Example 12 with Relationship

use of com.structurizr.model.Relationship in project dsl by structurizr.

the class AbstractExpressionParser method evaluateExpression.

private Set<ModelItem> evaluateExpression(String expr, DslContext context) {
    Set<ModelItem> modelItems = new LinkedHashSet<>();
    if (expr.startsWith(ELEMENT_EQUALS_EXPRESSION)) {
        expr = expr.substring(ELEMENT_EQUALS_EXPRESSION.length());
        if (isExpression(expr)) {
            modelItems.addAll(evaluateExpression(expr, context));
        } else {
            modelItems.addAll(parseIdentifier(expr, context));
        }
    } else if (expr.startsWith(RELATIONSHIP_EQUALS_EXPRESSION)) {
        expr = expr.substring(RELATIONSHIP_EQUALS_EXPRESSION.length());
        if (WILDCARD.equals(expr)) {
            expr = WILDCARD + RELATIONSHIP + WILDCARD;
        }
        if (isExpression(expr)) {
            modelItems.addAll(evaluateExpression(expr, context));
        } else {
            modelItems.addAll(parseIdentifier(expr, context));
        }
    } else if (RELATIONSHIP.equals(expr)) {
        throw new RuntimeException("Unexpected identifier \"->\"");
    } else if (expr.startsWith(RELATIONSHIP) || expr.endsWith(RELATIONSHIP)) {
        // this is an element expression: ->identifier identifier-> ->identifier->
        boolean includeAfferentCouplings = false;
        boolean includeEfferentCouplings = false;
        String identifier = expr;
        if (identifier.startsWith(RELATIONSHIP)) {
            includeAfferentCouplings = true;
            identifier = identifier.substring(RELATIONSHIP.length());
        }
        if (identifier.endsWith(RELATIONSHIP)) {
            includeEfferentCouplings = true;
            identifier = identifier.substring(0, identifier.length() - RELATIONSHIP.length());
        }
        identifier = identifier.trim();
        Set<Element> elements;
        if (isExpression(identifier)) {
            elements = parseExpression(identifier, context).stream().filter(mi -> mi instanceof Element).map(mi -> (Element) mi).collect(Collectors.toSet());
        } else {
            elements = getElements(identifier, context);
        }
        if (elements.isEmpty()) {
            throw new RuntimeException("The element \"" + identifier + "\" does not exist");
        }
        for (Element element : elements) {
            modelItems.add(element);
            if (includeAfferentCouplings) {
                modelItems.addAll(findAfferentCouplings(element));
            }
            if (includeEfferentCouplings) {
                modelItems.addAll(findEfferentCouplings(element));
            }
        }
    } else if (expr.contains(RELATIONSHIP)) {
        String[] identifiers = expr.split(RELATIONSHIP);
        String sourceIdentifier = identifiers[0].trim();
        String destinationIdentifier = identifiers[1].trim();
        String sourceExpression = RELATIONSHIP_SOURCE_EQUALS_EXPRESSION + sourceIdentifier;
        String destinationExpression = RELATIONSHIP_DESTINATION_EQUALS_EXPRESSION + destinationIdentifier;
        if (WILDCARD.equals(sourceIdentifier) && WILDCARD.equals(destinationIdentifier)) {
            modelItems.addAll(context.getWorkspace().getModel().getRelationships());
        } else if (WILDCARD.equals(destinationIdentifier)) {
            modelItems.addAll(parseExpression(sourceExpression, context));
        } else if (WILDCARD.equals(sourceIdentifier)) {
            modelItems.addAll(parseExpression(destinationExpression, context));
        } else {
            modelItems.addAll(parseExpression(sourceExpression + " && " + destinationExpression, context));
        }
    } else if (expr.toLowerCase().startsWith(ELEMENT_PARENT_EQUALS_EXPRESSION)) {
        String parentIdentifier = expr.substring(ELEMENT_PARENT_EQUALS_EXPRESSION.length());
        Element parentElement = context.getElement(parentIdentifier);
        if (parentElement == null) {
            throw new RuntimeException("The parent element \"" + parentIdentifier + "\" does not exist");
        } else {
            context.getWorkspace().getModel().getElements().forEach(element -> {
                if (element.getParent() == parentElement) {
                    modelItems.add(element);
                }
            });
        }
    } else if (expr.toLowerCase().startsWith(ELEMENT_TYPE_EQUALS_EXPRESSION)) {
        modelItems.addAll(evaluateElementTypeExpression(expr, context));
    } else if (expr.toLowerCase().startsWith(ELEMENT_TAG_EQUALS_EXPRESSION.toLowerCase())) {
        String[] tags = expr.substring(ELEMENT_TAG_EQUALS_EXPRESSION.length()).split(",");
        context.getWorkspace().getModel().getElements().forEach(element -> {
            if (hasAllTags(element, tags)) {
                modelItems.add(element);
            }
        });
    } else if (expr.toLowerCase().startsWith(ELEMENT_TAG_NOT_EQUALS_EXPRESSION)) {
        String[] tags = expr.substring(ELEMENT_TAG_NOT_EQUALS_EXPRESSION.length()).split(",");
        context.getWorkspace().getModel().getElements().forEach(element -> {
            if (!hasAllTags(element, tags)) {
                modelItems.add(element);
            }
        });
    } else if (expr.startsWith(RELATIONSHIP_TAG_EQUALS_EXPRESSION)) {
        String[] tags = expr.substring(RELATIONSHIP_TAG_EQUALS_EXPRESSION.length()).split(",");
        context.getWorkspace().getModel().getRelationships().forEach(relationship -> {
            if (hasAllTags(relationship, tags)) {
                modelItems.add(relationship);
            }
        });
    } else if (expr.startsWith(RELATIONSHIP_TAG_NOT_EQUALS_EXPRESSION)) {
        String[] tags = expr.substring(RELATIONSHIP_TAG_NOT_EQUALS_EXPRESSION.length()).split(",");
        context.getWorkspace().getModel().getRelationships().forEach(relationship -> {
            if (!hasAllTags(relationship, tags)) {
                modelItems.add(relationship);
            }
        });
    } else if (expr.startsWith(RELATIONSHIP_SOURCE_EQUALS_EXPRESSION)) {
        String identifier = expr.substring(RELATIONSHIP_SOURCE_EQUALS_EXPRESSION.length());
        Set<Element> sourceElements = new HashSet<>();
        if (isExpression(identifier)) {
            Set<ModelItem> set = parseExpression(identifier, context);
            for (ModelItem modelItem : set) {
                if (modelItem instanceof Element) {
                    sourceElements.add((Element) modelItem);
                }
            }
        } else {
            Element source = context.getElement(identifier);
            if (source == null) {
                throw new RuntimeException("The element \"" + identifier + "\" does not exist");
            }
            if (source instanceof ElementGroup) {
                sourceElements.addAll(((ElementGroup) source).getElements());
            } else {
                sourceElements.add(source);
            }
        }
        context.getWorkspace().getModel().getRelationships().forEach(relationship -> {
            if (sourceElements.contains(relationship.getSource())) {
                modelItems.add(relationship);
            }
        });
    } else if (expr.startsWith(RELATIONSHIP_DESTINATION_EQUALS_EXPRESSION)) {
        String identifier = expr.substring(RELATIONSHIP_DESTINATION_EQUALS_EXPRESSION.length());
        Set<Element> destinationElements = new HashSet<>();
        if (isExpression(identifier)) {
            Set<ModelItem> set = parseExpression(identifier, context);
            for (ModelItem modelItem : set) {
                if (modelItem instanceof Element) {
                    destinationElements.add((Element) modelItem);
                }
            }
        } else {
            Element destination = context.getElement(identifier);
            if (destination == null) {
                throw new RuntimeException("The element \"" + identifier + "\" does not exist");
            }
            if (destination instanceof ElementGroup) {
                destinationElements.addAll(((ElementGroup) destination).getElements());
            } else {
                destinationElements.add(destination);
            }
        }
        context.getWorkspace().getModel().getRelationships().forEach(relationship -> {
            if (destinationElements.contains(relationship.getDestination())) {
                modelItems.add(relationship);
            }
        });
    }
    return modelItems;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) HashSet(java.util.HashSet) Relationship(com.structurizr.model.Relationship) StructurizrDslExpressions(com.structurizr.dsl.StructurizrDslExpressions) Set(java.util.Set) StringUtils(com.structurizr.util.StringUtils) StaticStructureElementInstance(com.structurizr.model.StaticStructureElementInstance) Collectors(java.util.stream.Collectors) Element(com.structurizr.model.Element) ModelItem(com.structurizr.model.ModelItem) LinkedHashSet(java.util.LinkedHashSet) HashSet(java.util.HashSet) Set(java.util.Set) LinkedHashSet(java.util.LinkedHashSet) Element(com.structurizr.model.Element) ModelItem(com.structurizr.model.ModelItem) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet)

Example 13 with Relationship

use of com.structurizr.model.Relationship in project java by structurizr.

the class StaticView method addAnimation.

/**
 * Adds an animation step, with the specified elements.
 *
 * @param elements      the elements that should be shown in the animation step
 */
public void addAnimation(Element... elements) {
    if (elements == null || elements.length == 0) {
        throw new IllegalArgumentException("One or more elements must be specified.");
    }
    Set<String> elementIdsInPreviousAnimationSteps = new HashSet<>();
    for (Animation animationStep : animations) {
        elementIdsInPreviousAnimationSteps.addAll(animationStep.getElements());
    }
    Set<Element> elementsInThisAnimationStep = new HashSet<>();
    Set<Relationship> relationshipsInThisAnimationStep = new HashSet<>();
    for (Element element : elements) {
        if (isElementInView(element)) {
            if (!elementIdsInPreviousAnimationSteps.contains(element.getId())) {
                elementIdsInPreviousAnimationSteps.add(element.getId());
                elementsInThisAnimationStep.add(element);
            }
        }
    }
    if (elementsInThisAnimationStep.size() == 0) {
        throw new IllegalArgumentException("None of the specified elements exist in this view.");
    }
    for (RelationshipView relationshipView : this.getRelationships()) {
        if ((elementsInThisAnimationStep.contains(relationshipView.getRelationship().getSource()) && elementIdsInPreviousAnimationSteps.contains(relationshipView.getRelationship().getDestination().getId())) || (elementIdsInPreviousAnimationSteps.contains(relationshipView.getRelationship().getSource().getId()) && elementsInThisAnimationStep.contains(relationshipView.getRelationship().getDestination()))) {
            relationshipsInThisAnimationStep.add(relationshipView.getRelationship());
        }
    }
    animations.add(new Animation(animations.size() + 1, elementsInThisAnimationStep, relationshipsInThisAnimationStep));
}
Also used : Element(com.structurizr.model.Element) Relationship(com.structurizr.model.Relationship) HashSet(java.util.HashSet)

Example 14 with Relationship

use of com.structurizr.model.Relationship in project moduliths by moduliths.

the class Documenter method addComponentsToView.

private void addComponentsToView(Supplier<Stream<Module>> modules, ComponentView view, Options options, Consumer<ComponentView> afterCleanup) {
    Styles styles = view.getViewSet().getConfiguration().getStyles();
    Map<Module, Component> components = getComponents(options);
    // 
    modules.get().distinct().filter(// 
    options.getExclusions().negate()).map(// 
    it -> applyBackgroundColor(it, components, options, styles)).filter(// 
    options.getComponentFilter()).forEach(view::add);
    // view.getViewSet().getConfiguration().getStyles().findElementStyle(element).getBackground()
    // Remove filtered dependency types
    // 
    DependencyType.allBut(options.getDependencyTypes()).map(// 
    Object::toString).forEach(it -> view.removeRelationshipsWithTag(it));
    afterCleanup.accept(view);
    // Filter outgoing relationships of target-only modules
    // 
    modules.get().filter(options.getTargetOnly()).forEach(module -> {
        Component component = components.get(module);
        // 
        view.getRelationships().stream().map(// 
        RelationshipView::getRelationship).filter(// 
        it -> it.getSource().equals(component)).forEach(it -> view.remove(it));
    });
    // … as well as all elements left without a relationship
    if (options.hideElementsWithoutRelationships()) {
        view.removeElementsWithNoRelationships();
    }
    afterCleanup.accept(view);
    // Remove default relationships if more qualified ones exist
    // 
    view.getRelationships().stream().map(// 
    RelationshipView::getRelationship).collect(// 
    Collectors.groupingBy(Connection::of)).values().stream().forEach(it -> potentiallyRemoveDefaultRelationship(view, it));
}
Also used : RequiredArgsConstructor(lombok.RequiredArgsConstructor) Diagram(com.structurizr.io.Diagram) C4PlantUMLExporter(com.structurizr.io.plantuml.C4PlantUMLExporter) BasicPlantUMLWriter(com.structurizr.io.plantuml.BasicPlantUMLWriter) SpringBean(org.moduliths.model.SpringBean) JavaClass(com.tngtech.archunit.core.domain.JavaClass) Path(java.nio.file.Path) With(lombok.With) Predicate(java.util.function.Predicate) SoftwareSystem(com.structurizr.model.SoftwareSystem) RelationshipView(com.structurizr.view.RelationshipView) Asciidoctor(org.moduliths.docs.Asciidoctor) Collectors(java.util.stream.Collectors) DependencyDepth(org.moduliths.model.Module.DependencyDepth) Shape(com.structurizr.view.Shape) Tags(com.structurizr.model.Tags) Stream(java.util.stream.Stream) Relationship(com.structurizr.model.Relationship) Writer(java.io.Writer) Entry(java.util.Map.Entry) Styles(com.structurizr.view.Styles) java.util(java.util) Getter(lombok.Getter) Function(java.util.function.Function) Supplier(java.util.function.Supplier) Component(com.structurizr.model.Component) Value(lombok.Value) Modules(org.moduliths.model.Modules) AccessLevel(lombok.AccessLevel) BiConsumer(java.util.function.BiConsumer) View(com.structurizr.view.View) Nullable(org.springframework.lang.Nullable) Model(com.structurizr.model.Model) Container(com.structurizr.model.Container) ComponentView(com.structurizr.view.ComponentView) Files(java.nio.file.Files) StringWriter(java.io.StringWriter) FileWriter(java.io.FileWriter) MultiValueMap(org.springframework.util.MultiValueMap) IOException(java.io.IOException) File(java.io.File) Workspace(com.structurizr.Workspace) Consumer(java.util.function.Consumer) DependencyType(org.moduliths.model.Module.DependencyType) Module(org.moduliths.model.Module) Paths(java.nio.file.Paths) PlantUMLWriter(com.structurizr.io.plantuml.PlantUMLWriter) AllArgsConstructor(lombok.AllArgsConstructor) LinkedMultiValueMap(org.springframework.util.LinkedMultiValueMap) Element(com.structurizr.model.Element) Assert(org.springframework.util.Assert) RelationshipView(com.structurizr.view.RelationshipView) Module(org.moduliths.model.Module) Component(com.structurizr.model.Component) Styles(com.structurizr.view.Styles)

Example 15 with Relationship

use of com.structurizr.model.Relationship in project moduliths by moduliths.

the class Documenter method addDependencies.

private void addDependencies(Module module, Component component, Options options) {
    DEPENDENCY_DESCRIPTIONS.entrySet().stream().forEach(entry -> {
        // 
        module.getDependencies(modules, entry.getKey()).stream().map(// 
        it -> getComponents(options).get(it)).forEach(it -> {
            Relationship relationship = component.uses(it, entry.getValue());
            relationship.addTags(entry.getKey().toString());
        });
    });
    // 
    module.getBootstrapDependencies(modules).forEach(it -> {
        Relationship relationship = component.uses(getComponents(options).get(it), "uses");
        relationship.addTags(DependencyType.USES_COMPONENT.toString());
    });
}
Also used : RequiredArgsConstructor(lombok.RequiredArgsConstructor) Diagram(com.structurizr.io.Diagram) C4PlantUMLExporter(com.structurizr.io.plantuml.C4PlantUMLExporter) BasicPlantUMLWriter(com.structurizr.io.plantuml.BasicPlantUMLWriter) SpringBean(org.moduliths.model.SpringBean) JavaClass(com.tngtech.archunit.core.domain.JavaClass) Path(java.nio.file.Path) With(lombok.With) Predicate(java.util.function.Predicate) SoftwareSystem(com.structurizr.model.SoftwareSystem) RelationshipView(com.structurizr.view.RelationshipView) Asciidoctor(org.moduliths.docs.Asciidoctor) Collectors(java.util.stream.Collectors) DependencyDepth(org.moduliths.model.Module.DependencyDepth) Shape(com.structurizr.view.Shape) Tags(com.structurizr.model.Tags) Stream(java.util.stream.Stream) Relationship(com.structurizr.model.Relationship) Writer(java.io.Writer) Entry(java.util.Map.Entry) Styles(com.structurizr.view.Styles) java.util(java.util) Getter(lombok.Getter) Function(java.util.function.Function) Supplier(java.util.function.Supplier) Component(com.structurizr.model.Component) Value(lombok.Value) Modules(org.moduliths.model.Modules) AccessLevel(lombok.AccessLevel) BiConsumer(java.util.function.BiConsumer) View(com.structurizr.view.View) Nullable(org.springframework.lang.Nullable) Model(com.structurizr.model.Model) Container(com.structurizr.model.Container) ComponentView(com.structurizr.view.ComponentView) Files(java.nio.file.Files) StringWriter(java.io.StringWriter) FileWriter(java.io.FileWriter) MultiValueMap(org.springframework.util.MultiValueMap) IOException(java.io.IOException) File(java.io.File) Workspace(com.structurizr.Workspace) Consumer(java.util.function.Consumer) DependencyType(org.moduliths.model.Module.DependencyType) Module(org.moduliths.model.Module) Paths(java.nio.file.Paths) PlantUMLWriter(com.structurizr.io.plantuml.PlantUMLWriter) AllArgsConstructor(lombok.AllArgsConstructor) LinkedMultiValueMap(org.springframework.util.LinkedMultiValueMap) Element(com.structurizr.model.Element) Assert(org.springframework.util.Assert) Relationship(com.structurizr.model.Relationship)

Aggregations

Relationship (com.structurizr.model.Relationship)15 Element (com.structurizr.model.Element)8 SoftwareSystem (com.structurizr.model.SoftwareSystem)6 Workspace (com.structurizr.Workspace)4 RelationshipView (com.structurizr.view.RelationshipView)4 Component (com.structurizr.model.Component)3 Container (com.structurizr.model.Container)3 JavaClass (com.tngtech.archunit.core.domain.JavaClass)3 HashSet (java.util.HashSet)3 Collectors (java.util.stream.Collectors)3 Stream (java.util.stream.Stream)3 Test (org.junit.jupiter.api.Test)3 Diagram (com.structurizr.io.Diagram)2 BasicPlantUMLWriter (com.structurizr.io.plantuml.BasicPlantUMLWriter)2 C4PlantUMLExporter (com.structurizr.io.plantuml.C4PlantUMLExporter)2 PlantUMLWriter (com.structurizr.io.plantuml.PlantUMLWriter)2 Model (com.structurizr.model.Model)2 ModelItem (com.structurizr.model.ModelItem)2 Person (com.structurizr.model.Person)2 Tags (com.structurizr.model.Tags)2