001: /*
002: * uDig - User Friendly Desktop Internet GIS client
003: * http://udig.refractions.net
004: * (C) 2004, Refractions Research Inc.
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation;
009: * version 2.1 of the License.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: */
017: package net.refractions.udig.catalog;
018:
019: import java.io.IOException;
020: import java.net.URL;
021: import java.util.List;
022:
023: import net.refractions.udig.catalog.internal.Messages;
024: import net.refractions.udig.ui.ErrorManager;
025:
026: import org.eclipse.core.runtime.IProgressMonitor;
027: import org.eclipse.core.runtime.SubProgressMonitor;
028:
029: import com.vividsolutions.jts.geom.Envelope;
030:
031: /**
032: * Interface to capture both the Local Catalog resources and Web Registry Service.
033: * <p>
034: * Conceptually provides a searchable Catalog of "Spatial Data Sources". Metadata search is
035: * abitrary.
036: * </p>
037: *
038: * @author David Zwiers, Refractions Research
039: * @since 0.7.0
040: * @see IService
041: */
042: public abstract class ICatalog implements IResolve {
043: /**
044: * Catalogs do not have a parent so null is returned.
045: * <p>
046: * We can consider adding a global 'root' parent - but we will wait until we find a need, or if
047: * users request.
048: * </p>
049: *
050: * @return null as catalogs do not have a parent
051: */
052: public IResolve parent(IProgressMonitor monitor) {
053: return null;
054: }
055:
056: /**
057: * Adds the specified entry to this catalog. In some cases the catalog will be backed onto a
058: * server, which may not allow for additions.
059: * <p>
060: * An IService may belong to more than one Catalog.
061: * </p>
062: *
063: * @param entry
064: * @throws UnsupportedOperationException
065: */
066: public abstract void add(IService service)
067: throws UnsupportedOperationException;
068:
069: /**
070: * Removes the specified entry to this catalog. In some cases the catalog will be backed onto a
071: * server, which may not allow for deletions.
072: *
073: * @param service
074: * @throws UnsupportedOperationException
075: */
076: public abstract void remove(IService service)
077: throws UnsupportedOperationException;
078:
079: /**
080: * Replaces the specified entry in this catalog. In some cases the catalog will be backed onto a
081: * server, which may not allow for deletions.
082: *
083: * @param id
084: * @param service
085: * @throws UnsupportedOperationException
086: */
087: public abstract void replace(URL id, IService service)
088: throws UnsupportedOperationException;
089:
090: /**
091: * Will attempt to morph into the adaptee, and return that object. Required adaptions:
092: * <ul>
093: * <li>ICatalogInfo.class
094: * <li>List.class <IService>
095: * </ul>
096: * May Block.
097: *
098: * @param adaptee
099: * @param monitor May Be Null
100: * @return
101: * @see ICatalogInfo
102: * @see IService
103: */
104: public abstract <T> T resolve(Class<T> adaptee,
105: IProgressMonitor monitor) throws IOException;
106:
107: /**
108: * Aquire info on this Catalog.
109: * <p>
110: * This is functionally equivalent to: <core>resolve(ICatalogInfo.class,monitor)</code>
111: * </p>
112: *
113: * @see ICatalog#resolve(Class, IProgressMonitor)
114: * @return ICatalogInfo resolve(ICatalogInfo.class,IProgressMonitor monitor);
115: */
116: public ICatalogInfo getInfo(IProgressMonitor monitor)
117: throws IOException {
118: return resolve(ICatalogInfo.class, monitor);
119: }
120:
121: /**
122: * Find resources matching this id directly from this Catalog.
123: *
124: * @param resource used to match resolves
125: * @param monitor used to show the progress of the find.
126: * @return List (possibly empty) of matching Resolves
127: */
128: public abstract List<IResolve> find(URL resource,
129: IProgressMonitor monitor);
130:
131: /**
132: * Find Service matching this id directly from this Catalog. This method is guaranteed to be non-blocking.
133: *
134: * @deprecated This method cannot be guarnteed to be non blocking for external catalogs, please use getById instead
135: * @param id used to match resolves
136: * @param monitor TODO
137: * @return List (possibly empty) of matching Resolves
138: */
139: public abstract List<IService> findService(URL query);
140:
141: /**
142: * Look in catalog for exact match with provided id.
143: *
144: * @param type Type of IResolve if known
145: * @param id id used for lookup
146: * @param monitor
147: * @return Resolve or null if not found
148: */
149: public abstract <T extends IResolve> T getById(Class<T> type,
150: URL id, IProgressMonitor monitor);
151:
152: /**
153: * Performs a search on this catalog based on the specified inputs.
154: * <p>
155: * The pattern uses the following conventions:
156: * <ul>
157: * <li>
158: * <li> use " " to surround a phase
159: * <li> use + to represent 'AND'
160: * <li> use - to represent 'OR'
161: * <li> use ! to represent 'NOT'
162: * <li> use ( ) to designate scope
163: * </ul>
164: * The bbox provided shall be in Lat - Long, or null if the search is not to be contained within
165: * a specified area.
166: * </p>
167: *
168: * @param pattern Search pattern (see above)
169: * @param bbox The bbox in Lat-Long (ESPG 4269), or null
170: * @param monitor for progress, or null if monitoring is not desired
171: * @return List matching IResolve
172: */
173: public abstract List<IResolve> search(String pattern,
174: Envelope bbox, IProgressMonitor monitor) throws IOException;
175:
176: /**
177: * Indicate class and id.
178: *
179: * @return string representing this IResolve
180: */
181: public String toString() {
182: StringBuffer buf = new StringBuffer();
183: String classname = getClass().getName();
184: String name = classname
185: .substring(classname.lastIndexOf('.') + 1);
186: buf.append(name);
187: buf.append("("); //$NON-NLS-1$
188: buf.append(getIdentifier());
189: buf.append(")"); //$NON-NLS-1$
190: return buf.toString();
191: }
192:
193: /**
194: * @param listener
195: */
196: public abstract void addCatalogListener(
197: IResolveChangeListener listener);
198:
199: /**
200: * @param listener
201: */
202: public abstract void removeCatalogListener(
203: IResolveChangeListener listener);
204:
205: /**
206: * Create an IGeoResource that is will be deleted after the session. The descriptor object passed in
207: * is used to determine the type of resource that is created. For example if the descriptor object is
208: * a FeatureType then a IGeoResource that can resolve to a FeatureStore will be returned.
209: *
210: * @param descriptor An object whose type is in the {@link #getTemporaryDescriptorClasses()} array.
211: * @return an IGeoResource that is will be deleted after the session.
212: * @throws IllegalArgumentException if the descriptor type is not known.
213: */
214: public abstract IGeoResource createTemporaryResource(
215: Object descriptor) throws IllegalArgumentException;
216:
217: /**
218: * Returns The list of class names that this catalog can use to create Temporary Resources.
219: *
220: * @return The list of class names that this catalog can use to create Temporary Resources.
221: */
222: public abstract String[] getTemporaryDescriptorClasses();
223:
224: public void dispose(IProgressMonitor monitor) {
225: monitor.beginTask(Messages.ICatalog_dispose, 100);
226: List<? extends IResolve> members;
227: try {
228: members = members(new SubProgressMonitor(monitor, 1));
229: } catch (Throwable e) {
230: ErrorManager
231: .get()
232: .displayException(
233: e,
234: "Error disposing members of catalog: " + getIdentifier(), CatalogPlugin.ID); //$NON-NLS-1$
235: return;
236: }
237: int steps = (int) ((double) 99 / (double) members.size());
238: for (IResolve resolve : members) {
239: try {
240: SubProgressMonitor subProgressMonitor = new SubProgressMonitor(
241: monitor, steps);
242: resolve.dispose(subProgressMonitor);
243: subProgressMonitor.done();
244: } catch (Throwable e) {
245: ErrorManager
246: .get()
247: .displayException(
248: e,
249: "Error disposing members of catalog: " + getIdentifier(), CatalogPlugin.ID); //$NON-NLS-1$
250: }
251: }
252:
253: }
254: }
|