Revision 20308

View differences:

trunk/libraries/libGPE/src/org/gvsig/gpe/GPEFactory.java
2 2

  
3 3
import java.net.URI;
4 4
import java.util.ArrayList;
5
import java.util.HashSet;
5 6
import java.util.Iterator;
7
import java.util.Set;
6 8

  
9
import javax.xml.parsers.SAXParserFactory;
10

  
7 11
import org.gvsig.gpe.exceptions.GPEParserCreationException;
8 12
import org.gvsig.gpe.exceptions.GPEWriterHandlerCreationException;
9 13
import org.gvsig.gpe.parser.GPEParser;
......
108 112
 *
109 113
 */
110 114
/**
111
 * This class is used to register the GPE parsers. All the 
112
 * parsers must be registered in this class before to be
113
 * used for the consumer application
115
 * API entry point to create parsers and writers based on MIME-Type identification.
116
 * <p>
117
 * This factory uses a SPI (Service Provider Interface) mechanism to look up for {@link GPEParser}
118
 * and {@link IGPEWriterHandlerImplementor} implementations that can deal with a requested
119
 * MIME-Type.
120
 * </p>
121
 * <h2>Implementation Lookup</h2>
122
 * <p>
123
 * The SPI mechanism keeps parser implementations decoupled from client applications allowing the
124
 * transparent interchange of implementation, thus defining a format plugin system.
125
 * </p>
126
 * <p>
127
 * Parser and Writer implementations registers themselves lazily by providing a small configuration
128
 * file bundled together with the rest of the implementation resources. This configuration file
129
 * consist of a text file at a specific location and with an specific file name, this factory look
130
 * up mechanism will search for in order to find out the implementation class names.
131
 * </p>
132
 * <p>
133
 * To register a GPEParser implememntation, a file named <code>org.gvsig.gpe.parser.GPEParser</code>
134
 * shall exist in the class path (hence the ability to have multiple files equally namded budled in
135
 * different jar files), in the implementation's <code>META-INF/services</code> folder.
136
 * </p>
137
 * <p>
138
 * To register a Writer handler implementation, the same approach shall be followed with a file
139
 * named <code>META-INF/services/org.gvsig.gpe.writer.IGPEWriterHandlerImplementor</code>
140
 * </p>
141
 * <p>
142
 * The content of both files for a given implementation consists of full qualified class names, one
143
 * per line. For example, an hypotetical <code>MyFormatParser</code> in the package
144
 * <code>org.mycompany.gpe</code> and bundled in a jar file called <code>myformat.jar</code>
145
 * shall provide the following resources:
146
 * 
147
 * <pre>
148
 * <code>
149
 * $jar tvf myformat.jar
150
 * META-INF/services/org.gvsig.gpe.parser.GPEParser
151
 * org/mycompany/gpe/MyFormatParser.class
152
 * </code>
153
 * </pre>
154
 * 
155
 * And the content of the file <code>META-INF/services/org.gvsig.gpe.parser.GPEParser</code> shall
156
 * be a single line of text with the <code>org.mycompany.gpe.MyFormatParser</code> class name.
157
 * 
114 158
 * @author Jorge Piera LLodr? (jorge.piera@iver.es)
115 159
 * @author Carlos S?nchez Peri??n (sanchez_carper@gva.es)
116 160
 */
