Skip to content

Commit

Permalink
A few enhancements.
Browse files Browse the repository at this point in the history
  • Loading branch information
simonbrowndotje committed Aug 18, 2024
1 parent bdff6a1 commit 4730125
Show file tree
Hide file tree
Showing 17 changed files with 128 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import org.apache.bcel.classfile.ConstantPool;
import org.apache.bcel.classfile.Method;
import org.apache.bcel.generic.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.*;

Expand All @@ -17,6 +19,8 @@
*/
public final class ComponentFinder {

private static final Log log = LogFactory.getLog(ComponentFinder.class);

private static final String COMPONENT_TYPE_PROPERTY_NAME = "component.type";
private static final String COMPONENT_SOURCE_PROPERTY_NAME = "component.src";

Expand Down Expand Up @@ -96,11 +100,15 @@ private void findDependencies(com.structurizr.component.Type type) {
* Find components, using all configured rules, in the order they were added.
*/
public void findComponents() {
Set<DiscoveredComponent> discoveredComponents = new HashSet<>();
Set<DiscoveredComponent> discoveredComponents = new LinkedHashSet<>();
Map<DiscoveredComponent, Component> componentMap = new HashMap<>();

for (ComponentFinderStrategy componentFinderStrategy : componentFinderStrategies) {
discoveredComponents.addAll(componentFinderStrategy.findComponents(typeRepository));
Set<DiscoveredComponent> set = componentFinderStrategy.findComponents(typeRepository);
if (set.isEmpty()) {
throw new RuntimeException("No components were found by " + componentFinderStrategy);
}
discoveredComponents.addAll(set);
}

for (DiscoveredComponent discoveredComponent : discoveredComponents) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.structurizr.model.Component;

import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;

/**
Expand Down Expand Up @@ -36,7 +37,7 @@ class ComponentFinderStrategy {
}

Set<DiscoveredComponent> findComponents(TypeRepository typeRepository) {
Set<DiscoveredComponent> components = new HashSet<>();
Set<DiscoveredComponent> components = new LinkedHashSet<>();

Set<Type> types = typeRepository.getTypes();
for (Type type : types) {
Expand All @@ -60,4 +61,12 @@ void visit(Component component) {
this.componentVisitor.visit(component);
}

@Override
public String toString() {
return "ComponentFinderStrategy{" +
"typeMatcher=" + typeMatcher +
", typeFilter=" + typeFilter +
'}';
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.structurizr.component.filter.TypeFilter;
import com.structurizr.component.matcher.TypeMatcher;
import com.structurizr.component.naming.DefaultNamingStrategy;
import com.structurizr.component.naming.SimpleNamingStrategy;
import com.structurizr.component.naming.NamingStrategy;
import com.structurizr.component.supporting.DefaultSupportingTypesStrategy;
import com.structurizr.component.supporting.SupportingTypesStrategy;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
package com.structurizr.component;

import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;

final class TypeRepository {

private final Set<Type> types = new HashSet<>();
private final Set<Type> types = new LinkedHashSet<>();

public void add(Type type) {
this.types.add(type);
}

public Set<Type> getTypes() {
return new HashSet<>(types);
return new LinkedHashSet<>(types);
}

Type getType(String fullyQualifiedClassName) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,9 @@ public boolean accept(Type type) {
return true;
}

@Override
public String toString() {
return "DefaultTypeFilter{}";
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,9 @@ public boolean accept(Type type) {
return !type.isAbstract();
}

@Override
public String toString() {
return "ExcludeAbstractClassTypeFilter{}";
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,22 @@
*/
public class ExcludeTypesByRegexFilter implements TypeFilter {

private final String[] regexes;
private final String regex;

public ExcludeTypesByRegexFilter(String... regexes) {
this.regexes = regexes;
public ExcludeTypesByRegexFilter(String regex) {
this.regex = regex;
}

@Override
public boolean accept(Type type) {
for (String regex : regexes) {
if (type.getFullyQualifiedName().matches(regex)) {
return false;
}
}
return !type.getFullyQualifiedName().matches(regex);
}

return true;
@Override
public String toString() {
return "ExcludeTypesByRegexFilter{" +
"regex='" + regex + '\'' +
'}';
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.structurizr.component.filter;

import com.structurizr.component.Type;

/**
* A type filter that includes by matching a regex against the fully qualified type name.
*/
public class IncludeTypesByRegexFilter implements TypeFilter {

private final String regex;

public IncludeTypesByRegexFilter(String regex) {
this.regex = regex;
}

@Override
public boolean accept(Type type) {
return type.getFullyQualifiedName().matches(regex);
}

@Override
public String toString() {
return "IncludeTypesByRegexFilter{" +
"regex='" + regex + '\'' +
'}';
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,11 @@ public boolean matches(Type type) {
return false;
}

@Override
public String toString() {
return "AnnotationTypeMatcher{" +
"annotationType='" + annotationType + '\'' +
'}';
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,11 @@ public boolean matches(Type type) {
return false;
}

@Override
public String toString() {
return "ExtendsTypeMatcher{" +
"className='" + className + '\'' +
'}';
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,11 @@ public boolean matches(Type type) {
return interfaceNames.contains(interfaceName);
}

@Override
public String toString() {
return "ImplementsTypeMatcher{" +
"interfaceName='" + interfaceName + '\'' +
'}';
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,11 @@ public boolean matches(Type type) {
return type.getFullyQualifiedName().endsWith(suffix);
}

@Override
public String toString() {
return "NameSuffixTypeMatcher{" +
"suffix='" + suffix + '\'' +
'}';
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,11 @@ public boolean matches(Type type) {
}
}

@Override
public String toString() {
return "RegexTypeMatcher{" +
"regex=" + regex +
'}';
}

}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@
import com.structurizr.component.Type;

/**
* Uses the simple/short name of the type (i.e. without the package name).
* Uses Apache commons-lang to split a camel/Pascal cased name into separate words
* (e.g. "CustomerRepository" -> "Customer Repository").
*/
public class DefaultNamingStrategy implements NamingStrategy {

@Override
public String nameOf(Type type) {
return type.getName();
String[] parts = org.apache.commons.lang3.StringUtils.splitByCharacterTypeCamelCase(type.getName());
return String.join(" ", parts);
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.structurizr.component.naming;

import com.structurizr.component.Type;

/**
* Uses the simple/short name of the type (i.e. without the package name).
*/
public class SimpleNamingStrategy implements NamingStrategy {

public String nameOf(Type type) {
return type.getName();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import com.structurizr.component.ComponentFinderBuilder;
import com.structurizr.component.ComponentFinderStrategyBuilder;
import com.structurizr.component.matcher.NameSuffixTypeMatcher;
import com.structurizr.component.naming.CommonsLangCamelCaseNamingStrategy;
import com.structurizr.component.naming.DefaultNamingStrategy;
import com.structurizr.model.*;

public class Example {
Expand All @@ -25,14 +25,12 @@ public static void main(String[] args) {
.withStrategy(
new ComponentFinderStrategyBuilder()
.matchedBy(new NameSuffixTypeMatcher("Controller", "Web MVC Controller"))
.namedBy(new CommonsLangCamelCaseNamingStrategy())
.forEach(component -> user.uses(component, "Uses"))
.build()
)
.withStrategy(
new ComponentFinderStrategyBuilder()
.matchedBy(new NameSuffixTypeMatcher("Repository", "Data Repository"))
.namedBy(new CommonsLangCamelCaseNamingStrategy())
.forEach(component -> component.uses(databaseSchema, "Reads from and writes to"))
.build()
)
Expand Down

0 comments on commit 4730125

Please sign in to comment.