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