    001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.4_testing/src/org/deegree/io/datastore/sde/SDEDatastore.java $
    002    /*----------------    FILE HEADER  ------------------------------------------
    003
    004     This file is part of deegree.
    005     Copyright (C) 2006 by: M.O.S.S. Computer Grafik Systeme GmbH
    006     Hohenbrunner Weg 13
    007     D-82024 Taufkirchen
    008     http://www.moss.de/
    009
    010     This library is free software; you can redistribute it and/or
    011     modify it under the terms of the GNU Lesser General Public
    012     License as published by the Free Software Foundation; either
    013     version 2.1 of the License, or (at your option) any later version.
    014
    015     This library is distributed in the hope that it will be useful,
    016     but WITHOUT ANY WARRANTY; without even the implied warranty of
    017     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    018     Lesser General Public License for more details.
    019
    020     You should have received a copy of the GNU Lesser General Public
    021     License along with this library; if not, write to the Free Software
    022     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    023
    024     ---------------------------------------------------------------------------*/
    025    package org.deegree.io.datastore.sde;
    026
    027    import org.deegree.datatypes.QualifiedName;
    028    import org.deegree.framework.log.ILogger;
    029    import org.deegree.framework.log.LoggerFactory;
    030    import org.deegree.io.JDBCConnection;
    031    import org.deegree.io.datastore.AnnotationDocument;
    032    import org.deegree.io.datastore.Datastore;
    033    import org.deegree.io.datastore.DatastoreConfiguration;
    034    import org.deegree.io.datastore.DatastoreException;
    035    import org.deegree.io.datastore.DatastoreTransaction;
    036    import org.deegree.io.datastore.schema.MappedFeatureType;
    037    import org.deegree.io.datastore.schema.MappedGMLSchema;
    038    import org.deegree.io.datastore.sql.SQLAnnotationDocument;
    039    import org.deegree.io.datastore.sql.SQLDatastoreConfiguration;
    040    import org.deegree.io.datastore.sql.StatementBuffer;
    041    import org.deegree.io.datastore.sql.TableAliasGenerator;
    042    import org.deegree.io.sdeapi.SDEAdapter;
    043    import org.deegree.io.sdeapi.SDEConnection;
    044    import org.deegree.io.sdeapi.SDEConnectionPool;
    045    import org.deegree.model.crs.CoordinateSystem;
    046    import org.deegree.model.feature.FeatureCollection;
    047    import org.deegree.model.filterencoding.Filter;
    048    import org.deegree.model.spatialschema.Geometry;
    049    import org.deegree.ogcwebservices.wfs.operation.Query;
    050
    051    import com.esri.sde.sdk.client.SeCoordinateReference;
    052    import com.esri.sde.sdk.client.SeQuery;
    053    import com.esri.sde.sdk.client.SeShape;
    054
    055    /**
    056     * Datastore implementation for an ESRI SDE database.
    057     *
    058     * @author <a href="mailto:cpollmann@moss.de">Christoph Pollmann</a>
    059     * @author last edited by: $Author: mschneider $
    060     *
    061     * @version $Revision: 23718 $, $Date: 2010-04-21 13:19:03 +0200 (Mi, 21. Apr 2010) $
    062     */
    063    public class SDEDatastore extends Datastore {
    064
    065        private static final ILogger LOG = LoggerFactory.getLogger( SDEDatastore.class );
    066
    067        private SDEConnectionPool pool = null;
    068
    069        @Override
    070        public AnnotationDocument getAnnotationParser() {
    071            return new SQLAnnotationDocument( this.getClass() );
    072        }
    073
    074        @Override
    075        public void configure( DatastoreConfiguration config )
    076                                throws DatastoreException {
    077            super.configure( config );
    078            this.pool = SDEConnectionPool.getInstance();
    079        }
    080
    081        @Override
    082        public DatastoreConfiguration getConfiguration() {
    083            return super.getConfiguration();
    084        }
    085
    086        @Override
    087        public void bindSchema( MappedGMLSchema schema )
    088                                throws DatastoreException {
    089            super.bindSchema( schema );
    090        }
    091
    092        @Override
    093        public MappedGMLSchema[] getSchemas() {
    094            return super.getSchemas();
    095        }
    096
    097        @Override
    098        public MappedFeatureType getFeatureType( QualifiedName ftName ) {
    099            return super.getFeatureType( ftName );
    100        }
    101
    102        @Override
    103        public void close()
    104                                throws DatastoreException {
    105            pool = null;
    106        }
    107
    108        @Override
    109        public FeatureCollection performQuery( final Query query, final MappedFeatureType[] rootFts )
    110                                throws DatastoreException {
    111
    112            FeatureCollection result = null;
    113            SDEConnection conn = acquireConnection();
    114            SDEQueryHandler queryHandler = new SDEQueryHandler( this, new TableAliasGenerator(), conn, rootFts, query );
    115            result = queryHandler.performQuery();
    116            releaseConnection( conn );
    117            return result;
    118        }
    119
    120        @Override
    121        public DatastoreTransaction acquireTransaction()
    122                                throws DatastoreException {
    123            DatastoreTransaction transactionHandler = new SDETransaction( this, new TableAliasGenerator(),
    124                                                                          acquireConnection() );
    125            return transactionHandler;
    126        }
    127
    128        /**
    129         * Returns a specific <code>WhereBuilder</code> implementation for SDE.
    130         *
    131         * @param rootFts
    132         * @param aliases
    133         * @param filter
    134         * @param aliasGenerator
    135         * @return a specific <code>WhereBuilder</code> implementation for SDE.
    136         * @throws DatastoreException
    137         */
    138        public SDEWhereBuilder getWhereBuilder( MappedFeatureType[] rootFts, String[] aliases, Filter filter,
    139                                                TableAliasGenerator aliasGenerator )
    140                                throws DatastoreException {
    141            SDEWhereBuilder wb = new SDEWhereBuilder( rootFts, aliases, filter, aliasGenerator );
    142            return wb;
    143        }
    144
    145        /**
    146         * Converts a database specific geometry <code>Object</code> from the <code>ResultSet</code> to a deegree
    147         * <code>Geometry</code>.
    148         *
    149         * @param value
    150         * @param coordinateSystem
    151         * @return corresponding deegree geometry
    152         * @throws DatastoreException
    153         */
    154        public Geometry convertDBToDegreeGeometry( Object value, CoordinateSystem coordinateSystem )
    155                                throws DatastoreException {
    156
    157            Geometry geometry = null;
    158            if ( value != null ) {
    159                try {
    160                    geometry = SDEAdapter.wrap( (SeShape) value, coordinateSystem );
    161                } catch ( Exception e ) {
    162                    throw new DatastoreException( "Error converting SeShape to Geometry: " + e.getMessage() );
    163                }
    164            }
    165            return geometry;
    166        }
    167
    168        /**
    169         * Converts a deegree <code>Geometry</code> to a database specific geometry <code>Object</code>.
    170         *
    171         * @param geometry
    172         * @return corresponding database specific geometry object
    173         * @throws DatastoreException
    174         */
    175        public Object convertDegreeToDBGeometry( Geometry geometry )
    176                                throws DatastoreException {
    177            Object value = null;
    178            if ( geometry != null ) {
    179                try {
    180                    // TODO: SRS handling
    181                    SeCoordinateReference coordRef = new SeCoordinateReference();
    182                    value = SDEAdapter.export( geometry, coordRef );
    183                } catch ( Exception e ) {
    184                    throw new DatastoreException( "Error converting Geometry to SeShape: " + e.getMessage(), e );
    185                }
    186            }
    187            return value;
    188        }
    189
    190        /**
    191         * Returns the database connection requested for.
    192         *
    193         * @return Connection
    194         * @throws DatastoreException
    195         */
    196        protected SDEConnection acquireConnection()
    197                                throws DatastoreException {
    198            JDBCConnection jdbcConnection = ( (SQLDatastoreConfiguration) this.getConfiguration() ).getJDBCConnection();
    199            SDEConnection conn = null;
    200            try {
    201                String url = jdbcConnection.getURL();
    202                String[] tmp = url.split( ":" );
    203                int instance = 5151;
    204                if ( 2 == tmp.length ) {
    205                    url = tmp[0];
    206                    instance = Integer.parseInt( tmp[1] );
    207                }
    208                conn = pool.acquireConnection( url, instance, jdbcConnection.getSDEDatabase(),
    209                                               jdbcConnection.getSDEVersion(), jdbcConnection.getUser(),
    210                                               jdbcConnection.getPassword() );
    211            } catch ( Exception e ) {
    212                String msg = "Cannot acquire database connection: " + e.getMessage();
    213                LOG.logInfo( msg );
    214                throw new DatastoreException( msg, e );
    215            }
    216            return conn;
    217        }
    218
    219        /**
    220         * Releases the connection.
    221         *
    222         * @param conn
    223         *            Connection to be released.
    224         * @throws DatastoreException
    225         */
    226        protected void releaseConnection( SDEConnection conn )
    227                                throws DatastoreException {
    228            JDBCConnection jdbcConnection = ( (SQLDatastoreConfiguration) this.getConfiguration() ).getJDBCConnection();
    229            try {
    230                String url = jdbcConnection.getURL();
    231                String[] tmp = url.split( ":" );
    232                int instance = 5151;
    233                if ( 2 == tmp.length ) {
    234                    url = tmp[0];
    235                    instance = Integer.parseInt( tmp[1] );
    236                }
    237                pool.releaseConnection( conn, url, instance, jdbcConnection.getSDEDatabase(),
    238                                        jdbcConnection.getSDEVersion(), jdbcConnection.getUser() );
    239            } catch ( Exception e ) {
    240                String msg = "Cannot release database connection: " + e.getMessage();
    241                LOG.logInfo( msg );
    242                throw new DatastoreException( msg, e );
    243            }
    244        }
    245
    246        /**
    247         * Converts the <code>StatementBuffer</code> into a <code>PreparedStatement</code>, which is initialized and
    248         * ready to be performed.
    249         *
    250         * @param conn
    251         *            connection to be used to create the <code>PreparedStatement</code>
    252         * @param statementBuffer
    253         * @return the <code>PreparedStatment</code>, ready to be performed
    254         */
    255        public SeQuery prepareStatement( SDEConnection conn, StatementBuffer statementBuffer ) {
    256            LOG.logDebug( "Preparing statement: " + statementBuffer.getQueryString() );
    257
    258            SeQuery query = null;
    259            try {
    260                query = new SeQuery( conn.getConnection() );
    261                query.prepareSql( statementBuffer.getQueryString() );
    262            } catch ( Exception e ) {
    263                e.printStackTrace();
    264            }
    265
    266            // TODO
    267            return query;
    268        }
    269
    270        @Override
    271        public FeatureCollection performQuery( Query query, MappedFeatureType[] rootFts, DatastoreTransaction context )
    272                                throws DatastoreException {
    273            throw new DatastoreException( "method invocation for sde not applicable" );
    274        }
    275
    276        @Override
    277        public void releaseTransaction( DatastoreTransaction ta )
    278                                throws DatastoreException {
    279            releaseConnection( ( (SDETransaction) ta ).getConnection() );
    280        }
    281    }