Package org.geotools.jdbc

Source Code of org.geotools.jdbc.PreparedFilterToSQL

/*
*    GeoTools - The Open Source Java GIS Toolkit
*    http://geotools.org
*
*    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
*
*    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;
*    version 2.1 of the License.
*
*    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.
*/
package org.geotools.jdbc;

import java.awt.RenderingHints;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.geotools.data.jdbc.FilterToSQL;
import org.opengis.filter.Id;
import org.opengis.filter.expression.Literal;
import org.opengis.filter.identity.Identifier;

import com.vividsolutions.jts.geom.Geometry;

/**
* Extension of FilterToSQL intended for use with prepared statements.
* <p>
* Each time a {@link Literal} is visited, a '?' is encoded, and the
* value and type of the literal are stored, available after the fact
* via {@link #getLiteralValues()} and {@link #getLiteralTypes()}.
*
* </p>
* @author Justin Deoliveira, OpenGEO
* @author Andrea Aime, OpenGEO
*
*
*
*
* @source $URL$
*/
public class PreparedFilterToSQL extends FilterToSQL {
    /**
     * ordered list of literal values encountered and their types
     */
    protected List<Object> literalValues = new ArrayList<Object>();
    protected List<Class> literalTypes = new ArrayList<Class>();
    protected List<Integer> SRIDs = new ArrayList<Integer>();
    protected List<Integer> dimensions = new ArrayList<Integer>();
    protected PreparedStatementSQLDialect dialect;
    boolean prepareEnabled = true;
   
    /**
     * Default constructor
     * @deprecated Use {@link PreparedFilterToSQL(PreparedStatementSQLDialect)} instead
     */
    public PreparedFilterToSQL() {
        this.dialect = null;
    }
   
    /**
     * Contructor taking a reference to the SQL dialect, will use it to
     * encode geometry placeholders
     * @param dialect
     */
    public PreparedFilterToSQL(PreparedStatementSQLDialect dialect) {
        this.dialect = dialect;
    }

    /**
     * If true (default) a sql statement with literal placemarks is created, otherwise
     * a normal statement is created
     * @return
     */
    public boolean isPrepareEnabled() {
        return prepareEnabled;
    }

    public void setPrepareEnabled(boolean prepareEnabled) {
        this.prepareEnabled = prepareEnabled;
    }

    public PreparedFilterToSQL(Writer out) {
        super(out);
    }

    public Object visit(Literal expression, Object context)
            throws RuntimeException {
        if(!prepareEnabled)
            return super.visit(expression, context);
       
        // evaluate the literal and store it for later
        Object literalValue = evaluateLiteral( expression, (context instanceof Class ? (Class) context : null) );
        literalValues.add(literalValue);
        SRIDs.add(currentSRID);
        dimensions.add(currentDimension);
       
        Class clazz = null;
        if(context instanceof Class)
            clazz = (Class) context;
        else if(literalValue != null)
            clazz = literalValue.getClass();
        literalTypes.add( clazz );
       
        try {
            if ( literalValue == null || dialect == null ) {
                out.write( "?" );
            }
            else {
                StringBuffer sb = new StringBuffer();
                if ( Geometry.class.isAssignableFrom(literalValue.getClass()) ) {
                    int srid = currentSRID != null ? currentSRID : -1;
                    int dimension = currentDimension != null ? currentDimension : -1;
                    dialect.prepareGeometryValue((Geometry) literalValue, dimension, srid, Geometry.class, sb);
                }
                else if ( encodingFunction ) {
                    dialect.prepareFunctionArgument(clazz,sb);
                }
                else {
                    sb.append("?");
                }
                out.write( sb.toString() );
            }
        }
        catch (IOException e) {
            throw new RuntimeException( e );
        }
       
        return context;
    }
   
    /**
     * Encodes an Id filter
     *
     * @param filter the
     *
     * @throws RuntimeException If there's a problem writing output
     *
     */
    public Object visit(Id filter, Object extraData) {
        if (mapper == null) {
            throw new RuntimeException(
                "Must set a fid mapper before trying to encode FIDFilters");
        }

        Set ids = filter.getIdentifiers();
       
        // prepare column name array
        String[] colNames = new String[mapper.getColumnCount()];

        for (int i = 0; i < colNames.length; i++) {
            colNames[i] = mapper.getColumnName(i);
        }

        for (Iterator i = ids.iterator(); i.hasNext(); ) {
            try {
                Identifier id = (Identifier) i.next();
                Object[] attValues = mapper.getPKAttributes(id.toString());

                out.write("(");

                for (int j = 0; j < attValues.length; j++) {
                    out.write( escapeName(colNames[j]) );
                    out.write(" = ");
                    out.write('?');
                   
                    // store the value for later usage
                    literalValues.add(attValues[j]);
                    // no srid, pk are not formed with geometry values
                    SRIDs.add(-1);
                    dimensions.add(-1);
                    // if it's not null, we can also infer the type
                    literalTypes.add(attValues[j] != null ?  attValues[j].getClass() : null);

                    if (j < (attValues.length - 1)) {
                        out.write(" AND ");
                    }
                }

                out.write(")");

                if (i.hasNext()) {
                    out.write(" OR ");
                }
            } catch (java.io.IOException e) {
                throw new RuntimeException(IO_ERROR, e);
            }
        }
       
        return extraData;
    }
   
    public List<Object> getLiteralValues() {
        return literalValues;
    }
   
    public List<Class> getLiteralTypes() {
        return literalTypes;
    }
   
    /**
     * Returns the list of native SRID for each literal that happens to be a geometry, or null otherwise
     * @return
     */
    public List<Integer> getSRIDs() {
        return SRIDs;
    }

    /**
     * Returns the list of dimensions for each literal tha happens to be a geometry, or null otherwise
     * @return
     */
    public List<Integer> getDimensions() {
        return dimensions;
    }

}
TOP

Related Classes of org.geotools.jdbc.PreparedFilterToSQL

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.