//$Header: /home/deegree/jail/deegreerepository/deegree/src/org/deegree/ogcwebservices/wmps/GetMapServiceInvokerForNL.java,v 1.28 2006/11/27 09:07:52 poth Exp $
/*---------------- FILE HEADER ------------------------------------------
This file is part of deegree.
Copyright (C) 2001-2006 by:
EXSE, Department of Geography, University of Bonn
http://www.giub.uni-bonn.de/deegree/
lat/lon GmbH
http://www.lat-lon.de
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact:
Andreas Poth
lat/lon GmbH
Aennchenstr. 19
53115 Bonn
Germany
E-Mail: poth@lat-lon.de
Prof. Dr. Klaus Greve
Department of Geography
University of Bonn
Meckenheimer Allee 166
53115 Bonn
Germany
E-Mail: greve@giub.uni-bonn.de
---------------------------------------------------------------------------*/
package org.deegree.ogcwebservices.wmps;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.StringReader;
import java.util.ArrayList;
import org.deegree.datatypes.QualifiedName;
import org.deegree.framework.log.ILogger;
import org.deegree.framework.log.LoggerFactory;
import org.deegree.framework.util.CharsetUtils;
import org.deegree.framework.util.IDGenerator;
import org.deegree.framework.util.StringTools;
import org.deegree.framework.xml.XMLTools;
import org.deegree.graphics.MapFactory;
import org.deegree.graphics.Theme;
import org.deegree.graphics.sld.UserStyle;
import org.deegree.model.coverage.grid.ImageGridCoverage;
import org.deegree.model.crs.CRSFactory;
import org.deegree.model.crs.GeoTransformer;
import org.deegree.model.crs.IGeoTransformer;
import org.deegree.model.feature.FeatureCollection;
import org.deegree.model.filterencoding.ComplexFilter;
import org.deegree.model.filterencoding.FeatureFilter;
import org.deegree.model.filterencoding.FeatureId;
import org.deegree.model.filterencoding.Filter;
import org.deegree.model.spatialschema.Envelope;
import org.deegree.model.spatialschema.GMLGeometryAdapter;
import org.deegree.ogcwebservices.InconsistentRequestException;
import org.deegree.ogcwebservices.OGCWebServiceException;
import org.deegree.ogcwebservices.OGCWebServiceRequest;
import org.deegree.ogcwebservices.wcs.WCSException;
import org.deegree.ogcwebservices.wcs.getcoverage.GetCoverage;
import org.deegree.ogcwebservices.wcs.getcoverage.ResultCoverage;
import org.deegree.ogcwebservices.wfs.WFService;
import org.deegree.ogcwebservices.wfs.capabilities.WFSCapabilities;
import org.deegree.ogcwebservices.wfs.capabilities.WFSFeatureType;
import org.deegree.ogcwebservices.wfs.operation.FeatureResult;
import org.deegree.ogcwebservices.wfs.operation.GetFeature;
import org.deegree.ogcwebservices.wfs.operation.Query;
import org.deegree.ogcwebservices.wms.capabilities.Layer;
import org.deegree.ogcwebservices.wms.configuration.AbstractDataSource;
import org.deegree.ogcwebservices.wms.configuration.LocalWCSDataSource;
import org.deegree.ogcwebservices.wms.configuration.LocalWFSDataSource;
import org.deegree.ogcwebservices.wms.configuration.RemoteWMSDataSource;
import org.deegree.ogcwebservices.wms.operation.GetMap;
import org.deegree.ogcwebservices.wms.operation.GetMapResult;
import org.opengis.coverage.grid.GridCoverage;
import org.w3c.dom.Document;
/**
* This is a copy of the WMS package.
*
* @version $Revision: 1.28 $
* @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
* @author last edited by: $Author: poth $
*
* @version 1.0. $Revision: 1.28 $, $Date: 2006/11/27 09:07:52 $
*
* @since 2.0
*/
/**
* Inner class for accessing the data of one named layer and creating <tt>DisplayElement</tt>s
* and a <tt>Thrme</tt> from it. The class extends <tt>Thread</tt> and implements the run
* method, so that a parallel data accessing from several layers is possible.
*
* @version $Revision: 1.28 $
* @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
*/
class GetMapServiceInvokerForNL extends Thread {
private static final ILogger LOG = LoggerFactory.getLogger( GetMapServiceInvokerForNL.class );
private final DefaultGetMapHandler handler;
private Layer layer;
private UserStyle style;
private int index = 0;
private AbstractDataSource datasource;
/**
* Creates a new ServiceInvokerForNL object.
*
* @param handler
* @param lay
* @param source
* @param style
* @param index
* index of the requested layer
*/
GetMapServiceInvokerForNL( DefaultGetMapHandler handler, Layer lay, AbstractDataSource source,
UserStyle style, int index ) {
this.layer = lay;
this.handler = handler;
this.index = index;
this.style = style;
this.datasource = source;
}
/**
* overrides the run-method of the parent class <tt>Thread</tt> for enabling a multi-threaded
* access to the data.
*/
@Override
public void run() {
LOG.entering();
if ( this.datasource != null ) {
OGCWebServiceRequest request = null;
try {
int type = this.datasource.getType();
switch ( type ) {
case AbstractDataSource.LOCALWFS:
case AbstractDataSource.REMOTEWFS: {
request = createGetFeatureRequest( (LocalWFSDataSource) this.datasource );
break;
}
case AbstractDataSource.LOCALWCS:
case AbstractDataSource.REMOTEWCS: {
request = createGetCoverageRequest( this.datasource );
break;
}
case AbstractDataSource.REMOTEWMS: {
request = GetMap.createGetMapRequest( this.datasource, handler.request,
style.getName(), layer.getName() );
break;
}
}
} catch ( Exception e ) {
OGCWebServiceException exce = new OGCWebServiceException(
"ServiceInvokerForNL: "
+ this.layer.getName(),
"Couldn't create query!"
+ StringTools.stackTraceToString( e.getStackTrace() ) );
this.handler.putTheme( this.index, exce );
this.handler.increaseCounter();
LOG.exiting();
return;
}
try {
Object o = this.datasource.getOGCWebService().doService( request );
handleResponse( o );
} catch ( Exception e ) {
LOG.logError( "", e );
OGCWebServiceException exce = new OGCWebServiceException(
"ServiceInvokerForNL: "
+ this.layer.getName(),
"Couldn't perform doService()!"
+ e.getMessage() );
this.handler.putTheme( this.index, exce );
this.handler.increaseCounter();
LOG.exiting();
return;
}
} else {
// increase counter because there is no service to call so it
// is assumed that the request for the current layer if fullfilled
this.handler.increaseCounter();
}
LOG.exiting();
}
/**
* creates a getFeature request considering the getMap request and the filterconditions defined
* in the submitted <tt>DataSource</tt> object. The request will be encapsualted within a
* <tt>OGCWebServiceEvent</tt>.
*
* @param ds
* @return GetFeature event object containing a GetFeature request
* @throws Exception
*/
private GetFeature createGetFeatureRequest( LocalWFSDataSource ds )
throws Exception {
LOG.entering();
Envelope bbox = this.handler.request.getBoundingBox();
// transform request bounding box to the coordinate reference
// system the WFS holds the data if requesting CRS and WFS-Data
// crs are different
WFService wfs = (WFService) ds.getOGCWebService();
// WFSCapabilities capa = (WFSCapabilities)wfs.getWFSCapabilities();
WFSCapabilities capa = wfs.getCapabilities();
QualifiedName gn = ds.getName();
WFSFeatureType ft = capa.getFeatureTypeList().getFeatureType( gn );
if ( ft == null ) {
throw new OGCWebServiceException( "Feature Type:" + ds.getName()
+ " is not known by the WFS" );
}
// enable different formatations of the crs encoding for GML geometries
String GML_SRS = "http://www.opengis.net/gml/srs/";
String old_gml_srs = ft.getDefaultSRS().toASCIIString();
String old_srs;
if ( old_gml_srs.startsWith( GML_SRS ) ) {
old_srs = old_gml_srs.substring( 31 ).replace( '#', ':' ).toUpperCase();
} else {
old_srs = old_gml_srs;
}
String new_srs = this.handler.request.getSrs();
String new_gml_srs;
if ( old_gml_srs.startsWith( GML_SRS ) ) {
new_gml_srs = GML_SRS + new_srs.replace( ':', '#' ).toLowerCase();
} else {
new_gml_srs = new_srs;
}
if ( !( old_srs.equalsIgnoreCase( new_gml_srs ) ) ) {
IGeoTransformer gt = new GeoTransformer( CRSFactory.create( old_srs ) );
bbox = gt.transform( bbox, this.handler.reqCRS );
}
// no filter condition has been defined
StringBuffer sb = new StringBuffer( 5000 );
sb.append( "<?xml version='1.0' encoding='" + CharsetUtils.getSystemCharset() + "'?>" );
sb.append( "<GetFeature xmlns='http://www.opengis.net/wfs' " );
sb.append( "xmlns:ogc='http://www.opengis.net/ogc' " );
sb.append( "xmlns:gml='http://www.opengis.net/gml' " );
sb.append( "xmlns:" ).append( ds.getName().getPrefix() ).append( '=' );
sb.append( "'" ).append( ds.getName().getNamespace() ).append( "' " );
sb.append( "service='WFS' version='1.1.0' " );
if ( ds.getType() == AbstractDataSource.LOCALWFS ) {
sb.append( "outputFormat='FEATURECOLLECTION'>" );
} else {
sb.append( "outputFormat='text/xml; subtype=gml/3.1.1'>" );
}
sb.append( "<Query typeName='" + ds.getName().getAsString() + "'>" );
Query query = ds.getQuery();
if ( query == null ) {
sb.append( "<ogc:Filter><ogc:BBOX>" );
sb.append( "<PropertyName>" );
sb.append( ds.getGeometryProperty().getAsString() );
sb.append( "</PropertyName>" );
sb.append( GMLGeometryAdapter.exportAsBox( bbox ) );
sb.append( "</ogc:BBOX>" );
sb.append( "</ogc:Filter></Query></GetFeature>" );
} else {
Filter filter = query.getFilter();
sb.append( "<ogc:Filter>" );
if ( filter instanceof ComplexFilter ) {
sb.append( "<ogc:And>" );
sb.append( "<ogc:BBOX><PropertyName>" ).append( ds.getName().getPrefix() );
sb.append( ':' ).append( ds.getGeometryProperty() );
sb.append( "</PropertyName>" );
sb.append( GMLGeometryAdapter.exportAsBox( bbox ) );
sb.append( "</ogc:BBOX>" );
// add filter as defined in the layers datasource description
// to the filter expression
org.deegree.model.filterencoding.Operation op = ( (ComplexFilter) filter ).getOperation();
sb.append( op.toXML() ).append( "</ogc:And>" );
} else {
ArrayList featureIds = ( (FeatureFilter) filter ).getFeatureIds();
if ( featureIds.size() > 1 ) {
sb.append( "<ogc:And>" );
}
for ( int i = 0; i < featureIds.size(); i++ ) {
FeatureId fid = (FeatureId) featureIds.get( i );
sb.append( fid.toXML() );
}
if ( featureIds.size() > 1 ) {
sb.append( "</ogc:And>" );
}
}
sb.append( "</ogc:Filter></Query></GetFeature>" );
}
// create dom representation of the request
Document doc = XMLTools.parse( new StringReader( sb.toString() ) );
// create OGCWebServiceEvent object
IDGenerator idg = IDGenerator.getInstance();
GetFeature gfr = GetFeature.create( "" + idg.generateUniqueID(), doc.getDocumentElement() );
LOG.exiting();
return gfr;
}
/**
* creates a getCoverage request considering the getMap request and the filterconditions defined
* in the submitted <tt>DataSource</tt> object The request will be encapsualted within a
* <tt>OGCWebServiceEvent</tt>.
*
* @param ds
* @return GetCoverage event object containing a GetCoverage request
* @throws InconsistentRequestException
*/
private GetCoverage createGetCoverageRequest( AbstractDataSource ds )
throws InconsistentRequestException {
LOG.entering();
Envelope bbox = this.handler.request.getBoundingBox();
GetCoverage gcr = ( (LocalWCSDataSource) ds ).getGetCoverageRequest();
String crs = this.handler.request.getSrs();
if ( gcr != null && gcr.getDomainSubset().getRequestSRS() != null ) {
crs = gcr.getDomainSubset().getRequestSRS().getCode();
}
String format = this.handler.request.getFormat();
int pos = format.indexOf( '/' );
if ( pos > -1 )
format = format.substring( pos + 1, format.length() );
if ( gcr != null && !"%default%".equals( gcr.getOutput().getFormat().getCode() ) ) {
format = gcr.getOutput().getFormat().getCode();
}
if ( format.indexOf( "svg" ) > -1 ) {
format = "tiff";
}
String version = "1.0.0";
if ( gcr != null && gcr.getVersion() != null ) {
version = gcr.getVersion();
}
String lay = ds.getName().getAsString();
if ( gcr != null && !"%default%".equals( gcr.getSourceCoverage() ) ) {
lay = gcr.getSourceCoverage();
}
String ipm = null;
if ( gcr != null && gcr.getInterpolationMethod() != null ) {
ipm = gcr.getInterpolationMethod().value;
}
// TODO
// handle rangesets e.g. time and elevation
StringBuffer sb = new StringBuffer( 1000 );
sb.append( "service=WCS&request=GetCoverage" );
sb.append( "&version=" ).append( version );
sb.append( "&COVERAGE=" ).append( lay );
sb.append( "&CRS=" ).append( crs );
sb.append( "&BBOX=" ).append( bbox.getMin().getX() ).append( ',' ).append(
bbox.getMin().getY() ).append(
',' ).append(
bbox.getMax().getX() ).append(
',' ).append(
bbox.getMax().getY() );
sb.append( "&WIDTH=" ).append( this.handler.request.getWidth() );
sb.append( "&HEIGHT=" ).append( this.handler.request.getHeight() );
sb.append( "&FORMAT=" ).append( format );
sb.append( "&INTERPOLATIONMETHOD=" ).append( ipm );
try {
IDGenerator idg = IDGenerator.getInstance();
gcr = GetCoverage.create( "id" + idg.generateUniqueID(), sb.toString() );
} catch ( WCSException e ) {
throw new InconsistentRequestException( e.getMessage() );
} catch ( org.deegree.ogcwebservices.OGCWebServiceException e ) {
throw new InconsistentRequestException( e.getMessage() );
}
LOG.exiting();
return gcr;
}
/**
* The method implements the <tt>OGCWebServiceClient</tt> interface. So a deegree OWS
* implementation accessed by this class is able to return the result of a request by calling
* the write-method.
*
* @param result
* to a GetXXX request
*/
private void handleResponse( Object result ) {
try {
if ( result instanceof ResultCoverage ) {
handleGetCoverageResponse( (ResultCoverage) result );
} else if ( result instanceof FeatureResult ) {
handleGetFeatureResponse( (FeatureResult) result );
} else if ( result instanceof GetMapResult ) {
handleGetMapResponse( (GetMapResult) result );
} else {
OGCWebServiceException exce = new OGCWebServiceException( "ServiceInvokerForNL: "
+ this.layer.getName(),
"unknown response format!" );
this.handler.putTheme( this.index, exce );
}
} catch ( Exception e ) {
LOG.logError( "-", e );
OGCWebServiceException exce = new OGCWebServiceException( "ServiceInvokerForNL: "
+ this.layer.getName(),
e.toString() );
this.handler.putTheme( this.index, exce );
}
// increase counter to indicate that one more layers requesting is
// completed
this.handler.increaseCounter();
}
/**
* replaces all pixels within the passed image having a color that is defined to be transparent
* within their datasource with a transparent color.
*
* @param img
* @return BufferedImage
*/
private BufferedImage setTransparentColors( BufferedImage img ) {
LOG.entering();
Color[] colors = null;
if ( this.datasource.getType() == AbstractDataSource.LOCALWCS ) {
LocalWCSDataSource ds = (LocalWCSDataSource) this.datasource;
colors = ds.getTransparentColors();
} else {
RemoteWMSDataSource ds = (RemoteWMSDataSource) this.datasource;
colors = ds.getTransparentColors();
}
if ( colors != null && colors.length > 0 ) {
int[] clrs = new int[colors.length];
for ( int i = 0; i < clrs.length; i++ ) {
clrs[i] = colors[i].getRGB();
}
if ( img.getType() != BufferedImage.TYPE_INT_ARGB ) {
// if the incoming image does not allow transparency
// it must be copyed to a image of ARGB type
BufferedImage tmp = new BufferedImage( img.getWidth(), img.getHeight(),
BufferedImage.TYPE_INT_ARGB );
Graphics g = tmp.getGraphics();
g.drawImage( img, 0, 0, null );
g.dispose();
img = tmp;
}
// TODO
// should be replaced by a JAI operation
int w = img.getWidth();
int h = img.getHeight();
for ( int i = 0; i < w; i++ ) {
for ( int j = 0; j < h; j++ ) {
int col = img.getRGB( i, j );
if ( shouldBeTransparent( clrs, col ) ) {
img.setRGB( i, j, 0x00FFFFFF );
}
}
}
}
LOG.exiting();
return img;
}
/**
* Should be transparent.
*
* @param colors
* @param color
* @return boolean
*/
private boolean shouldBeTransparent( int[] colors, int color ) {
for ( int i = 0; i < colors.length; i++ ) {
if ( colors[i] == color ) {
return true;
}
}
return false;
}
/**
* handles the response of a cascaded WMS and calls a factory to create <tt>DisplayElement</tt>
* and a <tt>Theme</tt> from it
*
* @param response
* @throws Exception
*/
private void handleGetMapResponse( GetMapResult response )
throws Exception {
LOG.entering();
BufferedImage bi = (BufferedImage) response.getMap();
bi = setTransparentColors( bi );
GridCoverage gc = new ImageGridCoverage( null, this.handler.request.getBoundingBox(), bi );
org.deegree.graphics.Layer rl = MapFactory.createRasterLayer( this.layer.getName(), gc );
Theme theme = MapFactory.createTheme( this.datasource.getName().getAsString(), rl );
this.handler.putTheme( this.index, theme );
LOG.exiting();
}
/**
* handles the response of a WFS and calls a factory to create <tt>DisplayElement</tt> and a
* <tt>Theme</tt> from it
*
* @param response
* @throws Exception
*/
private void handleGetFeatureResponse( FeatureResult response )
throws Exception {
LOG.entering();
FeatureCollection fc = null;
Object o = response.getResponse();
if ( o instanceof FeatureCollection ) {
fc = (FeatureCollection) o;
} else {
throw new Exception( "unknown data format at a GetFeature response" );
}
org.deegree.graphics.Layer fl = MapFactory.createFeatureLayer( this.layer.getName(),
this.handler.reqCRS, fc );
this.handler.putTheme( this.index,
MapFactory.createTheme( this.datasource.getName().getAsString(), fl,
new UserStyle[] { this.style } ) );
LOG.exiting();
}
/**
* handles the response of a WCS and calls a factory to create <tt>DisplayElement</tt> and a
* <tt>Theme</tt> from it
*
* @param response
* @throws Exception
*/
private void handleGetCoverageResponse( ResultCoverage response )
throws Exception {
LOG.entering();
ImageGridCoverage gc = (ImageGridCoverage) response.getCoverage();
BufferedImage bi = gc.getAsImage( -1, -1 );
bi = setTransparentColors( bi );
gc = new ImageGridCoverage( null, this.handler.request.getBoundingBox(), bi );
org.deegree.graphics.Layer rl = MapFactory.createRasterLayer( this.layer.getName(), gc );
this.handler.putTheme( this.index,
MapFactory.createTheme( this.datasource.getName().getAsString(), rl ) );
LOG.exiting();
}
}
/***************************************************************************************************
* Changes to this class. What the people have been up to:
*
* $Log: GetMapServiceInvokerForNL.java,v $
* Revision 1.28 2006/11/27 09:07:52 poth
* JNI integration of proj4 has been removed. The CRS functionality now will be done by native deegree code.
*
* Revision 1.27 2006/11/22 14:05:06 schmitz
* Moved some createGetMapRequest methods to GetMap.
* Added a generic DoServiceTask.
*
* Revision 1.26 2006/11/14 15:36:40 poth
* bug fix - set correct WFS version for GetFeature request
*
* Revision 1.25 2006/10/17 20:31:19 poth
* *** empty log message ***
*
* Revision 1.24 2006/09/27 16:46:41 poth
* transformation method signature changed
*
* Revision 1.23 2006/09/13 07:37:58 deshmukh
* removed excess debug statements.
*
* Revision 1.22 2006/09/11 16:22:28 mays
* changing content of Map for vebdor specific parameters: the contents from configuration are added by the contents from handler request.
* also: started cleaning up the footer
*
* Revision 1.21 2006/08/10 07:11:35 deshmukh WMPS has been modified to support the new
* configuration changes and the excess code not needed has been replaced.
*
* Revision 1.20 2006/08/01 13:41:48 deshmukh The wmps configuration has been modified and extended.
* Also fixed the javadoc.
*
* Revision 1.19 2006/07/13 12:24:45 poth adaptions required according to changes in
* org.deegree.ogcwebservice.wms.operations.GetMap
*
* Revision 1.18 2006/06/12 09:34:53 deshmukh extended the print map capabilites to support the get
* request and changed the db structure.
*
* Revision 1.17 2006/06/07 12:37:51 deshmukh Reset the changes made to the WMPS.
*
* Revision 1.15 2006/05/11 20:15:19 poth *** empty log message ***
*
* Revision 1.14 2006/05/11 20:10:29 poth *** empty log message ***
*
* Changes to this class. What the people have been up to: Changes to this class. What
* the people have been up to: Revision 1.13 2006/05/03 20:09:52 poth Changes to this class. What
* the people have been up to: *** empty log message *** Changes to this class. What the people have
* been up to: Changes to this class. What the people have been up to: Revision 1.12 2006/05/01
* 20:15:26 poth Changes to this class. What the people have been up to: *** empty log message ***
* Changes to this class. What the people have been up to: Changes to this class. What the people
* have been up to: Revision 1.11 2006/04/06 20:25:24 poth Changes to this class. What the people
* have been up to: *** empty log message *** Changes to this class. What the people have been up
* to: Changes to this class. What the people have been up to: Revision 1.10 2006/03/30 21:20:25
* poth Changes to this class. What the people have been up to: *** empty log message *** Changes to
* this class. What the people have been up to: Changes to this class. What the people have been up
* to: Revision 1.9 2006/02/02 21:10:20 deshmukh Changes to this class. What the people have been up
* to: restructured wmps Changes to this class. What the people have been up to: Changes to this
* class. What the people have been up to: Revision 1.8 2006/02/02 08:09:30 deshmukh Changes to this
* class. What the people have been up to: removed unnecessary comments Changes to this class. What
* the people have been up to: Changes to this class. What the people have been up to: Revision 1.7
* 2006/01/31 17:12:27 deshmukh Changes to this class. What the people have been up to: WMPService
* implemented Changes to this class. What the people have been up to: Changes to this class. What
* the people have been up to: Revision 1.6 2006/01/18 16:53:45 deshmukh Changes to this class. What
* the people have been up to: *** empty log message *** Changes to this class. What the people have
* been up to: Changes to this class. What the people have been up to: Revision 1.5 2006/01/17
* 16:54:58 deshmukh Changes to this class. What the people have been up to: *** empty log message
* *** Changes to this class. What the people have been up to: Changes to this class. What the
* people have been up to: Revision 1.4 2006/01/16 10:49:55 deshmukh Changes to this class. What the
* people have been up to: *** empty log message *** Changes to this class. What the people have
* been up to: Changes to this class. What the people have been up to: Revision 1.3 2006/01/13
* 15:26:55 deshmukh Changes to this class. What the people have been up to: *** empty log message
* *** Changes to this class. What the people have been up to: Changes to this class. What the
* people have been up to: Revision 1.2 2006/01/11 15:43:34 deshmukh Changes to this class. What the
* people have been up to: *** empty log message *** Changes to this class. What the people have
* been up to: Revision 1.1 2006/01/10 16:37:22 deshmukh ** empty log message ***
*
* Revision 1.20 2006/01/05 17:43:54 poth ** empty log message ***
*
* Revision 1.19 2005/12/21 17:30:10 poth no message
*
* Revision 1.18 2005/12/18 19:06:30 poth no message
*
* Revision 1.17 2005/12/11 18:31:05 poth no message
*
* Revision 1.16 2005/11/25 11:59:26 poth no message
*
* Revision 1.15 2005/11/22 17:31:33 poth no message
*
* Revision 1.14 2005/11/22 17:19:13 poth no message
*
* Revision 1.13 2005/11/16 13:45:00 mschneider Merge of wfs development branch.
*
* Revision 1.12.2.2 2005/11/08 13:52:24 mschneider Refactoring.
*
* Revision 1.12.2.1 2005/11/07 23:01:27 mschneider ** empty log message ***
*
* Revision 1.12 2005/09/29 11:30:25 poth no message
*
* Revision 1.11 2005/09/27 19:53:19 poth no message
*
* Revision 1.10 2005/09/27 19:43:52 poth no message
*
* Revision 1.9 2005/08/26 21:13:02 poth no message
*
* Revision 1.8 2005/08/24 16:11:14 mschneider Renamed GenericName to QualifiedName.
*
* Revision 1.7 2005/08/19 07:45:11 poth no message
*
* Revision 1.6 2005/08/10 07:33:02 poth no message
*
* Revision 1.5 2005/08/09 17:26:56 poth no message
*
* Revision 1.4 2005/08/09 15:48:24 poth no message
*
* Revision 1.3 2005/07/22 16:19:56 poth no message
*
* Revision 1.2 2005/07/07 15:54:40 poth no message
*
* Revision 1.1 2005/06/28 15:58:11 poth no message
*
*
**************************************************************************************************/