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

org.nuiton.eugene.models.friend.ClassDef Maven / Gradle / Ivy

There is a newer version: 3.0-alpha-15
Show newest version
package org.nuiton.eugene.models.friend;

/*-
 * #%L
 * EUGene :: EUGene
 * %%
 * Copyright (C) 2004 - 2017 Ultreia.io
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Lesser Public License for more details.
 * 
 * You should have received a copy of the GNU General Lesser Public
 * License along with this program.  If not, see
 * .
 * #L%
 */

import com.google.common.base.Joiner;
import java.beans.Introspector;
import java.io.BufferedWriter;
import java.io.IOException;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuiton.eugene.models.object.ObjectModelAttribute;
import org.nuiton.eugene.models.object.ObjectModelClass;
import org.nuiton.eugene.models.object.ObjectModelInterface;
import org.nuiton.eugene.models.object.ObjectModelOperation;
import org.nuiton.eugene.models.object.xml.ObjectModelAttributeImpl;
import org.nuiton.eugene.models.object.xml.ObjectModelClassImpl;
import org.nuiton.eugene.models.object.xml.ObjectModelImpl;
import org.nuiton.eugene.models.object.xml.ObjectModelImplRef;
import org.nuiton.eugene.models.object.xml.ObjectModelImplSuperClassRef;

/**
 * Created by tchemit on 22/06/17.
 *
 * @author Tony Chemit - [email protected]
 */
public class ClassDef extends ClassifierDef {

    private static final String PREFIX = "class ";
    private final boolean isAbstract;

    public static ClassDef of(ObjectModelClass aClass, String defaultPackage) {
        ClassDef result = new ClassDef(getRelativeType(aClass.getQualifiedName(), defaultPackage), defaultPackage, aClass.isAbstract());
        Collection superclasses = aClass.getSuperclasses();
        if (!superclasses.isEmpty()) {
            result.setExtend(getRelativeType(superclasses.iterator().next().getQualifiedName(), defaultPackage));
        }
        result.loadStereotypesAndTagValues(aClass);
        for (ObjectModelInterface objectModelInterface : aClass.getInterfaces()) {
            result.addImplement(getRelativeType(objectModelInterface.getQualifiedName(), defaultPackage));
        }
        for (ObjectModelOperation objectModelOperation : aClass.getOperations()) {
            result.add(OperationDef.of(objectModelOperation, defaultPackage));
        }
        String reverseDefaultName = Introspector.decapitalize(aClass.getName());
        for (ObjectModelAttribute anAttribute : aClass.getAttributes()) {
            if (anAttribute.isNavigable()) {
                result.add(AttributeDef.of(anAttribute, defaultPackage, reverseDefaultName));
            }
        }
        return result;
    }

    public static ClassDef of(String firstLine, List groupLines, String defaultPackage) {
        firstLine = StringUtils.removeStart(firstLine, PREFIX);
        Pair pair = splitTagValues(firstLine);
        firstLine = pair.getLeft();
        boolean isAbstract=false;
        if (firstLine.startsWith("abstract ")) {
            firstLine = firstLine.substring("abstract ".length()).trim();
            isAbstract = true;
        }
        String tagValues = pair.getRight();
        int implementIndexOf = firstLine.indexOf(">>");
        String implement = null;
        if (implementIndexOf != -1) {
            implement = firstLine.substring(implementIndexOf + 2).trim();
            firstLine = firstLine.substring(0, implementIndexOf - 1);
        }

        int extendIndexOf = firstLine.indexOf('>');
        String extend = null;
        if (extendIndexOf != -1) {
            extend = firstLine.substring(extendIndexOf + 1).trim();
            firstLine = firstLine.substring(0, extendIndexOf - 1);
        }
        ClassDef def = new ClassDef(firstLine.trim(), defaultPackage, isAbstract);
        if (tagValues != null) {
            def.loadStereotypesAndTagValues(tagValues);
        }
        if (implement != null) {
            for (String oneImplement : implement.split(" ")) {
                def.addImplement(oneImplement.trim());
            }
        }
        if (extend != null) {
            def.setExtend(extend.trim());
        }

        for (String groupLine : groupLines) {
            if (groupLine.contains("(")) {
                def.add(OperationDef.of(groupLine));
            } else {
                def.add(AttributeDef.of(groupLine));
            }
        }
        return def;
    }

    /** Logger. */
    private static final Log log = LogFactory.getLog(ClassDef.class);

    private String extend;
    private String fullyQualifiedExtend;
    private final List implement = new LinkedList<>();
    private final List fullyQualifiedImplement = new LinkedList<>();

