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

org.nuiton.eugene.models.object.ObjectModelBuilder Maven / Gradle / Ivy

There is a newer version: 3.0
Show newest version
/*
 * #%L
 * EUGene :: EUGene
 * %%
 * Copyright (C) 2004 - 2010 CodeLutin
 * %%
 * 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%
 */


package org.nuiton.eugene.models.object;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuiton.eugene.models.object.xml.ObjectModeImplAssociationClassParticipant;
import org.nuiton.eugene.models.object.xml.ObjectModelAssociationClassImpl;
import org.nuiton.eugene.models.object.xml.ObjectModelAttributeImpl;
import org.nuiton.eugene.models.object.xml.ObjectModelClassImpl;
import org.nuiton.eugene.models.object.xml.ObjectModelClassifierImpl;
import org.nuiton.eugene.models.object.xml.ObjectModelElementImpl;
import org.nuiton.eugene.models.object.xml.ObjectModelEnumerationImpl;
import org.nuiton.eugene.models.object.xml.ObjectModelImpl;
import org.nuiton.eugene.models.object.xml.ObjectModelImplRef;
import org.nuiton.eugene.models.object.xml.ObjectModelImplSuperClassRef;
import org.nuiton.eugene.models.object.xml.ObjectModelImplTagValue;
import org.nuiton.eugene.models.object.xml.ObjectModelInterfaceImpl;
import org.nuiton.eugene.models.object.xml.ObjectModelOperationImpl;
import org.nuiton.eugene.models.object.xml.ObjectModelParameterImpl;

/**
 * Builder to fill an empty ObjectModel. The object model name is important if
 * you want to use the model in generators.
 *
 * Created: 3 nov. 2009
 *
 * @author Florian Desbois - [email protected]
 */
public class ObjectModelBuilder {

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

    protected ObjectModelImpl model;

    /**
     * Constructor. Must have a name for the new model created.
     *
     * @param name model name
     */
    public ObjectModelBuilder(String name) {
        model = new ObjectModelImpl();
        model.setName(name);
    }

    /**
     * Get the building model
     *
     * @return the ObjectModel which is currently built
     */
    public ObjectModel getModel() {
        return model;
    }

    /**
     * Add a tagValue to the model.
     *
     * @param name  tagValue name
     * @param value tagValue value
     */
    public void addTagValue(String name, String value) {
        ObjectModelImplTagValue tagValue = new ObjectModelImplTagValue();
        tagValue.setName(name);
        tagValue.setValue(value);
        model.addTagValue(tagValue);
    }

    /**
     * Add a tagValue to an element
     *
     * @param element where the tag value will be added
     * @param name    tagValue name
     * @param value   tagValue value
     */
    public void addTagValue(ObjectModelElement element,
                            String name,
                            String value) {
        ObjectModelElementImpl impl = (ObjectModelElementImpl) element;

        ObjectModelImplTagValue tagValue = new ObjectModelImplTagValue();
        tagValue.setName(name);
        tagValue.setValue(value);
        impl.addTagValue(tagValue);
    }

    /**
     * Create a new class in the model.
     * Modifiers allowed : ABSTRACT, STATIC.
     *
     * @param name        class name
     * @param packageName class package
     * @param modifiers   class modifiers
     * @return the new ObjectModelClass added to the model
     */
    public ObjectModelClass createClass(String name,
                                        String packageName,
                                        ObjectModelModifier... modifiers) {
        ObjectModelClassImpl result = new ObjectModelClassImpl();
        return createClass(result, name, packageName, modifiers);
    }

    protected ObjectModelClass createClass(ObjectModelClassImpl clazz,
                                           String name,
                                           String packageName,
                                           ObjectModelModifier... modifiers)
            throws IllegalArgumentException {
        clazz.setName(name);
        clazz.setPackage(packageName);
        setClassModifiers(clazz, modifiers);
        model.addClass(clazz);
        return clazz;
    }

