001: /* uDig - User Friendly Desktop Internet GIS client
002: * http://udig.refractions.net
003: * (C) 2004, Refractions Research Inc.
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation;
008: * version 2.1 of the License.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: */
015: package net.refractions.udig.core;
016:
017: import java.io.IOException;
018:
019: import net.refractions.udig.core.internal.CorePlugin;
020:
021: import org.eclipse.core.runtime.IAdaptable;
022: import org.eclipse.core.runtime.IProgressMonitor;
023: import org.eclipse.core.runtime.Platform;
024:
025: /**
026: * Methods to help manage adapters
027: * @author jones
028: * @since 1.1.0
029: */
030: public class AdapterUtil {
031: public static final AdapterUtil instance = new AdapterUtil();
032:
033: private AdapterUtil() {
034: }
035:
036: /**
037: * Determines if a class can be adapted based on its string representation.
038: *
039: * @param targetClass class name to check if adaptation can go to
040: * @param obj source object to adapt from
041: * @return
042: */
043: public boolean canAdaptTo(String targetClass, Object obj) {
044: ClassLoader classLoader = obj.getClass().getClassLoader();
045: return canAdaptTo(targetClass, obj, classLoader);
046: }
047:
048: /**
049: * Determines if a class can be adapted based on its string representation.
050: *
051: * @param targetClass class name to check if adaptation can go to
052: * @param obj source object to adapt from
053: * @param classLoader object to instantiate the class with
054: * @return
055: */
056: public boolean canAdaptTo(String targetClass, Object obj,
057: ClassLoader classLoader) {
058: Class<?> target = null;
059: if (classLoader == null) {
060: classLoader = obj.getClass().getClassLoader();
061: }
062: try {
063: target = classLoader.loadClass(targetClass);
064: } catch (Throwable e) {
065: //do nothing this is ok.
066: return false;
067: }
068: if (target.isAssignableFrom(obj.getClass()))
069: return true;
070:
071: //see if platform can adapt the object
072: if (Platform.getAdapterManager().hasAdapter(obj, targetClass))
073: return true;
074:
075: // see if the object is a blocking adaptable object and can adapt to the correct class type
076: IBlockingAdaptable blockingAdaptable = getBlockingAdapter(obj);
077: if (blockingAdaptable != null
078: && blockingAdaptable.canAdaptTo(target))
079: return true;
080:
081: // see if the object is adaptable and can adapt to the class type.
082: IAdaptable adaptable = getAdaptable(obj);
083: if (adaptable != null) {
084: return adaptable.getAdapter(target) != null;
085: }
086: return false;
087: }
088:
089: public IAdaptable getAdaptable(Object obj) {
090: if (obj instanceof IAdaptable) {
091: return (IAdaptable) obj;
092: }
093: if (Platform.getAdapterManager().hasAdapter(obj,
094: IAdaptable.class.getSimpleName()))
095: return (IAdaptable) Platform.getAdapterManager()
096: .getAdapter(obj, IAdaptable.class);
097: return null;
098: }
099:
100: public IBlockingAdaptable getBlockingAdapter(Object obj) {
101: if (obj instanceof IBlockingAdaptable) {
102: return (IBlockingAdaptable) obj;
103: }
104: if (Platform.getAdapterManager().hasAdapter(obj,
105: IBlockingAdaptable.class.getName()))
106: return (IBlockingAdaptable) Platform.getAdapterManager()
107: .getAdapter(obj, IBlockingAdaptable.class);
108: if (obj instanceof IAdaptable) {
109: IAdaptable adapter = (IAdaptable) obj;
110: return (IBlockingAdaptable) adapter
111: .getAdapter(IBlockingAdaptable.class);
112: }
113: return null;
114: }
115:
116: /**
117: * Since the target object may not be the object that the operation actually operates on, the
118: * getOperationTarget() finds the real object and returns it or null if for some reason the
119: * operation can be performed on the target.
120: * <p>
121: * Example:
122: * </p>
123: * A FeatureType readonly operation is called on a IResolve. The getOperationTarget would
124: * resolve(FeatureSource.class) and return the Feature Source for the operation.
125: *
126: * @param target the object the action is called on.
127: * @param definition the Configuration element definition of the operation.
128: * @param monitor The progress monitor for the operation job.
129: * @return
130: * @throws IOException
131: */
132: @SuppressWarnings("unchecked")
133: public <T> T getOperationTarget(String targetClass, Object obj,
134: IProgressMonitor monitor) throws IOException {
135: Class<T> target = null;
136: try {
137: target = (Class<T>) obj.getClass().getClassLoader()
138: .loadClass(targetClass);
139: return getOperationTarget(target, obj, monitor);
140: } catch (ClassNotFoundException e) {
141: //do nothing.
142: CorePlugin
143: .log(
144: "This exception is bad. The framework should not allow this to be reached.", e); //$NON-NLS-1$
145: return null;
146: }
147:
148: }
149:
150: /**
151: * Since the target object may not be the object that the operation actually operates on, the
152: * getOperationTarget() finds the real object and returns it or null if for some reason the
153: * operation can be performed on the target.
154: * <p>
155: * Example:
156: * </p>
157: * A FeatureType readonly operation is called on a IResolve. The getOperationTarget would
158: * resolve(FeatureSource.class) and return the Feature Source for the operation.
159: *
160: * @param target the object the action is called on.
161: * @param definition the Configuration element definition of the operation.
162: * @param monitor The progress monitor for the operation job.
163: * @return
164: * @throws IOException
165: */
166: public <T> T getOperationTarget(Class<T> target, Object obj,
167: IProgressMonitor monitor) throws IOException {
168:
169: if (target.isAssignableFrom(obj.getClass()))
170: return target.cast(obj);
171: if (Platform.getAdapterManager().hasAdapter(obj,
172: target.getName())) {
173: return target.cast(Platform.getAdapterManager()
174: .loadAdapter(obj, target.getName()));
175: }
176: IBlockingAdaptable blockingAdaptable = getBlockingAdapter(obj);
177: if (blockingAdaptable != null
178: && blockingAdaptable.canAdaptTo(target))
179: return blockingAdaptable.getAdapter(target, monitor);
180: if (obj instanceof IAdaptable) {
181: IAdaptable adaptable = (IAdaptable) obj;
182: return target.cast(adaptable.getAdapter(target));
183: }
184: return null;
185: }
186:
187: }
|