001: //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/trunk/src/org/deegree/model/coverage/grid/GridCoverageExchange.java $
002: /*---------------- FILE HEADER ------------------------------------------
003:
004: This file is part of deegree
005: Copyright (C) 2001-2008 by:
006: EXSE, Department of Geography, University of Bonn
007: http://www.giub.uni-bonn.de/deegree/
008: lat/lon GmbH
009: http://www.lat-lon.de
010:
011: This library is free software; you can redistribute it and/or
012: modify it under the terms of the GNU Lesser General Public
013: License as published by the Free Software Foundation; either
014: version 2.1 of the License, or (at your option) any later version.
015:
016: This library is distributed in the hope that it will be useful,
017: but WITHOUT ANY WARRANTY; without even the implied warranty of
018: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
019: Lesser General Public License for more details.
020:
021: You should have received a copy of the GNU Lesser General Public
022: License along with this library; if not, write to the Free Software
023: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
024:
025: Contact:
026:
027: Andreas Poth
028: lat/lon GmbH
029: Aennchenstr. 19
030: 53115 Bonn
031: Germany
032: E-Mail: poth@lat-lon.de
033:
034: Klaus Greve
035: Department of Geography
036: University of Bonn
037: Meckenheimer Allee 166
038: 53115 Bonn
039: Germany
040: E-Mail: klaus.greve@giub.uni-bonn.de
041:
042: ---------------------------------------------------------------------------*/
043: package org.deegree.model.coverage.grid;
044:
045: import java.io.IOException;
046: import java.io.InputStream;
047: import java.net.URI;
048: import java.util.ArrayList;
049: import java.util.HashMap;
050: import java.util.List;
051: import java.util.Map;
052:
053: import org.deegree.datatypes.CodeList;
054: import org.deegree.datatypes.QualifiedName;
055: import org.deegree.framework.log.ILogger;
056: import org.deegree.framework.log.LoggerFactory;
057: import org.deegree.framework.util.ConvenienceFileFilter;
058: import org.deegree.framework.util.StringTools;
059: import org.deegree.io.shpapi.ShapeFile;
060: import org.deegree.model.crs.CRSFactory;
061: import org.deegree.model.crs.CoordinateSystem;
062: import org.deegree.model.crs.UnknownCRSException;
063: import org.deegree.model.feature.Feature;
064: import org.deegree.model.spatialschema.Envelope;
065: import org.deegree.model.spatialschema.Geometry;
066: import org.deegree.model.spatialschema.GeometryFactory;
067: import org.deegree.ogcbase.CommonNamespaces;
068: import org.deegree.ogcwebservices.InvalidParameterValueException;
069: import org.deegree.ogcwebservices.wcs.configuration.Directory;
070: import org.deegree.ogcwebservices.wcs.configuration.Extension;
071: import org.deegree.ogcwebservices.wcs.configuration.File;
072: import org.deegree.ogcwebservices.wcs.configuration.GridDirectory;
073: import org.deegree.ogcwebservices.wcs.configuration.Shape;
074: import org.deegree.ogcwebservices.wcs.describecoverage.CoverageOffering;
075:
076: /**
077: * Support for creation of grid coverages from persistent formats as well as exporting a grid
078: * coverage to a persistent formats. For example, it allows for creation of grid coverages from the
079: * GeoTIFF Well-known binary format and exporting to the GeoTIFF file format. Basic implementations
080: * only require creation of grid coverages from a file format or resource. More sophesticated
081: * implementations may extract the grid coverages from a database. In such case, a
082: * <code>GridCoverageExchange</code> instance will hold a connection to a specific database and
083: * the {@link #dispose} method will need to be invoked in order to close this connection.
084: * <p>
085: *
086: * @author Andreas Poth
087: * @version 1.0
088: * @since 2.0
089: */
090: public class GridCoverageExchange {
091:
092: private static final ILogger LOG = LoggerFactory
093: .getLogger(GridCoverageExchange.class);
094:
095: private static final URI DEEGREEAPP = CommonNamespaces
096: .buildNSURI("http://www.deegree.org/app");
097:
098: private static final String APP_PREFIX = "app";
099:
100: public static final String SHAPE_IMAGE_FILENAME = "FILENAME";
101:
102: public static final String SHAPE_DIR_NAME = "FOLDER";
103:
104: private CoverageOffering coverageOffering;
105:
106: /**
107: * @param formats
108: */
109: public GridCoverageExchange(CoverageOffering coverageOffering) {
110: this .coverageOffering = coverageOffering;
111: }
112:
113: /**
114: * Returns a grid coverage reader that can manage the specified source
115: *
116: * @param source
117: * An object that specifies somehow the data source. Can be a
118: * {@link java.lang.String}, an {@link java.io.InputStream}, a
119: * {@link java.nio.channels.FileChannel}, whatever. It's up to the associated grid
120: * coverage reader to make meaningful use of it.
121: * @return The grid coverage reader.
122: * @throws IOException
123: * if an error occurs during reading.
124: *
125: * @revisit We need a mechanism to allow the right GridCoverageReader Something like an SPI.
126: * What if we can't find a GridCoverageReader? Do we return null or throw an Exception?
127: */
128: public GridCoverageReader getReader(Object source)
129: throws IOException {
130: if (!(source instanceof InputStream)) {
131: throw new IOException(
132: "source parameter must be an instance of InputStream");
133: }
134: return null;
135: }
136:
137: /**
138: * This method is a deegree specific enhancement of the <tt>GridCoverageExchange</tt>
139: * class/interface as defined by GeoAPI. Returns a grid coverage reader that can manage the
140: * specified source
141: *
142: * @param source
143: * An object that specifies somehow the data source.
144: * @param description
145: * an object describing the grid coverage and the access to avaiable metadata
146: * @param envelope
147: * @param format
148: * @return The grid coverage reader.
149: * @throws IOException
150: * if an error occurs during reading.
151: *
152: * @revisit We need a mechanism to allow the right GridCoverageReader Something like an SPI.
153: * What if we can't find a GridCoverageReader? Do we return null or throw an Exception?
154: */
155: public GridCoverageReader getReader(InputStream source,
156: CoverageOffering description, Envelope envelope,
157: Format format) throws IOException {
158: GridCoverageReader gcr = null;
159: Extension ext = description.getExtension();
160: String type = ext.getType();
161: if (type.equals(Extension.FILEBASED)) {
162: if (format.getName().toUpperCase().indexOf("GEOTIFF") > -1) {
163: gcr = new GeoTIFFGridCoverageReader(source,
164: description, envelope, format);
165: } else if (isImageFormat(format)) {
166: gcr = new ImageGridCoverageReader(source, description,
167: envelope, format);
168: } else {
169: throw new IOException("not supported file format: "
170: + format.getName());
171: }
172: } else {
173: throw new IOException(
174: "coverage storage type: "
175: + type
176: + " is not supported with method: getReader(InputStream, "
177: + "CoverageOffering, Envelope, Format )");
178: }
179: return gcr;
180: }
181:
182: /**
183: * This method is a deegree specific enhancement of the <tt>GridCoverageExchange</tt>
184: * class/interface as defined by GeoAPI. Returns a grid coverage reader that can manage the
185: * specified source
186: *
187: * @param resource
188: * a string that specifies somehow the data source (e.g. a file).
189: * @param description
190: * an object describing the grid coverage and the access to avaiable metadata
191: * @param envelope
192: * @param format
193: *
194: * @return The grid coverage reader.
195: * @throws IOException
196: * if an error occurs during reading.
197: *
198: * @revisit We need a mechanism to allow the right GridCoverageReader Something like an SPI.
199: * What if we can't find a GridCoverageReader? Do we return null or throw an Exception?
200: */
201: public GridCoverageReader getReader(Object resource,
202: CoverageOffering description, Envelope envelope,
203: Format format) throws IOException,
204: InvalidParameterValueException {
205: GridCoverageReader gcr = null;
206: Extension ext = description.getExtension();
207: String type = ext.getType();
208: if (type.equals(Extension.FILEBASED)) {
209: File file = new File(null, (String) resource, envelope);
210: if (format.getName().toUpperCase().indexOf("GEOTIFF") > -1) {
211: LOG.logDebug("creating GeoTIFFGridCoverageReader");
212: gcr = new GeoTIFFGridCoverageReader(file, description,
213: envelope, format);
214: } else if (isImageFormat(format)) {
215: LOG.logDebug("creating ImageGridCoverageReader");
216: gcr = new ImageGridCoverageReader(file, description,
217: envelope, format);
218: } else {
219: throw new IOException("not supported file format: "
220: + format.getName());
221: }
222: } else if (type.equals(Extension.NAMEINDEXED)) {
223: LOG
224: .logDebug("creating nameIndexed CompoundGridCoverageReader");
225: Directory[] dirs = new Directory[] { (Directory) resource };
226: gcr = getReader(dirs, description, envelope, format);
227: } else if (type.equals(Extension.SHAPEINDEXED)) {
228: LOG
229: .logDebug("creating shapeIndexed CompoundGridCoverageReader");
230: File[] files = null;
231: try {
232: files = getFilesFromShape((Shape) resource, envelope,
233: description);
234: } catch (UnknownCRSException e) {
235: throw new InvalidParameterValueException(e);
236: }
237: if (LOG.getLevel() == ILogger.LOG_DEBUG) {
238: for (int i = 0; i < files.length; i++) {
239: LOG.logDebug("matching tile: ", files[i].getName());
240: }
241: }
242: gcr = getReader(files, description, envelope, format);
243: } else if (type.equals(Extension.ORACLEGEORASTER)) {
244: LOG.logDebug("creating OracleGeoRasterGridCoverageReader");
245: Class clzz;
246: try {
247: clzz = Class
248: .forName("org.deegree.model.coverage.grid.oracle.GeoRasterReaderAccess");
249: } catch (ClassNotFoundException e) {
250: LOG.logError(e.getMessage(), e);
251: throw new InvalidParameterValueException(e);
252: }
253: GCReaderAccess acc;
254: try {
255: acc = (GCReaderAccess) clzz.newInstance();
256: } catch (InstantiationException e) {
257: LOG.logError(e.getMessage(), e);
258: throw new InvalidParameterValueException(e);
259: } catch (IllegalAccessException e) {
260: LOG.logError(e.getMessage(), e);
261: throw new InvalidParameterValueException(e);
262: }
263: gcr = acc.createGridCoverageReader(resource, description,
264: envelope, format);
265: } else if (type.equals(Extension.DATABASEINDEXED)) {
266: LOG
267: .logDebug("creating databaseIndexed CompoundGridCoverageReader");
268: File[] files = null;
269: try {
270: files = getFilesFromDatabase(
271: (DatabaseIndexedGCMetadata) resource, envelope,
272: description);
273: } catch (UnknownCRSException e) {
274: LOG.logError(e.getMessage(), e);
275: throw new InvalidParameterValueException(e);
276: }
277: if (LOG.getLevel() == ILogger.LOG_DEBUG) {
278: for (int i = 0; i < files.length; i++) {
279: LOG.logDebug("matching tile: ", files[i].getName());
280: }
281: }
282: gcr = new CompoundGridCoverageReader(files, description,
283: envelope, format);
284: } else {
285: throw new IOException("coverage storage type: " + type
286: + " is not supported");
287: }
288: return gcr;
289: }
290:
291: /**
292: * reads the names of the grid coverage files intersecting the requested region from the passed
293: * database.
294: *
295: * @param dbigcmd
296: * @param envelope
297: * @param description
298: * @return file list
299: * @throws UnknownCRSException
300: * @throws InvalidParameterValueException
301: */
302: private File[] getFilesFromDatabase(
303: DatabaseIndexedGCMetadata dbigcmd, Envelope envelope,
304: CoverageOffering description) throws UnknownCRSException,
305: InvalidParameterValueException {
306:
307: CoordinateSystem crs = createNativeCRS(description);
308:
309: String className = null;
310: if (dbigcmd.getJDBCConnection().getDriver().toUpperCase()
311: .indexOf("ORACLE") > -1) {
312: className = DatabaseIndexAccessMessages.getString("oracle");
313: } else if (dbigcmd.getJDBCConnection().getDriver()
314: .toUpperCase().indexOf("POSTGRES") > -1) {
315: className = DatabaseIndexAccessMessages
316: .getString("postgres");
317: }
318: Class clzz;
319: try {
320: clzz = Class.forName(className);
321: } catch (ClassNotFoundException e) {
322: LOG.logError(e.getMessage(), e);
323: throw new InvalidParameterValueException(className, e);
324: }
325: DatabaseIndexAccess dbia;
326: try {
327: dbia = (DatabaseIndexAccess) clzz.newInstance();
328: } catch (InstantiationException e) {
329: LOG.logError(e.getMessage(), e);
330: throw new InvalidParameterValueException(className, e);
331: } catch (IllegalAccessException e) {
332: LOG.logError(e.getMessage(), e);
333: throw new InvalidParameterValueException(className, e);
334: }
335:
336: return dbia.getFiles(dbigcmd, envelope, crs);
337: }
338:
339: /**
340: * This method is a deegree specific enhancement of the <tt>GridCoverageExchange</tt>
341: * class/interface as defined by GeoAPI. Returns a grid coverage reader that can manage the
342: * specified source
343: *
344: * @param resources
345: * an array strings that specifies somehow the data sources (e.g. some files).
346: * @param description
347: * an object describing the grid coverage and the access to avaiable metadata
348: * @param envelope
349: * @return The grid coverage reader.
350: * @throws IOException
351: * if an error occurs during reading.
352: *
353: * @revisit We need a mechanism to allow the right GridCoverageReader Something like an SPI.
354: * What if we can't find a GridCoverageReader? Do we return null or throw an Exception?
355: */
356: public GridCoverageReader getReader(Object[] resources,
357: CoverageOffering description, Envelope envelope,
358: Format format) throws IOException,
359: InvalidParameterValueException {
360:
361: // CS_CoordinateSystem crs = createNativeCRS( description );
362: GridCoverageReader gcr = null;
363: Extension ext = description.getExtension();
364: String type = ext.getType();
365: File[] files = null;
366: if (type.equals(Extension.FILEBASED)) {
367: LOG
368: .logDebug("creating filebased CompoundGridCoverageReader");
369: files = (File[]) resources;
370: gcr = new CompoundGridCoverageReader(files, description,
371: envelope, format);
372: } else if (type.equals(Extension.NAMEINDEXED)) {
373: LOG
374: .logDebug("creating nameIndexed CompoundGridCoverageReader");
375: try {
376: files = getFilesFromDirectories(
377: (Directory[]) resources, envelope, description);
378: } catch (UnknownCRSException e) {
379: throw new InvalidParameterValueException(e);
380: }
381: gcr = new CompoundGridCoverageReader(files, description,
382: envelope, format);
383: } else if (type.equals(Extension.SHAPEINDEXED)) {
384: LOG
385: .logDebug("creating shapeIndexed CompoundGridCoverageReader");
386: files = (File[]) resources;
387: gcr = new CompoundGridCoverageReader(files, description,
388: envelope, format);
389: } else if (type.equals(Extension.ORACLEGEORASTER)) {
390: LOG.logDebug("creating OracleGeoRasterGridCoverageReader");
391: Class clzz;
392: try {
393: clzz = Class
394: .forName("org.deegree.model.coverage.grid.oracle.GeoRasterReaderAccess");
395: } catch (ClassNotFoundException e) {
396: LOG.logError(e.getMessage(), e);
397: throw new InvalidParameterValueException(e);
398: }
399: GCReaderAccess acc;
400: try {
401: acc = (GCReaderAccess) clzz.newInstance();
402: } catch (InstantiationException e) {
403: LOG.logError(e.getMessage(), e);
404: throw new InvalidParameterValueException(e);
405: } catch (IllegalAccessException e) {
406: LOG.logError(e.getMessage(), e);
407: throw new InvalidParameterValueException(e);
408: }
409: gcr = acc.createGridCoverageReader(resources[0],
410: description, envelope, format);
411: } else {
412: throw new IOException("coverage storage type: " + type
413: + " is not supported");
414: }
415:
416: return gcr;
417: }
418:
419: /**
420: * returns true if the passed format is an image format
421: *
422: * @param format
423: * @return <code>true</code> if the passed format is an image format
424: */
425: private boolean isImageFormat(Format format) {
426: String frmt = format.getName().toUpperCase();
427: return frmt.equalsIgnoreCase("png")
428: || frmt.equalsIgnoreCase("bmp")
429: || frmt.equalsIgnoreCase("tif")
430: || frmt.equalsIgnoreCase("tiff")
431: || frmt.equalsIgnoreCase("gif")
432: || frmt.equalsIgnoreCase("jpg")
433: || frmt.equalsIgnoreCase("jpeg")
434: || frmt.indexOf("ECW") > -1;
435: }
436:
437: /**
438: * reads the names of the grid coverage files intersecting the requested region from the passed
439: * shape (name).
440: *
441: * @param shape
442: * @param envelope
443: * requested envelope
444: * @param description
445: * description (metadata) of the source coverage
446: * @return file list
447: * @throws IOException
448: * @throws UnknownCRSException
449: */
450: private File[] getFilesFromShape(Shape shape, Envelope envelope,
451: CoverageOffering description) throws IOException,
452: UnknownCRSException {
453:
454: CoordinateSystem crs = createNativeCRS(description);
455:
456: String shapeBaseName = StringTools.replace(shape
457: .getRootFileName(), "\\", "/", true);
458: String shapeDir = shapeBaseName.substring(0, shapeBaseName
459: .lastIndexOf("/") + 1);
460:
461: ShapeFile shp = new ShapeFile(shapeBaseName);
462: File[] files = null;
463: int[] idx = shp.getGeoNumbersByRect(envelope);
464: if (idx != null) {
465: files = new File[idx.length];
466: try {
467: for (int i = 0; i < files.length; i++) {
468: Feature feature = shp.getFeatureByRecNo(idx[i]);
469: QualifiedName qn = new QualifiedName(APP_PREFIX,
470: SHAPE_IMAGE_FILENAME, DEEGREEAPP);
471: String img = (String) feature
472: .getDefaultProperty(qn).getValue();
473: qn = new QualifiedName(APP_PREFIX, SHAPE_DIR_NAME,
474: DEEGREEAPP);
475: String dir = (String) feature
476: .getDefaultProperty(qn).getValue();
477: if (!(new java.io.File(dir).isAbsolute())) {
478: // solve relative path; it is assumed that the tile directories
479: // are located in the same directory as the shape file
480: dir = shapeDir + dir;
481: }
482: Geometry geom = feature.getGeometryPropertyValues()[0];
483: Envelope env = geom.getEnvelope();
484: env = GeometryFactory.createEnvelope(env.getMin(),
485: env.getMax(), crs);
486: files[i] = new File(crs, dir
487: .concat("/".concat(img)), env);
488: }
489: } catch (Exception e) {
490: shp.close();
491: LOG.logError(e.getMessage(), e);
492: throw new IOException(e.getMessage());
493: }
494: } else {
495: files = new File[0];
496: }
497: shp.close();
498:
499: return files;
500:
501: }
502:
503: /**
504: * reads the names of the grid coverage files intersecting the requested region from raster data
505: * files contained in the passed directories
506: *
507: * @param directories
508: * list of directories searched for matching raster files
509: * @param envelope
510: * requested envelope
511: * @param description
512: * description (metadata) of the source coverage
513: * @return list of files intersecting the requested envelope
514: * @throws UnknownCRSException
515: * @throws IOException
516: */
517: private File[] getFilesFromDirectories(Directory[] directories,
518: Envelope envelope, CoverageOffering description)
519: throws UnknownCRSException {
520:
521: CoordinateSystem crs = createNativeCRS(description);
522:
523: List<File> list = new ArrayList<File>(1000);
524:
525: for (int i = 0; i < directories.length; i++) {
526:
527: double widthCRS = ((GridDirectory) directories[i])
528: .getTileWidth();
529: double heightCRS = ((GridDirectory) directories[i])
530: .getTileHeight();
531: String[] extensions = directories[i].getFileExtensions();
532: String dirName = directories[i].getName();
533:
534: ConvenienceFileFilter fileFilter = new ConvenienceFileFilter(
535: false, extensions);
536: java.io.File iofile = new java.io.File(dirName);
537: String[] tiles = iofile.list(fileFilter);
538: for (int j = 0; j < tiles.length; j++) {
539: int pos1 = tiles[j].indexOf('_');
540: int pos2 = tiles[j].lastIndexOf('.');
541: String tmp = tiles[j].substring(0, pos1);
542: double x1 = Double.parseDouble(tmp) / 1000d;
543: tmp = tiles[j].substring(pos1 + 1, pos2);
544: double y1 = Double.parseDouble(tmp) / 1000d;
545: Envelope env = GeometryFactory.createEnvelope(x1, y1,
546: x1 + widthCRS, y1 + heightCRS, crs);
547: if (env.intersects(envelope)) {
548: File file = new File(crs, dirName + '/' + tiles[j],
549: env);
550: list.add(file);
551: }
552: }
553:
554: }
555:
556: File[] files = list.toArray(new File[list.size()]);
557:
558: return files;
559: }
560:
561: /**
562: * creates an instance of <tt>CS_CoordinateSystem</tt> from the name of the native CRS of the
563: * grid coverage
564: *
565: * @param description
566: * @return
567: * @throws UnknownCRSException
568: */
569: private CoordinateSystem createNativeCRS(
570: CoverageOffering description) throws UnknownCRSException {
571: String srs = description.getSupportedCRSs().getNativeSRSs()[0]
572: .getCodes()[0];
573:
574: return CRSFactory.create(srs);
575: }
576:
577: /**
578: * Returns a GridCoverageWriter that can write the specified format. The file format name is
579: * determined from the {@link Format} interface. Sample file formats include:
580: *
581: * <blockquote><table>
582: * <tr>
583: * <td>"GeoTIFF"</td>
584: * <td> - GeoTIFF</td>
585: * </tr>
586: * <tr>
587: * <td>"PIX"</td>
588: * <td> - PCI Geomatics PIX</td>
589: * </tr>
590: * <tr>
591: * <td>"HDF-EOS"</td>
592: * <td> - NASA HDF-EOS</td>
593: * </tr>
594: * <tr>
595: * <td>"NITF"</td>
596: * <td> - National Image Transfer Format</td>
597: * </tr>
598: * <tr>
599: * <td>"STDS-DEM"</td>
600: * <td> - Standard Transfer Data Standard</td>
601: * </tr>
602: * </table></blockquote>
603: *
604: * @param destination
605: * An object that specifies somehow the data destination. Can be a
606: * {@link java.lang.String}, an {@link java.io.OutputStream}, a
607: * {@link java.nio.channels.FileChannel}, whatever. It's up to the associated grid
608: * coverage writer to make meaningful use of it.
609: * @param format
610: * the output format.
611: * @return The grid coverage writer.
612: * @throws IOException
613: * if an error occurs during reading.
614: */
615: public GridCoverageWriter getWriter(Object destination,
616: Format format) throws IOException {
617:
618: LOG.logDebug("requested format: ", format.getName());
619:
620: GridCoverageWriter gcw = null;
621:
622: if (!isKnownFormat(format)) {
623: throw new IOException("not supported Format: " + format);
624: }
625:
626: Map<String, Object> metadata = new HashMap<String, Object>();
627: metadata.put("offset", coverageOffering.getExtension()
628: .getOffset());
629: metadata.put("scaleFactor", coverageOffering.getExtension()
630: .getScaleFactor());
631: if (format.getName().equalsIgnoreCase("GEOTIFF")) {
632: gcw = new GeoTIFFGridCoverageWriter(destination, metadata,
633: null, null, format);
634: } else if (isImageFormat(format)) {
635: gcw = new ImageGridCoverageWriter(destination, metadata,
636: null, null, format);
637: } else if (format.getName().equalsIgnoreCase("GML")
638: || format.getName().equalsIgnoreCase("GML2")
639: || format.getName().equalsIgnoreCase("GML3")) {
640: gcw = new GMLGridCoverageWriter(destination, metadata,
641: null, null, format);
642: } else if (format.getName().equalsIgnoreCase("XYZ")) {
643: gcw = new XYZGridCoverageWriter(destination, metadata,
644: null, null, format);
645: } else {
646: throw new IOException("not supported Format: " + format);
647: }
648:
649: return gcw;
650: }
651:
652: /**
653: * validates if a passed format is known to an instance of <tt>GridCoverageExchange</tt>
654: *
655: * @param format
656: * @return <code>true</code> if the format is known, <code>false</code> otherwise.
657: */
658: private boolean isKnownFormat(Format format) {
659: CodeList[] codeList = coverageOffering.getSupportedFormats()
660: .getFormats();
661: for (int i = 0; i < codeList.length; i++) {
662: String[] codes = codeList[i].getCodes();
663: for (int j = 0; j < codes.length; j++) {
664: if (format.getName().equalsIgnoreCase(codes[j])) {
665: return true;
666: }
667: }
668: }
669: LOG.logDebug(format.getName() + " not supported");
670: return false;
671: }
672:
673: }
|