Search in sources :

Example 1 with Workspace

use of com.structurizr.Workspace in project dsl by structurizr.

the class StructurizrDslFormatter method format.

/**
 * Formats the specified Structurizr JSON to the Structurizr DSL.
 *
 * @param json       a JSON document
 * @throws StructurizrDslFormatterException if the workspace can't be formatted
 * @return a DSL representation of the workspace
 */
public String format(String json) throws StructurizrDslFormatterException {
    if (StringUtils.isNullOrEmpty(json)) {
        throw new StructurizrDslFormatterException("A JSON document must be specified");
    }
    Workspace workspace;
    Model model;
    try {
        workspace = WorkspaceUtils.fromJson(json);
        model = workspace.getModel();
    } catch (Exception e) {
        throw new StructurizrDslFormatterException(e.getMessage());
    }
    start(WORKSPACE_TOKEN, quote(workspace.getName()), quote(workspace.getDescription()));
    newline();
    start(IMPLIED_RELATIONSHIPS_TOKEN, quote("false"));
    end();
    start(IDENTIFIERS_TOKEN, quote("hierarchical"));
    end();
    newline();
    start(MODEL_TOKEN);
    List<Person> internalPeople = model.getPeople().stream().filter(p -> p.getLocation() == Location.Internal).sorted(Comparator.comparing(Person::getId)).collect(Collectors.toList());
    List<SoftwareSystem> internalSoftwareSystems = model.getSoftwareSystems().stream().filter(p -> p.getLocation() == Location.Internal).sorted(Comparator.comparing(SoftwareSystem::getId)).collect(Collectors.toList());
    if (workspace.getModel().getEnterprise() == null) {
        workspace.getModel().setEnterprise(new Enterprise("Enterprise"));
    }
    if (workspace.getModel().getEnterprise() != null && (!internalPeople.isEmpty() || !internalSoftwareSystems.isEmpty())) {
        start(ENTERPRISE_TOKEN, quote(workspace.getModel().getEnterprise().getName()));
        internalPeople.forEach(this::format);
        internalSoftwareSystems.forEach(this::format);
        end();
    }
    model.getPeople().stream().filter(p -> p.getLocation() != Location.Internal).sorted(Comparator.comparing(Person::getId)).forEach(this::format);
    model.getSoftwareSystems().stream().filter(p -> p.getLocation() != Location.Internal).sorted(Comparator.comparing(SoftwareSystem::getId)).forEach(this::format);
    model.getRelationships().stream().sorted(Comparator.comparing(Relationship::getId)).forEach(r -> {
        if (r.getSource() instanceof DeploymentElement || r.getDestination() instanceof DeploymentElement) {
        // deployment element relationships are formatted below, after the deployment nodes have been formatted
        } else {
            start(id(r.getSource(), true), RELATIONSHIP_TOKEN, id(r.getDestination(), true), quote(r.getDescription()), quote(r.getTechnology()), quote(tags(r)));
            formatModelItem(r);
            end();
        }
    });
    if (!workspace.getModel().getDeploymentNodes().isEmpty()) {
        newline();
        model.getDeploymentNodes().stream().map(DeploymentElement::getEnvironment).collect(Collectors.toSet()).stream().sorted().forEach(deploymentEnvironment -> {
            start(filter(deploymentEnvironment), ASSIGNMENT_OPERATOR_TOKEN, DEPLOYMENT_ENVIRONMENT_TOKEN, quote(deploymentEnvironment));
            model.getDeploymentNodes().stream().filter(dn -> dn.getParent() == null && dn.getEnvironment().equals(deploymentEnvironment)).sorted(Comparator.comparing(DeploymentNode::getId)).forEach(this::format);
            end();
        });
        newline();
        model.getRelationships().stream().sorted(Comparator.comparing(Relationship::getId)).forEach(r -> {
            if (StringUtils.isNullOrEmpty(r.getLinkedRelationshipId())) {
                if (r.getSource() instanceof DeploymentElement || r.getDestination() instanceof DeploymentElement) {
                    start(id(r.getSource(), true), RELATIONSHIP_TOKEN, id(r.getDestination(), true), quote(r.getDescription()), quote(r.getTechnology()), quote(tags(r)));
                    formatModelItem(r);
                    end();
                } else {
                // static structure element only relationships are formatted above
                }
            } else {
            // do nothing - linked relationships are created automatically
            }
        });
    }
    end();
    boolean hasViews = !workspace.getViews().isEmpty();
    boolean hasStyles = !workspace.getViews().getConfiguration().getStyles().getElements().isEmpty() || !workspace.getViews().getConfiguration().getStyles().getRelationships().isEmpty();
    boolean hasThemes = workspace.getViews().getConfiguration().getThemes() != null && workspace.getViews().getConfiguration().getThemes().length > 0;
    boolean hasBranding = workspace.getViews().getConfiguration().getBranding() != null && (!StringUtils.isNullOrEmpty(workspace.getViews().getConfiguration().getBranding().getLogo()) || workspace.getViews().getConfiguration().getBranding().getFont() != null);
    if (hasViews || hasStyles || hasThemes || hasBranding) {
        newline();
        start(VIEWS_TOKEN);
        ViewSet views = workspace.getViews();
        views.getSystemLandscapeViews().stream().sorted(Comparator.comparing(SystemLandscapeView::getKey)).forEach(view -> {
            if (view.getElements().size() > 0 || view.getRelationships().size() > 0) {
                start(SYSTEM_LANDSCAPE_VIEW_TOKEN, quote(view.getKey().replaceAll(" ", "")), quote(view.getDescription()));
                view.getElements().stream().map(ElementView::getElement).sorted(Comparator.comparing(Element::getId)).forEach(e -> {
                    start(INCLUDE_IN_VIEW_TOKEN, id(e, true));
                    end();
                });
                format(view.getAutomaticLayout());
                end();
                newline();
            }
        });
        views.getSystemContextViews().stream().sorted(Comparator.comparing(SystemContextView::getKey)).forEach(view -> {
            if (view.getElements().size() > 0 || view.getRelationships().size() > 0) {
                start(SYSTEM_CONTEXT_VIEW_TOKEN, id(view.getSoftwareSystem()), quote(view.getKey().replaceAll(" ", "")), quote(view.getDescription()));
                view.getElements().stream().map(ElementView::getElement).sorted(Comparator.comparing(Element::getId)).forEach(e -> {
                    start(INCLUDE_IN_VIEW_TOKEN, id(e, true));
                    end();
                });
                format(view.getAutomaticLayout());
                end();
                newline();
            }
        });
        views.getContainerViews().stream().sorted(Comparator.comparing(ContainerView::getKey)).forEach(view -> {
            if (view.getElements().size() > 0 || view.getRelationships().size() > 0) {
                start(CONTAINER_VIEW_TOKEN, id(view.getSoftwareSystem()), quote(view.getKey().replaceAll(" ", "")), quote(view.getDescription()));
                view.getElements().stream().map(ElementView::getElement).sorted(Comparator.comparing(Element::getId)).forEach(e -> {
                    start(INCLUDE_IN_VIEW_TOKEN, id(e, true));
                    end();
                });
                format(view.getAutomaticLayout());
                end();
                newline();
            }
        });
        views.getComponentViews().stream().sorted(Comparator.comparing(ComponentView::getKey)).forEach(view -> {
            if (view.getElements().size() > 0 || view.getRelationships().size() > 0) {
                start(COMPONENT_VIEW_TOKEN, id(view.getContainer(), true), quote(view.getKey().replaceAll(" ", "")), quote(view.getDescription()));
                view.getElements().stream().map(ElementView::getElement).sorted(Comparator.comparing(Element::getId)).forEach(e -> {
                    start(INCLUDE_IN_VIEW_TOKEN, id(e, true));
                    end();
                });
                format(view.getAutomaticLayout());
                end();
                newline();
            }
        });
        views.getFilteredViews().stream().sorted(Comparator.comparing(FilteredView::getKey)).forEach(view -> {
            StringBuilder tags = new StringBuilder();
            for (String tag : view.getTags()) {
                tags.append(tag);
                tags.append(" ");
            }
            start(FILTERED_VIEW_TOKEN, quote(view.getBaseViewKey().replaceAll(" ", "")), view.getMode().toString(), quote(tags.toString().trim()), quote(view.getKey().replaceAll(" ", "")), quote(view.getDescription()));
            end();
            newline();
        });
        views.getDynamicViews().stream().sorted(Comparator.comparing(DynamicView::getKey)).forEach(view -> {
            if (view.getElements().size() > 0 || view.getRelationships().size() > 0) {
                if (StringUtils.isNullOrEmpty(view.getElementId())) {
                    start(DYNAMIC_VIEW_TOKEN, quote("*"), quote(view.getKey()), quote(view.getDescription()));
                } else {
                    start(DYNAMIC_VIEW_TOKEN, id(view.getElement(), true), quote(view.getKey()), quote(view.getDescription()));
                }
                for (RelationshipView relationshipView : view.getRelationships()) {
                    start("# " + relationshipView.getOrder());
                    end();
                    Element source;
                    Element destination;
                    if (relationshipView.isResponse() != null && relationshipView.isResponse()) {
                        source = relationshipView.getRelationship().getDestination();
                        destination = relationshipView.getRelationship().getSource();
                    } else {
                        source = relationshipView.getRelationship().getSource();
                        destination = relationshipView.getRelationship().getDestination();
                    }
                    if (StringUtils.isNullOrEmpty(relationshipView.getDescription())) {
                        start(id(source, true), "->", id(destination, true));
                    } else {
                        start(id(source, true), "->", id(destination, true), quote(relationshipView.getDescription()));
                    }
                    end();
                }
                format(view.getAutomaticLayout());
                end();
                newline();
            }
        });
        views.getDeploymentViews().stream().sorted(Comparator.comparing(DeploymentView::getKey)).forEach(view -> {
            if (view.getElements().size() > 0 || view.getRelationships().size() > 0) {
                String scope;
                if (StringUtils.isNullOrEmpty(view.getSoftwareSystemId())) {
                    scope = "*";
                } else {
                    scope = id(view.getSoftwareSystem());
                }
                start(DEPLOYMENT_VIEW_TOKEN, scope, quote(view.getEnvironment()), quote(view.getKey()), quote(view.getDescription()));
                Set<Element> elements = new LinkedHashSet<>();
                for (ElementView elementView : view.getElements()) {
                    DeploymentElement deploymentElement = (DeploymentElement) elementView.getElement();
                    if (deploymentElement instanceof DeploymentNode) {
                    // ignore
                    } else {
                        elements.add(deploymentElement.getParent());
                    }
                }
                for (Element element : elements) {
                    start(INCLUDE_IN_VIEW_TOKEN, id(element, true));
                    end();
                }
                format(view.getAutomaticLayout());
                end();
                newline();
            }
        });
        if (hasStyles) {
            start(STYLES_TOKEN);
            workspace.getViews().getConfiguration().getStyles().getElements().stream().sorted(Comparator.comparing(ElementStyle::getTag)).forEach(style -> {
                boolean hasProperties = false;
                start(ELEMENT_STYLE_TOKEN, quote(style.getTag()));
                if (style.getShape() != null) {
                    hasProperties = true;
                    start(ELEMENT_STYLE_SHAPE_TOKEN, quote(style.getShape()));
                    end();
                }
                if (!StringUtils.isNullOrEmpty(style.getIcon())) {
                    hasProperties = true;
                    start(ELEMENT_STYLE_ICON_TOKEN, quote(style.getIcon()));
                    end();
                }
                if (style.getWidth() != null) {
                    hasProperties = true;
                    start(ELEMENT_STYLE_WIDTH_TOKEN, quote(style.getWidth()));
                    end();
                }
                if (style.getHeight() != null) {
                    hasProperties = true;
                    start(ELEMENT_STYLE_HEIGHT_TOKEN, quote(style.getHeight()));
                    end();
                }
                if (!StringUtils.isNullOrEmpty(style.getBackground())) {
                    hasProperties = true;
                    start(ELEMENT_STYLE_BACKGROUND_TOKEN, quote(style.getBackground()));
                    end();
                }
                if (!StringUtils.isNullOrEmpty(style.getColor())) {
                    hasProperties = true;
                    start(ELEMENT_STYLE_COLOR_TOKEN, quote(style.getColor()));
                    end();
                }
                if (!StringUtils.isNullOrEmpty(style.getStroke())) {
                    hasProperties = true;
                    start(ELEMENT_STYLE_STROKE_TOKEN, quote(style.getStroke()));
                    end();
                }
                if (style.getFontSize() != null) {
                    hasProperties = true;
                    start(ELEMENT_STYLE_FONT_SIZE_TOKEN, quote(style.getFontSize()));
                    end();
                }
                if (style.getBorder() != null) {
                    hasProperties = true;
                    start(ELEMENT_STYLE_BORDER_TOKEN, quote(style.getBorder()));
                    end();
                }
                if (style.getOpacity() != null) {
                    hasProperties = true;
                    start(ELEMENT_STYLE_OPACITY_TOKEN, quote(style.getOpacity()));
                    end();
                }
                if (style.getMetadata() != null) {
                    hasProperties = true;
                    start(ELEMENT_STYLE_METADATA_TOKEN, quote(style.getMetadata()));
                    end();
                }
                if (style.getDescription() != null) {
                    hasProperties = true;
                    start(ELEMENT_STYLE_DESCRIPTION_TOKEN, quote(style.getDescription()));
                    end();
                }
                if (!hasProperties) {
                    start("# empty style");
                    end();
                }
                end();
            });
            workspace.getViews().getConfiguration().getStyles().getRelationships().stream().sorted(Comparator.comparing(RelationshipStyle::getTag)).forEach(style -> {
                boolean hasProperties = false;
                start(RELATIONSHIP_STYLE_TOKEN, quote(style.getTag()));
                if (style.getThickness() != null) {
                    hasProperties = true;
                    start(RELATIONSHIP_STYLE_THICKNESS_TOKEN, quote(style.getThickness()));
                    end();
                }
                if (!StringUtils.isNullOrEmpty(style.getColor())) {
                    hasProperties = true;
                    start(RELATIONSHIP_STYLE_COLOR_TOKEN, quote(style.getColor()));
                    end();
                }
                if (style.getDashed() != null) {
                    hasProperties = true;
                    start(RELATIONSHIP_STYLE_DASHED_TOKEN, quote(style.getDashed()));
                    end();
                }
                if (style.getRouting() != null) {
                    hasProperties = true;
                    start(RELATIONSHIP_STYLE_ROUTING_TOKEN, quote(style.getRouting()));
                    end();
                }
                if (style.getFontSize() != null) {
                    hasProperties = true;
                    start(RELATIONSHIP_STYLE_FONT_SIZE_TOKEN, quote(style.getFontSize()));
                    end();
                }
                if (style.getWidth() != null) {
                    hasProperties = true;
                    start(RELATIONSHIP_STYLE_WIDTH_TOKEN, quote(style.getWidth()));
                    end();
                }
                if (style.getPosition() != null) {
                    hasProperties = true;
                    start(RELATIONSHIP_STYLE_POSITION_TOKEN, quote(style.getPosition()));
                    end();
                }
                if (style.getOpacity() != null) {
                    hasProperties = true;
                    start(RELATIONSHIP_STYLE_OPACITY_TOKEN, quote(style.getOpacity()));
                    end();
                }
                if (!hasProperties) {
                    start("# empty style");
                    end();
                }
                end();
            });
            end();
        }
        if (hasThemes) {
            String[] themes = views.getConfiguration().getThemes();
            for (String theme : themes) {
                start(THEMES_TOKEN, quote(theme));
                end();
            }
        }
        if (hasBranding) {
            newline();
            start(BRANDING_TOKEN);
            String brandingLogo = workspace.getViews().getConfiguration().getBranding().getLogo();
            Font brandingFont = workspace.getViews().getConfiguration().getBranding().getFont();
            if (!StringUtils.isNullOrEmpty(brandingLogo)) {
                start(BRANDING_LOGO_TOKEN, quote(brandingLogo));
                end();
            }
            if (brandingFont != null) {
                if (!StringUtils.isNullOrEmpty(brandingFont.getUrl())) {
                    start(BRANDING_FONT_TOKEN, quote(brandingFont.getName()), quote(brandingFont.getUrl()));
                    end();
                } else if (!DEFAULT_FONT.equals(brandingFont.getName())) {
                    start(BRANDING_FONT_TOKEN, quote(brandingFont.getName()));
                    end();
                }
            }
            end();
        }
        newline();
        end();
    }
    newline();
    end();
    return buf.toString().replaceAll("\\{\\s*}", "");
}
Also used : IOException(java.io.IOException) Workspace(com.structurizr.Workspace)

