001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/tags/2.1/src/org/deegree/io/datastore/sql/VirtualContentProvider.java $ 002 /*---------------- FILE HEADER ------------------------------------------ 003 004 This file is part of deegree. 005 Copyright (C) 2001-2006 by: 006 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 Aennchenstraße 19 030 53177 Bonn 031 Germany 032 E-Mail: poth@lat-lon.de 033 034 Prof. Dr. Klaus Greve 035 Department of Geography 036 University of Bonn 037 Meckenheimer Allee 166 038 53115 Bonn 039 Germany 040 E-Mail: greve@giub.uni-bonn.de 041 042 ---------------------------------------------------------------------------*/ 043 package org.deegree.io.datastore.sql; 044 045 import java.sql.Connection; 046 import java.util.List; 047 048 import org.deegree.datatypes.Types; 049 import org.deegree.i18n.Messages; 050 import org.deegree.io.datastore.schema.content.ConstantContent; 051 import org.deegree.io.datastore.schema.content.FieldContent; 052 import org.deegree.io.datastore.schema.content.FunctionParam; 053 import org.deegree.io.datastore.schema.content.SQLFunctionCall; 054 import org.deegree.io.datastore.schema.content.SpecialContent; 055 import org.deegree.io.datastore.schema.content.SpecialContent.VARIABLE; 056 import org.deegree.model.filterencoding.ComplexFilter; 057 import org.deegree.model.filterencoding.Filter; 058 import org.deegree.model.filterencoding.FilterTools; 059 import org.deegree.model.spatialschema.Envelope; 060 import org.deegree.model.spatialschema.Geometry; 061 import org.deegree.model.spatialschema.GeometryFactory; 062 063 /** 064 * Responsible for determining the value of properties that are mapped to {@link SQLFunctionCall}s. 065 * <p> 066 * This involves the lookup of the values of variables ({@link SpecialContent} instances). 067 * 068 * <table border="1"> 069 * <tr> 070 * <th>Variable name</th> 071 * <th>Description</th> 072 * </tr> 073 * <tr> 074 * <td>$QUERY.BBOX</td> 075 * <td>Bounding box of the query (null if it is not present).</td> 076 * </tr> 077 * </table> 078 * </p> 079 * 080 * @see SQLFunctionCall 081 * @see SpecialContent 082 * 083 * @author <a href="mailto:schneider@lat-lon.de">Markus Schneider</a> 084 * @author last edited by: $Author: mschneider $ 085 * 086 * @version $Revision: 7781 $, $Date: 2007-07-17 17:56:59 +0200 (Di, 17 Jul 2007) $ 087 */ 088 public class VirtualContentProvider { 089 090 // used in case that no BBOX is available 091 private static final Envelope DEFAULT_BBOX = GeometryFactory.createEnvelope( 0.0, 0.0, 0.0, 0.0, null ); 092 093 private Filter filter; 094 095 private AbstractSQLDatastore ds; 096 097 private Connection conn; 098 099 /** 100 * Creates a new instance of {@link VirtualContentProvider}. 101 * 102 * @param filter 103 * @param ds 104 * @param conn 105 */ 106 VirtualContentProvider( Filter filter, AbstractSQLDatastore ds, Connection conn ) { 107 this.filter = filter; 108 this.ds = ds; 109 this.conn = conn; 110 } 111 112 /** 113 * Appends a {@link SQLFunctionCall} to the given {@link StatementBuffer}. 114 * <p> 115 * This includes the correct qualification of all columns that are used as {@link FunctionParam}s. 116 * 117 * @param query 118 * @param tableAlias 119 * @param call 120 */ 121 public void appendSQLFunctionCall( StatementBuffer query, String tableAlias, SQLFunctionCall call ) { 122 123 String callString = call.getCall(); 124 int[] usedVars = call.getUsedVars(); 125 List<FunctionParam> params = call.getParams(); 126 for ( int j = 0; j < usedVars.length; j++ ) { 127 int varNo = usedVars[j]; 128 String varString = "\\$" + varNo; 129 FunctionParam param = params.get( varNo - 1 ); 130 if ( param instanceof FieldContent ) { 131 String replace = tableAlias + "." + ( (FieldContent) param ).getField().getField(); 132 callString = callString.replaceAll( varString, replace ); 133 } else if ( param instanceof ConstantContent ) { 134 String replace = ( (ConstantContent) param ).getValue(); 135 callString = callString.replaceAll( varString, replace ); 136 } else if ( param instanceof SpecialContent ) { 137 appendSpecialContentValue( query, (SpecialContent) param ); 138 callString = callString.replaceFirst( varString, "?" ); 139 } else { 140 assert false; 141 } 142 } 143 query.append( callString ); 144 } 145 146 /** 147 * Appends the variable from a {@link SpecialContent} property to the given 148 * {@link StatementBuffer}. 149 * 150 * @param query 151 * @param param 152 */ 153 public void appendSpecialContentValue( StatementBuffer query, SpecialContent param ) { 154 155 VARIABLE var = param.getVariable(); 156 157 switch ( var ) { 158 case QUERY_BBOX: { 159 160 Object bboxDBGeometry = null; 161 162 try { 163 Envelope requestBBOX = DEFAULT_BBOX; 164 165 if ( this.filter instanceof ComplexFilter ) { 166 Object[] objects = FilterTools.extractFirstBBOX( (ComplexFilter) filter ); 167 if ( objects[0] != null ) { 168 requestBBOX = (Envelope) objects[0]; 169 } 170 } 171 Geometry geometry = GeometryFactory.createSurface( requestBBOX, null ); 172 bboxDBGeometry = this.ds.convertDeegreeToDBGeometry( geometry, param.getSRS(), this.conn ); 173 } catch ( Exception e ) { 174 String msg = Messages.getMessage( "DATASTORE_EXTRACTBBOX" ); 175 throw new RuntimeException( msg, e ); 176 } 177 178 // TODO: remove quick hack to make this work on Oracle 179 if (this.ds.getClass().getName().equals( "org.deegree.io.datastore.sql.oracle.OracleDatastore" )) { 180 query.addArgument( bboxDBGeometry, Types.STRUCT ); 181 } else { 182 query.addArgument( bboxDBGeometry, Types.OTHER ); 183 } 184 185 186 break; 187 } 188 default: { 189 assert false; 190 } 191 } 192 } 193 }