    private final List attributes = new LinkedList<>();

    private ClassDef(String name, String defaultPackage, boolean isAbstract) {
        super(name, defaultPackage);
        this.isAbstract = isAbstract;
    }

    public String getFullyQualifiedExtend() {
        return fullyQualifiedExtend;
    }

    public List getFullyQualifiedImplement() {
        return fullyQualifiedImplement;
    }

    @Override
    public void write(BufferedWriter writer) throws IOException {
        writer.newLine();
        if (isAbstract) {
            writer.append("abstract ");
        }
        writer.append(getName());
        if (extend != null) {
            writer.append(" > ").append(getExtend());
        }
        writeSimpleList(getImplement(), " >> ", writer);
        writeStereotypesAndTagValues(writer);
        for (AttributeDef attributeDef : attributes) {
            attributeDef.write(writer);
        }
        for (OperationDef operationDef : getOperations()) {
            operationDef.write(writer);
        }
        writer.newLine();
    }

    private void addImplement(String implement) {
        log.info(String.format("Add implement: %s on %s", implement, getName()));
        this.implement.add(implement);
    }

    private void add(AttributeDef attributeDef) {
        log.info(String.format("Add attribute: %s on %s", attributeDef, getName()));
        attributes.add(attributeDef);
    }

    @Override
    public int compareTo(ClassDef o) {
        if (isAbstract) {
            return o.isAbstract ? getFullyQualifiedName().compareTo(o.getFullyQualifiedName()) : -1;
        } else {
            return o.isAbstract ? 1 : getFullyQualifiedName().compareTo(o.getFullyQualifiedName());
        }
    }

    private void setExtend(String extend) {
        this.extend = extend;
    }

    @Override
    public String toString() {
        return getName()
                + (getExtend() == null ? "" : " extends " + extend)
                + (getImplement().isEmpty() ? "" : " implements " + Joiner.on(",").join(implement))
                + (attributes.isEmpty() ? "" : " attrs: " + Joiner.on(",").join(attributes))
                + (getOperations().isEmpty() ? "" : " ops: " + Joiner.on(",").join(getOperations()));
    }

    private String getExtend() {
        return extend;
    }

    private List getImplement() {
        return implement;
    }

    public List getAttributes() {
        return attributes;
    }

    @Override
    void resolveTypes(Map classesMapping) {
        super.resolveTypes(classesMapping);
        for (AttributeDef attributeDef : attributes) {
            attributeDef.resolveType(classesMapping);
        }
        if (extend != null) {
            fullyQualifiedExtend = resolveType(extend, classesMapping);
        }

        fullyQualifiedImplement.clear();
        for (String implement : implement) {
            fullyQualifiedImplement.add(resolveType(implement, classesMapping));
        }
    }

    ObjectModelClassImpl toObjectModel() {
        ObjectModelClassImpl result = new ObjectModelClassImpl();
        toObjectModel(result);
        if (isAbstract) {
            result.setAbstract(true);
        }
        if (extend != null) {
            ObjectModelImplRef ref = new ObjectModelImplSuperClassRef();
            ref.setName(fullyQualifiedExtend);
            result.addSuperclass(ref);
        }
        for (String implement : fullyQualifiedImplement) {
            ObjectModelImplRef ref = new ObjectModelImplRef();
            ref.setName(implement);
            result.addInterface(ref);
        }
        return result;
    }

    void addReverseAttributes(ObjectModelImpl model) {
        ObjectModelClassImpl aClass = (ObjectModelClassImpl) model.getClass(getFullyQualifiedName());
        for (AttributeDef attribute : this.attributes) {

            ObjectModelAttributeImpl attribute1 = attribute.toObjectModel(this);
            aClass.addAttribute(attribute1);

            String fullyQualifiedType = attribute.getFullyQualifiedType();
            ObjectModelClassImpl classifier = (ObjectModelClassImpl) model.getClass(fullyQualifiedType);
            if (classifier != null) {
                String reverseName = attribute.getReverseName(this);
                ObjectModelAttributeImpl reverseAttribute = (ObjectModelAttributeImpl) classifier.getAttribute(reverseName);
                if (reverseAttribute != null && reverseAttribute.getName().equals(attribute.getName())) {
                    log.warn("You could us a bidirectional relation for " + aClass.getQualifiedName() + "#" + attribute1.getName());
                    continue;
                }
                reverseAttribute = attribute.toReverseModel(this);
                classifier.addAttribute(reverseAttribute);
            }
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy