/**
* <copyright>
* </copyright>
*
* $Id$
*/
package com.openMap1.mapper.impl;
import org.eclipse.emf.ecore.EObject;
import com.openMap1.mapper.util.MapperValidator;
import java.util.Iterator;
import java.util.Map;
import com.openMap1.mapper.core.Xpth;
import com.openMap1.mapper.core.MapperException;
import com.openMap1.mapper.util.ModelUtil;
import com.openMap1.mapper.util.GenUtil;
import com.openMap1.mapper.AssocEndMapping;
import com.openMap1.mapper.AssocMapping;
import com.openMap1.mapper.MapperPackage;
import com.openMap1.mapper.Mapping;
import com.openMap1.mapper.NodeDef;
import com.openMap1.mapper.ObjMapping;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.util.BasicDiagnostic;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.DiagnosticChain;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
/**
* <!-- begin-user-doc -->
* An implementation of the model object '<em><b>Assoc End Mapping</b></em>'.
* <!-- end-user-doc -->
* <p>
* The following features are implemented:
* <ul>
* <li>{@link com.openMap1.mapper.impl.AssocEndMappingImpl#getMappedRole <em>Mapped Role</em>}</li>
* <li>{@link com.openMap1.mapper.impl.AssocEndMappingImpl#getObjectToAssociationPath <em>Object To Association Path</em>}</li>
* <li>{@link com.openMap1.mapper.impl.AssocEndMappingImpl#getAssociationToObjectPath <em>Association To Object Path</em>}</li>
* <li>{@link com.openMap1.mapper.impl.AssocEndMappingImpl#isRequiredForObject <em>Required For Object</em>}</li>
* </ul>
* </p>
*
* @generated
*/
public class AssocEndMappingImpl extends MappingImpl implements AssocEndMapping {
/**
* The default value of the '{@link #getMappedRole() <em>Mapped Role</em>}' attribute.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @see #getMappedRole()
* @generated
* @ordered
*/
protected static final String MAPPED_ROLE_EDEFAULT = null;
/**
* The cached value of the '{@link #getMappedRole() <em>Mapped Role</em>}' attribute.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @see #getMappedRole()
* @generated
* @ordered
*/
protected String mappedRole = MAPPED_ROLE_EDEFAULT;
/**
* The default value of the '{@link #getObjectToAssociationPath() <em>Object To Association Path</em>}' attribute.
* <!-- begin-user-doc -->
* The default has been altered to "" to avoid confusion, as I think it can
* easily be accidentally edited to ""
* <!-- end-user-doc -->
* @see #getObjectToAssociationPath()
* @ordered
*/
protected static final String OBJECT_TO_ASSOCIATION_PATH_EDEFAULT = "";
/**
* The cached value of the '{@link #getObjectToAssociationPath() <em>Object To Association Path</em>}' attribute.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @see #getObjectToAssociationPath()
* @generated
* @ordered
*/
protected String objectToAssociationPath = OBJECT_TO_ASSOCIATION_PATH_EDEFAULT;
/**
* The default value of the '{@link #getAssociationToObjectPath() <em>Association To Object Path</em>}' attribute.
* <!-- begin-user-doc -->
* The default has been altered to "" to avoid confusion, as I think it can
* easily be accidentally edited to ""
* <!-- end-user-doc -->
* @see #getAssociationToObjectPath()
* @ordered
*/
protected static final String ASSOCIATION_TO_OBJECT_PATH_EDEFAULT = "";
/**
* The cached value of the '{@link #getAssociationToObjectPath() <em>Association To Object Path</em>}' attribute.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @see #getAssociationToObjectPath()
* @generated
* @ordered
*/
protected String associationToObjectPath = ASSOCIATION_TO_OBJECT_PATH_EDEFAULT;
/**
* The default value of the '{@link #isRequiredForObject() <em>Required For Object</em>}' attribute.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @see #isRequiredForObject()
* @generated
* @ordered
*/
protected static final boolean REQUIRED_FOR_OBJECT_EDEFAULT = false;
/**
* The cached value of the '{@link #isRequiredForObject() <em>Required For Object</em>}' attribute.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @see #isRequiredForObject()
* @generated
* @ordered
*/
protected boolean requiredForObject = REQUIRED_FOR_OBJECT_EDEFAULT;
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
protected AssocEndMappingImpl() {
super();
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
protected EClass eStaticClass() {
return MapperPackage.Literals.ASSOC_END_MAPPING;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public String getMappedRole() {
return mappedRole;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public void setMappedRole(String newMappedRole) {
String oldMappedRole = mappedRole;
mappedRole = newMappedRole;
if (eNotificationRequired())
eNotify(new ENotificationImpl(this, Notification.SET, MapperPackage.ASSOC_END_MAPPING__MAPPED_ROLE, oldMappedRole, mappedRole));
}
/**
* <!-- begin-user-doc -->
* If the subset is unset, this method must return ""
* <!-- end-user-doc -->
*/
public String getSubset() {
if (subset == null) subset = "";
return subset;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public String getObjectToAssociationPath() {
return objectToAssociationPath;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public void setObjectToAssociationPath(String newObjectToAssociationPath) {
String oldObjectToAssociationPath = objectToAssociationPath;
objectToAssociationPath = newObjectToAssociationPath;
if (eNotificationRequired())
eNotify(new ENotificationImpl(this, Notification.SET, MapperPackage.ASSOC_END_MAPPING__OBJECT_TO_ASSOCIATION_PATH, oldObjectToAssociationPath, objectToAssociationPath));
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public String getAssociationToObjectPath() {
return associationToObjectPath;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public void setAssociationToObjectPath(String newAssociationToObjectPath) {
String oldAssociationToObjectPath = associationToObjectPath;
associationToObjectPath = newAssociationToObjectPath;
if (eNotificationRequired())
eNotify(new ENotificationImpl(this, Notification.SET, MapperPackage.ASSOC_END_MAPPING__ASSOCIATION_TO_OBJECT_PATH, oldAssociationToObjectPath, associationToObjectPath));
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public boolean isRequiredForObject() {
return requiredForObject;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public void setRequiredForObject(boolean newRequiredForObject) {
boolean oldRequiredForObject = requiredForObject;
requiredForObject = newRequiredForObject;
if (eNotificationRequired())
eNotify(new ENotificationImpl(this, Notification.SET, MapperPackage.ASSOC_END_MAPPING__REQUIRED_FOR_OBJECT, oldRequiredForObject, requiredForObject));
}
/**
* <!-- begin-user-doc -->
* This was a check that the class at the other end of the association has
* an eReference, with the correct role name, leading to the
* class at this end of the association.
* <!-- end-user-doc -->
*/
public boolean classHasRoleToClass(DiagnosticChain diagnostics, Map<?,?> context) {
boolean roleOK = (referenceToThisEndClass() != null);
// if there is no association to this end, so the role name is "", the mapping may be OK
if (getMappedRole().equals("")) roleOK = true;
String className = "<cannot find class>";
try {className = getOtherEndClass().getName();}
catch (Exception ex) {roleOK = false;} // if you can't find the class, it is a fault
if (!roleOK) {
if (diagnostics != null) {
diagnostics.add
(new BasicDiagnostic
(Diagnostic.ERROR,
MapperValidator.DIAGNOSTIC_SOURCE,
MapperValidator.ASSOC_END_MAPPING__CLASS_HAS_ROLE_TO_CLASS,
("Class '" + className + "' at the other end of the association mapping "
+ " has no association with role '" + getMappedRole()
+ "' to this end class '" + getMappedClass() + "'"),
new Object [] { this }));
}
return false;
}
return true;
}
/**
* check that the role name is some role of the other end
* class, pointing to the class at this end;
* if it is so, return the EReference
* @return
*/
private EReference referenceToThisEndClass()
{
EReference ref = null;
try{
EClass thisClass = ModelUtil.getEClass(getMappedClass(),getMappedPackage(),this);
// check all the associations of the other end class for this role and (inherited) class
if ((thisClass != null) && (getOtherEndClass() != null))
for (Iterator<EReference> it = getOtherEndClass().getEAllReferences().iterator();it.hasNext();)
{
EReference next = it.next();
if ((next.getName() != null) && (next.getName().equals(getMappedRole())))
{
EClassifier end = next.getEType();
if ((end instanceof EClass) &&
(((EClass)end).isSuperTypeOf(thisClass))) ref = next;
}
}
}
catch (Exception ex) {ref = null;}
return ref;
}
/**
*
* @return the EClass at the other end of this association
* @throws MapperException
*/
public EClass getOtherEndClass()
{
return ModelUtil.getEClass(getOtherEndMapping().getMappedClass(),getOtherEndMapping().getMappedPackage(),this);
}
/**
*
* @return the mapping for the other end of this association
* @throws MapperException
*/
public AssocEndMapping getOtherEndMapping()
{
AssocEndMapping aem = null;
try{
// get the other end of the association mapping
AssocMapping am = (AssocMapping)eContainer();
// getEnd() gives 1 or 2, so eOther is 1 or 0
int eOther = 2 - getEnd();
aem = am.getMappedEnd(eOther);
}
catch (MapperException ex)
{GenUtil.surprise(ex,"AssocEndMappingImpl.getOtherEndMapping");}
return aem;
}
/**
* <!-- begin-user-doc -->
* check that there is an object mapping
* of the same class and subset as the association end mapping;
* <!-- end-user-doc -->
*/
public boolean objectMappingExists(DiagnosticChain diagnostics, Map<?,?> context) {
boolean objectMappingExists = false;
try {
ObjMapping om = ModelUtil.getObjectMapping(ModelUtil.getModelRoot(this), getClassSet());
if (om != null) objectMappingExists = true;
}
catch (MapperException ex) {objectMappingExists = false;}
if (!objectMappingExists) {
if (diagnostics != null) {
diagnostics.add
(new BasicDiagnostic
(Diagnostic.ERROR,
MapperValidator.DIAGNOSTIC_SOURCE,
MapperValidator.ASSOC_END_MAPPING__OBJECT_MAPPING_EXISTS,
("Link mapping requires a single object mapping for class "
+ getClassSet().stringForm()
+ "; there is none."),
new Object [] { this }));
}
return false;
}
return true;
}
/**
* <!-- begin-user-doc -->
* check the path from the object mapping node to the association
* mapping node is valid
* <!-- end-user-doc -->
*/
public boolean objectToAssociationPathIsValid(DiagnosticChain diagnostics, Map<?,?> context) {
// 'false' means do not check uniqueness
boolean isValidPath = validObjectToAssociationPath(false);
if (!isValidPath) {
if (diagnostics != null) {
diagnostics.add
(new BasicDiagnostic
(Diagnostic.ERROR,
MapperValidator.DIAGNOSTIC_SOURCE,
MapperValidator.ASSOC_END_MAPPING__OBJECT_TO_ASSOCIATION_PATH_IS_VALID,
"path from object mapping node to association mapping node is not valid",
new Object [] { this }));
}
return false;
}
return true;
}
/**
* check if a path is valid; possibly also check if it is unique
* @param mustBeUnique
* @return
*/
public boolean validObjectToAssociationPath(boolean mustBeUnique)
{
boolean isValidPath = true;
try{
Xpth path = getObjectToAssociationXPath();
NodeDef mappedNode = ModelUtil.mappingNode(ModelUtil.getObjectMapping(this));
// only definite paths can be unique
if (mustBeUnique)
isValidPath = ModelUtil.isRelativeDefinitePath(mappedNode, path, mustBeUnique,false);
else isValidPath = ModelUtil.isRelativePath(mappedNode, path);
}
catch (MapperException ex) {isValidPath = false;}
return isValidPath;
}
/**
* <!-- begin-user-doc -->
* write warnings if the paths from the other end object to the association node and then
* on to this end object give a multiplicity which does not match that in the class model.
* Two possible warnings: for min and max cardinalities.
* Only do the checks if the paths are valid.
* <!-- end-user-doc -->
*/
public boolean PathMatchesCardinality(DiagnosticChain diagnostics, Map<?,?> context) {
boolean matchesMinCardinality = true;
boolean matchesMaxCardinality = true;
String minWarning = "";
String maxWarning = "";
String assocName = "";
// only do the checks if the paths are valid and the association exists in the class model
boolean isUnique = false;
if ( (getOtherEndClass() != null) //fails if there is no class model
&& (getOtherEndMapping().validObjectToAssociationPath(isUnique))
&& (validAssocToObjectPath(isUnique)) && (referenceToThisEndClass() != null)) try
{
assocName = getOtherEndClass().getName() + "." + getMappedRole() + "(" + getMappedClass() + ")";
// find start nodes and XPaths for the two successive traverses needed to navigate the association
NodeDef startNode = ModelUtil.mappingNode(ModelUtil.getObjectMapping(getOtherEndMapping()));
Xpth path1 = getOtherEndMapping().getObjectToAssociationXPath();
NodeDef assocNode = ModelUtil.mappingNode(this);
Xpth path2 = getAssociationToObjectXPath();
// find cardinalities implied by the paths
int min = 0;
if ((ModelUtil.getMinCardinality(startNode,path1) == 1) &&
(ModelUtil.getMinCardinality(assocNode,path2) == 1)) min = 1;
int max = -1;
if ((ModelUtil.getMaxCardinality(startNode,path1) == 1) &&
(ModelUtil.getMaxCardinality(assocNode,path2) == 1)) max = 1;
// find cardinalities in the class model
int minFromModel = referenceToThisEndClass().getLowerBound(); // can be 1, or 0
int maxFromModel = referenceToThisEndClass().getUpperBound(); // can be 1, -1(unbounded) or -2 (undefined)
if (maxFromModel == -2 ) maxFromModel = -1; // treat undefined as unbounded
// warnings for min cardinality
minWarning = "Min multiplicity of " + assocName + " is "
+ minFromModel + " in the class model, " + min + " from the mappings";
// if the mappings give lower multiplicity than the class model, there is always a problem
if (minFromModel > min) {matchesMinCardinality = false;}
// if the mappings give higher multiplicity than the model, cross-conditions might correct it
if ((minFromModel < min) && (getCrossConditions().size() == 0)
&& (getOtherEndMapping().getCrossConditions().size() == 0))
{
matchesMinCardinality = false;
minWarning = minWarning + ", and there are no cross-conditions.";
}
// warnings for max cardinality
maxWarning = "Max multiplicity of " + assocName + " is "
+ multString(maxFromModel) + " in the class model, " + multString(max) + " from the mappings";
// if the mapping paths give lower multiplicity than the class model, there is always a problem
if ((max == 1) && (maxFromModel == -1)) {matchesMaxCardinality = false;}
// if the mapping paths give higher multiplicity than the model, cross-conditions might correct it
if ((max == -1) && (maxFromModel == 1) && (getCrossConditions().size() == 0)
&& (getOtherEndMapping().getCrossConditions().size() == 0))
{
matchesMaxCardinality = false;
maxWarning = maxWarning + ", and there are no cross-conditions.";
}
}
catch (MapperException ex) {GenUtil.surprise(ex, "AssocEndMappingImpl.PathMatchesCardinality");}
if (!matchesMinCardinality) {
if (diagnostics != null) {
diagnostics.add
(new BasicDiagnostic
(Diagnostic.WARNING,
MapperValidator.DIAGNOSTIC_SOURCE,
MapperValidator.ASSOC_END_MAPPING__PATH_MATCHES_CARDINALITY,
minWarning,
new Object [] { this }));
}
return false;
}
if (!matchesMaxCardinality) {
if (diagnostics != null) {
diagnostics.add
(new BasicDiagnostic
(Diagnostic.WARNING,
MapperValidator.DIAGNOSTIC_SOURCE,
MapperValidator.ASSOC_END_MAPPING__PATH_MATCHES_CARDINALITY,
maxWarning,
new Object [] { this }));
}
return false;
}
return true;
}
private String multString(int max)
{
if (max == 1) return "1";
if (max == -1) return "unbounded";
return "unknown";
}
/**
* <!-- begin-user-doc -->
* check that the path from the association node to the object node
* (which may have been supplied by the user, or may be the default shortest path)
* is a valid path in the structure
* <!-- end-user-doc -->
*/
public boolean AssociationToObjectPathIsValid(DiagnosticChain diagnostics, Map<?,?> context) {
// do not demand a unique path; there may be cross-conditions
boolean isValidPath = validAssocToObjectPath(false);
if (!isValidPath) {
if (diagnostics != null) {
diagnostics.add
(new BasicDiagnostic
(Diagnostic.ERROR,
MapperValidator.DIAGNOSTIC_SOURCE,
MapperValidator.ASSOC_END_MAPPING__ASSOCIATION_TO_OBJECT_PATH_IS_VALID,
"Path from association node to object node is not a valid path",
new Object [] { this }));
}
return false;
}
return true;
}
/**
* check if a path is valid; possibly also check if it is unique
* @param mustBeUnique
* @return
*/
public boolean validAssocToObjectPath(boolean mustBeUnique)
{
boolean isValidPath = true;
try{
Xpth path = getAssociationToObjectXPath();
// System.out.println(path.stringForm());
NodeDef mappedNode = ModelUtil.mappingNode(this);
if (mustBeUnique)
// only definite paths can be unique
isValidPath = ModelUtil.isRelativeDefinitePath(mappedNode, path, mustBeUnique,false);
else isValidPath = ModelUtil.isRelativePath(mappedNode, path);
}
catch (MapperException ex) {isValidPath = false;}
return isValidPath;
}
/**
* <!-- begin-user-doc -->
* check (if there are no cross conditions)
* that the path from the association end node to the object node
* leads to a unique node
* <!-- end-user-doc -->
*/
public boolean objectIsUniqueFromAssociation(DiagnosticChain diagnostics, Map<?,?> context) {
boolean uniqueToObject = true;
if (getCrossConditions().size() == 0) try // need only test when there are no cross-conditions
{
// if the default shortest path has not been overridden
if (getAssociationToObjectPath().equals(""))
{uniqueToObject = ModelUtil.hasUniqueShortestPathToObjectMapping(this);}
// shortest path has been overridden; but if the supplied shortest path is invalid, that has been noted already
else if (validAssocToObjectPath(false))
{uniqueToObject = validAssocToObjectPath(true);} // if it is valid, check it for uniqueness
}
catch (MapperException ex) {} // missing object mapping; already detected, do not add misleading messages
if (!uniqueToObject) {
if (diagnostics != null) {
diagnostics.add
(new BasicDiagnostic
(Diagnostic.ERROR,
MapperValidator.DIAGNOSTIC_SOURCE,
MapperValidator.ASSOC_END_MAPPING__OBJECT_IS_UNIQUE_FROM_ASSOCIATION,
"The association mapping for association '" + this.getMappedRole()
+ "' of class " + getClassSet().stringForm()
+ " cannot be linked to a single instance of the object mapping, " +
"and there are no cross-conditions to make it unique.",
new Object [] { this }));
}
return false;
}
return true;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
public Object eGet(int featureID, boolean resolve, boolean coreType) {
switch (featureID) {
case MapperPackage.ASSOC_END_MAPPING__MAPPED_ROLE:
return getMappedRole();
case MapperPackage.ASSOC_END_MAPPING__OBJECT_TO_ASSOCIATION_PATH:
return getObjectToAssociationPath();
case MapperPackage.ASSOC_END_MAPPING__ASSOCIATION_TO_OBJECT_PATH:
return getAssociationToObjectPath();
case MapperPackage.ASSOC_END_MAPPING__REQUIRED_FOR_OBJECT:
return isRequiredForObject() ? Boolean.TRUE : Boolean.FALSE;
}
return super.eGet(featureID, resolve, coreType);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
public void eSet(int featureID, Object newValue) {
switch (featureID) {
case MapperPackage.ASSOC_END_MAPPING__MAPPED_ROLE:
setMappedRole((String)newValue);
return;
case MapperPackage.ASSOC_END_MAPPING__OBJECT_TO_ASSOCIATION_PATH:
setObjectToAssociationPath((String)newValue);
return;
case MapperPackage.ASSOC_END_MAPPING__ASSOCIATION_TO_OBJECT_PATH:
setAssociationToObjectPath((String)newValue);
return;
case MapperPackage.ASSOC_END_MAPPING__REQUIRED_FOR_OBJECT:
setRequiredForObject(((Boolean)newValue).booleanValue());
return;
}
super.eSet(featureID, newValue);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
public void eUnset(int featureID) {
switch (featureID) {
case MapperPackage.ASSOC_END_MAPPING__MAPPED_ROLE:
setMappedRole(MAPPED_ROLE_EDEFAULT);
return;
case MapperPackage.ASSOC_END_MAPPING__OBJECT_TO_ASSOCIATION_PATH:
setObjectToAssociationPath(OBJECT_TO_ASSOCIATION_PATH_EDEFAULT);
return;
case MapperPackage.ASSOC_END_MAPPING__ASSOCIATION_TO_OBJECT_PATH:
setAssociationToObjectPath(ASSOCIATION_TO_OBJECT_PATH_EDEFAULT);
return;
case MapperPackage.ASSOC_END_MAPPING__REQUIRED_FOR_OBJECT:
setRequiredForObject(REQUIRED_FOR_OBJECT_EDEFAULT);
return;
}
super.eUnset(featureID);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
public boolean eIsSet(int featureID) {
switch (featureID) {
case MapperPackage.ASSOC_END_MAPPING__MAPPED_ROLE:
return MAPPED_ROLE_EDEFAULT == null ? mappedRole != null : !MAPPED_ROLE_EDEFAULT.equals(mappedRole);
case MapperPackage.ASSOC_END_MAPPING__OBJECT_TO_ASSOCIATION_PATH:
return OBJECT_TO_ASSOCIATION_PATH_EDEFAULT == null ? objectToAssociationPath != null : !OBJECT_TO_ASSOCIATION_PATH_EDEFAULT.equals(objectToAssociationPath);
case MapperPackage.ASSOC_END_MAPPING__ASSOCIATION_TO_OBJECT_PATH:
return ASSOCIATION_TO_OBJECT_PATH_EDEFAULT == null ? associationToObjectPath != null : !ASSOCIATION_TO_OBJECT_PATH_EDEFAULT.equals(associationToObjectPath);
case MapperPackage.ASSOC_END_MAPPING__REQUIRED_FOR_OBJECT:
return requiredForObject != REQUIRED_FOR_OBJECT_EDEFAULT;
}
return super.eIsSet(featureID);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
public String toString() {
if (eIsProxy()) return super.toString();
StringBuffer result = new StringBuffer(super.toString());
result.append(" (mappedRole: ");
result.append(mappedRole);
result.append(", objectToAssociationPath: ");
result.append(objectToAssociationPath);
result.append(", associationToObjectPath: ");
result.append(associationToObjectPath);
result.append(", requiredForObject: ");
result.append(requiredForObject);
result.append(')');
return result.toString();
}
/**
* Two mappings (usually in different mapping sets) are equivalent if they
* refer to the same thing in the Class model (eg the same class, the same property)
* and with the same subset.
* Two mappings in the same mapping set should never be equivalent.
* @param m
* @return
*/
public boolean equivalentTo(Mapping m)
{
boolean eq = false;
if (m instanceof AssocEndMapping)
{
AssocEndMapping am = (AssocEndMapping)m;
eq = ((am.getClassSet().equals(getClassSet()))
&& (am.getMappedRole().equals(getMappedRole())));
}
return eq;
}
/**
* The node which this mapping is attached to.
* Container is AssocMapping; its container is NodeMappingSet; its container is Node
* @return
*/
public NodeDef mappedNode()
{
NodeDef mn = (NodeDef)(this.eContainer().eContainer().eContainer());
return mn;
}
// cached instance variable
private Xpth objectToAssociationXPath = null;
/**
* Xpth from the object mapping of the end class to this node.
* If a path has not been provided, so it is still the default "",
* calculate the default shortest path.
* @return
*/
public Xpth getObjectToAssociationXPath() throws MapperException
{
if (objectToAssociationXPath == null)
{
if ((getObjectToAssociationPath() != null) && (!getObjectToAssociationPath().equals("")))
{objectToAssociationXPath = new Xpth(ModelUtil.getGlobalNamespaceSet(this),getObjectToAssociationPath());}
else
{
ObjMapping om = ModelUtil.getObjectMapping(this);
objectToAssociationXPath = om.getRootXPath().defaultCrossPath(this.getRootXPath());
}
}
return objectToAssociationXPath;
}
// cached instance variable
private Xpth associationToObjectXPath = null;
/**
* Xpth from this node to the object mapping of the end class.
* If a path has not been provided and it is still the default "",
* calculate the default shortest path.
* @return
*/
public Xpth getAssociationToObjectXPath() throws MapperException
{
if (associationToObjectXPath == null)
{
if ((getAssociationToObjectPath() != null) && (!getAssociationToObjectPath().equals("")))
{associationToObjectXPath = new Xpth(ModelUtil.getGlobalNamespaceSet(this),getAssociationToObjectPath());}
else
{
ObjMapping om = ModelUtil.getObjectMapping(this);
associationToObjectXPath = this.getRootXPath().defaultCrossPath(om.getRootXPath());
}
}
return associationToObjectXPath;
}
/**
* end = 1 or 2 is now calculated automatically using the association
* from the owning AssocMapping
* @return
*/
public int getEnd()
{
int end = 0; // returned if there is any error
EObject container = eContainer();
if (container instanceof AssocMapping)
{
AssocMapping am = (AssocMapping)container;
if (am.getMappedEnd1().equals(this)) end = 1;
if (am.getMappedEnd2().equals(this)) end = 2;
}
return end;
}
/**
* details of this mapping, to be written out in the details column of the Mappings view
*/
public String getOwnDetails()
{
String details = super.getOwnDetails();
if (this.isRequiredForObject()) details = details + "required;";
if (!(getObjectToAssociationPath().equals("")))
details = details + "cross path from object = '" + getObjectToAssociationPath() + "';";
if (!(getAssociationToObjectPath().equals("")))
details = details + "cross path to object = '" + getAssociationToObjectPath() + "';";
return details;
}
/**
* @return the association end mapping for the other end of this association
*/
public AssocEndMapping otherEndMapping()
{
AssocEndMapping aem = null;
try{
AssocMapping am = (AssocMapping)eContainer();
aem = am.getMappedEnd(2-getEnd()); // convert [1,2] to [2,1]
}
catch(Exception ex) {}
return aem;
}
} //AssocEndMappingImpl