    /**
     * Set modifiers to a class. Only STATIC and ABSTRACT are actually supported.
     *
     * @param clazz     ObjectModelClassImpl where modifiers will be set
     * @param modifiers Array of ObjectModelModifier to set
     * @throws IllegalArgumentException for unsupported modifier
     */
    protected void setClassModifiers(ObjectModelClassImpl clazz,
                                     ObjectModelModifier... modifiers)
            throws IllegalArgumentException {

        clazz.addModifier(modifiers);
//        for (ObjectModelModifier modifier : modifiers) {
//            switch (modifier) {
//                case ABSTRACT:
//                    clazz.setAbstract(true);
//                    break;
//                case STATIC:
//                    clazz.setStatic(true);
//                    break;
//                default:
//                    throw new IllegalArgumentException(
//                            "Unsupported modifier type '" + modifier.name() + "'");
//            }
//        }
    }

    /**
     * Create a new interface in the model.
     *
     * @param name        interface name
     * @param packageName interface package
     * @return the new ObjectModelInterface added to the model
     */
    public ObjectModelInterface createInterface(String name,
                                                String packageName) {
        ObjectModelInterfaceImpl result = new ObjectModelInterfaceImpl();
        result.setName(name);
        result.setPackage(packageName);
        model.addInterface(result);
        return result;
    }

    /**
     * Create a new interface in the model.
     *
     * @param name        interface name
     * @param packageName interface package
     * @return the new ObjectModelInterface added to the model
     */
    public ObjectModelEnumeration createEnumeration(String name,
                                                    String packageName) {
        ObjectModelEnumerationImpl result = new ObjectModelEnumerationImpl();
        result.setName(name);
        result.setPackage(packageName);
        model.addEnumeration(result);
        return result;
    }


    /**
     * Add an attribute to a classifier (interface, class, enum) without default value.
     * Default visibility is set to PUBLIC.
     *
     * @param classifier where the attribute will be added
     * @param name       attribute name
     * @param type       attribute type (full qualified name)
     * @return the new ObjectModelAttribute added
     */
    public ObjectModelAttribute addAttribute(ObjectModelClassifier classifier,
                                             String name,
                                             String type) {
        return addAttribute(classifier, name, type, "");
    }

    /**
     * Add an attribute to a classifier (interface, class, enum).
     * Modifiers allowed : STATIC, FINAL, TRANSIENT, PUBLIC, PRIVATE, PROTECTED, PACKAGE, ORDERED, UNIQUE.
     * The last visibility set will be keeped.
     *
     * @param classifier where the attribute will be added
     * @param name       attribute name
     * @param type       attribute type (full qualified name)
     * @param value      default value for the attribute
     * @param modifiers  attribute modifiers
     * @return the new ObjectModelAttribute added
     * @throws IllegalArgumentException illegal Modifier
     * @see ObjectModelModifier#isVisibility()
     */
    public ObjectModelAttribute addAttribute(ObjectModelClassifier classifier,
                                             String name,
                                             String type,
                                             String value,
                                             ObjectModelModifier... modifiers)
            throws IllegalArgumentException {
        ObjectModelAttributeImpl attribute = new ObjectModelAttributeImpl();
        attribute.setName(name);
        attribute.setType(type);
        attribute.setDefaultValue(value);

        attribute.addModifier(modifiers);
//        for (ObjectModelModifier modifier : modifiers) {
//            if (modifier.isVisibility()) {
//                attribute.setVisibility(modifier.toString());
//            } else {
//                switch (modifier) {
//                    case STATIC:
//                        attribute.setStatic(true);
//                        break;
//                    case FINAL:
//                        attribute.setFinal(true);
//                        break;
//                    case ORDERED:
//                        attribute.setOrdering(modifier.toString());
//                        break;
//                    case UNIQUE:
//                        attribute.setUnique(true);
//                        break;
//                    case TRANSIENT:
//                        attribute.setTransient(true);
//                        break;
//                    default:
//                        throw new IllegalArgumentException(
//                                "Unsupported modifier type '" + modifier.name() + "'");
//                }
//            }
//        }

        ObjectModelClassifierImpl classifierImpl = (ObjectModelClassifierImpl) classifier;
        classifierImpl.addAttribute(attribute);
        return attribute;
    }

    /**
     * Add an association A to B. Create only attribute association for classifierA.
     * MODIFIERS allowed : PUBLIC, PRIVATE, PACKAGE, PROTECTED, AGGREGATE, COMPOSITE, ORDERED, UNIQUE
     * STATIC, NAVIGABLE.
     * You have to use method {@link #addReverseAssociation(ObjectModelAttribute, String, int, int, ObjectModelModifier...)}
     * to create attribute association for classifierB.
     *
     * @param classifierA     classifier from
     * @param classifierB     classifier to
     * @param roleName        role of A in association
     * @param minMultiplicity minimum multiplicity of A in association
     * @param maxMultiplicity maximum multiplicity of A in association
     * @param modifiers       for the association
     * @return the attribute corresponding to the association for classifierA
     * @throws IllegalArgumentException illegal modifier
     */
    public ObjectModelAttribute addAssociation(ObjectModelClassifier classifierA,
                                               ObjectModelClassifier classifierB,
                                               String roleName,
                                               int minMultiplicity,
                                               int maxMultiplicity,
                                               ObjectModelModifier... modifiers)
            throws IllegalArgumentException {

        ObjectModelAttributeImpl attribute = new ObjectModelAttributeImpl();

        attribute.setName(roleName);
        attribute.setMinMultiplicity(minMultiplicity);
        attribute.setMaxMultiplicity(maxMultiplicity);
        attribute.setType(classifierB.getQualifiedName());

        attribute.addModifier(modifiers);
//        for (ObjectModelModifier modifier : modifiers) {
//
//            if (modifier.isVisibility()) {
//                attribute.setVisibility(modifier.toString());
//            } else if (modifier.isAssociationType()) {
//                attribute.setAssociationType(modifier.toString());
//            } else {
//                switch (modifier) {
//                    case ORDERED:
//                        attribute.setOrdering(modifier.toString());
//                        break;
//                    case UNIQUE:
//                        attribute.setUnique(true);
//                        break;
//                    case STATIC:
//                        attribute.setStatic(true);
//                        break;
//                    case NAVIGABLE:
//                        attribute.setNavigable(true);
//                        break;
//                    default:
//                        throw new IllegalArgumentException(
//                                "Unsupported modifier type '" + modifier.name() + "'");
//                }
//            }
//        }
        ObjectModelClassifierImpl impl = (ObjectModelClassifierImpl) classifierA;
        impl.addAttribute(attribute);
        return attribute;
    }

    /**
     * Create reverse association from an other association.
     * MODIFIERS allowed : PUBLIC, PRIVATE, PACKAGE, PROTECTED, AGGREGATE, COMPOSITE, ORDERED, UNIQUE
     * STATIC, NAVIGABLE.
     *
     * @param attrAssociation other association A to B
     * @param roleName        role of B in association
     * @param minMultiplicity minimum multiplicity of B in association
     * @param maxMultiplicity maximum multiplicity of B in association
     * @param modifiers       for the association
     * @return the attribute corresponding to the association for classifierB
     * @see #addAssociation(ObjectModelClassifier, ObjectModelClassifier, String, int, int, ObjectModelModifier...)
     */
    public ObjectModelAttribute addReverseAssociation(ObjectModelAttribute attrAssociation,
                                                      String roleName,
                                                      int minMultiplicity,
                                                      int maxMultiplicity,
                                                      ObjectModelModifier... modifiers) {

        ObjectModelAttributeImpl associationA = (ObjectModelAttributeImpl) attrAssociation;
        // Add reverse parameters
        associationA.setReverseAttributeName(roleName);
        associationA.setReverseMaxMultiplicity(maxMultiplicity);

        ObjectModelClassifierImpl classifierA =
                (ObjectModelClassifierImpl) associationA.getDeclaringElement();

        String typeB = associationA.getType();
        // Get classifierB from model
        ObjectModelClassifierImpl classifierB = (ObjectModelClassifierImpl) model.getClassifier(typeB);

        // Create reverse association
        ObjectModelAttributeImpl associationB =
                (ObjectModelAttributeImpl) addAssociation(classifierB,
                                                          classifierA,
                                                          roleName,
                                                          minMultiplicity,
                                                          maxMultiplicity,
                                                          modifiers);

        associationB.setReverseAttributeName(associationA.getName());
        associationB.setReverseMaxMultiplicity(associationA.getMaxMultiplicity());

        return associationB;
    }

