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.catalog.internal;
016:
017: import java.io.IOException;
018: import java.util.HashMap;
019: import java.util.HashSet;
020: import java.util.List;
021: import java.util.Map;
022: import java.util.Set;
023:
024: import net.refractions.udig.catalog.IResolve;
025: import net.refractions.udig.catalog.IResolveAdapterFactory;
026: import net.refractions.udig.catalog.IResolveManager;
027: import net.refractions.udig.core.internal.ExtensionPointList;
028:
029: import org.eclipse.core.runtime.CoreException;
030: import org.eclipse.core.runtime.IConfigurationElement;
031: import org.eclipse.core.runtime.IProgressMonitor;
032:
033: /**
034: * Default implementation of {@link IResolveManager}
035: * @author Jesse
036: * @since 1.1.0
037: */
038: public class ResolveManager implements IResolveManager {
039:
040: private static final String LIST_ID = "net.refractions.udig.catalog.resolvers"; //$NON-NLS-1$
041: Map<IConfigurationElement, IResolveAdapterFactory> factories = new HashMap<IConfigurationElement, IResolveAdapterFactory>();
042: Map<IResolveAdapterFactory, Set<Class>> exceptions = new HashMap<IResolveAdapterFactory, Set<Class>>();
043: Set<IResolveAdapterFactory> registeredFactories = new HashSet<IResolveAdapterFactory>();
044:
045: public ResolveManager() {
046: List<IConfigurationElement> extensionList = ExtensionPointList
047: .getExtensionPointList(LIST_ID);
048:
049: for (IConfigurationElement element : extensionList) {
050: factories.put(element, null);
051: }
052: }
053:
054: public boolean canResolve(IResolve resolve, Class targetClass) {
055: //search registered factories for resolves
056: if (findRegisteredFactory(resolve, targetClass) != null)
057: return true;
058:
059: Set<IConfigurationElement> elements = factories.keySet();
060: // search extension point for resolves.
061: for (IConfigurationElement element : elements) {
062: if (canResolve(element, resolve, targetClass)) {
063: return true;
064: }
065: }
066:
067: return false;
068: }
069:
070: private IResolveAdapterFactory findRegisteredFactory(
071: IResolve resolve, Class targetClass) {
072: for (IResolveAdapterFactory factory : registeredFactories) {
073: if (factory.canAdapt(resolve, targetClass)) {
074: Set<Class> set = exceptions.get(factory);
075: if (set == null || !set.contains(targetClass))
076: return factory;
077: }
078: }
079: return null;
080: }
081:
082: @SuppressWarnings("unchecked")
083: private boolean canResolve(IConfigurationElement element,
084: IResolve resolve, Class targetClass) {
085: String requiredType = element.getAttribute("resolveableType"); //$NON-NLS-1$
086: try {
087: Class<?> clazz = resolve.getClass().getClassLoader()
088: .loadClass(requiredType);
089: if (!clazz.isAssignableFrom(resolve.getClass()))
090: return false;
091:
092: IConfigurationElement[] children = element
093: .getChildren("resolve"); //$NON-NLS-1$
094: for (IConfigurationElement child : children) {
095: String resolveType = child.getAttribute("type"); //$NON-NLS-1$
096: try {
097: ClassLoader classLoader = targetClass
098: .getClassLoader();
099: if (classLoader == null)
100: classLoader = ClassLoader
101: .getSystemClassLoader();
102: Class<?> resolvedClass = classLoader
103: .loadClass(resolveType);
104:
105: if (targetClass.isAssignableFrom(resolvedClass))
106: return true;
107: } catch (ClassNotFoundException e2) {
108: continue;
109: }
110: }
111: return false;
112: } catch (ClassNotFoundException e) {
113: return false;
114: }
115: }
116:
117: public void registerResolves(IResolveAdapterFactory factory) {
118: registeredFactories.add(factory);
119: }
120:
121: public <T> T resolve(IResolve resolve, Class<T> targetType,
122: IProgressMonitor monitor) throws IOException {
123: if (!canResolve(resolve, targetType))
124: return null;
125: IResolveAdapterFactory factory = findFactory(resolve,
126: targetType);
127:
128: if (factory == null)
129: return null;
130:
131: return targetType.cast(factory.adapt(resolve, targetType,
132: monitor));
133: }
134:
135: private IResolveAdapterFactory findFactory(IResolve resolve,
136: Class targetType) {
137: IResolveAdapterFactory factory = findRegisteredFactory(resolve,
138: targetType);
139: if (factory != null)
140: return factory;
141:
142: Set<IConfigurationElement> elements = factories.keySet();
143: IConfigurationElement found = null;
144:
145: for (IConfigurationElement element : elements) {
146: if (canResolve(resolve, targetType)) {
147: found = element;
148: break;
149: }
150: }
151:
152: if (found == null)
153: return null;
154:
155: factory = factories.get(found);
156: if (factory != null)
157: return factory;
158:
159: try {
160: factory = (IResolveAdapterFactory) found
161: .createExecutableExtension("class"); //$NON-NLS-1$
162: factories.put(found, factory);
163: } catch (CoreException e) {
164: throw (RuntimeException) new RuntimeException()
165: .initCause(e);
166: }
167:
168: return factory;
169: }
170:
171: public void unregisterResolves(IResolveAdapterFactory factory) {
172: registeredFactories.remove(factory);
173: exceptions.remove(registeredFactories);
174: }
175:
176: public void unregisterResolves(IResolveAdapterFactory factory,
177: Class resolveType) {
178: if (!registeredFactories.contains(factory))
179: throw new IllegalArgumentException(factory
180: + " is not a registered factory"); //$NON-NLS-1$
181:
182: Set<Class> set = exceptions.get(factory);
183: if (set == null) {
184: set = new HashSet<Class>();
185: exceptions.put(factory, set);
186: }
187:
188: set.add(resolveType);
189: }
190:
191: }
|