//------------------------------------------------------------------------------ // Copyright (c) 2005, 2006 IBM Corporation and others. // All rights reserved. This program and the accompanying materials // are made available under the terms of the Eclipse Public License v1.0 // which accompanies this distribution, and is available at // http://www.eclipse.org/legal/epl-v10.html // // Contributors: // IBM Corporation - initial implementation //------------------------------------------------------------------------------ package org.eclipse.epf.uma.ecore.util; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.eclipse.emf.ecore.EStructuralFeature; /** * Supports the reverse traversal of an association between two model objects. * * @author Phong Nguyen Le * @author Kelvin Low * @since 1.0 */ public class OppositeFeature { private String name; private EStructuralFeature targetFeature; private boolean isMany; private boolean resolveOwner = true; private Class ownerClass; //private static boolean deliverOnResolve; /** * Maps source model objects to OppositeFeature objects. */ public static final Map classOppositeFeaturesMap = new HashMap(); /** * Maps EStructuralFeature objects to OppositeFeature objects. */ public static final Map featureOppositeFeatureMap = new HashMap(); /** * Creates a new instance. * * @param ownerClass * the model class that owns this opposite feature * @param name * the name of this opposite feature * @param targetFeature * the feature which this opposite feature is based on * @param isMany * if <true>, the multiplicity of the association is unbounded * @param resolveOwner * if <true>, resolve the owner class if it is a proxy */ public OppositeFeature(Class ownerClass, String name, EStructuralFeature targetFeature, boolean isMany, boolean resolveOwner) { this.ownerClass = ownerClass; this.name = name; this.targetFeature = targetFeature; this.isMany = isMany; this.resolveOwner = resolveOwner; } /** * Creates a new instance. * * @param ownerClass * the model class that owns this opposite feature * @param name * the name of this opposite feature * @param targetFeature * the feature which this opposite feature is based on * @param isMany * if <true>, the multiplicity of the association is unbounded */ public OppositeFeature(Class ownerClass, String name, EStructuralFeature targetFeature, boolean isMany) { this(ownerClass, name, targetFeature, isMany, true); } /** * Gets the modal class that owns this opposite feature. * * @return the modal class that owns this opposite feature */ public Class getOwnerClass() { return ownerClass; } /** * Checks whether the association is unbounded. * * @return <code>true</code> if the association is unbounded */ public boolean isMany() { return isMany; } /** * Gets the name of this opposite feature. * * @return the opposite feature name */ public String getName() { return name; } /** * Gets the feature which this opposite feature is based on. * * @return the original feature generated by EMF */ public EStructuralFeature getTargetFeature() { return targetFeature; } /** * Gets the ID of this opposite feature. * * @return the opposite feature ID */ public int getFeatureID() { return -1 - targetFeature.getFeatureID(); } /** * Checks whether the owner class of this opposite feature, if proxied, * should be resolved when the target feature is set. * * @return <true> if the owner class, if proxied, should be resolved */ public boolean resolveOwner() { return resolveOwner; } /** * Gets a string representation of this opposite feature. * * @return A <code>String</code> containing the key attributes of this * opposite feature. */ public String toString() { return name + "[targetFeature=" + targetFeature //$NON-NLS-1$ + ", isMany=" + isMany + "]"; //$NON-NLS-1$ //$NON-NLS-2$ } /** * Registers the given opposite feature. * * @param oppositeFeature * the opposite feature to register */ public static final void registerOppositeFeature( OppositeFeature oppositeFeature) { Class cls = oppositeFeature.getOwnerClass(); Set features = (Set) classOppositeFeaturesMap.get(cls); if (features == null) { features = new HashSet(); classOppositeFeaturesMap.put(cls, features); } features.add(oppositeFeature); featureOppositeFeatureMap.put(oppositeFeature.getTargetFeature(), oppositeFeature); } /** * Checks whether notification is sent when a proxy owner class is resolved. * * @return <code>true</code> if notification is being sent when a proxy * owner class is resolved */ /* public static final boolean isDeliverOnResolve() { return deliverOnResolve; } */ /** * Enables notification when a proxy owner class is resolved. * * @param enableNotification * if <code>true</code>, send notification when a proxy owner * class is resolved */ /* public static final void setDeliverOnResolve(boolean enableNotification) { deliverOnResolve = enableNotification; } */ /** * Gets the opposite feature for the given feature. * * @param feature * an EMF <code>EStructuralFeature</code> feature * @return an opposite feature that is based on the given feature */ public static final OppositeFeature getOppositeFeature( EStructuralFeature feature) { return (OppositeFeature) featureOppositeFeatureMap.get(feature); } }