Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
poussecafe.doc.HtmlWriter Maven / Gradle / Ivy
package poussecafe.doc;
import freemarker.template.Configuration;
import freemarker.template.Template;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import org.apache.commons.io.IOUtils;
import poussecafe.doc.model.BoundedContextComponentDoc;
import poussecafe.doc.model.ComponentDoc;
import poussecafe.doc.model.DomainProcessSteps;
import poussecafe.doc.model.DomainProcessStepsFactory;
import poussecafe.doc.model.UbiquitousLanguageEntry;
import poussecafe.doc.model.UbiquitousLanguageFactory;
import poussecafe.doc.model.aggregatedoc.AggregateDoc;
import poussecafe.doc.model.aggregatedoc.AggregateDocId;
import poussecafe.doc.model.aggregatedoc.AggregateDocRepository;
import poussecafe.doc.model.boundedcontextdoc.BoundedContextDoc;
import poussecafe.doc.model.boundedcontextdoc.BoundedContextDocRepository;
import poussecafe.doc.model.domainprocessdoc.DomainProcessDoc;
import poussecafe.doc.model.domainprocessdoc.DomainProcessDocRepository;
import poussecafe.doc.model.domainprocessdoc.Step;
import poussecafe.doc.model.entitydoc.EntityDoc;
import poussecafe.doc.model.entitydoc.EntityDocId;
import poussecafe.doc.model.entitydoc.EntityDocRepository;
import poussecafe.doc.model.relation.ComponentType;
import poussecafe.doc.model.relation.Relation;
import poussecafe.doc.model.relation.RelationRepository;
import poussecafe.doc.model.servicedoc.ServiceDoc;
import poussecafe.doc.model.servicedoc.ServiceDocRepository;
import poussecafe.doc.model.vodoc.ValueObjectDoc;
import poussecafe.doc.model.vodoc.ValueObjectDocId;
import poussecafe.doc.model.vodoc.ValueObjectDocRepository;
import static java.util.stream.Collectors.toList;
public class HtmlWriter {
public void writeHtml() {
try {
FileWriter stream = new FileWriter(new File(configuration.outputDirectory(), "index.html"));
copyCss();
Configuration freemarkerConfig = new Configuration(Configuration.VERSION_2_3_28);
freemarkerConfig.setClassForTemplateLoading(getClass(), "/");
Template template = freemarkerConfig.getTemplate("index.html");
HashMap domain = new HashMap<>();
domain.put("name", configuration.domainName());
domain.put("version", configuration.version());
List boundedContextDocs = boundedContextDocRepository.findAll();
domain.put("boundedContexts",
boundedContextDocs
.stream()
.sorted(this::compareBoundedContexts)
.map(this::adapt)
.collect(toList()));
HashMap model = new HashMap<>();
model.put("includeGenerationDate", configuration.includeGenerationDate());
model.put("domain", domain);
model.put("generationDate", new Date());
model.put("ubiquitousLanguage",
ubitquitousLanguageFactory
.buildUbiquitousLanguage()
.stream()
.filter(doc -> !doc.componentDoc().trivial())
.map(this::adapt)
.collect(toList()));
template.process(model, stream);
stream.close();
} catch (Exception e) {
throw new RuntimeException("Error while writing HTML", e);
}
}
private PousseCafeDocletConfiguration configuration;
private BoundedContextDocRepository boundedContextDocRepository;
private int compareBoundedContexts(BoundedContextDoc boundedContextDoc1, BoundedContextDoc boundedContextDoc2) {
return compareTo(boundedContextDoc1.attributes().componentDoc().value(), boundedContextDoc2.attributes().componentDoc().value());
}
private int compareTo(ComponentDoc componentDoc1,
ComponentDoc componentDoc2) {
return componentDoc1.name().compareTo(componentDoc2.name());
}
private HashMap adapt(BoundedContextDoc boundedContextDoc) {
HashMap view = new HashMap<>();
view.put("id", boundedContextDoc.id());
view.put("name", boundedContextDoc.attributes().componentDoc().value().name());
view.put("description", boundedContextDoc.attributes().componentDoc().value().description());
view.put("aggregates", aggregateDocRepository
.findByBoundedContextId(boundedContextDoc.attributes().identifier().value())
.stream()
.sorted(this::compareAggregates)
.map(this::adapt)
.collect(toList()));
view.put("services", serviceDocRepository
.findByBoundedContextId(boundedContextDoc.attributes().identifier().value())
.stream()
.sorted(this::compareServices)
.map(this::adapt)
.collect(toList()));
view.put("domainProcesses", domainProcessDocRepository
.findByBoundedContextId(boundedContextDoc.attributes().identifier().value())
.stream()
.sorted(this::compareDomainProcesses)
.map(this::adapt)
.collect(toList()));
return view;
}
private AggregateDocRepository aggregateDocRepository;
private int compareAggregates(AggregateDoc aggregateDoc1, AggregateDoc aggregateDoc2) {
return compareTo(aggregateDoc1.attributes().boundedContextComponentDoc().value(), aggregateDoc2.attributes().boundedContextComponentDoc().value());
}
private int compareTo(BoundedContextComponentDoc boundedContextComponentDoc1,
BoundedContextComponentDoc boundedContextComponentDoc2) {
return compareTo(boundedContextComponentDoc1.componentDoc(), boundedContextComponentDoc2.componentDoc());
}
private ServiceDocRepository serviceDocRepository;
private int compareServices(ServiceDoc serviceDoc1, ServiceDoc serviceDoc2) {
return compareTo(serviceDoc1.attributes().boundedContextComponentDoc().value(), serviceDoc2.attributes().boundedContextComponentDoc().value());
}
private DomainProcessDocRepository domainProcessDocRepository;
private int compareDomainProcesses(DomainProcessDoc boundedContextDoc1, DomainProcessDoc boundedContextDoc2) {
return compareTo(boundedContextDoc1.attributes().boundedContextComponentDoc().value(), boundedContextDoc2.attributes().boundedContextComponentDoc().value());
}
private HashMap adapt(AggregateDoc aggregateDoc) {
HashMap view = new HashMap<>();
view.put("id", aggregateDoc.id());
view.put("name", aggregateDoc.attributes().boundedContextComponentDoc().value().componentDoc().name());
view.put("description", aggregateDoc.attributes().boundedContextComponentDoc().value().componentDoc().description());
view.put("entities", findEntities(aggregateDoc.attributes().identifier().value()).stream()
.sorted(this::compareEntities)
.map(this::adapt)
.collect(toList()));
view.put("valueObjects", findValueObjects(aggregateDoc.attributes().identifier().value()).stream()
.sorted(this::compareValueObjects)
.map(this::adapt)
.collect(toList()));
return view;
}
private List findEntities(AggregateDocId aggregateDocId) {
return findEntities(aggregateDocId.stringValue()).stream()
.map(entityDocRepository::find)
.filter(Objects::nonNull)
.filter(doc -> !doc.attributes().boundedContextComponentDoc().value().componentDoc().trivial())
.collect(toList());
}
private int compareEntities(EntityDoc entityDoc1, EntityDoc entityDoc2) {
return compareTo(entityDoc1.attributes().boundedContextComponentDoc().value(), entityDoc2.attributes().boundedContextComponentDoc().value());
}
private Set findEntities(String fromClassName) {
Set ids = new HashSet<>();
for(Relation relation : relationRepository.findWithFromClassName(fromClassName)) {
if(relation.toComponent().type() == ComponentType.ENTITY) {
ids.add(EntityDocId.ofClassName(relation.toComponent().className()));
}
if(relation.toComponent().type() != ComponentType.AGGREGATE) {
ids.addAll(findEntities(relation.toComponent().className()));
}
}
return ids;
}
private RelationRepository relationRepository;
private EntityDocRepository entityDocRepository;
private HashMap adapt(EntityDoc entityDoc) {
HashMap view = new HashMap<>();
view.put("id", entityDoc.id());
view.put("name", entityDoc.attributes().boundedContextComponentDoc().value().componentDoc().name());
view.put("description", entityDoc.attributes().boundedContextComponentDoc().value().componentDoc().description());
return view;
}
private List findValueObjects(AggregateDocId aggregateDocId) {
return findValueObjects(aggregateDocId.stringValue()).stream()
.map(valueObjectDocRepository::find)
.filter(Objects::nonNull)
.filter(doc -> !doc.attributes().boundedContextComponentDoc().value().componentDoc().trivial())
.collect(toList());
}
private int compareValueObjects(ValueObjectDoc valueObjectDoc1, ValueObjectDoc valueObjectDoc2) {
return compareTo(valueObjectDoc1.attributes().boundedContextComponentDoc().value(), valueObjectDoc2.attributes().boundedContextComponentDoc().value());
}
private Set findValueObjects(String fromClassName) {
Set ids = new HashSet<>();
for(Relation relation : relationRepository.findWithFromClassName(fromClassName)) {
if(relation.toComponent().type() == ComponentType.VALUE_OBJECT) {
ids.add(ValueObjectDocId.ofClassName(relation.toComponent().className()));
}
if(relation.toComponent().type() != ComponentType.AGGREGATE) {
ids.addAll(findValueObjects(relation.toComponent().className()));
}
}
return ids;
}
private ValueObjectDocRepository valueObjectDocRepository;
private HashMap adapt(ValueObjectDoc entityDoc) {
HashMap view = new HashMap<>();
view.put("id", entityDoc.id());
view.put("name", entityDoc.attributes().boundedContextComponentDoc().value().componentDoc().name());
view.put("description", entityDoc.attributes().boundedContextComponentDoc().value().componentDoc().description());
return view;
}
private HashMap adapt(ServiceDoc serviceDoc) {
HashMap view = new HashMap<>();
view.put("id", serviceDoc.id());
view.put("name", serviceDoc.attributes().boundedContextComponentDoc().value().componentDoc().name());
view.put("description", serviceDoc.attributes().boundedContextComponentDoc().value().componentDoc().description());
return view;
}
private HashMap adapt(DomainProcessDoc domainProcessDoc) {
HashMap view = new HashMap<>();
view.put("id", domainProcessDoc.id());
view.put("name", domainProcessDoc.attributes().boundedContextComponentDoc().value().componentDoc().name());
view.put("description", domainProcessDoc.attributes().boundedContextComponentDoc().value().componentDoc().description());
DomainProcessSteps domainProcessSteps = domainProcessStepsFactory.buildDomainProcessSteps(domainProcessDoc);
view.put("steps", domainProcessSteps.orderedSteps().stream()
.filter(step -> !step.componentDoc().trivial())
.filter(step -> !step.external())
.map(this::adapt)
.collect(toList()));
return view;
}
private DomainProcessStepsFactory domainProcessStepsFactory;
private HashMap adapt(Step step) {
HashMap view = new HashMap<>();
view.put("name", step.componentDoc().name());
view.put("description", step.componentDoc().description());
return view;
}
private HashMap adapt(UbiquitousLanguageEntry entry) {
HashMap view = new HashMap<>();
view.put("name", entry.qualifiedName());
view.put("type", entry.getType());
view.put("description", entry.componentDoc().shortDescription().orElse(entry.componentDoc().description()));
return view;
}
private void copyCss()
throws IOException {
IOUtils.copy(getClass().getResourceAsStream("/style.css"),
new FileOutputStream(new File(configuration.outputDirectory(), "style.css")));
}
private UbiquitousLanguageFactory ubitquitousLanguageFactory;
}