Example 2 with Workspace

use of com.structurizr.Workspace in project dsl by structurizr.

the class DynamicViewParser method parse.

DynamicView parse(DslContext context, Tokens tokens) {
    // dynamic <*|software system identifier|container identifier> [key] [description] {
    Workspace workspace = context.getWorkspace();
    String key = "";
    String description = "";
    DecimalFormat format = new DecimalFormat("000");
    if (tokens.hasMoreThan(DESCRIPTION_INDEX)) {
        throw new RuntimeException("Too many tokens, expected: " + GRAMMAR);
    }
    if (!tokens.includes(SCOPE_IDENTIFIER_INDEX)) {
        throw new RuntimeException("Expected: " + GRAMMAR);
    }
    if (tokens.includes(DESCRIPTION_INDEX)) {
        description = tokens.get(DESCRIPTION_INDEX);
    }
    DynamicView view;
    String scopeIdentifier = tokens.get(SCOPE_IDENTIFIER_INDEX);
    if (WILDCARD.equals(scopeIdentifier)) {
        if (tokens.includes(KEY_INDEX)) {
            key = tokens.get(KEY_INDEX);
        } else {
            key = VIEW_TYPE + "-" + format.format(workspace.getViews().getDynamicViews().size() + 1);
        }
        validateViewKey(key);
        view = workspace.getViews().createDynamicView(key, description);
    } else {
        Element element = context.getElement(scopeIdentifier);
        if (element == null) {
            throw new RuntimeException("The software system or container \"" + scopeIdentifier + "\" does not exist");
        }
        if (element instanceof SoftwareSystem) {
            if (tokens.includes(KEY_INDEX)) {
                key = tokens.get(KEY_INDEX);
            } else {
                key = removeNonWordCharacters(element.getName()) + "-" + VIEW_TYPE + "-" + format.format(workspace.getViews().getDynamicViews().size() + 1);
            }
            validateViewKey(key);
            view = workspace.getViews().createDynamicView((SoftwareSystem) element, key, description);
        } else if (element instanceof Container) {
            Container container = (Container) element;
            if (tokens.includes(KEY_INDEX)) {
                key = tokens.get(KEY_INDEX);
            } else {
                key = removeNonWordCharacters(container.getSoftwareSystem().getName()) + "-" + removeNonWordCharacters(container.getName()) + "-" + VIEW_TYPE + "-" + format.format(workspace.getViews().getDynamicViews().size() + 1);
            }
            validateViewKey(key);
            view = workspace.getViews().createDynamicView((Container) element, key, description);
        } else {
            throw new RuntimeException("The element \"" + scopeIdentifier + "\" is not a software system or container");
        }
    }
    view.setExternalBoundariesVisible(true);
    return view;
}
Also used : Container(com.structurizr.model.Container) DecimalFormat(java.text.DecimalFormat) Element(com.structurizr.model.Element) SoftwareSystem(com.structurizr.model.SoftwareSystem) DynamicView(com.structurizr.view.DynamicView) Workspace(com.structurizr.Workspace)

Example 3 with Workspace

use of com.structurizr.Workspace in project dsl by structurizr.

the class RelationshipStyleParser method parseRelationshipStyle.

RelationshipStyle parseRelationshipStyle(DslContext context, Tokens tokens) {
    if (tokens.hasMoreThan(FIRST_PROPERTY_INDEX)) {
        throw new RuntimeException("Too many tokens, expected: relationship <tag> {");
    }
    if (tokens.includes(FIRST_PROPERTY_INDEX)) {
        String tag = tokens.get(1);
        if (StringUtils.isNullOrEmpty(tag)) {
            throw new RuntimeException("A tag must be specified");
        }
        Workspace workspace = context.getWorkspace();
        return workspace.getViews().getConfiguration().getStyles().addRelationshipStyle(tag);
    } else {
        throw new RuntimeException("Expected: relationship <tag> {");
    }
}
Also used : Workspace(com.structurizr.Workspace)

Example 4 with Workspace

use of com.structurizr.Workspace in project dsl by structurizr.

the class SystemContextViewParser method parse.

SystemContextView parse(DslContext context, Tokens tokens) {
    // systemContext <software system identifier> [key] [description] {
    Workspace workspace = context.getWorkspace();
    SoftwareSystem softwareSystem;
    String key = "";
    String description = "";
    if (tokens.hasMoreThan(DESCRIPTION_INDEX)) {
        throw new RuntimeException("Too many tokens, expected: " + GRAMMAR);
    }
    if (!tokens.includes(SOFTWARE_SYSTEM_IDENTIFIER_INDEX)) {
        throw new RuntimeException("Expected: " + GRAMMAR);
    }
    String softwareSystemIdentifier = tokens.get(SOFTWARE_SYSTEM_IDENTIFIER_INDEX);
    Element element = context.getElement(softwareSystemIdentifier);
    if (element == null) {
        throw new RuntimeException("The software system \"" + softwareSystemIdentifier + "\" does not exist");
    }
    if (element instanceof SoftwareSystem) {
        softwareSystem = (SoftwareSystem) element;
    } else {
        throw new RuntimeException("The element \"" + softwareSystemIdentifier + "\" is not a software system");
    }
    if (tokens.includes(KEY_INDEX)) {
        key = tokens.get(KEY_INDEX);
    } else {
        key = removeNonWordCharacters(softwareSystem.getName()) + "-" + VIEW_TYPE;
    }
    validateViewKey(key);
    if (tokens.includes(DESCRIPTION_INDEX)) {
        description = tokens.get(DESCRIPTION_INDEX);
    }
    SystemContextView view = workspace.getViews().createSystemContextView(softwareSystem, key, description);
    view.setEnterpriseBoundaryVisible(true);
    return view;
}
Also used : SystemContextView(com.structurizr.view.SystemContextView) Element(com.structurizr.model.Element) SoftwareSystem(com.structurizr.model.SoftwareSystem) Workspace(com.structurizr.Workspace)

Example 5 with Workspace

use of com.structurizr.Workspace in project dsl by structurizr.

the class SystemLandscapeViewParser method parse.

SystemLandscapeView parse(DslContext context, Tokens tokens) {
    if (tokens.hasMoreThan(DESCRIPTION_INDEX)) {
        throw new RuntimeException("Too many tokens, expected: " + GRAMMAR);
    }
    Workspace workspace = context.getWorkspace();
    String key = "";
    String description = "";
    if (tokens.includes(KEY_INDEX)) {
        key = tokens.get(KEY_INDEX);
    } else {
        key = VIEW_TYPE;
    }
    validateViewKey(key);
    if (tokens.includes(DESCRIPTION_INDEX)) {
        description = tokens.get(DESCRIPTION_INDEX);
    }
    SystemLandscapeView view = workspace.getViews().createSystemLandscapeView(key, description);
    view.setEnterpriseBoundaryVisible(true);
    return view;
}
Also used : SystemLandscapeView(com.structurizr.view.SystemLandscapeView) Workspace(com.structurizr.Workspace)

Aggregations

Workspace (com.structurizr.Workspace)155 Test (org.junit.Test)98 Test (org.junit.jupiter.api.Test)36 File (java.io.File)23 Container (com.structurizr.model.Container)22 SoftwareSystem (com.structurizr.model.SoftwareSystem)22 Component (com.structurizr.model.Component)12 JavaClasses (com.tngtech.archunit.core.domain.JavaClasses)12 ClassFileImporter (com.tngtech.archunit.core.importer.ClassFileImporter)12 Application (org.archifacts.core.model.Application)12 ArtifactContainer (org.archifacts.core.model.ArtifactContainer)10 ArrayList (java.util.ArrayList)6 EncryptedWorkspace (com.structurizr.encryption.EncryptedWorkspace)5 Element (com.structurizr.model.Element)5 Model (com.structurizr.model.Model)5 Artifact (org.archifacts.core.model.Artifact)5 MiscArtifact (org.archifacts.core.model.MiscArtifact)5 Person (com.structurizr.model.Person)4 Relationship (com.structurizr.model.Relationship)4 SystemContextView (com.structurizr.view.SystemContextView)4