001: package org.geotools.xml;
002:
003: import java.util.ArrayList;
004: import java.util.Collection;
005: import java.util.Iterator;
006: import java.util.List;
007:
008: import org.eclipse.emf.common.util.EList;
009: import org.eclipse.emf.ecore.EFactory;
010: import org.eclipse.emf.ecore.EObject;
011: import org.eclipse.emf.ecore.EStructuralFeature;
012:
013: /**
014: * Utility methods for working with emf model objects.
015: *
016: * @author Justin Deoliveira, The Open Planning Project, jdeolive@openplans.org
017: *
018: */
019: public class EMFUtils {
020:
021: /**
022: * Determines if an eobject has a particular property.
023: *
024: * @param eobject The eobject.
025: * @param property The property to check for.
026: *
027: * @return <code>true</code> if the property exists, otherwise <code>false</code.
028: */
029: public static boolean has(EObject eobject, String property) {
030: return feature(eobject, property) != null;
031: }
032:
033: /**
034: * Sets a property of an eobject.
035: *
036: * @param eobject THe object.
037: * @param property The property to set.
038: * @param value The value of the property.
039: */
040: public static void set(EObject eobject, String property,
041: Object value) {
042: EStructuralFeature feature = feature(eobject, property);
043: eobject.eSet(feature, value);
044: }
045:
046: /**
047: * Gets the property of an eobject.
048: *
049: * @param eobject The object.
050: * @param property The property to get.
051: *
052: * @return The value of the property.
053: */
054: public static Object get(EObject eobject, String property) {
055: EStructuralFeature feature = feature(eobject, property);
056: return eobject.eGet(feature);
057: }
058:
059: /**
060: * Adds a value to a multi-valued propert of an eobject.
061: * <p>
062: * The <param>property</param> must map to a multi-valued property of the
063: * eobject. The {@link #isCollection(EObject, String)} method can be used
064: * to test this.
065: * </p>
066: *
067: * @param eobject The object.
068: * @param property The multi-valued property.
069: * @param value The value to add.
070: */
071: public static void add(EObject eobject, String property,
072: Object value) {
073: EStructuralFeature feature = feature(eobject, property);
074: if (feature != null && isCollection(eobject, property)) {
075: Collection collection = (Collection) get(eobject, property);
076: collection.add(value);
077: }
078: }
079:
080: /**
081: * Determines if a property of an eobject is a collection.
082: * <p>
083: * In the event the property does not exist, this method will return
084: * <code>false</code>
085: * </p>
086: *
087: * @return <code>true</code> if hte property is a collection, otherwise
088: * <code>false</code>
089: */
090: public static boolean isCollection(EObject eobject, String property) {
091: EStructuralFeature feature = feature(eobject, property);
092: if (feature == null) {
093: return false;
094: }
095:
096: if (EList.class.isAssignableFrom(feature.getEType()
097: .getInstanceClass())) {
098: return true;
099: }
100:
101: return false;
102: }
103:
104: /**
105: * Method which looks up a structure feature of an eobject, first doing
106: * an exact name match, then a case insensitive one.
107: *
108: * @param eobject The eobject.
109: * @param property The property
110: *
111: * @return The structure feature, or <code>null</code> if not found.
112: */
113: public static EStructuralFeature feature(EObject eobject,
114: String property) {
115: EStructuralFeature feature = eobject.eClass()
116: .getEStructuralFeature(property);
117: if (feature != null)
118: return feature;
119:
120: //do a case insentive check, need to do the walk up the type hierarchy
121: for (Iterator itr = eobject.eClass()
122: .getEAllStructuralFeatures().iterator(); itr.hasNext();) {
123: feature = (EStructuralFeature) itr.next();
124: if (feature.getName().equalsIgnoreCase(property)) {
125: return feature;
126: }
127: }
128:
129: return null;
130: }
131:
132: /**
133: * Sets a particular property on each {@link EObject} in a list to a particular value.
134: * <p>
135: * The following must hold:
136: * <code>
137: * objects.size() == values.size()
138: * </code>
139: * </p>
140: *
141: * @param objects A list of {@link EObject}.
142: * @param property The property to set on each eobject in <code>objects</code>
143: * @param values The value to set on each eobjct in <code>objects</code>
144: */
145: public static void set(List objects, String property, List values) {
146:
147: for (int i = 0; i < objects.size(); i++) {
148: EObject eobject = (EObject) objects.get(i);
149: set(eobject, property, values.get(i));
150: }
151:
152: }
153:
154: /**
155: * Sets a particular property on each {@link EObject} in a list to a particular value.
156: * <p>
157: *
158: * @param objects A list of {@link EObject}.
159: * @param property The property to set on each eobject in <code>objects</code>
160: * @param value The value to set on each eobjct in <code>objects</code>
161: */
162: public static void set(List objects, String property, Object value) {
163:
164: for (int i = 0; i < objects.size(); i++) {
165: EObject eobject = (EObject) objects.get(i);
166: set(eobject, property, value);
167: }
168:
169: }
170:
171: /**
172: * Obtains the values of a particular property on each {@link EObject} in a list.
173: *
174: * @param objects A list of {@link EObject}.
175: * @param property The property to obtain.
176: *
177: * @return The list of values.
178: */
179: public static List get(List objects, String property) {
180:
181: List values = new ArrayList();
182: for (int i = 0; i < objects.size(); i++) {
183: EObject eobject = (EObject) objects.get(i);
184: EStructuralFeature feature = feature(eobject, property);
185:
186: values.add(eobject.eGet(feature));
187: }
188:
189: return values;
190:
191: }
192:
193: /**
194: * Determines if a particular propety has been set on an eobject.
195: *
196: * @param eobjects The eobject.
197: * @param property The property to check.
198: *
199: * @return <code>true</code> if the property has been set, otherwise <code>false</code>
200: */
201: public static boolean isSet(EObject eobject, String property) {
202:
203: EStructuralFeature feature = feature(eobject, property);
204: return eobject.eIsSet(feature);
205:
206: }
207:
208: /**
209: * Determines if a particular propety has been set on each {@link EObject} in a list.
210: *
211: * @param objects A list of {@link EObject}
212: * @param property The property to check.
213: *
214: * @return <code>true</code> if every element in the list has been set, otherwise <code>false</code>
215: */
216: public static boolean isSet(List objects, String property) {
217:
218: for (int i = 0; i < objects.size(); i++) {
219: EObject eobject = (EObject) objects.get(i);
220: if (!isSet(eobject, property))
221: return false;
222: }
223:
224: return true;
225: }
226:
227: /**
228: * Determines if a particular propety is unset on each {@link EObject} in a list.
229: *
230: * @param objects A list of {@link EObject}
231: * @param property The property to check.
232: *
233: * @return <code>true</code> if every element in the list is unset, otherwise <code>false</code>
234: */
235: public static boolean isUnset(List objects, String property) {
236:
237: for (int i = 0; i < objects.size(); i++) {
238: EObject eobject = (EObject) objects.get(i);
239: if (isSet(eobject, property))
240: return false;
241:
242: }
243:
244: return true;
245: }
246:
247: /**
248: * Clones an eobject.
249: *
250: * @param prototype The object to be cloned from.
251: * @param factory The factory used to create the clone.
252: *
253: * @return THe cloned object, with all properties the same to the original.
254: */
255: public static EObject clone(EObject prototype, EFactory factory) {
256: EObject clone = factory.create(prototype.eClass());
257: for (Iterator i = clone.eClass().getEStructuralFeatures()
258: .iterator(); i.hasNext();) {
259: EStructuralFeature feature = (EStructuralFeature) i.next();
260: clone.eSet(feature, prototype.eGet(feature));
261: }
262:
263: return clone;
264: }
265:
266: /**
267: * Copies all the properties from one object to anoter.
268: *
269: * @param source The object to copy from.
270: * @param target The object to copy to.
271: */
272: public static void copy(EObject source, EObject target) {
273: for (Iterator i = source.eClass().getEStructuralFeatures()
274: .iterator(); i.hasNext();) {
275: EStructuralFeature feature = (EStructuralFeature) i.next();
276: target.eSet(feature, source.eGet(feature));
277: }
278: }
279: }
|