    /**
     * Create association class. The two extremities of the association must be existing before creating
     * the association class.
     * Modifiers allowed : ABSTRACT, STATIC.
     *
     * @param name             association class name
     * @param packageName      association package name
     * @param attrAssociationA attribute association for classifierA involved in association class
     * @param attrAssociationB attribute association for classifierB involved in association class
     * @param modifiers        for the association class
     * @return the new association class created with participants A and B
     */
    public ObjectModelAssociationClass createAssociationClass(String name,
                                                              String packageName,
                                                              ObjectModelAttribute attrAssociationA,
                                                              ObjectModelAttribute attrAssociationB,
                                                              ObjectModelModifier... modifiers) {

        ObjectModelAssociationClassImpl associationClass = new ObjectModelAssociationClassImpl();
        createClass(associationClass, name, packageName, modifiers);

        // Add associationClass in attrAssociationA
        ObjectModelAttributeImpl attrA =
                (ObjectModelAttributeImpl) attrAssociationA;
        attrA.setAssociationClassName(associationClass.getQualifiedName());

        // Add associationClass in attrAssociationB
        ObjectModelAttributeImpl attrB =
                (ObjectModelAttributeImpl) attrAssociationB;
        attrB.setAssociationClassName(associationClass.getQualifiedName());

        // Create participantA
        ObjectModeImplAssociationClassParticipant participantA =
                new ObjectModeImplAssociationClassParticipant();

        participantA.setAttribute(attrA.getName());
        ObjectModelClassifier classifierA =
                (ObjectModelClassifier) attrA.getDeclaringElement();
        participantA.setName(classifierA.getQualifiedName());

        associationClass.addParticipant(participantA);

        // Create participantB
        ObjectModeImplAssociationClassParticipant participantB =
                new ObjectModeImplAssociationClassParticipant();

        participantB.setAttribute(attrB.getName());
        ObjectModelClassifier classifierB =
                (ObjectModelClassifier) attrB.getDeclaringElement();
        participantB.setName(classifierB.getQualifiedName());

        associationClass.addParticipant(participantB);

        return associationClass;
    }

    /**
     * Add an operation to a classifier.
     * Modifiers allowed : STATIC, ABSTRACT, PUBLIC, PRIVATE, PROTECTED, PACKAGE.
     * The last visibility set will be keeped.
     *
     * @param classifier where the operation will be added
     * @param name       operation name
     * @param returnType operation type (full qualified name)
     * @param modifiers  operation modifiers
     * @return the new ObjectModelOperation added
     * @throws IllegalArgumentException illegal Modifier
     */
    public ObjectModelOperation addOperation(ObjectModelClassifier classifier,
                                             String name,
                                             String returnType,
                                             ObjectModelModifier... modifiers)
            throws IllegalArgumentException {
        ObjectModelOperationImpl result = new ObjectModelOperationImpl();
        result.setName(name);

        if (returnType != null) {
            ObjectModelParameterImpl returnParameter =
                    new ObjectModelParameterImpl();
            returnParameter.setType(returnType);
            result.setReturnParameter(returnParameter);
        }

        result.addModifier(modifiers);
//        for (ObjectModelModifier modifier : modifiers) {
//            if (modifier.isVisibility()) {
//                result.setVisibility(modifier.toString());
//            } else {
//                switch (modifier) {
//                    case STATIC:
//                        result.setStatic(true);
//                        break;
//                    case ABSTRACT:
//                        result.setAbstract(true);
//                        break;
//                    default:
//                        throw new IllegalArgumentException("Unsupported modifier type '" + modifier.name() + "'");
//                }
//            }
//        }

        ((ObjectModelClassifierImpl) classifier).addOperation(result);
        return result;
    }

