001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/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.getLogger( GridCoverageExchange.class ); 093 094 private static final URI DEEGREEAPP = CommonNamespaces.buildNSURI( "http://www.deegree.org/app" ); 095 096 private static final String APP_PREFIX = "app"; 097 098 public static final String SHAPE_IMAGE_FILENAME = "FILENAME"; 099 100 public static final String SHAPE_DIR_NAME = "FOLDER"; 101 102 private CoverageOffering coverageOffering; 103 104 /** 105 * @param formats 106 */ 107 public GridCoverageExchange( CoverageOffering coverageOffering ) { 108 this.coverageOffering = coverageOffering; 109 } 110 111 /** 112 * Returns a grid coverage reader that can manage the specified source 113 * 114 * @param source 115 * An object that specifies somehow the data source. Can be a 116 * {@link java.lang.String}, an {@link java.io.InputStream}, a 117 * {@link java.nio.channels.FileChannel}, whatever. It's up to the associated grid 118 * coverage reader to make meaningful use of it. 119 * @return The grid coverage reader. 120 * @throws IOException 121 * if an error occurs during reading. 122 * 123 * @revisit We need a mechanism to allow the right GridCoverageReader Something like an SPI. 124 * What if we can't find a GridCoverageReader? Do we return null or throw an Exception? 125 */ 126 public GridCoverageReader getReader( Object source ) 127 throws IOException { 128 if ( !( source instanceof InputStream ) ) { 129 throw new IOException( "source parameter must be an instance of InputStream" ); 130 } 131 return null; 132 } 133 134 /** 135 * This method is a deegree specific enhancement of the <tt>GridCoverageExchange</tt> 136 * class/interface as defined by GeoAPI. Returns a grid coverage reader that can manage the 137 * specified source 138 * 139 * @param source 140 * An object that specifies somehow the data source. 141 * @param description 142 * an object describing the grid coverage and the access to avaiable metadata 143 * @param envelope 144 * @param format 145 * @return The grid coverage reader. 146 * @throws IOException 147 * if an error occurs during reading. 148 * 149 * @revisit We need a mechanism to allow the right GridCoverageReader Something like an SPI. 150 * What if we can't find a GridCoverageReader? Do we return null or throw an Exception? 151 */ 152 public GridCoverageReader getReader( InputStream source, CoverageOffering description, Envelope envelope, 153 Format format ) 154 throws IOException { 155 GridCoverageReader gcr = null; 156 Extension ext = description.getExtension(); 157 String type = ext.getType(); 158 if ( type.equals( Extension.FILEBASED ) ) { 159 if ( format.getName().toUpperCase().indexOf( "GEOTIFF" ) > -1 ) { 160 gcr = new GeoTIFFGridCoverageReader( source, description, envelope, format ); 161 } else if ( isImageFormat( format ) ) { 162 gcr = new ImageGridCoverageReader( source, description, envelope, format ); 163 } else { 164 throw new IOException( "not supported file format: " + format.getName() ); 165 } 166 } else { 167 throw new IOException( "coverage storage type: " + type 168 + " is not supported with method: getReader(InputStream, " 169 + "CoverageOffering, Envelope, Format )" ); 170 } 171 return gcr; 172 } 173 174 /** 175 * This method is a deegree specific enhancement of the <tt>GridCoverageExchange</tt> 176 * class/interface as defined by GeoAPI. Returns a grid coverage reader that can manage the 177 * specified source 178 * 179 * @param resource 180 * a string that specifies somehow the data source (e.g. a file). 181 * @param description 182 * an object describing the grid coverage and the access to avaiable metadata 183 * @param envelope 184 * @param format 185 * 186 * @return The grid coverage reader. 187 * @throws IOException 188 * if an error occurs during reading. 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 ) ) { 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 * @return The grid coverage reader. 323 * @throws IOException 324 * if an error occurs during reading. 325 * 326 * @revisit We need a mechanism to allow the right GridCoverageReader Something like an SPI. 327 * What if we can't find a GridCoverageReader? Do we return null or throw an Exception? 328 */ 329 public GridCoverageReader getReader( Object[] resources, CoverageOffering description, Envelope envelope, 330 Format format ) 331 throws IOException, InvalidParameterValueException { 332 333 // CS_CoordinateSystem crs = createNativeCRS( description ); 334 GridCoverageReader gcr = null; 335 Extension ext = description.getExtension(); 336 String type = ext.getType(); 337 File[] files = null; 338 if ( type.equals( Extension.FILEBASED ) ) { 339 LOG.logDebug( "creating filebased CompoundGridCoverageReader" ); 340 files = (File[]) resources; 341 gcr = new CompoundGridCoverageReader( files, description, envelope, format ); 342 } else if ( type.equals( Extension.NAMEINDEXED ) ) { 343 LOG.logDebug( "creating nameIndexed CompoundGridCoverageReader" ); 344 try { 345 files = getFilesFromDirectories( (Directory[]) resources, envelope, description ); 346 } catch ( UnknownCRSException e ) { 347 throw new InvalidParameterValueException( e ); 348 } 349 gcr = new CompoundGridCoverageReader( files, description, envelope, format ); 350 } else if ( type.equals( Extension.SHAPEINDEXED ) ) { 351 LOG.logDebug( "creating shapeIndexed CompoundGridCoverageReader" ); 352 files = (File[]) resources; 353 gcr = new CompoundGridCoverageReader( files, description, envelope, format ); 354 } else if ( type.equals( Extension.ORACLEGEORASTER ) ) { 355 LOG.logDebug( "creating OracleGeoRasterGridCoverageReader" ); 356 Class clzz; 357 try { 358 clzz = Class.forName( "org.deegree.model.coverage.grid.oracle.GeoRasterReaderAccess" ); 359 } catch ( ClassNotFoundException e ) { 360 LOG.logError( e.getMessage(), e ); 361 throw new InvalidParameterValueException( e ); 362 } 363 GCReaderAccess acc; 364 try { 365 acc = (GCReaderAccess) clzz.newInstance(); 366 } catch ( InstantiationException e ) { 367 LOG.logError( e.getMessage(), e ); 368 throw new InvalidParameterValueException( e ); 369 } catch ( IllegalAccessException e ) { 370 LOG.logError( e.getMessage(), e ); 371 throw new InvalidParameterValueException( e ); 372 } 373 gcr = acc.createGridCoverageReader( resources[0], description, envelope, format ); 374 } else { 375 throw new IOException( "coverage storage type: " + type + " is not supported" ); 376 } 377 378 return gcr; 379 } 380 381 /** 382 * returns true if the passed format is an image format 383 * 384 * @param format 385 * @return <code>true</code> if the passed format is an image format 386 */ 387 private boolean isImageFormat( Format format ) { 388 String frmt = format.getName().toUpperCase(); 389 return frmt.equalsIgnoreCase( "png" ) || frmt.equalsIgnoreCase( "bmp" ) || frmt.equalsIgnoreCase( "tif" ) 390 || frmt.equalsIgnoreCase( "tiff" ) || frmt.equalsIgnoreCase( "gif" ) || frmt.equalsIgnoreCase( "jpg" ) 391 || frmt.equalsIgnoreCase( "jpeg" ) || frmt.indexOf( "ECW" ) > -1; 392 } 393 394 /** 395 * reads the names of the grid coverage files intersecting the requested region from the passed 396 * shape (name). 397 * 398 * @param shape 399 * @param envelope 400 * requested envelope 401 * @param description 402 * description (metadata) of the source coverage 403 * @return file list 404 * @throws IOException 405 * @throws UnknownCRSException 406 */ 407 private File[] getFilesFromShape( Shape shape, Envelope envelope, CoverageOffering description ) 408 throws IOException, UnknownCRSException { 409 410 CoordinateSystem crs = createNativeCRS( description ); 411 412 String shapeBaseName = StringTools.replace( shape.getRootFileName(), "\\", "/", true ); 413 String shapeDir = shapeBaseName.substring( 0, shapeBaseName.lastIndexOf( "/" ) + 1 ); 414 415 ShapeFile shp = new ShapeFile( shapeBaseName ); 416 File[] files = null; 417 int[] idx = shp.getGeoNumbersByRect( envelope ); 418 if ( idx != null ) { 419 files = new File[idx.length]; 420 try { 421 for ( int i = 0; i < files.length; i++ ) { 422 Feature feature = shp.getFeatureByRecNo( idx[i] ); 423 QualifiedName qn = new QualifiedName( APP_PREFIX, SHAPE_IMAGE_FILENAME, DEEGREEAPP ); 424 String img = (String) feature.getDefaultProperty( qn ).getValue(); 425 qn = new QualifiedName( APP_PREFIX, SHAPE_DIR_NAME, DEEGREEAPP ); 426 String dir = (String) feature.getDefaultProperty( qn ).getValue(); 427 if ( !( new java.io.File( dir ).isAbsolute() ) ) { 428 // solve relative path; it is assumed that the tile directories 429 // are located in the same directory as the shape file 430 dir = shapeDir + dir; 431 } 432 Geometry geom = feature.getGeometryPropertyValues()[0]; 433 Envelope env = geom.getEnvelope(); 434 env = GeometryFactory.createEnvelope( env.getMin(), env.getMax(), crs ); 435 files[i] = new File( crs, dir.concat( "/".concat( img ) ), env ); 436 } 437 } catch ( Exception e ) { 438 shp.close(); 439 LOG.logError( e.getMessage(), e ); 440 throw new IOException( e.getMessage() ); 441 } 442 } else { 443 files = new File[0]; 444 } 445 shp.close(); 446 447 return files; 448 449 } 450 451 /** 452 * reads the names of the grid coverage files intersecting the requested region from raster data 453 * files contained in the passed directories 454 * 455 * @param directories 456 * list of directories searched for matching raster files 457 * @param envelope 458 * requested envelope 459 * @param description 460 * description (metadata) of the source coverage 461 * @return list of files intersecting the requested envelope 462 * @throws UnknownCRSException 463 * @throws IOException 464 */ 465 private File[] getFilesFromDirectories( Directory[] directories, Envelope envelope, CoverageOffering description ) 466 throws UnknownCRSException { 467 468 CoordinateSystem crs = createNativeCRS( description ); 469 470 List<File> list = new ArrayList<File>( 1000 ); 471 472 for ( int i = 0; i < directories.length; i++ ) { 473 474 double widthCRS = ( (GridDirectory) directories[i] ).getTileWidth(); 475 double heightCRS = ( (GridDirectory) directories[i] ).getTileHeight(); 476 String[] extensions = directories[i].getFileExtensions(); 477 String dirName = directories[i].getName(); 478 479 ConvenienceFileFilter fileFilter = new ConvenienceFileFilter( false, extensions ); 480 java.io.File iofile = new java.io.File( dirName ); 481 String[] tiles = iofile.list( fileFilter ); 482 for ( int j = 0; j < tiles.length; j++ ) { 483 int pos1 = tiles[j].indexOf( '_' ); 484 int pos2 = tiles[j].lastIndexOf( '.' ); 485 String tmp = tiles[j].substring( 0, pos1 ); 486 double x1 = Double.parseDouble( tmp ) / 1000d; 487 tmp = tiles[j].substring( pos1 + 1, pos2 ); 488 double y1 = Double.parseDouble( tmp ) / 1000d; 489 Envelope env = GeometryFactory.createEnvelope( x1, y1, x1 + widthCRS, y1 + heightCRS, crs ); 490 if ( env.intersects( envelope ) ) { 491 File file = new File( crs, dirName + '/' + tiles[j], env ); 492 list.add( file ); 493 } 494 } 495 496 } 497 498 File[] files = list.toArray( new File[list.size()] ); 499 500 return files; 501 } 502 503 /** 504 * creates an instance of <tt>CS_CoordinateSystem</tt> from the name of the native CRS of the 505 * grid coverage 506 * 507 * @param description 508 * @return 509 * @throws UnknownCRSException 510 */ 511 private CoordinateSystem createNativeCRS( CoverageOffering description ) 512 throws UnknownCRSException { 513 String srs = description.getSupportedCRSs().getNativeSRSs()[0].getCodes()[0]; 514 515 return CRSFactory.create( srs ); 516 } 517 518 /** 519 * Returns a GridCoverageWriter that can write the specified format. The file format name is 520 * determined from the {@link Format} interface. Sample file formats include: 521 * 522 * <blockquote><table> 523 * <tr> 524 * <td>"GeoTIFF"</td> 525 * <td> - GeoTIFF</td> 526 * </tr> 527 * <tr> 528 * <td>"PIX"</td> 529 * <td> - PCI Geomatics PIX</td> 530 * </tr> 531 * <tr> 532 * <td>"HDF-EOS"</td> 533 * <td> - NASA HDF-EOS</td> 534 * </tr> 535 * <tr> 536 * <td>"NITF"</td> 537 * <td> - National Image Transfer Format</td> 538 * </tr> 539 * <tr> 540 * <td>"STDS-DEM"</td> 541 * <td> - Standard Transfer Data Standard</td> 542 * </tr> 543 * </table></blockquote> 544 * 545 * @param destination 546 * An object that specifies somehow the data destination. Can be a 547 * {@link java.lang.String}, an {@link java.io.OutputStream}, a 548 * {@link java.nio.channels.FileChannel}, whatever. It's up to the associated grid 549 * coverage writer to make meaningful use of it. 550 * @param format 551 * the output format. 552 * @return The grid coverage writer. 553 * @throws IOException 554 * if an error occurs during reading. 555 */ 556 public GridCoverageWriter getWriter( Object destination, Format format ) 557 throws IOException { 558 559 LOG.logDebug( "requested format: ", format.getName() ); 560 561 GridCoverageWriter gcw = null; 562 563 if ( !isKnownFormat( format ) ) { 564 throw new IOException( "not supported Format: " + format ); 565 } 566 567 Map<String, Object> metadata = new HashMap<String, Object>(); 568 metadata.put( "offset", coverageOffering.getExtension().getOffset() ); 569 metadata.put( "scaleFactor", coverageOffering.getExtension().getScaleFactor() ); 570 if ( format.getName().equalsIgnoreCase( "GEOTIFF" ) ) { 571 gcw = new GeoTIFFGridCoverageWriter( destination, metadata, null, null, format ); 572 } else if ( isImageFormat( format ) ) { 573 gcw = new ImageGridCoverageWriter( destination, metadata, null, null, format ); 574 } else if ( format.getName().equalsIgnoreCase( "GML" ) || format.getName().equalsIgnoreCase( "GML2" ) 575 || format.getName().equalsIgnoreCase( "GML3" ) ) { 576 gcw = new GMLGridCoverageWriter( destination, metadata, null, null, format ); 577 } else if ( format.getName().equalsIgnoreCase( "XYZ" ) ) { 578 gcw = new XYZGridCoverageWriter( destination, metadata, null, null, format ); 579 } else { 580 throw new IOException( "not supported Format: " + format ); 581 } 582 583 return gcw; 584 } 585 586 /** 587 * validates if a passed format is known to an instance of <tt>GridCoverageExchange</tt> 588 * 589 * @param format 590 * @return <code>true</code> if the format is known, <code>false</code> otherwise. 591 */ 592 private boolean isKnownFormat( Format format ) { 593 CodeList[] codeList = coverageOffering.getSupportedFormats().getFormats(); 594 for ( int i = 0; i < codeList.length; i++ ) { 595 String[] codes = codeList[i].getCodes(); 596 for ( int j = 0; j < codes.length; j++ ) { 597 if ( format.getName().equalsIgnoreCase( codes[j] ) ) { 598 return true; 599 } 600 } 601 } 602 LOG.logDebug( format.getName() + " not supported" ); 603 return false; 604 } 605 606 }