001: //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/trunk/src/org/deegree/io/datastore/sql/VirtualContentProvider.java $
002: /*---------------- FILE HEADER ------------------------------------------
003:
004: This file is part of deegree.
005: Copyright (C) 2001-2008 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: apoth $
085: *
086: * @version $Revision: 9342 $, $Date: 2007-12-27 04:32:57 -0800 (Thu, 27 Dec 2007) $
087: */
088: public class VirtualContentProvider {
089:
090: // used in case that no BBOX is available
091: private static final Envelope DEFAULT_BBOX = GeometryFactory
092: .createEnvelope(0.0, 0.0, 0.0, 0.0, null);
093:
094: private Filter filter;
095:
096: private AbstractSQLDatastore ds;
097:
098: private Connection conn;
099:
100: /**
101: * Creates a new instance of {@link VirtualContentProvider}.
102: *
103: * @param filter
104: * @param ds
105: * @param conn
106: */
107: VirtualContentProvider(Filter filter, AbstractSQLDatastore ds,
108: Connection conn) {
109: this .filter = filter;
110: this .ds = ds;
111: this .conn = conn;
112: }
113:
114: /**
115: * Appends a {@link SQLFunctionCall} to the given {@link StatementBuffer}.
116: * <p>
117: * This includes the correct qualification of all columns that are used as {@link FunctionParam}s.
118: *
119: * @param query
120: * @param tableAlias
121: * @param call
122: */
123: public void appendSQLFunctionCall(StatementBuffer query,
124: String tableAlias, SQLFunctionCall call) {
125:
126: String callString = call.getCall();
127: int[] usedVars = call.getUsedVars();
128: List<FunctionParam> params = call.getParams();
129: for (int j = 0; j < usedVars.length; j++) {
130: int varNo = usedVars[j];
131: String varString = "\\$" + varNo;
132: FunctionParam param = params.get(varNo - 1);
133: if (param instanceof FieldContent) {
134: String replace = tableAlias + "."
135: + ((FieldContent) param).getField().getField();
136: callString = callString.replaceAll(varString, replace);
137: } else if (param instanceof ConstantContent) {
138: String replace = ((ConstantContent) param).getValue();
139: callString = callString.replaceAll(varString, replace);
140: } else if (param instanceof SpecialContent) {
141: appendSpecialContentValue(query, (SpecialContent) param);
142: callString = callString.replaceFirst(varString, "?");
143: } else {
144: assert false;
145: }
146: }
147: query.append(callString);
148: }
149:
150: /**
151: * Appends the variable from a {@link SpecialContent} property to the given
152: * {@link StatementBuffer}.
153: *
154: * @param query
155: * @param param
156: */
157: public void appendSpecialContentValue(StatementBuffer query,
158: SpecialContent param) {
159:
160: VARIABLE var = param.getVariable();
161:
162: switch (var) {
163: case QUERY_BBOX: {
164:
165: Object bboxDBGeometry = null;
166:
167: try {
168: Envelope requestBBOX = DEFAULT_BBOX;
169:
170: if (this .filter instanceof ComplexFilter) {
171: Object[] objects = FilterTools
172: .extractFirstBBOX((ComplexFilter) filter);
173: if (objects[0] != null) {
174: requestBBOX = (Envelope) objects[0];
175: }
176: }
177: Geometry geometry = GeometryFactory.createSurface(
178: requestBBOX, null);
179: bboxDBGeometry = this .ds.convertDeegreeToDBGeometry(
180: geometry, param.getSRS(), this .conn);
181: } catch (Exception e) {
182: String msg = Messages
183: .getMessage("DATASTORE_EXTRACTBBOX");
184: throw new RuntimeException(msg, e);
185: }
186:
187: // TODO: remove quick hack to make this work on Oracle
188: if (this .ds
189: .getClass()
190: .getName()
191: .equals(
192: "org.deegree.io.datastore.sql.oracle.OracleDatastore")) {
193: query.addArgument(bboxDBGeometry, Types.STRUCT);
194: } else {
195: query.addArgument(bboxDBGeometry, Types.OTHER);
196: }
197:
198: break;
199: }
200: default: {
201: assert false;
202: }
203: }
204: }
205: }
|