001: /*
002: * Geotools2 - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2002, Geotools Project Managment Committee (PMC)
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 org.geotools.data.coverage.grid;
018:
019: import java.util.ArrayList;
020: import java.util.Arrays;
021: import java.util.Collections;
022: import java.util.HashSet;
023: import java.util.Iterator;
024: import java.util.List;
025: import java.util.Set;
026:
027: import org.geotools.factory.FactoryCreator;
028: import org.geotools.factory.FactoryRegistry;
029: import org.geotools.resources.LazySet;
030: import org.opengis.coverage.grid.Format;
031: import org.opengis.coverage.grid.GridCoverage;
032:
033: /**
034: * Enable programs to find all available grid format implementations.
035: *
036: * <p>
037: * In order to be located by this finder datasources must provide an
038: * implementation of the {@link GridFormatFactorySpi} interface.
039: * </p>
040: *
041: * <p>
042: * In addition to implementing this interface datasouces should have a services
043: * file:<br/><code>META-INF/services/org.geotools.data.GridFormatFactorySpi</code>
044: * </p>
045: *
046: * <p>
047: * The file should contain a single line which gives the full name of the
048: * implementing class.
049: * </p>
050: *
051: * <p>
052: * Example:<br/><code>org.geotools.data.mytype.MyTypeGridFormatFactory</code>
053: * </p>
054: *
055: * @author Simone Giannecchini
056: * @deprecated use
057: * {@link org.geotools.coverage.grid.io.GridFormatFinder}
058: * instead.
059: */
060: public final class GridFormatFinder {
061: /**
062: * The service registry for this manager. Will be initialized only when
063: * first needed.
064: */
065: private static FactoryRegistry registry;
066:
067: /**
068: * Do not allows any instantiation of this class.
069: */
070: private GridFormatFinder() {
071: // singleton
072: }
073:
074: /**
075: * Finds all avalaible implementations of {@link GridFormatFactorySpi} which
076: * have registered using the services mechanism, and that have the
077: * appropriate libraries on the classpath.
078: *
079: * @return An unmodifiable {@link Set} of all discovered datastores which
080: * have registered factories, and whose available method returns
081: * true.
082: */
083: public static synchronized Set getAvailableFormats() {
084: // get all GridFormatFactorySpi implementations
085: Iterator it = getServiceRegistry().getServiceProviders(
086: GridFormatFactorySpi.class);
087: final Set formats = new HashSet(5);
088: GridFormatFactorySpi spi;
089: while (it.hasNext()) {
090: spi = (GridFormatFactorySpi) it.next();
091: if (spi.isAvailable())
092: formats.add(spi);
093:
094: }
095: return Collections.unmodifiableSet(formats);
096: }
097:
098: /**
099: * Returns the service registry. The registry will be created the first time
100: * this method is invoked.
101: */
102: private static FactoryRegistry getServiceRegistry() {
103: assert Thread.holdsLock(GridFormatFinder.class);
104: if (registry == null) {
105: registry = new FactoryCreator(Arrays
106: .asList(new Class[] { GridFormatFactorySpi.class }));
107: }
108: return registry;
109: }
110:
111: /**
112: * Scans for factory plug-ins on the application class path. This method is
113: * needed because the application class path can theoretically change, or
114: * additional plug-ins may become available. Rather than re-scanning the
115: * classpath on every invocation of the API, the class path is scanned
116: * automatically only on the first invocation. Clients can call this method
117: * to prompt a re-scan. Thus this method need only be invoked by
118: * sophisticated applications which dynamically make new plug-ins available
119: * at runtime.
120: */
121: public static synchronized void scanForPlugins() {
122:
123: getServiceRegistry().scanForPlugins();
124:
125: }
126:
127: /**
128: * Returns an array with all available {@link GridFormatFactorySpi}
129: * implementations.
130: *
131: * <p>
132: * It can be used toget basic information about all the available
133: * {@link GridCoverage} plugins. Note that this method finds all the
134: * implemented plugins but returns only the availaible one.
135: *
136: * <p>
137: * A plugin could be implemented but not availaible due to missing
138: * dependencies.
139: *
140: *
141: * @return an array with all available {@link GridFormatFactorySpi}
142: * implementations.
143: */
144: public static Format[] getFormatArray() {
145: GridFormatFactorySpi element;
146: Set formats = GridFormatFinder.getAvailableFormats();
147: List formatSet = new ArrayList(formats.size());
148: for (Iterator iter = formats.iterator(); iter.hasNext();) {
149: element = (GridFormatFactorySpi) iter.next();
150: formatSet.add(element.createFormat());
151: }
152: return (Format[]) formatSet
153: .toArray(new Format[formatSet.size()]);
154: }
155:
156: /**
157: * Returns all the {@link Format}s that can read the supplied
158: * {@link Object} o.
159: *
160: * @param o
161: * is the object to search a {@link Format} that is able to read
162: * @return an unmodifiable {@link Set} comprising all the {@link Format}
163: * that can read the {@link Object} o.
164: */
165: public static synchronized Set findFormats(Object o) {
166: final Set availaibleFormats = getAvailableFormats();
167: final Set formats = new HashSet();
168: final Iterator it = availaibleFormats.iterator();
169: Format retVal = null;
170: GridFormatFactorySpi spi = null;
171: while (it.hasNext()) {
172: // get the factory
173: spi = (GridFormatFactorySpi) it.next();
174: // create a format for it
175: retVal = spi.createFormat();
176: // check if we can accept it
177: if (retVal instanceof AbstractGridFormat) {
178: if (((AbstractGridFormat) retVal).accepts(o))
179: formats.add(retVal);
180: }
181:
182: }
183:
184: return Collections.unmodifiableSet(formats);
185: }
186:
187: /**
188: * Returns a {@link Format} that is able to read a certain object. If no
189: * {@link Format} is able to read such an {@link Object} we return an
190: * {@link UnknownFormat} object.
191: *
192: * <p>
193: * It is worth to point out that this method will try to convert each format
194: * implementation to {@link AbstractGridFormat} because the original
195: * {@link Format} interface did not allow for an accept method hence we had
196: * to subclass the interface to add such method and we did so by the
197: * {@link AbstractGridFormat} abstract class.
198: *
199: * @param o
200: * the object to check for acceptance.
201: * @return an {@link AbstractGridFormat} that has stated to accept this
202: * {@link Object} o or <code>null</code> in no plugins was able to
203: * accept it.
204: */
205: public static synchronized Format findFormat(Object o) {
206: final Set formats = findFormats(o);
207: final Iterator it = formats.iterator();
208: if (it.hasNext())
209: return (Format) it.next();
210: return new UnknownFormat();
211:
212: }
213: }
|