
ch.ifocusit.plantuml.classdiagram.AbstractClassDiagramBuilder Maven / Gradle / Ivy
/*-
* Plantuml builder
*
* Copyright (C) 2023 Focus IT
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 ch.ifocusit.plantuml.classdiagram;
import ch.ifocusit.plantuml.PlantUmlBuilder;
import ch.ifocusit.plantuml.classdiagram.model.Association;
import ch.ifocusit.plantuml.classdiagram.model.attribute.ClassAttribute;
import ch.ifocusit.plantuml.classdiagram.model.clazz.JavaClazz;
import ch.ifocusit.plantuml.classdiagram.model.method.ClassMethod;
import ch.ifocusit.plantuml.utils.ClassUtils;
import ch.ifocusit.plantuml.utils.PlantUmlUtils;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Stream;
/**
* Build class diagram from Class definition.
*
* @author Julien Boz
*/
@SuppressWarnings({"rawtypes", "unchecked", "unused"})
public abstract class AbstractClassDiagramBuilder implements LinkMaker {
private Predicate additionalFieldPredicate = a -> !a.getName().equals("ENUM$VALUES");
private static final List DEFAULT_METHODS_EXCLUDED = List.of("equals", "hashCode", "toString");
// by default java Object methods and getter/setter will be ignored
private Predicate additionalMethodPredicate = m -> !DEFAULT_METHODS_EXCLUDED.contains(m.getName())
&& ClassUtils.isNotGetterSetter(m.getMethod());
protected final PlantUmlBuilder builder = new PlantUmlBuilder();
protected final Set clazzes = new TreeSet<>();
protected final Set detectedAssociations = new HashSet<>();
protected LinkMaker linkMaker = this;
private String[] startOptions;
private String[] endOptions;
private String header;
private String title;
private String footer;
private final Map cache = new HashMap<>();
/**
* Add not specified Object.
*/
protected boolean withDependencies = false;
protected boolean hideSelfLink = true;
public AbstractClassDiagramBuilder() {
}
public B setHeader(String header) {
this.header = header;
return (B) this;
}
public B setTitle(String title) {
this.title = title;
return (B) this;
}
public B setStartOptions(String... lines) {
this.startOptions = lines;
return (B) this;
}
public B setEndOptions(String... lines) {
this.endOptions = lines;
return (B) this;
}
public B setFooter(String footer) {
this.footer = footer;
return (B) this;
}
public B excludes(String... excludes) {
// keep the corresponding fields
Predicate notMatchField = field -> Stream.of(excludes)
.noneMatch(excl -> field.toStringAttribute().matches(excl));
this.additionalFieldPredicate = this.additionalFieldPredicate.and(notMatchField);
// keep the corresponding fields
Predicate notMatchMethod = field -> Stream.of(excludes)
.noneMatch(excl -> field.toStringMethod().matches(excl));
this.additionalMethodPredicate = this.additionalMethodPredicate.and(notMatchMethod);
return (B) this;
}
public B addFieldPredicate(
Predicate predicate) {
this.additionalFieldPredicate = this.additionalFieldPredicate.and(predicate);
return (B) this;
}
public B addMethodPredicate(
Predicate predicate) {
this.additionalMethodPredicate = this.additionalMethodPredicate.and(predicate);
return (B) this;
}
public B withLinkMaker(LinkMaker linkMaker) {
this.linkMaker = linkMaker;
return (B) this;
}
public String build() {
// parse classes repository
// extract java classes definitions
readClasses();
// from java classes, detect associations
detectAssociations();
// generate diagram from configuration
builder.start(startOptions);
builder.appendHeader(header);
builder.appendTitle(title);
addPackages(); // add package definition
addTypes(); // add types definition
addAssociations(); // then add their associations
builder.appendFooter(footer);
builder.end(endOptions);
return builder.build();
}
public abstract void addPackages();
public abstract void detectAssociations();
public boolean hideFields(JavaClazz javaClazz) {
return PlantUmlUtils.hideFields(javaClazz, header)
|| PlantUmlUtils.hideFields(javaClazz, footer);
}
public boolean hideMethods(JavaClazz javaClazz) {
return PlantUmlUtils.hideMethods(javaClazz, header)
|| PlantUmlUtils.hideMethods(javaClazz, footer);
}
public abstract void readClasses();
public void addTypes() {
clazzes.forEach(builder::addType);
}
public Predicate filterFields() {
return additionalFieldPredicate;
}
public Predicate filterMethods() {
return additionalMethodPredicate;
}
public void addAssociations() {
detectedAssociations.stream().sorted().forEach(builder::addAssociation);
}
public B withDependencies(boolean flag) {
withDependencies = flag;
return (B) this;
}
public B hideSelfLink() {
hideSelfLink = true;
return (B) this;
}
public B showSelfLink() {
hideSelfLink = false;
return (B) this;
}
public B withDependencies() {
return withDependencies(true);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy