AssociationEndFacadeLogic.java

// license-header java merge-point
//
// Attention: generated code (by MetafacadeLogic.vsl) - do not modify!
//
package org.andromda.metafacades.uml14;

import java.util.Collection;
import org.andromda.core.metafacade.MetafacadeBase;
import org.andromda.core.metafacade.ModelValidationMessage;
import org.andromda.metafacades.uml.AssociationEndFacade;
import org.andromda.metafacades.uml.AssociationFacade;
import org.andromda.metafacades.uml.ClassifierFacade;
import org.andromda.translation.ocl.validation.OCLCollections;
import org.andromda.translation.ocl.validation.OCLIntrospector;
import org.andromda.translation.ocl.validation.OCLResultEnsurer;
import org.apache.log4j.Logger;
import org.omg.uml.foundation.core.AssociationEnd;

/**
 * A property related by memberEnd or its specializations to an association represents an end of the
 * association. The type of the property is the type of the end of the association .Property
 * represents a declared state of one or more instances in terms of a named relationship to a value
 * or values. When a property is an association end, the value or values are related to the instance
 * or instances at the other end(s) of the association.
 * MetafacadeLogic for AssociationEndFacade
 *
 * @see AssociationEndFacade
 */
public abstract class AssociationEndFacadeLogic
    extends ModelElementFacadeLogicImpl
    implements AssociationEndFacade
{
    /**
     * The underlying UML object
     * @see AssociationEnd
     */
    protected AssociationEnd metaObject;

    /** Create Metafacade implementation instance using the MetafacadeFactory from the context
     * @param metaObjectIn
     * @param context
     */
    protected AssociationEndFacadeLogic(AssociationEnd metaObjectIn, String context)
    {
        super(metaObjectIn, getContext(context));
        this.metaObject = metaObjectIn;
    }

    /**
     * The logger instance.
     */
    private static final Logger logger = Logger.getLogger(AssociationEndFacadeLogic.class);

    /**
     * Gets the context for this metafacade logic instance.
     * @param context String. Set to AssociationEndFacade if null
     * @return context String
     */
    private static String getContext(String context)
    {
        if (context == null)
        {
            context = "org.andromda.metafacades.uml.AssociationEndFacade";
        }
        return context;
    }

    /** Reset context only for non-root metafacades
     * @param context
     */
    @Override
    public void resetMetafacadeContext(String context)
    {
        if (!this.contextRoot) // reset context only for non-root metafacades
        {
            context = getContext(context);  // to have same value as in original constructor call
            setMetafacadeContext (context);
        }
    }

    /**
     * @return boolean true always
     * @see AssociationEndFacade
     */
    public boolean isAssociationEndFacadeMetaType()
    {
        return true;
    }

    // --------------- attributes ---------------------

   /**
    * @see AssociationEndFacade#isOne2One()
    * @return boolean
    */
    protected abstract boolean handleIsOne2One();

    private boolean __one2One1a;
    private boolean __one2One1aSet = false;

    /**
     * True if this association end's and the other end's multiplicities are both one.
     * @return (boolean)handleIsOne2One()
     */
    public final boolean isOne2One()
    {
        boolean one2One1a = this.__one2One1a;
        if (!this.__one2One1aSet)
        {
            // one2One has no pre constraints
            one2One1a = handleIsOne2One();
            // one2One has no post constraints
            this.__one2One1a = one2One1a;
            if (isMetafacadePropertyCachingEnabled())
            {
                this.__one2One1aSet = true;
            }
        }
        return one2One1a;
    }

   /**
    * @see AssociationEndFacade#isOne2Many()
    * @return boolean
    */
    protected abstract boolean handleIsOne2Many();

    private boolean __one2Many2a;
    private boolean __one2Many2aSet = false;

    /**
     * True if this association end's multiplicity is one while the other end's is many.
     * @return (boolean)handleIsOne2Many()
     */
    public final boolean isOne2Many()
    {
        boolean one2Many2a = this.__one2Many2a;
        if (!this.__one2Many2aSet)
        {
            // one2Many has no pre constraints
            one2Many2a = handleIsOne2Many();
            // one2Many has no post constraints
            this.__one2Many2a = one2Many2a;
            if (isMetafacadePropertyCachingEnabled())
            {
                this.__one2Many2aSet = true;
            }
        }
        return one2Many2a;
    }

   /**
    * @see AssociationEndFacade#isMany2One()
    * @return boolean
    */
    protected abstract boolean handleIsMany2One();

    private boolean __many2One3a;
    private boolean __many2One3aSet = false;

    /**
     * True if this association end's multiplicity is many while the other end's is one.
     * @return (boolean)handleIsMany2One()
     */
    public final boolean isMany2One()
    {
        boolean many2One3a = this.__many2One3a;
        if (!this.__many2One3aSet)
        {
            // many2One has no pre constraints
            many2One3a = handleIsMany2One();
            // many2One has no post constraints
            this.__many2One3a = many2One3a;
            if (isMetafacadePropertyCachingEnabled())
            {
                this.__many2One3aSet = true;
            }
        }
        return many2One3a;
    }

   /**
    * @see AssociationEndFacade#isMany2Many()
    * @return boolean
    */
    protected abstract boolean handleIsMany2Many();

    private boolean __many2Many4a;
    private boolean __many2Many4aSet = false;

    /**
     * True if this association end's and the other end's multiplicities are both many.
     * @return (boolean)handleIsMany2Many()
     */
    public final boolean isMany2Many()
    {
        boolean many2Many4a = this.__many2Many4a;
        if (!this.__many2Many4aSet)
        {
            // many2Many has no pre constraints
            many2Many4a = handleIsMany2Many();
            // many2Many has no post constraints
            this.__many2Many4a = many2Many4a;
            if (isMetafacadePropertyCachingEnabled())
            {
                this.__many2Many4aSet = true;
            }
        }
        return many2Many4a;
    }

   /**
    * @see AssociationEndFacade#isAggregation()
    * @return boolean
    */
    protected abstract boolean handleIsAggregation();

    private boolean __aggregation5a;
    private boolean __aggregation5aSet = false;

    /**
     * True if this association end represents an aggregation relationship.
     * @return (boolean)handleIsAggregation()
     */
    public final boolean isAggregation()
    {
        boolean aggregation5a = this.__aggregation5a;
        if (!this.__aggregation5aSet)
        {
            // aggregation has no pre constraints
            aggregation5a = handleIsAggregation();
            // aggregation has no post constraints
            this.__aggregation5a = aggregation5a;
            if (isMetafacadePropertyCachingEnabled())
            {
                this.__aggregation5aSet = true;
            }
        }
        return aggregation5a;
    }

   /**
    * @see AssociationEndFacade#isComposition()
    * @return boolean
    */
    protected abstract boolean handleIsComposition();

    private boolean __composition6a;
    private boolean __composition6aSet = false;

    /**
     * True if this association end represents a composition relationship.
     * @return (boolean)handleIsComposition()
     */
    public final boolean isComposition()
    {
        boolean composition6a = this.__composition6a;
        if (!this.__composition6aSet)
        {
            // composition has no pre constraints
            composition6a = handleIsComposition();
            // composition has no post constraints
            this.__composition6a = composition6a;
            if (isMetafacadePropertyCachingEnabled())
            {
                this.__composition6aSet = true;
            }
        }
        return composition6a;
    }

   /**
    * @see AssociationEndFacade#isOrdered()
    * @return boolean
    */
    protected abstract boolean handleIsOrdered();

    private boolean __ordered7a;
    private boolean __ordered7aSet = false;

    /**
     * Indicates whether or not the association ends are ordered (if multiplicity is greater than
     * 1).
     * @return (boolean)handleIsOrdered()
     */
    public final boolean isOrdered()
    {
        boolean ordered7a = this.__ordered7a;
        if (!this.__ordered7aSet)
        {
            // ordered has no pre constraints
            ordered7a = handleIsOrdered();
            // ordered has no post constraints
            this.__ordered7a = ordered7a;
            if (isMetafacadePropertyCachingEnabled())
            {
                this.__ordered7aSet = true;
            }
        }
        return ordered7a;
    }

   /**
    * @see AssociationEndFacade#isReadOnly()
    * @return boolean
    */
    protected abstract boolean handleIsReadOnly();

    private boolean __readOnly8a;
    private boolean __readOnly8aSet = false;

    /**
     * True if the association end cannot be changed.
     * @return (boolean)handleIsReadOnly()
     */
    public final boolean isReadOnly()
    {
        boolean readOnly8a = this.__readOnly8a;
        if (!this.__readOnly8aSet)
        {
            // readOnly has no pre constraints
            readOnly8a = handleIsReadOnly();
            // readOnly has no post constraints
            this.__readOnly8a = readOnly8a;
            if (isMetafacadePropertyCachingEnabled())
            {
                this.__readOnly8aSet = true;
            }
        }
        return readOnly8a;
    }

   /**
    * @see AssociationEndFacade#isNavigable()
    * @return boolean
    */
    protected abstract boolean handleIsNavigable();

    private boolean __navigable9a;
    private boolean __navigable9aSet = false;

    /**
     * True if it is possible to navigate from the other end to this association end .
     * @return (boolean)handleIsNavigable()
     */
    public final boolean isNavigable()
    {
        boolean navigable9a = this.__navigable9a;
        if (!this.__navigable9aSet)
        {
            // navigable has no pre constraints
            navigable9a = handleIsNavigable();
            // navigable has no post constraints
            this.__navigable9a = navigable9a;
            if (isMetafacadePropertyCachingEnabled())
            {
                this.__navigable9aSet = true;
            }
        }
        return navigable9a;
    }

   /**
    * @see AssociationEndFacade#getGetterName()
    * @return String
    */
    protected abstract String handleGetGetterName();

    private String __getterName10a;
    private boolean __getterName10aSet = false;

    /**
     * A name suitable for use when accessing this association end in programming code.
     * @return (String)handleGetGetterName()
     */
    public final String getGetterName()
    {
        String getterName10a = this.__getterName10a;
        if (!this.__getterName10aSet)
        {
            // getterName has no pre constraints
            getterName10a = handleGetGetterName();
            // getterName has no post constraints
            this.__getterName10a = getterName10a;
            if (isMetafacadePropertyCachingEnabled())
            {
                this.__getterName10aSet = true;
            }
        }
        return getterName10a;
    }

   /**
    * @see AssociationEndFacade#getSetterName()
    * @return String
    */
    protected abstract String handleGetSetterName();

    private String __setterName11a;
    private boolean __setterName11aSet = false;

    /**
     * A name suitable for use when accessing this association end in programming code.
     * @return (String)handleGetSetterName()
     */
    public final String getSetterName()
    {
        String setterName11a = this.__setterName11a;
        if (!this.__setterName11aSet)
        {
            // setterName has no pre constraints
            setterName11a = handleGetSetterName();
            // setterName has no post constraints
            this.__setterName11a = setterName11a;
            if (isMetafacadePropertyCachingEnabled())
            {
                this.__setterName11aSet = true;
            }
        }
        return setterName11a;
    }

   /**
    * @see AssociationEndFacade#getGetterSetterTypeName()
    * @return String
    */
    protected abstract String handleGetGetterSetterTypeName();

    private String __getterSetterTypeName12a;
    private boolean __getterSetterTypeName12aSet = false;

    /**
     * The name of the type that is returned on the accessor and mutator operations,  determined in
     * part by the multiplicity.
     * @return (String)handleGetGetterSetterTypeName()
     */
    public final String getGetterSetterTypeName()
    {
        String getterSetterTypeName12a = this.__getterSetterTypeName12a;
        if (!this.__getterSetterTypeName12aSet)
        {
            // getterSetterTypeName has no pre constraints
            getterSetterTypeName12a = handleGetGetterSetterTypeName();
            // getterSetterTypeName has no post constraints
            this.__getterSetterTypeName12a = getterSetterTypeName12a;
            if (isMetafacadePropertyCachingEnabled())
            {
                this.__getterSetterTypeName12aSet = true;
            }
        }
        return getterSetterTypeName12a;
    }

   /**
    * @see AssociationEndFacade#isMany()
    * @return boolean
    */
    protected abstract boolean handleIsMany();

    private boolean __many13a;
    private boolean __many13aSet = false;

    /**
     * True if this association end's multiplicity is greater than one.
     * @return (boolean)handleIsMany()
     */
    public final boolean isMany()
    {
        boolean many13a = this.__many13a;
        if (!this.__many13aSet)
        {
            // many has no pre constraints
            many13a = handleIsMany();
            // many has no post constraints
            this.__many13a = many13a;
            if (isMetafacadePropertyCachingEnabled())
            {
                this.__many13aSet = true;
            }
        }
        return many13a;
    }

   /**
    * @see AssociationEndFacade#isRequired()
    * @return boolean
    */
    protected abstract boolean handleIsRequired();

    private boolean __required14a;
    private boolean __required14aSet = false;

    /**
     * True if this association end's multiplicity is strictly greater than zero.
     * @return (boolean)handleIsRequired()
     */
    public final boolean isRequired()
    {
        boolean required14a = this.__required14a;
        if (!this.__required14aSet)
        {
            // required has no pre constraints
            required14a = handleIsRequired();
            // required has no post constraints
            this.__required14a = required14a;
            if (isMetafacadePropertyCachingEnabled())
            {
                this.__required14aSet = true;
            }
        }
        return required14a;
    }

   /**
    * @see AssociationEndFacade#isChild()
    * @return boolean
    */
    protected abstract boolean handleIsChild();

    private boolean __child15a;
    private boolean __child15aSet = false;

    /**
     * Returns whether or not (true/false) this association end is the child end of the assocation
     * (i.e. the other end's aggregation is composition).
     * @return (boolean)handleIsChild()
     */
    public final boolean isChild()
    {
        boolean child15a = this.__child15a;
        if (!this.__child15aSet)
        {
            // child has no pre constraints
            child15a = handleIsChild();
            // child has no post constraints
            this.__child15a = child15a;
            if (isMetafacadePropertyCachingEnabled())
            {
                this.__child15aSet = true;
            }
        }
        return child15a;
    }

   /**
    * @see AssociationEndFacade#getUpper()
    * @return int
    */
    protected abstract int handleGetUpper();

    private int __upper16a;
    private boolean __upper16aSet = false;

    /**
     * the upper value for the multiplicity (will be -1 for *)
     * -only applicable for UML2
     * @return (int)handleGetUpper()
     */
    public final int getUpper()
    {
        int upper16a = this.__upper16a;
        if (!this.__upper16aSet)
        {
            // upper has no pre constraints
            upper16a = handleGetUpper();
            // upper has no post constraints
            this.__upper16a = upper16a;
            if (isMetafacadePropertyCachingEnabled())
            {
                this.__upper16aSet = true;
            }
        }
        return upper16a;
    }

   /**
    * @see AssociationEndFacade#getLower()
    * @return int
    */
    protected abstract int handleGetLower();

    private int __lower17a;
    private boolean __lower17aSet = false;

    /**
     * the lower value for the multiplicity
     * -only applicable for UML2
     * @return (int)handleGetLower()
     */
    public final int getLower()
    {
        int lower17a = this.__lower17a;
        if (!this.__lower17aSet)
        {
            // lower has no pre constraints
            lower17a = handleGetLower();
            // lower has no post constraints
            this.__lower17a = lower17a;
            if (isMetafacadePropertyCachingEnabled())
            {
                this.__lower17aSet = true;
            }
        }
        return lower17a;
    }

   /**
    * @see AssociationEndFacade#getDefault()
    * @return String
    */
    protected abstract String handleGetDefault();

    private String __default18a;
    private boolean __default18aSet = false;

    /**
     * UML2: Returns the value of the 'Default' attribute. Specifies a String that represents a
     * value to be used when no argument is supplied for the Property. A String that is evaluated to
     * give a default value for the Property when an object of the owning Classifier is
     * instantiated.  Can be something like: new ValueObject(values);
     * @return (String)handleGetDefault()
     */
    public final String getDefault()
    {
        String default18a = this.__default18a;
        if (!this.__default18aSet)
        {
            // default has no pre constraints
            default18a = handleGetDefault();
            // default has no post constraints
            this.__default18a = default18a;
            if (isMetafacadePropertyCachingEnabled())
            {
                this.__default18aSet = true;
            }
        }
        return default18a;
    }

   /**
    * @see AssociationEndFacade#getAggregationKind()
    * @return String
    */
    protected abstract String handleGetAggregationKind();

    private String __aggregationKind19a;
    private boolean __aggregationKind19aSet = false;

    /**
     * Returns the value of the 'Aggregation' attribute (none, shared, composite). The default value
     * is "none". The literals are from the enumeration org.eclipse.uml2.uml.AggregationKind.
     * Specifies the kind of aggregation that applies to the Property.
     * @return (String)handleGetAggregationKind()
     */
    public final String getAggregationKind()
    {
        String aggregationKind19a = this.__aggregationKind19a;
        if (!this.__aggregationKind19aSet)
        {
            // aggregationKind has no pre constraints
            aggregationKind19a = handleGetAggregationKind();
            // aggregationKind has no post constraints
            this.__aggregationKind19a = aggregationKind19a;
            if (isMetafacadePropertyCachingEnabled())
            {
                this.__aggregationKind19aSet = true;
            }
        }
        return aggregationKind19a;
    }

   /**
    * @see AssociationEndFacade#isLeaf()
    * @return boolean
    */
    protected abstract boolean handleIsLeaf();

    private boolean __leaf20a;
    private boolean __leaf20aSet = false;

    /**
     * IsLeaf property in the association end property. If true, attribute is final, cannot be
     * extended or implemented by a descendant. Default=false.
     * @return (boolean)handleIsLeaf()
     */
    public final boolean isLeaf()
    {
        boolean leaf20a = this.__leaf20a;
        if (!this.__leaf20aSet)
        {
            // leaf has no pre constraints
            leaf20a = handleIsLeaf();
            // leaf has no post constraints
            this.__leaf20a = leaf20a;
            if (isMetafacadePropertyCachingEnabled())
            {
                this.__leaf20aSet = true;
            }
        }
        return leaf20a;
    }

   /**
    * @see AssociationEndFacade#isUnique()
    * @return boolean
    */
    protected abstract boolean handleIsUnique();

    private boolean __unique21a;
    private boolean __unique21aSet = false;

    /**
     * UML2: If the association attribute is unique within the Collection type. UML14 always returns
     * false. Unique+Ordered determines the implementation Collection type. Default=false.
     * @return (boolean)handleIsUnique()
     */
    public final boolean isUnique()
    {
        boolean unique21a = this.__unique21a;
        if (!this.__unique21aSet)
        {
            // unique has no pre constraints
            unique21a = handleIsUnique();
            // unique has no post constraints
            this.__unique21a = unique21a;
            if (isMetafacadePropertyCachingEnabled())
            {
                this.__unique21aSet = true;
            }
        }
        return unique21a;
    }

   /**
    * @see AssociationEndFacade#getRemoverName()
    * @return String
    */
    protected abstract String handleGetRemoverName();

    private String __removerName22a;
    private boolean __removerName22aSet = false;

    /**
     * A name suitable for use when removing element from this association end in programming code.
     * @return (String)handleGetRemoverName()
     */
    public final String getRemoverName()
    {
        String removerName22a = this.__removerName22a;
        if (!this.__removerName22aSet)
        {
            // removerName has no pre constraints
            removerName22a = handleGetRemoverName();
            // removerName has no post constraints
            this.__removerName22a = removerName22a;
            if (isMetafacadePropertyCachingEnabled())
            {
                this.__removerName22aSet = true;
            }
        }
        return removerName22a;
    }

   /**
    * @see AssociationEndFacade#getAdderName()
    * @return String
    */
    protected abstract String handleGetAdderName();

    private String __adderName23a;
    private boolean __adderName23aSet = false;

    /**
     * A name suitable for use when adding new elements to this association end in programming code.
     * @return (String)handleGetAdderName()
     */
    public final String getAdderName()
    {
        String adderName23a = this.__adderName23a;
        if (!this.__adderName23aSet)
        {
            // adderName has no pre constraints
            adderName23a = handleGetAdderName();
            // adderName has no post constraints
            this.__adderName23a = adderName23a;
            if (isMetafacadePropertyCachingEnabled())
            {
                this.__adderName23aSet = true;
            }
        }
        return adderName23a;
    }

   /**
    * @see AssociationEndFacade#isBidirectional()
    * @return boolean
    */
    protected abstract boolean handleIsBidirectional();

    private boolean __bidirectional24a;
    private boolean __bidirectional24aSet = false;

    /**
     * Is true if update of one side of the association should also update the other side. false if
     * not.
     * @return (boolean)handleIsBidirectional()
     */
    public final boolean isBidirectional()
    {
        boolean bidirectional24a = this.__bidirectional24a;
        if (!this.__bidirectional24aSet)
        {
            // bidirectional has no pre constraints
            bidirectional24a = handleIsBidirectional();
            // bidirectional has no post constraints
            this.__bidirectional24a = bidirectional24a;
            if (isMetafacadePropertyCachingEnabled())
            {
                this.__bidirectional24aSet = true;
            }
        }
        return bidirectional24a;
    }

   /**
    * @see AssociationEndFacade#isDerived()
    * @return boolean
    */
    protected abstract boolean handleIsDerived();

    private boolean __derived25a;
    private boolean __derived25aSet = false;

    /**
     * If the association end is derived (its value is computed). UML2 only. UML14 always returns
     * false. Default=false.
     * @return (boolean)handleIsDerived()
     */
    public final boolean isDerived()
    {
        boolean derived25a = this.__derived25a;
        if (!this.__derived25aSet)
        {
            // derived has no pre constraints
            derived25a = handleIsDerived();
            // derived has no post constraints
            this.__derived25a = derived25a;
            if (isMetafacadePropertyCachingEnabled())
            {
                this.__derived25aSet = true;
            }
        }
        return derived25a;
    }

   /**
    * @see AssociationEndFacade#isStatic()
    * @return boolean
    */
    protected abstract boolean handleIsStatic();

    private boolean __static26a;
    private boolean __static26aSet = false;

    /**
     * Indicates if this associationEnd is 'static', meaning it has a classifier scope.
     * @return (boolean)handleIsStatic()
     */
    public final boolean isStatic()
    {
        boolean static26a = this.__static26a;
        if (!this.__static26aSet)
        {
            // static has no pre constraints
            static26a = handleIsStatic();
            // static has no post constraints
            this.__static26a = static26a;
            if (isMetafacadePropertyCachingEnabled())
            {
                this.__static26aSet = true;
            }
        }
        return static26a;
    }

    // ------------- associations ------------------

    /**
     * Gets the association ends belonging to this association.
     * @return (AssociationFacade)handleGetAssociation()
     */
    public final AssociationFacade getAssociation()
    {
        AssociationFacade getAssociation1r = null;
        // associationEnds has no pre constraints
        Object result = handleGetAssociation();
        MetafacadeBase shieldedResult = this.shieldedElement(result);
        try
        {
            getAssociation1r = (AssociationFacade)shieldedResult;
        }
        catch (ClassCastException ex)
        {
            // Bad things happen if the metafacade type mapping in metafacades.xml is wrong - Warn
            AssociationEndFacadeLogic.logger.warn("incorrect metafacade cast for AssociationEndFacadeLogic.getAssociation AssociationFacade " + result + ": " + shieldedResult);
        }
        // associationEnds has no post constraints
        return getAssociation1r;
    }

    /**
     * UML Specific type is transformed by shieldedElements to AndroMDA Metafacade type
     * @return Object
     */
    protected abstract Object handleGetAssociation();

    /**
     * A property related by memberEnd or its specializations to an association represents an end of
     * the
     * association. The type of the property is the type of the end of the association .Property
     * represents
     * a declared state of one or more instances in terms of a named relationship to a value or
     * values.
     * When a property is an association end, the value or values are related to the instance or
     * instances
     * at the other end(s) of the association.
     * @return (ClassifierFacade)handleGetType()
     */
    public final ClassifierFacade getType()
    {
        ClassifierFacade getType2r = null;
        // associationEndFacade has no pre constraints
        Object result = handleGetType();
        MetafacadeBase shieldedResult = this.shieldedElement(result);
        try
        {
            getType2r = (ClassifierFacade)shieldedResult;
        }
        catch (ClassCastException ex)
        {
            // Bad things happen if the metafacade type mapping in metafacades.xml is wrong - Warn
            AssociationEndFacadeLogic.logger.warn("incorrect metafacade cast for AssociationEndFacadeLogic.getType ClassifierFacade " + result + ": " + shieldedResult);
        }
        // associationEndFacade has no post constraints
        return getType2r;
    }

    /**
     * UML Specific type is transformed by shieldedElements to AndroMDA Metafacade type
     * @return Object
     */
    protected abstract Object handleGetType();

    /**
     * A property related by memberEnd or its specializations to an association represents an end of
     * the
     * association. The type of the property is the type of the end of the association .Property
     * represents
     * a declared state of one or more instances in terms of a named relationship to a value or
     * values.
     * When a property is an association end, the value or values are related to the instance or
     * instances
     * at the other end(s) of the association.
     * @return (AssociationEndFacade)handleGetOtherEnd()
     */
    public final AssociationEndFacade getOtherEnd()
    {
        AssociationEndFacade getOtherEnd3r = null;
        // associationEndFacade has no pre constraints
        Object result = handleGetOtherEnd();
        MetafacadeBase shieldedResult = this.shieldedElement(result);
        try
        {
            getOtherEnd3r = (AssociationEndFacade)shieldedResult;
        }
        catch (ClassCastException ex)
        {
            // Bad things happen if the metafacade type mapping in metafacades.xml is wrong - Warn
            AssociationEndFacadeLogic.logger.warn("incorrect metafacade cast for AssociationEndFacadeLogic.getOtherEnd AssociationEndFacade " + result + ": " + shieldedResult);
        }
        // associationEndFacade has no post constraints
        return getOtherEnd3r;
    }

    /**
     * UML Specific type is transformed by shieldedElements to AndroMDA Metafacade type
     * @return Object
     */
    protected abstract Object handleGetOtherEnd();

    /**
     * <p><b>Constraint:</b> org::andromda::metafacades::uml::AssociationEndFacade::association end needs a type</p>
     * <p><b>Error:</b> Each association end needs a type, you cannot leave the type unspecified.</p>
     * <p><b>OCL:</b> context AssociationEndFacade
inv: type.name->notEmpty()</p>
     * @param validationMessages Collection<ModelValidationMessage>
     * @see ModelElementFacadeLogicImpl#validateInvariants(Collection validationMessages)
     */
    @Override
    public void validateInvariants(Collection<ModelValidationMessage> validationMessages)
    {
        super.validateInvariants(validationMessages);
        try
        {
            final Object contextElement = this.THIS();
            boolean constraintValid = OCLResultEnsurer.ensure(OCLCollections.notEmpty(OCLIntrospector.invoke(contextElement,"type.name")));
            if (!constraintValid)
            {
                validationMessages.add(
                    new ModelValidationMessage(
                        (MetafacadeBase)contextElement ,
                        "org::andromda::metafacades::uml::AssociationEndFacade::association end needs a type",
                        "Each association end needs a type, you cannot leave the type unspecified."));
            }
        }
        catch (Throwable th)
        {
            Throwable cause = th.getCause();
            int depth = 0; // Some throwables have infinite recursion
            while (cause != null && depth < 7)
            {
                th = cause;
                depth++;
            }
            logger.error("Error validating constraint 'org::andromda::metafacades::uml::AssociationEndFacade::association end needs a type' ON "
                + this.THIS().toString() + ": " + th.getMessage(), th);
        }
    }
}