    /**
     * Add an operation to a classifier.
     * Modifiers allowed : STATIC, ABSTRACT, PUBLIC, PRIVATE, PROTECTED, PACKAGE.
     * The last visibility set will be keeped.
     *
     * @param classifier where the operation will be added
     * @param operation  operation to add
     * @return the added operation (says the given parameter)
     * @since 2.1.2
     */
    public ObjectModelOperation addOperation(ObjectModelClassifier classifier,
                                             ObjectModelOperation operation) {

        ((ObjectModelClassifierImpl) classifier).addOperation(
                (ObjectModelOperationImpl) operation);
        return operation;
    }

    /**
     * Set the body code for an Operation.
     *
     * @param operation where the code will be added
     * @param body      code to add to the operation
     */
    public void setOperationBody(ObjectModelOperation operation, String body) {
        ObjectModelOperationImpl operationImpl =
                (ObjectModelOperationImpl) operation;
        operationImpl.setBodyCode(body);
    }

    /**
     * Add an interface to a classifier. The interface may not exist in model.
     *
     * @param classifier             where the interface will be added
     * @param interfaceQualifiedName interface qualified name
     */
    public void addInterface(ObjectModelClassifier classifier,
                             String interfaceQualifiedName) {
        ObjectModelClassifierImpl impl = (ObjectModelClassifierImpl) classifier;

        ObjectModelImplRef interfacez = new ObjectModelImplRef();
        interfacez.setName(interfaceQualifiedName);

        impl.addInterface(interfacez);
    }

    /**
     * Add a superclass to an other class. The superclass may not exist in model.
     *
     * @param clazz                   where the superclass will be added
     * @param superclassQualifiedName superclass qualified name
     */
    public void addSuperclass(ObjectModelClass clazz,
                              String superclassQualifiedName) {
        ObjectModelClassImpl impl = (ObjectModelClassImpl) clazz;

        ObjectModelImplSuperClassRef superclass =
                new ObjectModelImplSuperClassRef();
        superclass.setName(superclassQualifiedName);

        impl.addSuperclass(superclass);
    }

    /**
     * Add a superclass to an other class. The superclass may not exist in model.
     *
     * @param clazz     where the superclass will be added
     * @param type      type of inner classifier to create
     * @param name      superclass qualified name
     * @param modifiers modifiers of the inner classifier
     * @return the new instanciated inner classifier
     * @throws IllegalArgumentException if given {@code type} is not a concrete classifier type
     */
    public ObjectModelClassifier addInnerClassifier(ObjectModelClass clazz,
                                                    ObjectModelType type,
                                                    String name,
                                                    ObjectModelModifier... modifiers)
            throws IllegalArgumentException {

        ObjectModelClassImpl impl = (ObjectModelClassImpl) clazz;
        ObjectModelClassifierImpl inner;
        switch (type) {

            case OBJECT_MODEL_ENUMERATION:
                inner = new ObjectModelEnumerationImpl();
                break;
            case OBJECT_MODEL_CLASS:
                inner = new ObjectModelClassImpl();
                setClassModifiers((ObjectModelClassImpl) inner, modifiers);
                break;
            case OBJECT_MODEL_INTERFACE:
                inner = new ObjectModelInterfaceImpl();
                break;
            default:
                throw new IllegalArgumentException("can not add a none classifier type " + type);
        }
        inner.setName(name);
        inner.setPackage(clazz.getPackageName() + "." + clazz.getName());
        inner.postInit();
        impl.addInnerClassifier(inner);
        inner.setObjectModelImpl(impl.getModel());

        if (log.isDebugEnabled()) {
            log.debug("Add inner classifier for " + clazz.getQualifiedName() +
                      " : " + inner.getQualifiedName());
        }

        return inner;
    }

    /**
     * Add a parameter to an operation.
     *
     * @param operation where the parameter will be added
     * @param type      paremeter type (full qualified name)
     * @param name      parameter name
     * @return the new ObjectModelParameter added
     */
    public ObjectModelParameter addParameter(ObjectModelOperation operation,
                                             String type,
                                             String name) {
        ObjectModelOperationImpl impl = (ObjectModelOperationImpl) operation;
        ObjectModelParameterImpl param = new ObjectModelParameterImpl();
        param.setType(type);
        param.setName(name);
        impl.addParameter(param);
        return param;
    }

    /**
     * Add an exception to an operation.
     *
     * @param operation where the exception will be added
     * @param exception name of the exception (full qualified name)
     */
    public void addException(ObjectModelOperation operation, String exception) {
        ObjectModelOperationImpl impl = (ObjectModelOperationImpl) operation;
        ObjectModelParameterImpl param = new ObjectModelParameterImpl();
        param.setType(exception);
        impl.addExceptionParameter(param);
    }

    /**
     * Set the documentation of an element in the model.
     *
     * @param element       where the documentation will be setted
     * @param documentation String documentation for the element
     */
    public void setDocumentation(ObjectModelElement element,
                                 String documentation) {
        ObjectModelElementImpl impl = (ObjectModelElementImpl) element;
        impl.setDocumentation(documentation);
    }

    /**
     * Add a stereotype to an element.
     *
     * @param element    where the stereotype will be added
     * @param stereotype name
     */
    public void addStereotype(ObjectModelElement element, String stereotype) {
        ObjectModelElementImpl impl = (ObjectModelElementImpl) element;
        ObjectModelImplRef ref = new ObjectModelImplRef();
        ref.setName(stereotype);
        impl.addStereotype(ref);
    }

    public void addLiteral(ObjectModelEnumeration enumz, String name) {
        ObjectModelEnumerationImpl impl = (ObjectModelEnumerationImpl) enumz;
        ObjectModelImplRef ref = new ObjectModelImplRef();
        ref.setName(name);
        impl.addLiteral(ref);
    }

    /**
     * Add a comment to an element.
     *
     * @param element where the comment will be added
     * @param comment comment to add
     * @since 2.1.2
     */
    public void addComment(ObjectModelElement element, String comment) {
        ObjectModelElementImpl impl = (ObjectModelElementImpl) element;
        impl.addComment(comment);
    }

    /**
     * Set the min multiplicity of an attribute in the model.
     *
     * @param attribute    where the multiplicity will be setted
     * @param multiplicity String description for the element
     */
    public void setMinMultiplicity(ObjectModelAttribute attribute,
                                   int multiplicity) {
        ObjectModelAttributeImpl impl = (ObjectModelAttributeImpl) attribute;
        impl.setMinMultiplicity(multiplicity);
    }

    /**
     * Set the max multiplicity of an attribute in the model.
     *
     * @param attribute    where the multiplicity will be setted
     * @param multiplicity String description for the element
     */
    public void setMaxMultiplicity(ObjectModelAttribute attribute,
                                   int multiplicity) {
        ObjectModelAttributeImpl impl = (ObjectModelAttributeImpl) attribute;
        impl.setMaxMultiplicity(multiplicity);
    }


    /**
     * Set the navigable flag of an attribute in the model.
     *
     * @param attribute where the navigable flag will be setted
     * @param navigable navigable flag value to set
     * @since 2.3
     */
    public void setNavigable(ObjectModelAttribute attribute,
                             boolean navigable) {
        ObjectModelAttributeImpl impl = (ObjectModelAttributeImpl) attribute;
        impl.setNavigable(navigable);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy