/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2003-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.data.oracle.attributeio;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
import oracle.jdbc.OracleConnection;
import oracle.sql.STRUCT;
import org.geotools.data.DataSourceException;
import org.geotools.data.jdbc.QueryData;
import org.geotools.data.jdbc.attributeio.AttributeIO;
import org.geotools.data.jdbc.datasource.DataSourceFinder;
import org.geotools.data.jdbc.datasource.UnWrapper;
import org.geotools.data.oracle.sdo.GeometryConverter;
import org.opengis.feature.type.AttributeDescriptor;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryCollection;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.MultiLineString;
import com.vividsolutions.jts.geom.MultiPoint;
import com.vividsolutions.jts.geom.MultiPolygon;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.Polygon;
import com.vividsolutions.jts.geom.PrecisionModel;
/**
* An attribute IO that uses the Oracle SDO API to read/write geometries
*
* @author Andrea Aime
* @author Sean Geoghegan, Defence Science and Technology Organisation.
*
* @source $URL$
*/
public class SDOAttributeIO implements AttributeIO {
private static final Logger LOGGER = org.geotools.util.logging.Logging.getLogger("org.geotools.data.oracle");
// geometry adpaters
// private AdapterJTS adapterJTS;
// private AdapterSDO adapterSDO;
GeometryConverter converter;
private QueryData queryData;
private Class targetClazz;
private GeometryFactory geometryFactory;
public SDOAttributeIO(AttributeDescriptor attributeType, QueryData queryData)
throws DataSourceException {
this.queryData = queryData;
geometryFactory = null;
try {
String tableName = queryData.getFeatureTypeInfo()
.getFeatureTypeName();
String columnName = attributeType.getLocalName();
targetClazz = attributeType.getType().getBinding();
LOGGER.fine("About to create Geometry convertor for " + tableName
+ "." + columnName);
// TODO should check that it is an OracleConnection
Connection conn = queryData.getConnection();
if(!(conn instanceof OracleConnection)) {
UnWrapper uw = DataSourceFinder.getUnWrapper(conn);
if(uw != null)
conn = uw.unwrap(conn);
}
OracleConnection oracleConnection = (OracleConnection) conn;
//GeometryFactory gFact = null;
int srid = queryData.getFeatureTypeInfo().getSRID(columnName);
if (srid != -1) {
//SRManager srManager = OraSpatialManager.getSpatialReferenceManager(conn);
//SpatialReference sr = srManager.retrieve(srid);
//gFact = OraSpatialManager.getGeometryFactory(sr);
PrecisionModel pm = new PrecisionModel();
geometryFactory = new GeometryFactory( pm, srid );
} else {
//gFact = OraSpatialManager.getGeometryFactory();
geometryFactory = new GeometryFactory();
}
//adapterSDO = new AdapterSDO(gFact, conn);
//adapterJTS = new AdapterJTS(gFact);
converter = new GeometryConverter( oracleConnection, geometryFactory );
// catch (SQLException e) {
// String msg = "Error setting up SDO Geometry convertor";
// LOGGER.log(Level.SEVERE, msg, e);
// throw new DataSourceException(msg + ":" + e.getMessage(), e);
// }
// catch (SRException e) {
// throw new DataSourceException(
// "Error setting up SDO Geometry convertor", e);
// }
} catch(IOException e) {
throw new DataSourceException(e);
} finally {
// hold try statement in place
}
}
/**
* @see org.geotools.data.jdbc.attributeio.AttributeIO#read(java.sql.ResultSet,
* int)
*/
public Object read(ResultSet rs, int position) throws IOException {
try {
Geometry geom = null;
Object struct = rs.getObject(position);
// oracle.sdoapi.geom.Geometry sdoGeom = adapterSDO.importGeometry(struct);
// geom = adapterJTS.exportGeometry(Geometry.class, sdoGeom);
geom = converter.asGeometry( (STRUCT) struct );
// in Oracle you can have polygons in a column declared to be multipolygon, and so on...
// so we better convert geometries, since our feature model is not so lenient
if(targetClazz.equals(MultiPolygon.class) && geom instanceof Polygon)
return geometryFactory.createMultiPolygon(new Polygon[] {(Polygon) geom});
else if(targetClazz.equals(MultiPoint.class) && geom instanceof Point)
return geometryFactory.createMultiPoint(new Point[] {(Point) geom});
else if(targetClazz.equals(MultiLineString.class) && geom instanceof LineString)
return geometryFactory.createMultiLineString(new LineString[] {(LineString) geom});
else if(targetClazz.equals(GeometryCollection.class))
return geometryFactory.createGeometryCollection(new Geometry[] {geom});
return geom;
} catch (SQLException e) {
String msg = "SQL Exception reading geometry column";
LOGGER.log(Level.SEVERE, msg, e);
throw new DataSourceException(msg, e);
}
// catch (InvalidGeometryException e) {
// String msg = "Problem with the geometry";
// LOGGER.log(Level.SEVERE, msg, e);
// throw new DataSourceException(msg, e);
// } catch (GeometryInputTypeNotSupportedException e) {
// String msg = "Geometry Conversion type error";
// LOGGER.log(Level.SEVERE, msg, e);
// throw new DataSourceException(msg, e);
// } catch (GeometryOutputTypeNotSupportedException e) {
// String msg = "Geometry Conversion type error";
// LOGGER.log(Level.SEVERE, msg, e);
// throw new DataSourceException(msg, e);
// }
}
/**
*
* @see org.geotools.data.jdbc.attributeio.AttributeIO#write(java.sql.ResultSet,
* int, java.lang.Object)
*/
public void write(ResultSet rs, int position, Object value)
throws IOException {
try {
//oracle.sdoapi.geom.Geometry sdoGeom = adapterJTS.importGeometry(value);
//Object o = adapterSDO.exportGeometry(STRUCT.class, sdoGeom);
Geometry geom = (Geometry) value;
STRUCT struct = converter.toSDO( geom );
rs.updateObject(position, struct);
} catch (SQLException sqlException) {
String msg = "SQL Exception writing geometry column";
LOGGER.log(Level.SEVERE, msg, sqlException);
throw new DataSourceException(msg, sqlException);
}
}
/**
* @see org.geotools.data.jdbc.attributeio.AttributeIO#write(java.sql.PreparedStatement, int, java.lang.Object)
*/
public void write(PreparedStatement ps, int position, Object value) throws IOException {
try {
Geometry geom = (Geometry) value;
STRUCT struct = converter.toSDO( geom );
ps.setObject(position, struct);
} catch (SQLException sqlException) {
String msg = "SQL Exception writing geometry column";
LOGGER.log(Level.SEVERE, msg, sqlException);
throw new DataSourceException(msg, sqlException);
}
}
}