117 161
public class GPEFactory {
118 162

  
119
	/**
120
	 * @return all the registered parsers
121
	 */
122
	public static Iterator availableParsers(){
123
		Iterator providers = sun.misc.Service.providers(GPEParser.class);
124
		return providers;
125
	}	
163
    /**
164
     * Looks up the available parser implementations and returns the list of supported MIME-Type
165
     * identifiers.
166
     * 
167
     * @return the list of available parsing MIME types
168
     */
169
//    public static Set getAvailableParserTypes() {
170
//        Set mimeTypes = new HashSet();
171
//        Iterator availableParsers = availableParsers();
172
//        while(availableParsers.hasNext()){
173
//            GPEParser parser = (GPEParser) availableParsers.next();
174
//            mimeTypes.add(parser.getMimeType());
175
//        }
176
//        return mimeTypes;
177
//    }
178
//
179
//    public static Set getAvailableWriterTypes() {
180
//        throw new UnsupportedOperationException();
181
//    }
126 182

  
127
	public static GPEParser createParserByClass(String prefferredImplClassName) {
128
		Class prefferredImplClass = null;
129
		try {
130
			prefferredImplClass = Class.forName(prefferredImplClassName);
131
		} catch (ClassNotFoundException e) {
132
			return null;
133
		}
183
    /**
184
     * Returns an iterator over instances of the registered parsers.
185
     * <p>
186
     * NOTE: since GPEParser is an abstract and statefull class rather than an interface, this
187
     * method shall stay private in order to ensure we return a new instance for the required format
188
     * every time.
189
     * </p>
190
     * 
191
     * @return all the registered parsers
192
     */
193
    private static Iterator availableParsers() {
194
        Iterator providers = sun.misc.Service.providers(GPEParser.class);
195
        return providers;
196
    }
134 197

  
135
		Iterator providers = availableParsers();
136
		while (providers.hasNext()) {
137
			GPEParser next = (GPEParser)providers.next();
138
			if (prefferredImplClass.isInstance(next)) {
139
				return next;
140
			}
141
		}	        
142
		return null;
143
	}
198
    /**
199
     * Returns an iterator over instances of the registered writers.
200
     * <p>
201
     * NOTE: since GPEWriter is an abstract and statefull class rather than an interface, this
202
     * method shall stay private in order to ensure we return a new instance for the required format
203
     * every time.
204
     * </p>
205
     * 
206
     * @return all the registered writers
207
     */
208
    private static Iterator availableWriters() {
209
        Iterator providers = sun.misc.Service.providers(IGPEWriterHandlerImplementor.class);
210
        return providers;
211
    }
144 212

  
145
	/**
146
	 * Create a new parser from a name
147
	 * @param name
148
	 * GPEParser name
149
	 * @param contenHandler
150
	 * Application contenHandler usett to throw the parsing events
151
	 * @param errorHandler
152
	 * Application errror handler used to put errors and warnings
153
	 * @throws GPEParserCreationException 
154
	 */
155
	public static GPEParser createParser(String name) throws GPEParserCreationException {
156
		Iterator providers = availableParsers();
157
		if (providers.hasNext()) {
158
			GPEParser parser = (GPEParser)providers.next();
159
			if (parser.getName().compareTo(name) == 0){
160
				return parser;	
161
			}
162
		}
163
		return null;
164
	}
213
    public static GPEParser createParserByClass(String prefferredImplClassName) {
214
        Class prefferredImplClass = null;
215
        try {
216
            prefferredImplClass = Class.forName(prefferredImplClassName);
217
        } catch (ClassNotFoundException e) {
218
            return null;
219
        }
165 220

  
166
	/**
167
	 * Gets the parser that can open the file (if it exists)
168
	 * @param uri
169
	 * File to open
170
	 * @return
171
	 * Null if the driver doesn't exist
172
	 * @throws GPEParserCreationException 
173
	 * @throws SecurityException 
174
	 * @throws IllegalArgumentException 
175
	 */
176
	public static GPEParser createParser(URI uri) throws GPEParserCreationException {
177
		Iterator providers = availableParsers();
178
		if (providers.hasNext()) {
179
			GPEParser parser = (GPEParser)providers.next();
180
			if (parser.accept(uri)){
181
				return parser;
182
			}
183
		}
184
		return null;
185
	}
221
        Iterator providers = availableParsers();
222
        while (providers.hasNext()) {
223
            GPEParser next = (GPEParser) providers.next();
224
            if (prefferredImplClass.isInstance(next)) {
225
                return next;
226
            }
227
        }
228
        return null;
229
    }
186 230

  
187
	public static Iterator availableWriters() {
188
		Iterator providers = sun.misc.Service.providers(IGPEWriterHandlerImplementor.class);
189
		return providers;
190
	}
231
    /**
232
     * Create a new parser from a name
233
     * 
234
     * @param name GPEParser name
235
     * @param contenHandler Application contenHandler usett to throw the parsing events
236
     * @param errorHandler Application errror handler used to put errors and warnings
237
     * @throws GPEParserCreationException
238
     */
239
    public static GPEParser createParser(String name) throws GPEParserCreationException {
240
        Iterator providers = availableParsers();
241
        if (providers.hasNext()) {
242
            GPEParser parser = (GPEParser) providers.next();
243
            if (parser.getName().compareTo(name) == 0) {
244
                return parser;
245
            }
246
        }
247
        return null;
248
    }
191 249

  
192
	/**
193
	 * Create a new content writer from a name
194
	 * @param name
195
	 * GPEWriterHandler name
196
	 * GPEParser name
197
	 * @param contenHandler
198
	 * Application contenHandler usett to throw the parsing events
199
	 * @param errorHandler
200
	 * Application errror handler used to put errors and warnings
201
	 * @throws GPEWriterHandlerCreationException 	
202
	 */
203
	public static GPEWriterHandler createWriter(String name) throws GPEWriterHandlerCreationException{
204
		Iterator providers = availableWriters();
205
		if (providers.hasNext()) {
206
			IGPEWriterHandlerImplementor implementor = (IGPEWriterHandlerImplementor)providers.next();
207
			if (implementor.getName().compareTo(name) == 0){
208
				new GPEWriterHandler(implementor);				
209
			}
210
		}
211
		return null;
212
	}
213
	
214
	public static GPEWriterHandler createWriterByClass(String prefferredImplClassName) {
250
    /**
251
     * Gets the parser that can open the file (if it exists)
252
     * 
253
     * @param uri File to open
254
     * @return Null if the driver doesn't exist
255
     * @throws GPEParserCreationException
256
     * @throws SecurityException
257
     * @throws IllegalArgumentException
258
     */
259
    public static GPEParser createParser(URI uri) throws GPEParserCreationException {
260
        Iterator providers = availableParsers();
261
        if (providers.hasNext()) {
262
            GPEParser parser = (GPEParser) providers.next();
263
            if (parser.accept(uri)) {
264
                return parser;
265
            }
266
        }
267
        return null;
268
    }
269

  
270
    /**
271
     * Create a new content writer from a name
272
     * 
273
     * @param name GPEWriterHandler name GPEParser name
274
     * @param contenHandler Application contenHandler usett to throw the parsing events
275
     * @param errorHandler Application errror handler used to put errors and warnings
276
     * @throws GPEWriterHandlerCreationException
277
     */
278
    public static GPEWriterHandler createWriter(String name)
279
            throws GPEWriterHandlerCreationException {
280
        Iterator providers = availableWriters();
281
        if (providers.hasNext()) {
282
            IGPEWriterHandlerImplementor implementor = (IGPEWriterHandlerImplementor) providers
283
                    .next();
284
            if (implementor.getName().compareTo(name) == 0) {
285
                new GPEWriterHandler(implementor);
286
            }
287
        }
288
        return null;
289
    }
290

  
291
    public static GPEWriterHandler createWriterByClass(String prefferredImplClassName) {
215 292
        Class prefferredImplClass = null;
216 293
        try {
217 294
            prefferredImplClass = Class.forName(prefferredImplClassName);
......
221 298

  
222 299
        Iterator providers = availableWriters();
223 300
        while (providers.hasNext()) {
224
            IGPEWriterHandlerImplementor next = (IGPEWriterHandlerImplementor)providers.next();
301
            IGPEWriterHandlerImplementor next = (IGPEWriterHandlerImplementor) providers.next();
225 302
            if (prefferredImplClass.isInstance(next)) {
226 303
                return new GPEWriterHandler(next);
227 304
            }
228
        }	        
305
        }
229 306
        return null;
230 307
    }
231 308

  
232
	/**
233
	 * Gets all the writers that can 
234
	 * @param format
235
	 * @return
236
	 */
237
	public static ArrayList getWriterHandlerByFormat(String format){
238
		Iterator providers = availableWriters();
239
		ArrayList possibleWriters = new ArrayList();
240
		if (providers.hasNext()) {
241
			IGPEWriterHandlerImplementor implementor = (IGPEWriterHandlerImplementor)providers.next();
242
			String[] formats = implementor.getFormats();
243
			for (int i=0 ; i<formats.length ; i++){
244
				if (formats[i].toLowerCase().compareTo(format.toLowerCase()) == 0){
245
					possibleWriters.add(new GPEWriterHandler(implementor));
246
				}
247
			}
248
		}
249
		return possibleWriters;
250
	}
309
    /**
310
     * Gets all the writers that can
311
     * 
312
     * @param format
313
     * @return
314
     */
315
    public static ArrayList getWriterHandlerByFormat(String format) {
316
        Iterator providers = availableWriters();
317
        ArrayList possibleWriters = new ArrayList();
318
        if (providers.hasNext()) {
319
            IGPEWriterHandlerImplementor implementor = (IGPEWriterHandlerImplementor) providers
320
                    .next();
321
            String[] formats = implementor.getFormats();
322
            for (int i = 0; i < formats.length; i++) {
323
                if (formats[i].toLowerCase().compareTo(format.toLowerCase()) == 0) {
324
                    possibleWriters.add(new GPEWriterHandler(implementor));
325
                }
326
            }
327
        }
328
        return possibleWriters;
329
    }
251 330

  
252
	/**
253
	 * Return true if exists a driver that can open the file
254
	 * @param uri
255
	 * File to open
256
	 * @return
257
	 * true if the driver exists
258
	 */
259
	public static boolean accept(URI uri){
260
		Iterator providers = availableParsers();
261
		if (providers.hasNext()) {
262
			GPEParser parser = (GPEParser)providers.next();
263
			if (parser.accept(uri)){
264
				return true;
265
			}
266
		}
267
		return false;
268
	}
331
    /**
332
     * Return true if exists a driver that can open the file
333
     * 
334
     * @param uri File to open
335
     * @return true if the driver exists
336
     */
337
    public static boolean accept(URI uri) {
338
        Iterator providers = availableParsers();
339
        if (providers.hasNext()) {
340
            GPEParser parser = (GPEParser) providers.next();
341
            if (parser.accept(uri)) {
342
                return true;
343
            }
344
        }
345
        return false;
346
    }
269 347
}

Also available in: Unified diff