/** * <copyright> * </copyright> * * $Id$ */ package com.openMap1.mapper.impl; import java.util.Map; import com.openMap1.mapper.core.MapperException; import com.openMap1.mapper.core.Xpth; import com.openMap1.mapper.util.ModelUtil; import com.openMap1.mapper.util.MapperValidator; import com.openMap1.mapper.LocalPropertyConversion; import com.openMap1.mapper.MapperPackage; import com.openMap1.mapper.Mapping; import com.openMap1.mapper.NodeDef; import com.openMap1.mapper.ObjMapping; import com.openMap1.mapper.PropMapping; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.common.notify.NotificationChain; 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.InternalEObject; import org.eclipse.emf.ecore.impl.ENotificationImpl; /** * <!-- begin-user-doc --> * An implementation of the model object '<em><b>Prop Mapping</b></em>'. * <!-- end-user-doc --> * <p> * The following features are implemented: * <ul> * <li>{@link com.openMap1.mapper.impl.PropMappingImpl#getMappedProperty <em>Mapped Property</em>}</li> * <li>{@link com.openMap1.mapper.impl.PropMappingImpl#getPropertyType <em>Property Type</em>}</li> * <li>{@link com.openMap1.mapper.impl.PropMappingImpl#getDefaultValue <em>Default Value</em>}</li> * <li>{@link com.openMap1.mapper.impl.PropMappingImpl#getObjectToPropertyPath <em>Object To Property Path</em>}</li> * <li>{@link com.openMap1.mapper.impl.PropMappingImpl#getLocalPropertyConversion <em>Local Property Conversion</em>}</li> * </ul> * </p> * * @generated */ public class PropMappingImpl extends MappingImpl implements PropMapping { /** * The default value of the '{@link #getMappedProperty() <em>Mapped Property</em>}' attribute. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @see #getMappedProperty() * @ordered */ protected static final String MAPPED_PROPERTY_EDEFAULT = ""; /** * The cached value of the '{@link #getMappedProperty() <em>Mapped Property</em>}' attribute. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @see #getMappedProperty() * @generated * @ordered */ protected String mappedProperty = MAPPED_PROPERTY_EDEFAULT; /** * The default value of the '{@link #getPropertyType() <em>Property Type</em>}' attribute. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @see #getPropertyType() * @ordered */ protected static final String PROPERTY_TYPE_EDEFAULT = ""; /** * The cached value of the '{@link #getPropertyType() <em>Property Type</em>}' attribute. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @see #getPropertyType() * @generated * @ordered */ protected String propertyType = PROPERTY_TYPE_EDEFAULT; /** * The default value of the '{@link #getDefaultValue() <em>Default Value</em>}' attribute. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @see #getDefaultValue() * @ordered */ protected static final String DEFAULT_VALUE_EDEFAULT = ""; /** * The cached value of the '{@link #getDefaultValue() <em>Default Value</em>}' attribute. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @see #getDefaultValue() * @generated * @ordered */ protected String defaultValue = DEFAULT_VALUE_EDEFAULT; /** * The default value of the '{@link #getObjectToPropertyPath() <em>Object To Property Path</em>}' attribute. * <!-- begin-user-doc --> * default path set to "", not null; because it can easily be edited to "" * <!-- end-user-doc --> * @see #getObjectToPropertyPath() * @ordered */ protected static final String OBJECT_TO_PROPERTY_PATH_EDEFAULT = ""; /** * The cached value of the '{@link #getObjectToPropertyPath() <em>Object To Property Path</em>}' attribute. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @see #getObjectToPropertyPath() * @generated * @ordered */ protected String objectToPropertyPath = OBJECT_TO_PROPERTY_PATH_EDEFAULT; /** * The cached value of the '{@link #getLocalPropertyConversion() <em>Local Property Conversion</em>}' containment reference. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @see #getLocalPropertyConversion() * @generated * @ordered */ protected LocalPropertyConversion localPropertyConversion; /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ protected PropMappingImpl() { super(); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ @Override protected EClass eStaticClass() { return MapperPackage.Literals.PROP_MAPPING; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public String getMappedProperty() { return mappedProperty; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public void setMappedProperty(String newMappedProperty) { String oldMappedProperty = mappedProperty; mappedProperty = newMappedProperty; if (eNotificationRequired()) eNotify(new ENotificationImpl(this, Notification.SET, MapperPackage.PROP_MAPPING__MAPPED_PROPERTY, oldMappedProperty, mappedProperty)); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public String getPropertyType() { return propertyType; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public void setPropertyType(String newPropertyType) { String oldPropertyType = propertyType; propertyType = newPropertyType; if (eNotificationRequired()) eNotify(new ENotificationImpl(this, Notification.SET, MapperPackage.PROP_MAPPING__PROPERTY_TYPE, oldPropertyType, propertyType)); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public String getDefaultValue() { return defaultValue; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public void setDefaultValue(String newDefaultValue) { String oldDefaultValue = defaultValue; defaultValue = newDefaultValue; if (eNotificationRequired()) eNotify(new ENotificationImpl(this, Notification.SET, MapperPackage.PROP_MAPPING__DEFAULT_VALUE, oldDefaultValue, defaultValue)); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public String getObjectToPropertyPath() { return objectToPropertyPath; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public void setObjectToPropertyPath(String newObjectToPropertyPath) { String oldObjectToPropertyPath = objectToPropertyPath; objectToPropertyPath = newObjectToPropertyPath; if (eNotificationRequired()) eNotify(new ENotificationImpl(this, Notification.SET, MapperPackage.PROP_MAPPING__OBJECT_TO_PROPERTY_PATH, oldObjectToPropertyPath, objectToPropertyPath)); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public LocalPropertyConversion getLocalPropertyConversion() { return localPropertyConversion; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public NotificationChain basicSetLocalPropertyConversion(LocalPropertyConversion newLocalPropertyConversion, NotificationChain msgs) { LocalPropertyConversion oldLocalPropertyConversion = localPropertyConversion; localPropertyConversion = newLocalPropertyConversion; if (eNotificationRequired()) { ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, MapperPackage.PROP_MAPPING__LOCAL_PROPERTY_CONVERSION, oldLocalPropertyConversion, newLocalPropertyConversion); if (msgs == null) msgs = notification; else msgs.add(notification); } return msgs; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public void setLocalPropertyConversion(LocalPropertyConversion newLocalPropertyConversion) { if (newLocalPropertyConversion != localPropertyConversion) { NotificationChain msgs = null; if (localPropertyConversion != null) msgs = ((InternalEObject)localPropertyConversion).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - MapperPackage.PROP_MAPPING__LOCAL_PROPERTY_CONVERSION, null, msgs); if (newLocalPropertyConversion != null) msgs = ((InternalEObject)newLocalPropertyConversion).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - MapperPackage.PROP_MAPPING__LOCAL_PROPERTY_CONVERSION, null, msgs); msgs = basicSetLocalPropertyConversion(newLocalPropertyConversion, msgs); if (msgs != null) msgs.dispatch(); } else if (eNotificationRequired()) eNotify(new ENotificationImpl(this, Notification.SET, MapperPackage.PROP_MAPPING__LOCAL_PROPERTY_CONVERSION, newLocalPropertyConversion, newLocalPropertyConversion)); } /** * <!-- begin-user-doc --> * Check that the class has the mapped property, * or that the class and subset has the mapped pseudo-property * (the drop-down which offered pseudo-properties in the editor gives pseudo-properties * for all subsets. Now, for validation ,we know a subset) * <!-- end-user-doc --> */ public boolean classHasProperty(DiagnosticChain diagnostics, Map<?,?> context) { boolean classHasProperty = ModelUtil.hasPropertyOrPseudoProperty(getMappedClass(), getMappedPackage(), getSubset(),getMappedProperty(), this); if (!classHasProperty) { if (diagnostics != null) { diagnostics.add (new BasicDiagnostic (Diagnostic.ERROR, MapperValidator.DIAGNOSTIC_SOURCE, MapperValidator.PROP_MAPPING__CLASS_HAS_PROPERTY, ("Class '" + getMappedClass() + "' does not have property '" + getMappedProperty() + "'"), new Object [] { this })); } return false; } return true; } /** * <!-- begin-user-doc --> * check that there is an object mapping of the same class and subset * as the property mapping; */ public boolean objectMappingExists(DiagnosticChain diagnostics, Map<?,?> context) { boolean objectMappingExists = false; // System.out.println("Checking property mapping " + getClassSet().className() + " (" + getClassSet().subset() + ")"); try { ObjMapping om = ModelUtil.getObjectMapping(ModelUtil.getModelRoot(this), getClassSet()); objectMappingExists = (om != null); } catch (MapperException ex) {objectMappingExists = false;} if (!objectMappingExists) { if (diagnostics != null) { // System.out.println("bad"); diagnostics.add (new BasicDiagnostic (Diagnostic.ERROR, MapperValidator.DIAGNOSTIC_SOURCE, MapperValidator.PROP_MAPPING__OBJECT_MAPPING_EXISTS, ("Property mapping requires a single object mapping for class " + getClassSet().stringForm() + "; there is none."), new Object [] { this })); } return false; } return true; } /** * <!-- begin-user-doc --> * check that the path from the object node to the property node * (which by default is the shortest path, but may be overridden) * is a valid path * <!-- end-user-doc --> */ public boolean objectToPropertyPathIsValid(DiagnosticChain diagnostics, Map<?,?> context) { // 'false' means do not check uniqueness (yet) boolean isValidPath = validObjectToPropertyPath(false); if (!isValidPath) { if (diagnostics != null) { diagnostics.add (new BasicDiagnostic (Diagnostic.ERROR, MapperValidator.DIAGNOSTIC_SOURCE, MapperValidator.PROP_MAPPING__OBJECT_TO_PROPERTY_PATH_IS_VALID, "path from object mapping node to property 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 */ private boolean validObjectToPropertyPath(boolean mustBeUnique) { boolean isValidPath = true; try{ Xpth path = getObjectToPropertyXPath(); NodeDef mappedNode = ModelUtil.mappingNode(ModelUtil.getObjectMapping(this)); 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 --> * check (if there are no cross conditions) * that the shortest path from the property node to the object node * leads to a unique node. * This validation condition has been abolished, because it is over-zealous. * There can be occasions where the property belongs to many object instances; * e.g the instances may be grouped together because they have the same value of the property * <!-- end-user-doc --> */ public boolean objectIsUniqueFromPropertyNode(DiagnosticChain diagnostics, Map<?,?> context) { boolean uniqueToObject = true; if (!uniqueToObject) { if (diagnostics != null) { } return false; } return true; } /** * <!-- begin-user-doc --> * check that the path from the object node to the property node gives a unique node * (if there are no cross-conditions, and if the cross path is valid - previously checked) * <!-- end-user-doc --> */ public boolean propertyIsUniqueFromObjectNode(DiagnosticChain diagnostics, Map<?,?> context) { boolean isUniquePath = true; if ((this.getCrossConditions().size() == 0) && (validObjectToPropertyPath(false))) { isUniquePath = validObjectToPropertyPath(true); } if (!isUniquePath) { if (diagnostics != null) { diagnostics.add (new BasicDiagnostic (Diagnostic.ERROR, MapperValidator.DIAGNOSTIC_SOURCE, MapperValidator.PROP_MAPPING__PROPERTY_IS_UNIQUE_FROM_OBJECT_NODE, "Path from object mapping node to property mapping node does not lead to a unique node" + ", and there are no cross-conditions", new Object [] { this })); } return false; } return true; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ @Override public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) { switch (featureID) { case MapperPackage.PROP_MAPPING__LOCAL_PROPERTY_CONVERSION: return basicSetLocalPropertyConversion(null, msgs); } return super.eInverseRemove(otherEnd, featureID, msgs); } /** * <!-- 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 */ @Override public Object eGet(int featureID, boolean resolve, boolean coreType) { switch (featureID) { case MapperPackage.PROP_MAPPING__MAPPED_PROPERTY: return getMappedProperty(); case MapperPackage.PROP_MAPPING__PROPERTY_TYPE: return getPropertyType(); case MapperPackage.PROP_MAPPING__DEFAULT_VALUE: return getDefaultValue(); case MapperPackage.PROP_MAPPING__OBJECT_TO_PROPERTY_PATH: return getObjectToPropertyPath(); case MapperPackage.PROP_MAPPING__LOCAL_PROPERTY_CONVERSION: return getLocalPropertyConversion(); } 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.PROP_MAPPING__MAPPED_PROPERTY: setMappedProperty((String)newValue); return; case MapperPackage.PROP_MAPPING__PROPERTY_TYPE: setPropertyType((String)newValue); return; case MapperPackage.PROP_MAPPING__DEFAULT_VALUE: setDefaultValue((String)newValue); return; case MapperPackage.PROP_MAPPING__OBJECT_TO_PROPERTY_PATH: setObjectToPropertyPath((String)newValue); return; case MapperPackage.PROP_MAPPING__LOCAL_PROPERTY_CONVERSION: setLocalPropertyConversion((LocalPropertyConversion)newValue); return; } super.eSet(featureID, newValue); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ @Override public void eUnset(int featureID) { switch (featureID) { case MapperPackage.PROP_MAPPING__MAPPED_PROPERTY: setMappedProperty(MAPPED_PROPERTY_EDEFAULT); return; case MapperPackage.PROP_MAPPING__PROPERTY_TYPE: setPropertyType(PROPERTY_TYPE_EDEFAULT); return; case MapperPackage.PROP_MAPPING__DEFAULT_VALUE: setDefaultValue(DEFAULT_VALUE_EDEFAULT); return; case MapperPackage.PROP_MAPPING__OBJECT_TO_PROPERTY_PATH: setObjectToPropertyPath(OBJECT_TO_PROPERTY_PATH_EDEFAULT); return; case MapperPackage.PROP_MAPPING__LOCAL_PROPERTY_CONVERSION: setLocalPropertyConversion((LocalPropertyConversion)null); return; } super.eUnset(featureID); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ @Override public boolean eIsSet(int featureID) { switch (featureID) { case MapperPackage.PROP_MAPPING__MAPPED_PROPERTY: return MAPPED_PROPERTY_EDEFAULT == null ? mappedProperty != null : !MAPPED_PROPERTY_EDEFAULT.equals(mappedProperty); case MapperPackage.PROP_MAPPING__PROPERTY_TYPE: return PROPERTY_TYPE_EDEFAULT == null ? propertyType != null : !PROPERTY_TYPE_EDEFAULT.equals(propertyType); case MapperPackage.PROP_MAPPING__DEFAULT_VALUE: return DEFAULT_VALUE_EDEFAULT == null ? defaultValue != null : !DEFAULT_VALUE_EDEFAULT.equals(defaultValue); case MapperPackage.PROP_MAPPING__OBJECT_TO_PROPERTY_PATH: return OBJECT_TO_PROPERTY_PATH_EDEFAULT == null ? objectToPropertyPath != null : !OBJECT_TO_PROPERTY_PATH_EDEFAULT.equals(objectToPropertyPath); case MapperPackage.PROP_MAPPING__LOCAL_PROPERTY_CONVERSION: return localPropertyConversion != null; } 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(" (mappedProperty: "); result.append(mappedProperty); result.append(", propertyType: "); result.append(propertyType); result.append(", defaultValue: "); result.append(defaultValue); result.append(", objectToPropertyPath: "); result.append(objectToPropertyPath); 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 PropMapping) { PropMapping pm = (PropMapping)m; eq = ((pm.getClassSet().equals(getClassSet())) && (pm.getMappedProperty().equals(getMappedProperty()))); } return eq; } /** * Xpth form of the path from the owning object to this property * If a cross path has not been supplied, calculates the default shortest XPath. * @return * @throws MapperException */ public Xpth getObjectToPropertyXPath() throws MapperException { Xpth path = null; // if a non-default cross-path has been supplied if ((getObjectToPropertyPath() != null) && (!getObjectToPropertyPath().equals(""))) {path = new Xpth(ModelUtil.getGlobalNamespaceSet(this),getObjectToPropertyPath());} // if no default cross-path has been supplied else { ObjMapping om = ModelUtil.getObjectMapping(this); if (om != null) path = om.getRootXPath().defaultCrossPath(this.getRootXPath()); else if (om == null) { } } return path; } /** * details of this mapping, to be written out in the details column of the Mappings view */ public String getOwnDetails() { String details = super.getOwnDetails(); if (!(getObjectToPropertyPath().equals(""))) details = details + "cross path = '" + getObjectToPropertyPath() + "';"; if ((getDefaultValue() != null) && (!(getDefaultValue().equals("")))) details = details + "default = '" + getDefaultValue() + "';"; return details; } } //PropMappingImpl