001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/ogcwebservices/sos/WFSRequestGenerator.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.ogcwebservices.sos; 037 038 import java.io.IOException; 039 import java.io.InputStream; 040 import java.util.ArrayList; 041 042 import org.deegree.datatypes.QualifiedName; 043 import org.deegree.framework.xml.NamespaceContext; 044 import org.deegree.framework.xml.XMLParsingException; 045 import org.deegree.framework.xml.XMLTools; 046 import org.deegree.model.filterencoding.ComplexFilter; 047 import org.deegree.model.filterencoding.Filter; 048 import org.deegree.model.filterencoding.Literal; 049 import org.deegree.model.filterencoding.LogicalOperation; 050 import org.deegree.model.filterencoding.Operation; 051 import org.deegree.model.filterencoding.OperationDefines; 052 import org.deegree.model.filterencoding.PropertyIsCOMPOperation; 053 import org.deegree.model.filterencoding.PropertyIsLikeOperation; 054 import org.deegree.model.filterencoding.PropertyName; 055 import org.deegree.model.filterencoding.SpatialOperation; 056 import org.deegree.model.spatialschema.Envelope; 057 import org.deegree.model.spatialschema.Geometry; 058 import org.deegree.model.spatialschema.GeometryException; 059 import org.deegree.model.spatialschema.GeometryFactory; 060 import org.deegree.ogcbase.CommonNamespaces; 061 import org.deegree.ogcwebservices.sos.getobservation.TInstant; 062 import org.deegree.ogcwebservices.sos.getobservation.TPeriod; 063 import org.w3c.dom.Document; 064 import org.w3c.dom.Element; 065 import org.xml.sax.SAXException; 066 067 /** 068 * generate the wfs requests 069 * 070 * @author <a href="mailto:mkulbe@lat-lon.de">Matthias Kulbe </a> 071 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a> 072 * 073 */ 074 075 public class WFSRequestGenerator { 076 077 private static final String XML_TEMPLATE = "RequestFrame.xml"; 078 079 private static NamespaceContext nsContext = CommonNamespaces.getNamespaceContext(); 080 081 /** 082 * cerates an empty WFS request 083 * 084 * @return the request 085 * @throws IOException 086 * @throws SAXException 087 */ 088 private static Document getEmptyWFSRequest() 089 throws IOException, SAXException { 090 091 InputStream is = WFSRequestGenerator.class.getResourceAsStream( XML_TEMPLATE ); 092 if ( is == null ) { 093 throw new IOException( "The resource '" + XML_TEMPLATE + " could not be found." ); 094 } 095 096 return XMLTools.parse( is ); 097 098 } 099 100 /** 101 * sets the QueryTypname in the WFS request 102 * 103 * @param doc 104 * representing GetFeature DOM-Object 105 * @param typename 106 * @throws XMLParsingException 107 */ 108 private static void setQueryTypeName( Document doc, QualifiedName typename ) 109 throws XMLParsingException { 110 111 Element query = (Element) XMLTools.getRequiredNode( doc, "wfs:GetFeature/wfs:Query", nsContext ); 112 query.setAttribute( "xmlns:" + typename.getPrefix(), typename.getNamespace().toASCIIString() ); 113 query.setAttribute( "typeName", typename.getPrefix() + ':' + typename.getLocalName() ); 114 } 115 116 /** 117 * sets a filter to the document 118 * 119 * @param doc 120 * @param filter 121 * @throws XMLParsingException 122 */ 123 private static void setFilter( Document doc, Filter filter ) 124 throws XMLParsingException { 125 126 Element query = (Element) XMLTools.getNode( doc, "wfs:GetFeature/wfs:Query", nsContext ); 127 128 org.deegree.model.filterencoding.XMLFactory.appendFilter( query, filter ); 129 130 } 131 132 /** 133 * creates a WFS Request with one or more isLike Operations 134 * 135 * @param literals 136 * @param featureType 137 * @param propertyName 138 * @return the request 139 * @throws IOException 140 * @throws SAXException 141 * @throws XMLParsingException 142 */ 143 public static Document createIsLikeOperationWFSRequest( String[] literals, QualifiedName featureType, 144 QualifiedName propertyName ) 145 throws IOException, SAXException, XMLParsingException { 146 147 if ( ( literals == null ) || ( featureType == null ) || ( propertyName == null ) ) { 148 String msg = "error: literals, featureType and propertyName can't be null"; 149 throw new IllegalArgumentException( msg ); 150 } 151 152 Document request = WFSRequestGenerator.getEmptyWFSRequest(); 153 154 WFSRequestGenerator.setQueryTypeName( request, featureType ); 155 156 ArrayList<Operation> al = new ArrayList<Operation>(); 157 158 for ( int i = 0; i < literals.length; i++ ) { 159 160 al.add( new PropertyIsLikeOperation( new PropertyName( propertyName ), new Literal( literals[i] ), '*', 161 '#', '!' ) ); 162 } 163 164 // wenn nur ein feature abgefragt wird, dass <or> weglassen 165 if ( al.size() == 1 ) { 166 Filter filter = new ComplexFilter( al.get( 0 ) ); 167 WFSRequestGenerator.setFilter( request, filter ); 168 } else if ( al.size() > 1 ) { 169 LogicalOperation lop = new LogicalOperation( OperationDefines.OR, al ); 170 WFSRequestGenerator.setFilter( request, new ComplexFilter( lop ) ); 171 } 172 173 return request; 174 175 } 176 177 /** 178 * @param bbox 179 * @param featureTypeName 180 * @param coordPropertyName 181 * @return the request 182 * @throws IOException 183 * @throws SAXException 184 * @throws XMLParsingException 185 * @throws GeometryException 186 */ 187 public static Document createBBoxWFSRequest( Envelope bbox, QualifiedName featureTypeName, 188 QualifiedName coordPropertyName ) 189 throws IOException, SAXException, XMLParsingException, GeometryException { 190 if ( ( bbox == null ) && ( featureTypeName == null ) && ( coordPropertyName == null ) ) { 191 String msg = "error: bbox, featureType and coordPropertyName can't be null"; 192 throw new IllegalArgumentException( msg ); 193 } 194 195 Document request = WFSRequestGenerator.getEmptyWFSRequest(); 196 197 WFSRequestGenerator.setQueryTypeName( request, featureTypeName ); 198 199 Geometry geom = GeometryFactory.createSurface( bbox, null ); 200 201 SpatialOperation bboxOperation = new SpatialOperation( OperationDefines.BBOX, 202 new PropertyName( coordPropertyName ), geom ); 203 204 ComplexFilter filter = new ComplexFilter( bboxOperation ); 205 WFSRequestGenerator.setFilter( request, filter ); 206 207 return request; 208 } 209 210 /** 211 * 212 * @param times 213 * @param featureTypeName 214 * @param timePropertyName 215 * @param filterOperation 216 * @return the request 217 * @throws IOException 218 * @throws SAXException 219 * @throws XMLParsingException 220 */ 221 public static Document createObservationWFSRequest( Object[] times, QualifiedName featureTypeName, 222 QualifiedName timePropertyName, Operation filterOperation ) 223 throws IOException, SAXException, XMLParsingException { 224 225 if ( ( times == null ) || ( featureTypeName == null ) || ( timePropertyName == null ) ) { 226 String msg = "error: times, featureType and timePropertyName can't be null"; 227 throw new IllegalArgumentException( msg ); 228 } 229 230 Document request = WFSRequestGenerator.getEmptyWFSRequest(); 231 232 WFSRequestGenerator.setQueryTypeName( request, featureTypeName ); 233 234 ArrayList<Operation> timeOperationList = new ArrayList<Operation>(); 235 236 // creates the time Filters 237 for ( int i = 0; i < times.length; i++ ) { 238 // if TInstant 239 if ( times[i] instanceof TInstant ) { 240 Operation op = new PropertyIsCOMPOperation( OperationDefines.PROPERTYISEQUALTO, 241 new PropertyName( timePropertyName ), 242 new Literal( ( (TInstant) times[i] ).getTPosition() ) ); 243 timeOperationList.add( op ); 244 // if TPeriod 245 } else if ( times[i] instanceof TPeriod ) { 246 247 ArrayList<Operation> al = new ArrayList<Operation>(); 248 Operation op = new PropertyIsCOMPOperation( OperationDefines.PROPERTYISGREATERTHANOREQUALTO, 249 new PropertyName( timePropertyName ), 250 new Literal( ( (TPeriod) times[i] ).getBegin() ) ); 251 al.add( op ); 252 op = new PropertyIsCOMPOperation( OperationDefines.PROPERTYISLESSTHANOREQUALTO, 253 new PropertyName( timePropertyName ), 254 new Literal( ( (TPeriod) times[i] ).getEnd() ) ); 255 al.add( op ); 256 timeOperationList.add( new LogicalOperation( OperationDefines.AND, al ) ); 257 } 258 } 259 260 Operation timeOp = null; 261 // connect time operations by <or> 262 if ( timeOperationList.size() == 1 ) { 263 timeOp = timeOperationList.get( 0 ); 264 } else if ( timeOperationList.size() > 1 ) { 265 timeOp = new LogicalOperation( OperationDefines.OR, timeOperationList ); 266 } 267 268 // sets the filter by operations 269 if ( ( timeOp != null ) && ( filterOperation != null ) ) { 270 ArrayList<Operation> operationList = new ArrayList<Operation>(); 271 operationList.add( timeOp ); 272 operationList.add( filterOperation ); 273 274 Filter filter = new ComplexFilter( new LogicalOperation( OperationDefines.AND, operationList ) ); 275 WFSRequestGenerator.setFilter( request, filter ); 276 } else if ( timeOp != null ) { 277 WFSRequestGenerator.setFilter( request, new ComplexFilter( timeOp ) ); 278 } else if ( filterOperation != null ) { 279 WFSRequestGenerator.setFilter( request, new ComplexFilter( filterOperation ) ); 280 } 281 282 return request; 283 } 284 285 }