All Downloads are FREE. Search and download functionalities are using the official Maven repository.

poussecafe.doc.RelationCreator Maven / Gradle / Ivy

There is a newer version: 0.29.0
Show newest version
package poussecafe.doc;

import java.util.function.Consumer;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.DeclaredType;
import jdk.javadoc.doclet.DocletEnvironment;
import poussecafe.doc.model.DocletServices;
import poussecafe.doc.model.aggregatedoc.AggregateDoc;
import poussecafe.doc.model.aggregatedoc.AggregateDocFactory;
import poussecafe.doc.model.aggregatedoc.AggregateDocId;
import poussecafe.doc.model.aggregatedoc.AggregateDocRepository;
import poussecafe.doc.model.entitydoc.EntityDoc;
import poussecafe.doc.model.entitydoc.EntityDocFactory;
import poussecafe.doc.model.entitydoc.EntityDocId;
import poussecafe.doc.model.entitydoc.EntityDocRepository;
import poussecafe.doc.model.relation.Component;
import poussecafe.doc.model.relation.ComponentType;
import poussecafe.doc.model.relation.RelationFactory.NewRelationParameters;
import poussecafe.doc.model.vodoc.ValueObjectDoc;
import poussecafe.doc.model.vodoc.ValueObjectDocFactory;
import poussecafe.doc.model.vodoc.ValueObjectDocId;
import poussecafe.doc.model.vodoc.ValueObjectDocRepository;
import poussecafe.doc.process.ComponentLinking;

public class RelationCreator implements Consumer {

    @Override
    public void accept(TypeElement classDoc) {
        if(aggregateDocFactory.isAggregateDoc(classDoc)) {
            tryRelationAggregateId(classDoc);
        }
        if(entityDocFactory.isEntityDoc(classDoc)) {
            tryRelationEntityId(classDoc);
        }
        if(aggregateDocFactory.isAggregateDoc(classDoc) || entityDocFactory.isEntityDoc(classDoc)) {
            tryAttributes(classDoc);
        }
        if(valueObjectDocFactory.isValueObjectDoc(classDoc)) {
            CodeExplorer codeExplorer = new CodeExplorer.Builder()
                    .basePackage(configuration.basePackage())
                    .rootClassDoc(classDoc)
                    .classRelationBuilder(this::classRelationBuilder)
                    .docletServices(docletServices)
                    .build();
            codeExplorer.explore();
        }
    }

    private AggregateDocFactory aggregateDocFactory;

    private EntityDocFactory entityDocFactory;

    private ValueObjectDocFactory valueObjectDocFactory;

    private PousseCafeDocletConfiguration configuration;

    private DocletServices docletServices;

    private void tryRelationAggregateId(TypeElement classDoc) {
        AggregateDoc aggregateDoc = aggregateDocRepository.find(AggregateDocId.ofClassName(classDoc.getQualifiedName().toString()));
        if(aggregateDoc != null) {
            ValueObjectDoc idDoc = valueObjectDocRepository.find(ValueObjectDocId.ofClassName(aggregateDoc.attributes().idClassName().value()));
            if(idDoc != null) {
                Logger.debug("Building bi-directional relation between aggregate " + classDoc.getQualifiedName() + " and its id " + aggregateDoc.attributes().idClassName().value());
                NewRelationParameters aggregateIdParameters = new NewRelationParameters();
                aggregateIdParameters.fromComponent = component(classDoc);
                aggregateIdParameters.toComponent = new Component(ComponentType.VALUE_OBJECT, aggregateDoc.attributes().idClassName().value());
                componentLinking.linkComponents(aggregateIdParameters);

                NewRelationParameters idAggregateParameters = new NewRelationParameters();
                idAggregateParameters.fromComponent = aggregateIdParameters.toComponent;
                idAggregateParameters.toComponent = aggregateIdParameters.fromComponent;
                componentLinking.linkComponents(idAggregateParameters);
            }
        }
    }

    private AggregateDocRepository aggregateDocRepository;

    private ValueObjectDocRepository valueObjectDocRepository;

    private void tryRelationEntityId(TypeElement classDoc) {
        EntityDoc entityDoc = entityDocRepository.find(EntityDocId.ofClassName(classDoc.getQualifiedName().toString()));
        if(entityDoc != null) {
            ValueObjectDoc idDoc = valueObjectDocRepository.find(ValueObjectDocId.ofClassName(entityDoc.attributes().idClassName().value()));
            if(idDoc != null) {
                Logger.debug("Building relation between entity " + classDoc.getQualifiedName() + " and its id " + entityDoc.attributes().idClassName().value());
                NewRelationParameters entityIdParameters = new NewRelationParameters();
                entityIdParameters.fromComponent = component(classDoc);
                entityIdParameters.toComponent = new Component(ComponentType.VALUE_OBJECT, entityDoc.attributes().idClassName().value());
                componentLinking.linkComponents(entityIdParameters);
            }
        }
    }

    private EntityDocRepository entityDocRepository;

    private Component component(TypeElement classDoc) {
        return new Component(componentType(classDoc), classDoc.getQualifiedName().toString());
    }

    private ComponentType componentType(TypeElement classDoc) {
        if(aggregateDocFactory.isAggregateDoc(classDoc)) {
            return ComponentType.AGGREGATE;
        } else if(entityDocFactory.isEntityDoc(classDoc)) {
            return ComponentType.ENTITY;
        } else if(valueObjectDocFactory.isValueObjectDoc(classDoc)) {
            return ComponentType.VALUE_OBJECT;
        } else {
            throw new IllegalArgumentException("Unsupported component class " + classDoc.getQualifiedName().toString());
        }
    }

    private ComponentLinking componentLinking;

    private void classRelationBuilder(TypeElement from, TypeElement to) {
        if(from != to) {
            linkComponents(from, to);
        }
    }

    private void linkComponents(TypeElement from,
            TypeElement to) {
        Logger.debug("Building relation between " + from.getQualifiedName() + " and " + to.getQualifiedName());
        NewRelationParameters parameters = new NewRelationParameters();
        parameters.fromComponent = component(from);
        parameters.toComponent = component(to);
        componentLinking.linkComponents(parameters);
    }

    private void tryAttributes(TypeElement classDoc) {
        DeclaredType superclass = (DeclaredType) classDoc.getSuperclass();
        TypeElement attributesClassDoc = (TypeElement) docletEnvironment.getTypeUtils().asElement(superclass.getTypeArguments().get(1));
        CodeExplorer pathFinder = new CodeExplorer.Builder()
                .rootClassDoc(classDoc)
                .basePackage(configuration.basePackage())
                .classRelationBuilder(this::classRelationBuilder)
                .docletServices(docletServices)
                .build();
        pathFinder.explore(attributesClassDoc);
    }

    private DocletEnvironment docletEnvironment;
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy