|
|
|
svn_geotools
|
Author: groldan
Date: 2009-07-07 11:55:29 -0400 (Tue, 07 Jul 2009) New Revision: 33511 Added: branches/2.5.x/modules/plugin/arcsde/common/ branches/2.5.x/modules/plugin/arcsde/common/pom.xml branches/2.5.x/modules/plugin/arcsde/common/src/ branches/2.5.x/modules/plugin/arcsde/common/src/main/ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/ArcSdeException.java branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/jndi/ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/jndi/ArcSDEConnectionFactory.java branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/jndi/SharedSessionPool.java branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/jndi/package-info.java branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionConfig.java branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionReference.java branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/Command.java branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/Commands.java branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ISession.java branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ISessionPool.java branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ISessionPoolFactory.java branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/SdeRow.java branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/Session.java branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/SessionPool.java branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/SessionPoolFactory.java branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/SessionWrapper.java branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/UnavailableArcSDEConnectionException.java branches/2.5.x/modules/plugin/arcsde/common/src/main/resources/ branches/2.5.x/modules/plugin/arcsde/common/src/test/ branches/2.5.x/modules/plugin/arcsde/common/src/test/java/ branches/2.5.x/modules/plugin/arcsde/common/src/test/java/org/ branches/2.5.x/modules/plugin/arcsde/common/src/test/java/org/geotools/ branches/2.5.x/modules/plugin/arcsde/common/src/test/java/org/geotools/arcsde/ branches/2.5.x/modules/plugin/arcsde/common/src/test/java/org/geotools/arcsde/jndi/ branches/2.5.x/modules/plugin/arcsde/common/src/test/java/org/geotools/arcsde/jndi/ArcSDEConnectionFactoryTest.java branches/2.5.x/modules/plugin/arcsde/common/src/test/java/org/geotools/arcsde/session/ branches/2.5.x/modules/plugin/arcsde/common/src/test/resources/ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/ArcSDEJNDIDataStoreFactory.java branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSDEDataStoreConfig.java branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/SessionTransactionState.java branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/session/ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionPool.java branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionPoolFactory.java branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/session/ArcSDEPooledConnection.java branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/ArcSDEJNDIDataStoreFactoryTest.java branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/session/ branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/session/SessionPoolTest.java Removed: branches/2.5.x/modules/plugin/arcsde/common/pom.xml branches/2.5.x/modules/plugin/arcsde/common/src/ branches/2.5.x/modules/plugin/arcsde/common/src/main/ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/ArcSdeException.java branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/jndi/ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/jndi/ArcSDEConnectionFactory.java branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/jndi/SharedSessionPool.java branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/jndi/package-info.java branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionConfig.java branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionReference.java branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/Command.java branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/Commands.java branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ISession.java branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ISessionPool.java branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ISessionPoolFactory.java branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/SdeRow.java branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/Session.java branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/SessionPool.java branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/SessionPoolFactory.java branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/SessionWrapper.java branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/UnavailableArcSDEConnectionException.java branches/2.5.x/modules/plugin/arcsde/common/src/main/resources/ branches/2.5.x/modules/plugin/arcsde/common/src/test/ branches/2.5.x/modules/plugin/arcsde/common/src/test/java/ branches/2.5.x/modules/plugin/arcsde/common/src/test/java/org/ branches/2.5.x/modules/plugin/arcsde/common/src/test/java/org/geotools/ branches/2.5.x/modules/plugin/arcsde/common/src/test/java/org/geotools/arcsde/ branches/2.5.x/modules/plugin/arcsde/common/src/test/java/org/geotools/arcsde/jndi/ branches/2.5.x/modules/plugin/arcsde/common/src/test/java/org/geotools/arcsde/jndi/ArcSDEConnectionFactoryTest.java branches/2.5.x/modules/plugin/arcsde/common/src/test/java/org/geotools/arcsde/session/ branches/2.5.x/modules/plugin/arcsde/common/src/test/resources/ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/ArcSdeException.java branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/SdeRow.java branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/pool/ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionPool.java branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionPoolFactory.java branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/session/ArcSDEPooledConnection.java branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/pool/ branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/session/SessionPoolTest.java Modified: branches/2.5.x/modules/plugin/arcsde/ branches/2.5.x/modules/plugin/arcsde/datastore/pom.xml branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/ArcSDEDataStoreFactory.java branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSDEAdapter.java branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSDEAttributeReader.java branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSDEDataStore.java branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSDEQuery.java branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSdeFeatureSource.java branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSdeFeatureStore.java branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSdeFeatureWriter.java branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcTransactionState.java branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/AutoCommitFeatureWriter.java branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/FIDReader.java branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/FeatureTypeInfoCache.java branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/versioning/ArcSdeVersionHandler.java branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/versioning/AutoCommitVersionHandler.java branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/versioning/TransactionVersionHandler.java branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/view/ColumnQualifier.java branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/view/ColumnReferenceQualifier.java branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/view/ExpressionQualifier.java branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/view/FromItemQualifier.java branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/view/ItemsListQualifier.java branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/view/OrderByElementQualifier.java branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/view/QueryInfoParser.java branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/view/SelectItemQualifier.java branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/view/SelectQualifier.java branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/view/SubSelectQualifier.java branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/view/TableQualifier.java branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/ArcSDEGridCoverage2DReaderJAI.java branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/ArcSDERasterFormat.java branches/2.5.x/modules/plugin/arcsde/datastore/src/main/resources/META-INF/services/org.geotools.data.DataStoreFactorySpi branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/ArcSDEDataStoreFactoryTest.java branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ArcSDEClobTest.java branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ArcSDEDataStoreNonSpatialTest.java branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ArcSDEDataStoreTest.java branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ArcSDEDataStoreVersioningTest.java branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ArcSDEFeatureSourceTest.java branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ArcSDEFeatureStoreTest.java branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ArcSDEFeatureStoreVersionedTest.java branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ArcSDEJavaApiTest.java branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ArcSDEQueryTest.java branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ClobTestData.java branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/FIDReaderTest.java branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/GeometryBuilderTest.java branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/InProcessViewSupportTestData.java branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/SDEJavaApiJoinTest.java branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/TestData.java branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/gce/ArcSDEGridCoverage2DReaderJAILegacyOnlineTest.java branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/gce/ArcSDEGridCoverage2DReaderJAIOnlineTest.java branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/gce/RasterInfoTest.java branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/gce/RasterTestData.java branches/2.5.x/modules/plugin/arcsde/pom.xml branches/2.5.x/modules/plugin/arcsde/sde-dummy/pom.xml Log: GEOT-2549 backport JNDI support from trunk to 2.5.x Property changes on: branches/2.5.x/modules/plugin/arcsde ___________________________________________________________________ Added: svn:mergeinfo + /trunk/modules/plugin/arcsde:31091-33502 Property changes on: branches/2.5.x/modules/plugin/arcsde/common ___________________________________________________________________ Added: svn:ignore + bin target Deleted: branches/2.5.x/modules/plugin/arcsde/common/pom.xml =================================================================== --- trunk/modules/plugin/arcsde/common/pom.xml 2009-07-07 01:13:56 UTC (rev 33502) +++ branches/2.5.x/modules/plugin/arcsde/common/pom.xml 2009-07-07 15:55:29 UTC (rev 33511) @@ -1,171 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- ======================================================================= - Maven Project Configuration File - - The Geotools Project - http://www.geotools.org/ - - Version: $Id$ - ======================================================================= --> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 - http://maven.apache.org/maven-v4_0_0.xsd"> - <modelVersion>4.0.0</modelVersion> - <parent> - <groupId>org.geotools</groupId> - <artifactId>arcsde-plugin</artifactId> - <version>2.6-SNAPSHOT</version> - </parent> - - - <!-- =========================================================== --> - <!-- Module Description --> - <!-- =========================================================== --> - <groupId>org.geotools</groupId> - <artifactId>gt-arcsde-common</artifactId> - <packaging>jar</packaging> - <name>ArcSDE support classes</name> - - - <scm> - <connection> - scm:svn:http://svn.osgeo.org/geotools/trunk/modules/plugin/arcsde/common/ - </connection> - <url>http://svn.osgeo.org/geotools/trunk/modules/plugin/arcsde/common/</url> - </scm> - - <description> ArcSDE support classes, including session pooling and JNDI support. </description> - <licenses> - <license> - <name>Lesser General Public License (LGPL)</name> - <url>http://www.gnu.org/copyleft/lesser.txt</url> - <distribution>repo</distribution> - </license> - </licenses> - - - <!-- =========================================================== --> - <!-- Developers and Contributors --> - <!-- =========================================================== --> - <developers> - <developer> - <name>Gabriel Roldan</name> - <id>groldan</id> - <email>[hidden email]</email> - <organization>OpenGeo</organization> - <organizationUrl>http://opengeo.org</organizationUrl> - <roles> - <role>Module Maintainer</role> - <role>Java Developer</role> - </roles> - </developer> - <developer> - <name>Jody Garnett</name> - <id>jgarnett</id> - <email>[hidden email]</email> - <organization>LISAsoft</organization> - <organizationUrl>http://www.lisasoft.com</organizationUrl> - <roles> - <role>Java Developer</role> - </roles> - </developer> - </developers> - - <!-- =========================================================== --> - <!-- Dependency Management --> - <!-- =========================================================== --> - <dependencies> - <dependency> - <groupId>commons-pool</groupId> - <artifactId>commons-pool</artifactId> - </dependency> - <dependency> - <groupId>simple-jndi</groupId> - <artifactId>simple-jndi</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.geotools</groupId> - <artifactId>gt-sample-data</artifactId> - <version>${project.version}</version> - <scope>test</scope> - </dependency> - </dependencies> - - - <!-- =========================================================== --> - <!-- Profile Configuration --> - <!-- =========================================================== --> - <profiles> - <profile> - <id>autoSDEDummyJars</id> - <activation> - <activeByDefault>true</activeByDefault> - </activation> - <dependencies> - <dependency> - <groupId>org.geotools</groupId> - <artifactId>gt-sde-dummy</artifactId> - <version>${project.version}</version> - <scope>provided</scope> - </dependency> - </dependencies> - <build> - <plugins> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-surefire-plugin</artifactId> - <configuration> - <!-- if we're using the dummy api, we should disable all tests --> - <excludes> - <exclude>**/*.java</exclude> - </excludes> - </configuration> - </plugin> - </plugins> - </build> - </profile> - <profile> - <id>arcsde</id> - <dependencies> - <dependency> - <groupId>com.esri</groupId> - <artifactId>jsde_sdk</artifactId> - <version>${sde.version}</version> - </dependency> - <dependency> - <groupId>com.esri</groupId> - <artifactId>jsde_jpe_sdk</artifactId> - <version>${sde.version}</version> - </dependency> - <dependency> - <groupId>com.ibm.icu</groupId> - <artifactId>icu4j</artifactId> - </dependency> - </dependencies> - <build> - <plugins> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-surefire-plugin</artifactId> - <configuration> - <!-- You need two things to run these tests successfully - 1) The esri ArcSDE jars installed. Either the 9.2 or 9.3 ones - from your ArcSDE Java SDK installation. - 2) A properly configured testparams.properties file. Make - sure it correctly references your SDE server with usernames and passwords - in there correctly. - - Since if you're building with the *real* SDE jars from SVN, I'd suggest - you enable these tests, just to make sure the SDE plugin is actually - correctly working right now! - --> - <includes> - <include>**/*Test.java</include> - </includes> - </configuration> - </plugin> - </plugins> - </build> - </profile> - </profiles> -</project> Copied: branches/2.5.x/modules/plugin/arcsde/common/pom.xml (from rev 33502, trunk/modules/plugin/arcsde/common/pom.xml) =================================================================== --- branches/2.5.x/modules/plugin/arcsde/common/pom.xml (rev 0) +++ branches/2.5.x/modules/plugin/arcsde/common/pom.xml 2009-07-07 15:55:29 UTC (rev 33511) @@ -0,0 +1,171 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- ======================================================================= + Maven Project Configuration File + + The Geotools Project + http://www.geotools.org/ + + Version: $Id$ + ======================================================================= --> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 + http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.geotools</groupId> + <artifactId>arcsde-plugin</artifactId> + <version>2.5-SNAPSHOT</version> + </parent> + + + <!-- =========================================================== --> + <!-- Module Description --> + <!-- =========================================================== --> + <groupId>org.geotools</groupId> + <artifactId>gt-arcsde-common</artifactId> + <packaging>jar</packaging> + <name>ArcSDE support classes</name> + + + <scm> + <connection> + scm:svn:http://svn.osgeo.org/geotools/trunk/modules/plugin/arcsde/common/ + </connection> + <url>http://svn.osgeo.org/geotools/trunk/modules/plugin/arcsde/common/</url> + </scm> + + <description> ArcSDE support classes, including session pooling and JNDI support. </description> + <licenses> + <license> + <name>Lesser General Public License (LGPL)</name> + <url>http://www.gnu.org/copyleft/lesser.txt</url> + <distribution>repo</distribution> + </license> + </licenses> + + + <!-- =========================================================== --> + <!-- Developers and Contributors --> + <!-- =========================================================== --> + <developers> + <developer> + <name>Gabriel Roldan</name> + <id>groldan</id> + <email>[hidden email]</email> + <organization>OpenGeo</organization> + <organizationUrl>http://opengeo.org</organizationUrl> + <roles> + <role>Module Maintainer</role> + <role>Java Developer</role> + </roles> + </developer> + <developer> + <name>Jody Garnett</name> + <id>jgarnett</id> + <email>[hidden email]</email> + <organization>LISAsoft</organization> + <organizationUrl>http://www.lisasoft.com</organizationUrl> + <roles> + <role>Java Developer</role> + </roles> + </developer> + </developers> + + <!-- =========================================================== --> + <!-- Dependency Management --> + <!-- =========================================================== --> + <dependencies> + <dependency> + <groupId>commons-pool</groupId> + <artifactId>commons-pool</artifactId> + </dependency> + <dependency> + <groupId>simple-jndi</groupId> + <artifactId>simple-jndi</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.geotools</groupId> + <artifactId>gt-sample-data</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + </dependencies> + + + <!-- =========================================================== --> + <!-- Profile Configuration --> + <!-- =========================================================== --> + <profiles> + <profile> + <id>autoSDEDummyJars</id> + <activation> + <activeByDefault>true</activeByDefault> + </activation> + <dependencies> + <dependency> + <groupId>org.geotools</groupId> + <artifactId>gt-sde-dummy</artifactId> + <version>${project.version}</version> + <scope>provided</scope> + </dependency> + </dependencies> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <!-- if we're using the dummy api, we should disable all tests --> + <excludes> + <exclude>**/*.java</exclude> + </excludes> + </configuration> + </plugin> + </plugins> + </build> + </profile> + <profile> + <id>arcsde</id> + <dependencies> + <dependency> + <groupId>com.esri</groupId> + <artifactId>jsde_sdk</artifactId> + <version>${sde.version}</version> + </dependency> + <dependency> + <groupId>com.esri</groupId> + <artifactId>jsde_jpe_sdk</artifactId> + <version>${sde.version}</version> + </dependency> + <dependency> + <groupId>com.ibm.icu</groupId> + <artifactId>icu4j</artifactId> + </dependency> + </dependencies> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <!-- You need two things to run these tests successfully + 1) The esri ArcSDE jars installed. Either the 9.2 or 9.3 ones + from your ArcSDE Java SDK installation. + 2) A properly configured testparams.properties file. Make + sure it correctly references your SDE server with usernames and passwords + in there correctly. + + Since if you're building with the *real* SDE jars from SVN, I'd suggest + you enable these tests, just to make sure the SDE plugin is actually + correctly working right now! + --> + <includes> + <include>**/*Test.java</include> + </includes> + </configuration> + </plugin> + </plugins> + </build> + </profile> + </profiles> +</project> Deleted: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/ArcSdeException.java =================================================================== --- trunk/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/ArcSdeException.java 2009-07-07 01:13:56 UTC (rev 33502) +++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/ArcSdeException.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -1,123 +0,0 @@ -/* - * 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.arcsde; - -import java.io.IOException; - -import com.esri.sde.sdk.client.SeError; -import com.esri.sde.sdk.client.SeException; - -/** - * An IOException that wraps an {@link SeException} in order to report the {@link SeError} messages - * that otherwise get hidden in a normal stack trace. - * - * @author Gabriel Roldan (TOPP) - * @version $Id$ - * @since 2.5 - * @source $URL: - * http://svn.geotools.org/geotools/trunk/gt/modules/plugin/arcsde/datastore/src/main/java - * /org/geotools/arcsde/ArcSdeException.java $ - */ -public class ArcSdeException extends IOException { - - private static final long serialVersionUID = -1392514883217797825L; - - public ArcSdeException(SeException cause) { - this("", cause); - } - - public ArcSdeException(String msg, SeException cause) { - super(msg); - if (cause != null) { - this.initCause(cause); - } - } - - @Override - public SeException getCause() { - return (SeException) super.getCause(); - } - - @Override - public String getMessage() { - String message = super.getMessage(); - SeError error = getSeError(); - StringBuffer sb = new StringBuffer(); - if (message != null) { - sb.append(message); - } - if (error != null) { - int sdeError = error.getSdeError(); - String sdeErrMsg = error.getSdeErrMsg(); - String extErrMsg = error.getExtErrMsg(); - String errDesc = error.getErrDesc(); - - sb.append("[SDE error ").append(sdeError); - if (sdeErrMsg != null && !"".equals(sdeErrMsg)) { - sb.append(" ").append(sdeErrMsg); - } - sb.append("]"); - if (errDesc != null && !"".equals(errDesc)) { - sb.append("[Error desc=").append(errDesc).append("]"); - } - if (extErrMsg != null && !"".equals(extErrMsg)) { - sb.append("[Extended desc=").append(extErrMsg).append("]"); - } - } - return sb.toString(); - } - - public SeError getSeError() { - SeException ex = getCause(); - if (ex == null) { - return null; - } - return ex.getSeError(); - } - - /** - * SeException is pretty sad (Caused by: com.esri.sde.sdk.client.SeException: ) leaving you to - * hunt and peck at the SeError for a good description of what went bad. - * <p> - * This class tries to grab as much information as possible form SeError. - * - * @return String describing the message from SeException. - */ - public static String toMessage(SeException e) { - StringBuffer buf = new StringBuffer(); - if (e.getSeError() != null) { - SeError error = e.getSeError(); - buf.append("SDE Error "); - buf.append(error.getSdeError()); - buf.append(" "); - buf.append(error.getSdeErrMsg()); - if (error.getExtErrMsg() != null) { - buf.append("\n"); - buf.append(error.getExtErrMsg()); - } - if (error.getErrDesc() != null) { - buf.append("\n"); - buf.append(error.getErrDesc()); - } - } - if (e.getMessage() != null) { - buf.append("\n"); - buf.append(e.getMessage()); - } - return buf.toString(); - } -} Copied: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/ArcSdeException.java (from rev 33502, trunk/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/ArcSdeException.java) =================================================================== --- branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/ArcSdeException.java (rev 0) +++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/ArcSdeException.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -0,0 +1,123 @@ +/* + * 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.arcsde; + +import java.io.IOException; + +import com.esri.sde.sdk.client.SeError; +import com.esri.sde.sdk.client.SeException; + +/** + * An IOException that wraps an {@link SeException} in order to report the {@link SeError} messages + * that otherwise get hidden in a normal stack trace. + * + * @author Gabriel Roldan (TOPP) + * @version $Id$ + * @since 2.5 + * @source $URL: + * http://svn.geotools.org/geotools/trunk/gt/modules/plugin/arcsde/datastore/src/main/java + * /org/geotools/arcsde/ArcSdeException.java $ + */ +public class ArcSdeException extends IOException { + + private static final long serialVersionUID = -1392514883217797825L; + + public ArcSdeException(SeException cause) { + this("", cause); + } + + public ArcSdeException(String msg, SeException cause) { + super(msg); + if (cause != null) { + this.initCause(cause); + } + } + + @Override + public SeException getCause() { + return (SeException) super.getCause(); + } + + @Override + public String getMessage() { + String message = super.getMessage(); + SeError error = getSeError(); + StringBuffer sb = new StringBuffer(); + if (message != null) { + sb.append(message); + } + if (error != null) { + int sdeError = error.getSdeError(); + String sdeErrMsg = error.getSdeErrMsg(); + String extErrMsg = error.getExtErrMsg(); + String errDesc = error.getErrDesc(); + + sb.append("[SDE error ").append(sdeError); + if (sdeErrMsg != null && !"".equals(sdeErrMsg)) { + sb.append(" ").append(sdeErrMsg); + } + sb.append("]"); + if (errDesc != null && !"".equals(errDesc)) { + sb.append("[Error desc=").append(errDesc).append("]"); + } + if (extErrMsg != null && !"".equals(extErrMsg)) { + sb.append("[Extended desc=").append(extErrMsg).append("]"); + } + } + return sb.toString(); + } + + public SeError getSeError() { + SeException ex = getCause(); + if (ex == null) { + return null; + } + return ex.getSeError(); + } + + /** + * SeException is pretty sad (Caused by: com.esri.sde.sdk.client.SeException: ) leaving you to + * hunt and peck at the SeError for a good description of what went bad. + * <p> + * This class tries to grab as much information as possible form SeError. + * + * @return String describing the message from SeException. + */ + public static String toMessage(SeException e) { + StringBuffer buf = new StringBuffer(); + if (e.getSeError() != null) { + SeError error = e.getSeError(); + buf.append("SDE Error "); + buf.append(error.getSdeError()); + buf.append(" "); + buf.append(error.getSdeErrMsg()); + if (error.getExtErrMsg() != null) { + buf.append("\n"); + buf.append(error.getExtErrMsg()); + } + if (error.getErrDesc() != null) { + buf.append("\n"); + buf.append(error.getErrDesc()); + } + } + if (e.getMessage() != null) { + buf.append("\n"); + buf.append(e.getMessage()); + } + return buf.toString(); + } +} Deleted: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/jndi/ArcSDEConnectionFactory.java =================================================================== --- trunk/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/jndi/ArcSDEConnectionFactory.java 2009-07-07 01:13:56 UTC (rev 33502) +++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/jndi/ArcSDEConnectionFactory.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -1,214 +0,0 @@ -/* - * http://geotools.org - * - * (C) 2002-2009, 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.arcsde.jndi; - -import static org.geotools.arcsde.session.ArcSDEConnectionConfig.CONNECTION_TIMEOUT_PARAM_NAME; -import static org.geotools.arcsde.session.ArcSDEConnectionConfig.INSTANCE_NAME_PARAM_NAME; -import static org.geotools.arcsde.session.ArcSDEConnectionConfig.MAX_CONNECTIONS_PARAM_NAME; -import static org.geotools.arcsde.session.ArcSDEConnectionConfig.MIN_CONNECTIONS_PARAM_NAME; -import static org.geotools.arcsde.session.ArcSDEConnectionConfig.PASSWORD_PARAM_NAME; -import static org.geotools.arcsde.session.ArcSDEConnectionConfig.PORT_NUMBER_PARAM_NAME; -import static org.geotools.arcsde.session.ArcSDEConnectionConfig.SERVER_NAME_PARAM_NAME; -import static org.geotools.arcsde.session.ArcSDEConnectionConfig.USER_NAME_PARAM_NAME; - -import java.io.IOException; -import java.util.Hashtable; -import java.util.Map; -import java.util.logging.Logger; - -import javax.naming.Context; -import javax.naming.Name; -import javax.naming.RefAddr; -import javax.naming.Reference; -import javax.naming.spi.ObjectFactory; - -import org.geotools.arcsde.session.ArcSDEConnectionConfig; -import org.geotools.arcsde.session.ISessionPool; -import org.geotools.arcsde.session.ISessionPoolFactory; -import org.geotools.arcsde.session.SessionPoolFactory; - -/** - * A {@link ObjectFactory} to create an ArcSDE {@link ISessionPool connection pool} to be JNDI - * managed. - * <p> - * This factory creates an {@link ISessionPool} out of the following mandatory parameters: - * <ul> - * <li> {@link ArcSDEConnectionConfig#SERVER_NAME_PARAM_NAME server} (String) the arcsde server name - * or IP address - * <li> {@link ArcSDEConnectionConfig#PORT_NUMBER_PARAM_NAME port} (Integer) the TCP/IP port number - * where ArcSDE is listening for connection requests - * <li> {@link ArcSDEConnectionConfig#INSTANCE_NAME_PARAM_NAME instance} (String) the name of the - * arcsde database - * <li> {@link ArcSDEConnectionConfig#USER_NAME_PARAM_NAME user} (String) the database user name to - * connect as - * <li> {@link ArcSDEConnectionConfig#PASSWORD_PARAM_NAME password} (String) the database user - * password - * </ul> - * And the following optional parameters: - * <ul> - * <li> {@link ArcSDEConnectionConfig#MIN_CONNECTIONS_PARAM_NAME pool.minConnections} (Integer) how - * many connections the connection pool shall be populated with at creation time - * <li> {@link ArcSDEConnectionConfig#MAX_CONNECTIONS_PARAM_NAME pool.maxConnections} (Integer) the - * maximum number of connections allowed to be held on the pool at any time - * <li> {@link ArcSDEConnectionConfig#CONNECTION_TIMEOUT_PARAM_NAME pool.timeOut} (Integer) how long - * to wait for an available connection before {@link ISessionPool#getSession()} fails, in - * milliseconds. - * </ul> - * </p> - * <p> - * See the package documentation for further information on how to configure JNDI resources for - * ArcSDE on GeoTools. - * </p> - * - * @author Gabriel Roldan (OpenGeo) - * @version $Id$ - * @since 2.5.7 - */ -public class ArcSDEConnectionFactory implements ObjectFactory { - - private static final Logger LOGGER = Logger.getLogger("org.geotools.arcsde.jndi"); - - private ISessionPoolFactory closablePoolFactory = SessionPoolFactory.getInstance(); - - /** - * @return an {@link ISessionPool} ready to be shared (ie, per connection option singleton). - * Whether shared or not is a matter of external JNDI configuration. - * @see ObjectFactory#getObjectInstance(Object, Name, Context, Hashtable) - */ - public Object getObjectInstance(final Object obj, final Name name, final Context nameCtx, - final Hashtable<?, ?> environment) throws Exception { - - final Reference ref = (Reference) obj; - - LOGGER.info("ArcSDEConnectionFactory: ref is " + ref); - - final String className = ref.getClassName(); - - LOGGER.info("ArcSDEConnectionFactory: className is " + className); - - // may an alternate SessionPoolFactory being set? - checkAlternateSessionPoolFactory(ref); - - Object dereferencedObject = null; - if (ISessionPool.class.getName().equals(className)) { - ArcSDEConnectionConfig config = createConfig(ref); - LOGGER.info("ArcSDEConnectionFactory: config is " + config); - - ISessionPool sharedPool = getSharedPool(config); - LOGGER.info("ArcSDEConnectionFactory: shared pool is " + sharedPool); - - dereferencedObject = sharedPool; - } else { - LOGGER.info("ArcSDEConnectionFactory: not a config"); - } - - return dereferencedObject; - } - - public ISessionPool getInstance(Map<String, String> properties) throws IOException { - ArcSDEConnectionConfig config = ArcSDEConnectionConfig.fromMap(properties); - validate(config); - ISessionPool sharedPool = getSharedPool(config); - return sharedPool; - } - - private void checkAlternateSessionPoolFactory(final Reference ref) { - String poolFactoryClassName = getProperty(ref, "sessionPoolFactory", null); - if (poolFactoryClassName == null) { - return; - } - - LOGGER.info("Using alternate session pool factory " + poolFactoryClassName); - final ISessionPoolFactory newFactory; - try { - Class<?> factoryClass = Class.forName(poolFactoryClassName); - newFactory = (ISessionPoolFactory) factoryClass.newInstance(); - - } catch (ClassNotFoundException e) { - throw new IllegalArgumentException("Alternate SessionPoolFactory class not found: " - + poolFactoryClassName); - } catch (InstantiationException e) { - throw new IllegalArgumentException(e); - } catch (IllegalAccessException e) { - throw new IllegalArgumentException(e); - } - setClosableSessionPoolFactory(newFactory); - } - - public void setClosableSessionPoolFactory(final ISessionPoolFactory newFactory) { - this.closablePoolFactory = newFactory; - } - - private ISessionPool getSharedPool(final ArcSDEConnectionConfig config) throws IOException { - ISessionPool sharedPool = SharedSessionPool.getInstance(config, closablePoolFactory); - return sharedPool; - } - - private ArcSDEConnectionConfig createConfig(final Reference ref) { - LOGGER.info("ArcSDEConnectionFactory: creating config"); - - String server = getProperty(ref, SERVER_NAME_PARAM_NAME, null); - String port = getProperty(ref, PORT_NUMBER_PARAM_NAME, null); - String user = getProperty(ref, USER_NAME_PARAM_NAME, null); - String password = getProperty(ref, PASSWORD_PARAM_NAME, null); - - String instance = getProperty(ref, INSTANCE_NAME_PARAM_NAME, null); - String minConnections = getProperty(ref, MIN_CONNECTIONS_PARAM_NAME, "1"); - String maxConnections = getProperty(ref, MAX_CONNECTIONS_PARAM_NAME, "6"); - String connTimeout = getProperty(ref, CONNECTION_TIMEOUT_PARAM_NAME, "500"); - - ArcSDEConnectionConfig config = new ArcSDEConnectionConfig(); - config.setServerName(server); - config.setPortNumber(Integer.parseInt(port)); - config.setDatabaseName(instance); - config.setUserName(user); - config.setPassword(password); - config.setMinConnections(Integer.parseInt(minConnections)); - config.setMaxConnections(Integer.parseInt(maxConnections)); - config.setConnTimeOut(Integer.parseInt(connTimeout)); - - validate(config); - - return config; - } - - private void validate(ArcSDEConnectionConfig config) { - if (config.getServerName() == null) { - throw new IllegalArgumentException("Missing param: " + SERVER_NAME_PARAM_NAME); - } - if (config.getPortNumber() == null) { - throw new IllegalArgumentException("Missing param: " + PORT_NUMBER_PARAM_NAME); - } - - if (config.getUserName() == null) { - throw new IllegalArgumentException("Missing param: " + USER_NAME_PARAM_NAME); - } - - if (config.getPassword() == null) { - throw new IllegalArgumentException("Missing param: " + PASSWORD_PARAM_NAME); - } - } - - protected String getProperty(final Reference ref, final String propName, final String defValue) { - final RefAddr addr = ref.get(propName); - if (addr == null) { - return defValue; - } - return (String) addr.getContent(); - } - -} Copied: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/jndi/ArcSDEConnectionFactory.java (from rev 33502, trunk/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/jndi/ArcSDEConnectionFactory.java) =================================================================== --- branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/jndi/ArcSDEConnectionFactory.java (rev 0) +++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/jndi/ArcSDEConnectionFactory.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -0,0 +1,214 @@ +/* + * http://geotools.org + * + * (C) 2002-2009, 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.arcsde.jndi; + +import static org.geotools.arcsde.session.ArcSDEConnectionConfig.CONNECTION_TIMEOUT_PARAM_NAME; +import static org.geotools.arcsde.session.ArcSDEConnectionConfig.INSTANCE_NAME_PARAM_NAME; +import static org.geotools.arcsde.session.ArcSDEConnectionConfig.MAX_CONNECTIONS_PARAM_NAME; +import static org.geotools.arcsde.session.ArcSDEConnectionConfig.MIN_CONNECTIONS_PARAM_NAME; +import static org.geotools.arcsde.session.ArcSDEConnectionConfig.PASSWORD_PARAM_NAME; +import static org.geotools.arcsde.session.ArcSDEConnectionConfig.PORT_NUMBER_PARAM_NAME; +import static org.geotools.arcsde.session.ArcSDEConnectionConfig.SERVER_NAME_PARAM_NAME; +import static org.geotools.arcsde.session.ArcSDEConnectionConfig.USER_NAME_PARAM_NAME; + +import java.io.IOException; +import java.util.Hashtable; +import java.util.Map; +import java.util.logging.Logger; + +import javax.naming.Context; +import javax.naming.Name; +import javax.naming.RefAddr; +import javax.naming.Reference; +import javax.naming.spi.ObjectFactory; + +import org.geotools.arcsde.session.ArcSDEConnectionConfig; +import org.geotools.arcsde.session.ISessionPool; +import org.geotools.arcsde.session.ISessionPoolFactory; +import org.geotools.arcsde.session.SessionPoolFactory; + +/** + * A {@link ObjectFactory} to create an ArcSDE {@link ISessionPool connection pool} to be JNDI + * managed. + * <p> + * This factory creates an {@link ISessionPool} out of the following mandatory parameters: + * <ul> + * <li> {@link ArcSDEConnectionConfig#SERVER_NAME_PARAM_NAME server} (String) the arcsde server name + * or IP address + * <li> {@link ArcSDEConnectionConfig#PORT_NUMBER_PARAM_NAME port} (Integer) the TCP/IP port number + * where ArcSDE is listening for connection requests + * <li> {@link ArcSDEConnectionConfig#INSTANCE_NAME_PARAM_NAME instance} (String) the name of the + * arcsde database + * <li> {@link ArcSDEConnectionConfig#USER_NAME_PARAM_NAME user} (String) the database user name to + * connect as + * <li> {@link ArcSDEConnectionConfig#PASSWORD_PARAM_NAME password} (String) the database user + * password + * </ul> + * And the following optional parameters: + * <ul> + * <li> {@link ArcSDEConnectionConfig#MIN_CONNECTIONS_PARAM_NAME pool.minConnections} (Integer) how + * many connections the connection pool shall be populated with at creation time + * <li> {@link ArcSDEConnectionConfig#MAX_CONNECTIONS_PARAM_NAME pool.maxConnections} (Integer) the + * maximum number of connections allowed to be held on the pool at any time + * <li> {@link ArcSDEConnectionConfig#CONNECTION_TIMEOUT_PARAM_NAME pool.timeOut} (Integer) how long + * to wait for an available connection before {@link ISessionPool#getSession()} fails, in + * milliseconds. + * </ul> + * </p> + * <p> + * See the package documentation for further information on how to configure JNDI resources for + * ArcSDE on GeoTools. + * </p> + * + * @author Gabriel Roldan (OpenGeo) + * @version $Id$ + * @since 2.5.7 + */ +public class ArcSDEConnectionFactory implements ObjectFactory { + + private static final Logger LOGGER = Logger.getLogger("org.geotools.arcsde.jndi"); + + private ISessionPoolFactory closablePoolFactory = SessionPoolFactory.getInstance(); + + /** + * @return an {@link ISessionPool} ready to be shared (ie, per connection option singleton). + * Whether shared or not is a matter of external JNDI configuration. + * @see ObjectFactory#getObjectInstance(Object, Name, Context, Hashtable) + */ + public Object getObjectInstance(final Object obj, final Name name, final Context nameCtx, + final Hashtable<?, ?> environment) throws Exception { + + final Reference ref = (Reference) obj; + + LOGGER.info("ArcSDEConnectionFactory: ref is " + ref); + + final String className = ref.getClassName(); + + LOGGER.info("ArcSDEConnectionFactory: className is " + className); + + // may an alternate SessionPoolFactory being set? + checkAlternateSessionPoolFactory(ref); + + Object dereferencedObject = null; + if (ISessionPool.class.getName().equals(className)) { + ArcSDEConnectionConfig config = createConfig(ref); + LOGGER.info("ArcSDEConnectionFactory: config is " + config); + + ISessionPool sharedPool = getSharedPool(config); + LOGGER.info("ArcSDEConnectionFactory: shared pool is " + sharedPool); + + dereferencedObject = sharedPool; + } else { + LOGGER.info("ArcSDEConnectionFactory: not a config"); + } + + return dereferencedObject; + } + + public ISessionPool getInstance(Map<String, String> properties) throws IOException { + ArcSDEConnectionConfig config = ArcSDEConnectionConfig.fromMap(properties); + validate(config); + ISessionPool sharedPool = getSharedPool(config); + return sharedPool; + } + + private void checkAlternateSessionPoolFactory(final Reference ref) { + String poolFactoryClassName = getProperty(ref, "sessionPoolFactory", null); + if (poolFactoryClassName == null) { + return; + } + + LOGGER.info("Using alternate session pool factory " + poolFactoryClassName); + final ISessionPoolFactory newFactory; + try { + Class<?> factoryClass = Class.forName(poolFactoryClassName); + newFactory = (ISessionPoolFactory) factoryClass.newInstance(); + + } catch (ClassNotFoundException e) { + throw new IllegalArgumentException("Alternate SessionPoolFactory class not found: " + + poolFactoryClassName); + } catch (InstantiationException e) { + throw new IllegalArgumentException(e); + } catch (IllegalAccessException e) { + throw new IllegalArgumentException(e); + } + setClosableSessionPoolFactory(newFactory); + } + + public void setClosableSessionPoolFactory(final ISessionPoolFactory newFactory) { + this.closablePoolFactory = newFactory; + } + + private ISessionPool getSharedPool(final ArcSDEConnectionConfig config) throws IOException { + ISessionPool sharedPool = SharedSessionPool.getInstance(config, closablePoolFactory); + return sharedPool; + } + + private ArcSDEConnectionConfig createConfig(final Reference ref) { + LOGGER.info("ArcSDEConnectionFactory: creating config"); + + String server = getProperty(ref, SERVER_NAME_PARAM_NAME, null); + String port = getProperty(ref, PORT_NUMBER_PARAM_NAME, null); + String user = getProperty(ref, USER_NAME_PARAM_NAME, null); + String password = getProperty(ref, PASSWORD_PARAM_NAME, null); + + String instance = getProperty(ref, INSTANCE_NAME_PARAM_NAME, null); + String minConnections = getProperty(ref, MIN_CONNECTIONS_PARAM_NAME, "1"); + String maxConnections = getProperty(ref, MAX_CONNECTIONS_PARAM_NAME, "6"); + String connTimeout = getProperty(ref, CONNECTION_TIMEOUT_PARAM_NAME, "500"); + + ArcSDEConnectionConfig config = new ArcSDEConnectionConfig(); + config.setServerName(server); + config.setPortNumber(Integer.parseInt(port)); + config.setDatabaseName(instance); + config.setUserName(user); + config.setPassword(password); + config.setMinConnections(Integer.parseInt(minConnections)); + config.setMaxConnections(Integer.parseInt(maxConnections)); + config.setConnTimeOut(Integer.parseInt(connTimeout)); + + validate(config); + + return config; + } + + private void validate(ArcSDEConnectionConfig config) { + if (config.getServerName() == null) { + throw new IllegalArgumentException("Missing param: " + SERVER_NAME_PARAM_NAME); + } + if (config.getPortNumber() == null) { + throw new IllegalArgumentException("Missing param: " + PORT_NUMBER_PARAM_NAME); + } + + if (config.getUserName() == null) { + throw new IllegalArgumentException("Missing param: " + USER_NAME_PARAM_NAME); + } + + if (config.getPassword() == null) { + throw new IllegalArgumentException("Missing param: " + PASSWORD_PARAM_NAME); + } + } + + protected String getProperty(final Reference ref, final String propName, final String defValue) { + final RefAddr addr = ref.get(propName); + if (addr == null) { + return defValue; + } + return (String) addr.getContent(); + } + +} Deleted: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/jndi/SharedSessionPool.java =================================================================== --- trunk/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/jndi/SharedSessionPool.java 2009-07-07 01:13:56 UTC (rev 33502) +++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/jndi/SharedSessionPool.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -1,143 +0,0 @@ -/* - * GeoTools - The Open Source Java GIS Toolkit - * http://geotools.org - * - * (C) 2002-2009, 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.arcsde.jndi; - -import java.io.IOException; -import java.util.Collections; -import java.util.Map; -import java.util.WeakHashMap; -import java.util.logging.Logger; - -import org.geotools.arcsde.session.ArcSDEConnectionConfig; -import org.geotools.arcsde.session.ISession; -import org.geotools.arcsde.session.ISessionPool; -import org.geotools.arcsde.session.ISessionPoolFactory; -import org.geotools.arcsde.session.UnavailableArcSDEConnectionException; - -/** - * A {@link ISessionPool session pool} that is not closable and hence can be shared between - * different applications/datastores when referenced by a JNDI context. - * - * - * @author Gabriel Roldan (OpenGeo) - * @version $Id$ - * @since 2.5.7 - * - */ -final class SharedSessionPool implements ISessionPool { - - private static final Logger LOGGER = Logger.getLogger("org.geotools.arcsde.session"); - - private static int instanceCounter; - - private final int instanceNumber; - - private final ISessionPool delegate; - - private static final Map<ArcSDEConnectionConfig, SharedSessionPool> instances = Collections - .synchronizedMap(new WeakHashMap<ArcSDEConnectionConfig, SharedSessionPool>()); - - protected SharedSessionPool(final ISessionPool delegate) throws IOException { - this.delegate = delegate; - this.instanceNumber = ++instanceCounter; - } - - public static ISessionPool getInstance(final ArcSDEConnectionConfig config, - final ISessionPoolFactory factory) throws IOException { - LOGGER.info("Getting shared session pool for " + config); - if (!instances.containsKey(config)) { - synchronized (instances) { - if (!instances.containsKey(config)) { - LOGGER.info("Creating shared session pool for " + config); - ISessionPool pool = factory.createPool(config); - SharedSessionPool sharedPool = new SharedSessionPool(pool); - instances.put(config, sharedPool); - LOGGER.info("Created shared pool " + sharedPool); - } - } - } - - SharedSessionPool sharedPool = instances.get(config); - LOGGER.info("Returning shared session pool " + sharedPool); - - return sharedPool; - } - - @Override - protected void finalize() { - LOGGER.info("Destroying session pool for " + getConfig()); - delegate.close(); - } - - /** - * @see ISessionPool#close() - */ - public void close() { - LOGGER.info("Ignoring SessionPool close, this is a shared pool"); - } - - /** - * @see ISessionPool#getAvailableCount() - */ - public int getAvailableCount() { - return delegate.getAvailableCount(); - } - - /** - * @see ISessionPool#getConfig() - */ - public ArcSDEConnectionConfig getConfig() { - return delegate.getConfig(); - } - - /** - * @see ISessionPool#getInUseCount() - */ - public int getInUseCount() { - return delegate.getInUseCount(); - } - - /** - * @see ISessionPool#getPoolSize() - */ - public int getPoolSize() { - return delegate.getPoolSize(); - } - - /** - * @see ISessionPool#getSession() - */ - public ISession getSession() throws IOException, UnavailableArcSDEConnectionException { - return delegate.getSession(); - } - - /** - * @see ISessionPool#isClosed() - */ - public boolean isClosed() { - return delegate.isClosed(); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(getClass().getSimpleName()); - sb.append("[(").append(instanceNumber).append("), "); - sb.append("delegate=").append(delegate).append("]"); - return sb.toString(); - } -} Copied: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/jndi/SharedSessionPool.java (from rev 33502, trunk/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/jndi/SharedSessionPool.java) =================================================================== --- branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/jndi/SharedSessionPool.java (rev 0) +++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/jndi/SharedSessionPool.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -0,0 +1,143 @@ +/* + * GeoTools - The Open Source Java GIS Toolkit + * http://geotools.org + * + * (C) 2002-2009, 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.arcsde.jndi; + +import java.io.IOException; +import java.util.Collections; +import java.util.Map; +import java.util.WeakHashMap; +import java.util.logging.Logger; + +import org.geotools.arcsde.session.ArcSDEConnectionConfig; +import org.geotools.arcsde.session.ISession; +import org.geotools.arcsde.session.ISessionPool; +import org.geotools.arcsde.session.ISessionPoolFactory; +import org.geotools.arcsde.session.UnavailableArcSDEConnectionException; + +/** + * A {@link ISessionPool session pool} that is not closable and hence can be shared between + * different applications/datastores when referenced by a JNDI context. + * + * + * @author Gabriel Roldan (OpenGeo) + * @version $Id$ + * @since 2.5.7 + * + */ +final class SharedSessionPool implements ISessionPool { + + private static final Logger LOGGER = Logger.getLogger("org.geotools.arcsde.session"); + + private static int instanceCounter; + + private final int instanceNumber; + + private final ISessionPool delegate; + + private static final Map<ArcSDEConnectionConfig, SharedSessionPool> instances = Collections + .synchronizedMap(new WeakHashMap<ArcSDEConnectionConfig, SharedSessionPool>()); + + protected SharedSessionPool(final ISessionPool delegate) throws IOException { + this.delegate = delegate; + this.instanceNumber = ++instanceCounter; + } + + public static ISessionPool getInstance(final ArcSDEConnectionConfig config, + final ISessionPoolFactory factory) throws IOException { + LOGGER.info("Getting shared session pool for " + config); + if (!instances.containsKey(config)) { + synchronized (instances) { + if (!instances.containsKey(config)) { + LOGGER.info("Creating shared session pool for " + config); + ISessionPool pool = factory.createPool(config); + SharedSessionPool sharedPool = new SharedSessionPool(pool); + instances.put(config, sharedPool); + LOGGER.info("Created shared pool " + sharedPool); + } + } + } + + SharedSessionPool sharedPool = instances.get(config); + LOGGER.info("Returning shared session pool " + sharedPool); + + return sharedPool; + } + + @Override + protected void finalize() { + LOGGER.info("Destroying session pool for " + getConfig()); + delegate.close(); + } + + /** + * @see ISessionPool#close() + */ + public void close() { + LOGGER.info("Ignoring SessionPool close, this is a shared pool"); + } + + /** + * @see ISessionPool#getAvailableCount() + */ + public int getAvailableCount() { + return delegate.getAvailableCount(); + } + + /** + * @see ISessionPool#getConfig() + */ + public ArcSDEConnectionConfig getConfig() { + return delegate.getConfig(); + } + + /** + * @see ISessionPool#getInUseCount() + */ + public int getInUseCount() { + return delegate.getInUseCount(); + } + + /** + * @see ISessionPool#getPoolSize() + */ + public int getPoolSize() { + return delegate.getPoolSize(); + } + + /** + * @see ISessionPool#getSession() + */ + public ISession getSession() throws IOException, UnavailableArcSDEConnectionException { + return delegate.getSession(); + } + + /** + * @see ISessionPool#isClosed() + */ + public boolean isClosed() { + return delegate.isClosed(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(getClass().getSimpleName()); + sb.append("[(").append(instanceNumber).append("), "); + sb.append("delegate=").append(delegate).append("]"); + return sb.toString(); + } +} Deleted: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/jndi/package-info.java =================================================================== --- trunk/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/jndi/package-info.java 2009-07-07 01:13:56 UTC (rev 33502) +++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/jndi/package-info.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -1,206 +0,0 @@ -/** - * This package contains relevant classes to support configuring a GeoTools ArcSDE - * <code>ISessionPool</code> (a pool of connections to an ArcSDE server) inside a Java Naming and - * Directory Interface (JNDI) context. - * <p> - * Since ArcSDE uses a legacy protocol to communicate between the ArcSDE service instance and the - * ArcSDE Java API, and it's not possible to connect to an ArcSDE service through the java JDBC API, - * we can't use the standard <code>javax.sql.DataSource</code> object factories. Hence, we provide a - * custom <code>javax.naming.ObjectFactory</code> specialized in creating ArcSDE connection pools - * for the GeoTools library. - * </p> - * <h3>Configuration inside a J2EE Container</h3> - * <p> - * The JNDI specification acts only at the API level, so how to configure a given resource to be accessible - * through JNDI is J2EE Container specific. Some of them provide a means to configure an - * ObjectFactory to provide a specific kind of resource (whether it is a JDBC DataSource, a standard - * Java Bean or any other object type). For instance, the Apache Tomcat container provides such a - * mechanism, but the JBoss Application Server does not, even though it uses Apache Tomcat - * internally. - * </p> - * - * <h4>Classpath configuration for container-wide shared connection pools</h4> - * <p> - * Whether an ArcSDE connection pool is going to be shared among different web applications - * on the same J2EE container is a matter of how you lay out the ArcSDE Jars on the classpath. - * That is, if you want to achieve a container instance wide shared session pool (for example - * to have various GeoServer instances sharing the same connection pool), you need to drop - * certain jar files in the container's shared libraries folder instead of inside - * {@code <geoserver war>/WEB-INF/lib}. For instance, the following jars shall be put on such - * a shared library directory: - * <ul> - * <li>{@code jsde_sdk.jar, jpe_sdk.jar and icu4j.jar} from your ArcSDE Java SDK installation. - * <li>{@code gt-arcsde-common-<version>.jar} - * <li>{@code commons-pool-1.3.jar} (or whatever commons-pool version the gt-arcsde-common depends on) - * </ul> - * gt-arcsde-<GT Version>.jar, which provides the actual DataStore implementation may be placed - * inside your app's {@code WEB-INF/lib} directory though. - * </p> - * <p> - * The following are configuration examples to set up <a href="http://geosever.org">GeoServer</a> - * for Tomcat and JBoss with ArcSDE JNDI support, but apply to any other web application where you - * want to use GeoTools with ArcSDE and JNDI. - * </p> - * <p> - * First off, you need to add an entry on the web application's WEB-INF/web.xml file to indicate the - * JNDI resource that's going to be available for the application. Open the WEB-INF/web.xml file - * and add an entry as the following as the last element before {@code </web-app>}: - * - * <pre> - * <code> - * <resource-ref> - * <description>JNDI arcsde resource configuration</description> - * <res-ref-name>geotools/arcsde</res-ref-name> - * <res-type>org.geotools.arcsde.session.ISessionPool</res-type> - * <res-auth>Container</res-auth> - * </resource-ref> - * </code> - * </pre> - * Where the values for description and res-ref-name are of your choice, res-ref-name being the path under - * which the arcsde connection pool is configured on your JNDI container (see bellow for instructions on how - * to configure such a resource on Tomcat and JBoss). - * </p> - * <h4>Configuration in Tomcat</h4> - * <p> - * <ul> - * <li>Copy the {@code jsde_sdk.jar, jpe_sdk.jar, icu4j.jar, commons-pool-1.3.jar and gt-arcsde-common-<version>.jar} - * files to the Tomcat shared libs folder (either <catalina home>/lib or <catalina home>/common/lib folder, - * depending on your Tomcat version). - * <li>Expand geoserver.war into <catalina home>/webapps - * <li>copy {@code gt-arcsde-<version>.jar} to <catalina home>/webapps/geoserver/WEB-INF/lib - * </ul> - * Finally, configure the {@link ArcSDEConnectionFactory ArcSDE Connection Factory} as explained in the - * <i>Adding Custom Resource Factories</i> section of the Tomcat's - * <a href="http://tomcat.apache.org/tomcat-6.0-doc/jndi-resources-howto.html">JNDI Resources HOW-TO</a>. That is, - * add an entry as the following to the file {@code <catalina home>/conf/context.xml} as a child of the root - * {@code <Context>} element: - * <pre> - * <code> - * <Resource name="geotools/arcsde" auth="Container" type="org.geotools.arcsde.session.ISessionPool" - * factory="org.geotools.arcsde.jndi.ArcSDEConnectionFactory" - * server="<arcsde server>" - * user="<arcsde user name>" - * password="<arcsde user password>" - * instance="<arcsde database name>" - * port="<arcsde instance port number>" - * /> - * </code> - * </pre> - * - * And that's it. Now you're able to select the <i>ArcSDE JNDI</i> DataStore factory and use the {@code "geotools/arcsde"} - * (or whatever entry name of your choice) as the DataStore's JNDI resource path name. - * </p> - * - * <h4>Configuration in JBoss Application Server (4.0.3+)</h4> - * <p> - * JBoss provides an extensible mechanism to configure any kind of object as a JNDI resource - * starting with JBoss version <b>4.0.3</b>. Prior versions do not provide this mechanism and hence - * it is not possible to configure a GeoTools ArcSDE connection pool for versions lower than 4.0.3. - * Disregard what the JBoss documentation says on its <a href="http://www.jboss.org/file-access/default/members/jbossweb/freezone/docs/latest/jndi-resources-howto.html" - * >JNDI Resources HOW-TO</a> , that seems to be a verbatim copy of the Tomcat documentation but is - * just not supported. - * </p> - * <p> - * To configure a JNDI ArcSDE session pool on JBoss, you need to create an xml file containing the managed bean definition - * that configures the ArcSDE connection pool. You can call this file as you want, for example {@code geoserver-service.xml}, - * and place it on the deploy folder for the JBoss configuration that you're going to run. - * For example, {@code <jboss installation dir>/server/default/deploy/geoserver-service.xml} - * </p> - * <p> - * The contents of the {@code geoserver-service.xml} file shall be as following. For more information about this kind of - * configuration consult the JBoss' <a href="http://www.jboss.org/community/wiki/JNDIBindingServiceMgr">JNDIBindingServiceMgr</a> - * documentation. - * <pre> - * <code> - * <?xml version="1.0" encoding="UTF-8"?> - * <!DOCTYPE server PUBLIC "-//JBoss//DTD MBean Service 4.0//EN" - * "http://www.jboss.org/j2ee/dtd/jboss-service_4_0.dtd"> - * <server> - * <mbean code="org.jboss.naming.JNDIBindingServiceMgr" - * name="jboss.tests:service=JNDIBindingServiceMgr"> - * <attribute name="BindingsConfig" serialDataType="jbxb"> - * <jndi:bindings - * xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" - * xmlns:jndi="urn:jboss:jndi-binding-service:1.0" - * xs:schemaLocation="urn:jboss:jndi-binding-service:1.0 resource:jndi-binding-service_1_0.xsd"> - * - * <jndi:binding name="geotools/arcsdeGlobal"> - * <java:properties xmlns:java="urn:jboss:java-properties" - * xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" - * xs:schemaLocation="urn:jboss:java-properties resource:java-properties_1_0.xsd"> - * <java:property> - * <java:key>server</java:key> - * <java:value>172.16.241.128</java:value> - * </java:property> - * <java:property> - * <java:key>port</java:key> - * <java:value>5151</java:value> - * </java:property> - * <java:property> - * <java:key>instance</java:key> - * <java:value>sde</java:value> - * </java:property> - * <java:property> - * <java:key>user</java:key> - * <java:value>sde</java:value> - * </java:property> - * <java:property> - * <java:key>password</java:key> - * <java:value>sde</java:value> - * </java:property> - * <java:property> - * <java:key>pool.minConnections</java:key> - * <java:value>2</java:value> - * </java:property> - * <java:property> - * <java:key>pool.maxConnections</java:key> - * <java:value>10</java:value> - * </java:property> - * <java:property> - * <java:key>pool.timeOut</java:key> - * <java:value>1000</java:value> - * </java:property> - * </java:properties> - * </jndi:binding> - * - * </jndi:bindings> - * </attribute> - * <depends>jboss:service=Naming</depends> - * </mbean> - * </server> - * </code> - * </pre> - * </p> - * <p> - * What we're doing here is to create a {@code java.util.Properties} object containing the connection parameters, and storing - * it on the JNDI container at the {@code geotools/arcsdeGlobal} path. This is going to be a globally accessible resource that - * the {@link ArcSDEConnectionFactory} will use to create the appropriate {@link org.geotools.arcsde.session.ISessionPool connection pool}. - * </p> - * <p> - * But to get this resource visible to your web application, there's one more step missing. In addition to the resource-ref - * entry in {@code WEB-INF/web.xml} mentioned above, JBoss requires an extra config file to manage the indirection between - * your web application and the globally configured JNDI resource. - * You'll need to create a file called {@code jboss-web.xml} as a sibling of {@code WEB-INF/web.xml} with the following content: - * <pre> - * <code> - * <?xml version="1.0" encoding="UTF-8"?> - * <jboss-web> - * <resource-ref> - * <res-ref-name>geotools/arcsde</res-ref-name> - * <res-type>org.geotools.arcsde.session.ISessionPool</res-type> - * <jndi-name>geotools/arcsdeGlobal</jndi-name> - * </resource-ref> - * </jboss-web> - * </code> - * </pre> - * Where {@code geotools/arcsdeGlobal} is the name of the globally configured resource, and {@code geotools/arcsde} - * is the JNDI name by which the resource will actually be accessible to your web application, and shall match - * the name used for the resource-ref entry in {@code WEB-INF/web.xml}. - * </p> - * <p> - * Now you're ready to select the <i>ArcSDE JNDI</i> DataStore factory and use the {@code "geotools/arcsde"} - * (or whatever entry name of your choice you have configured) as the DataStore's JNDI resource path name. - * </p> - */ -package org.geotools.arcsde.jndi; - Copied: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/jndi/package-info.java (from rev 33502, trunk/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/jndi/package-info.java) =================================================================== --- branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/jndi/package-info.java (rev 0) +++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/jndi/package-info.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -0,0 +1,206 @@ +/** + * This package contains relevant classes to support configuring a GeoTools ArcSDE + * <code>ISessionPool</code> (a pool of connections to an ArcSDE server) inside a Java Naming and + * Directory Interface (JNDI) context. + * <p> + * Since ArcSDE uses a legacy protocol to communicate between the ArcSDE service instance and the + * ArcSDE Java API, and it's not possible to connect to an ArcSDE service through the java JDBC API, + * we can't use the standard <code>javax.sql.DataSource</code> object factories. Hence, we provide a + * custom <code>javax.naming.ObjectFactory</code> specialized in creating ArcSDE connection pools + * for the GeoTools library. + * </p> + * <h3>Configuration inside a J2EE Container</h3> + * <p> + * The JNDI specification acts only at the API level, so how to configure a given resource to be accessible + * through JNDI is J2EE Container specific. Some of them provide a means to configure an + * ObjectFactory to provide a specific kind of resource (whether it is a JDBC DataSource, a standard + * Java Bean or any other object type). For instance, the Apache Tomcat container provides such a + * mechanism, but the JBoss Application Server does not, even though it uses Apache Tomcat + * internally. + * </p> + * + * <h4>Classpath configuration for container-wide shared connection pools</h4> + * <p> + * Whether an ArcSDE connection pool is going to be shared among different web applications + * on the same J2EE container is a matter of how you lay out the ArcSDE Jars on the classpath. + * That is, if you want to achieve a container instance wide shared session pool (for example + * to have various GeoServer instances sharing the same connection pool), you need to drop + * certain jar files in the container's shared libraries folder instead of inside + * {@code <geoserver war>/WEB-INF/lib}. For instance, the following jars shall be put on such + * a shared library directory: + * <ul> + * <li>{@code jsde_sdk.jar, jpe_sdk.jar and icu4j.jar} from your ArcSDE Java SDK installation. + * <li>{@code gt-arcsde-common-<version>.jar} + * <li>{@code commons-pool-1.3.jar} (or whatever commons-pool version the gt-arcsde-common depends on) + * </ul> + * gt-arcsde-<GT Version>.jar, which provides the actual DataStore implementation may be placed + * inside your app's {@code WEB-INF/lib} directory though. + * </p> + * <p> + * The following are configuration examples to set up <a href="http://geosever.org">GeoServer</a> + * for Tomcat and JBoss with ArcSDE JNDI support, but apply to any other web application where you + * want to use GeoTools with ArcSDE and JNDI. + * </p> + * <p> + * First off, you need to add an entry on the web application's WEB-INF/web.xml file to indicate the + * JNDI resource that's going to be available for the application. Open the WEB-INF/web.xml file + * and add an entry as the following as the last element before {@code </web-app>}: + * + * <pre> + * <code> + * <resource-ref> + * <description>JNDI arcsde resource configuration</description> + * <res-ref-name>geotools/arcsde</res-ref-name> + * <res-type>org.geotools.arcsde.session.ISessionPool</res-type> + * <res-auth>Container</res-auth> + * </resource-ref> + * </code> + * </pre> + * Where the values for description and res-ref-name are of your choice, res-ref-name being the path under + * which the arcsde connection pool is configured on your JNDI container (see bellow for instructions on how + * to configure such a resource on Tomcat and JBoss). + * </p> + * <h4>Configuration in Tomcat</h4> + * <p> + * <ul> + * <li>Copy the {@code jsde_sdk.jar, jpe_sdk.jar, icu4j.jar, commons-pool-1.3.jar and gt-arcsde-common-<version>.jar} + * files to the Tomcat shared libs folder (either <catalina home>/lib or <catalina home>/common/lib folder, + * depending on your Tomcat version). + * <li>Expand geoserver.war into <catalina home>/webapps + * <li>copy {@code gt-arcsde-<version>.jar} to <catalina home>/webapps/geoserver/WEB-INF/lib + * </ul> + * Finally, configure the {@link ArcSDEConnectionFactory ArcSDE Connection Factory} as explained in the + * <i>Adding Custom Resource Factories</i> section of the Tomcat's + * <a href="http://tomcat.apache.org/tomcat-6.0-doc/jndi-resources-howto.html">JNDI Resources HOW-TO</a>. That is, + * add an entry as the following to the file {@code <catalina home>/conf/context.xml} as a child of the root + * {@code <Context>} element: + * <pre> + * <code> + * <Resource name="geotools/arcsde" auth="Container" type="org.geotools.arcsde.session.ISessionPool" + * factory="org.geotools.arcsde.jndi.ArcSDEConnectionFactory" + * server="<arcsde server>" + * user="<arcsde user name>" + * password="<arcsde user password>" + * instance="<arcsde database name>" + * port="<arcsde instance port number>" + * /> + * </code> + * </pre> + * + * And that's it. Now you're able to select the <i>ArcSDE JNDI</i> DataStore factory and use the {@code "geotools/arcsde"} + * (or whatever entry name of your choice) as the DataStore's JNDI resource path name. + * </p> + * + * <h4>Configuration in JBoss Application Server (4.0.3+)</h4> + * <p> + * JBoss provides an extensible mechanism to configure any kind of object as a JNDI resource + * starting with JBoss version <b>4.0.3</b>. Prior versions do not provide this mechanism and hence + * it is not possible to configure a GeoTools ArcSDE connection pool for versions lower than 4.0.3. + * Disregard what the JBoss documentation says on its <a href="http://www.jboss.org/file-access/default/members/jbossweb/freezone/docs/latest/jndi-resources-howto.html" + * >JNDI Resources HOW-TO</a> , that seems to be a verbatim copy of the Tomcat documentation but is + * just not supported. + * </p> + * <p> + * To configure a JNDI ArcSDE session pool on JBoss, you need to create an xml file containing the managed bean definition + * that configures the ArcSDE connection pool. You can call this file as you want, for example {@code geoserver-service.xml}, + * and place it on the deploy folder for the JBoss configuration that you're going to run. + * For example, {@code <jboss installation dir>/server/default/deploy/geoserver-service.xml} + * </p> + * <p> + * The contents of the {@code geoserver-service.xml} file shall be as following. For more information about this kind of + * configuration consult the JBoss' <a href="http://www.jboss.org/community/wiki/JNDIBindingServiceMgr">JNDIBindingServiceMgr</a> + * documentation. + * <pre> + * <code> + * <?xml version="1.0" encoding="UTF-8"?> + * <!DOCTYPE server PUBLIC "-//JBoss//DTD MBean Service 4.0//EN" + * "http://www.jboss.org/j2ee/dtd/jboss-service_4_0.dtd"> + * <server> + * <mbean code="org.jboss.naming.JNDIBindingServiceMgr" + * name="jboss.tests:service=JNDIBindingServiceMgr"> + * <attribute name="BindingsConfig" serialDataType="jbxb"> + * <jndi:bindings + * xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" + * xmlns:jndi="urn:jboss:jndi-binding-service:1.0" + * xs:schemaLocation="urn:jboss:jndi-binding-service:1.0 resource:jndi-binding-service_1_0.xsd"> + * + * <jndi:binding name="geotools/arcsdeGlobal"> + * <java:properties xmlns:java="urn:jboss:java-properties" + * xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" + * xs:schemaLocation="urn:jboss:java-properties resource:java-properties_1_0.xsd"> + * <java:property> + * <java:key>server</java:key> + * <java:value>172.16.241.128</java:value> + * </java:property> + * <java:property> + * <java:key>port</java:key> + * <java:value>5151</java:value> + * </java:property> + * <java:property> + * <java:key>instance</java:key> + * <java:value>sde</java:value> + * </java:property> + * <java:property> + * <java:key>user</java:key> + * <java:value>sde</java:value> + * </java:property> + * <java:property> + * <java:key>password</java:key> + * <java:value>sde</java:value> + * </java:property> + * <java:property> + * <java:key>pool.minConnections</java:key> + * <java:value>2</java:value> + * </java:property> + * <java:property> + * <java:key>pool.maxConnections</java:key> + * <java:value>10</java:value> + * </java:property> + * <java:property> + * <java:key>pool.timeOut</java:key> + * <java:value>1000</java:value> + * </java:property> + * </java:properties> + * </jndi:binding> + * + * </jndi:bindings> + * </attribute> + * <depends>jboss:service=Naming</depends> + * </mbean> + * </server> + * </code> + * </pre> + * </p> + * <p> + * What we're doing here is to create a {@code java.util.Properties} object containing the connection parameters, and storing + * it on the JNDI container at the {@code geotools/arcsdeGlobal} path. This is going to be a globally accessible resource that + * the {@link ArcSDEConnectionFactory} will use to create the appropriate {@link org.geotools.arcsde.session.ISessionPool connection pool}. + * </p> + * <p> + * But to get this resource visible to your web application, there's one more step missing. In addition to the resource-ref + * entry in {@code WEB-INF/web.xml} mentioned above, JBoss requires an extra config file to manage the indirection between + * your web application and the globally configured JNDI resource. + * You'll need to create a file called {@code jboss-web.xml} as a sibling of {@code WEB-INF/web.xml} with the following content: + * <pre> + * <code> + * <?xml version="1.0" encoding="UTF-8"?> + * <jboss-web> + * <resource-ref> + * <res-ref-name>geotools/arcsde</res-ref-name> + * <res-type>org.geotools.arcsde.session.ISessionPool</res-type> + * <jndi-name>geotools/arcsdeGlobal</jndi-name> + * </resource-ref> + * </jboss-web> + * </code> + * </pre> + * Where {@code geotools/arcsdeGlobal} is the name of the globally configured resource, and {@code geotools/arcsde} + * is the JNDI name by which the resource will actually be accessible to your web application, and shall match + * the name used for the resource-ref entry in {@code WEB-INF/web.xml}. + * </p> + * <p> + * Now you're ready to select the <i>ArcSDE JNDI</i> DataStore factory and use the {@code "geotools/arcsde"} + * (or whatever entry name of your choice you have configured) as the DataStore's JNDI resource path name. + * </p> + */ +package org.geotools.arcsde.jndi; + Deleted: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionConfig.java =================================================================== --- trunk/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionConfig.java 2009-07-07 01:13:56 UTC (rev 33502) +++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionConfig.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -1,207 +0,0 @@ -/* - * 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.arcsde.session; - -import java.util.Map; - -/** - * Represents a set of ArcSDE database connection parameters. - * - * @author Gabriel Roldan - * @version $Id$ - */ -public class ArcSDEConnectionConfig { - /** ArcSDE server parameter name */ - public static final String SERVER_NAME_PARAM_NAME = "server"; - - /** ArcSDE server port parameter name */ - public static final String PORT_NUMBER_PARAM_NAME = "port"; - - /** ArcSDE databse name parameter name */ - public static final String INSTANCE_NAME_PARAM_NAME = "instance"; - - /** ArcSDE database user name parameter name */ - public static final String USER_NAME_PARAM_NAME = "user"; - - /** ArcSDE database user password parameter name */ - public static final String PASSWORD_PARAM_NAME = "password"; - - public static final String MIN_CONNECTIONS_PARAM_NAME = "pool.minConnections"; - - public static final String MAX_CONNECTIONS_PARAM_NAME = "pool.maxConnections"; - - public static final String CONNECTION_TIMEOUT_PARAM_NAME = "pool.timeOut"; - - /** name or IP of the ArcSDE server to connect to */ - private String serverName; - - /** port number where the ArcSDE instance listens for connections */ - private Integer portNumber; - - /** name of the ArcSDE database to connect to */ - private String databaseName; - - /** database user name to connect as */ - private String userName; - - /** database user password */ - private String password; - - /** minimum number of connection held in reserve, often 0 */ - private Integer minConnections = null; - - /** maximum number of connections */ - private Integer maxConnections = null; - - /** time to hold onto an idle connection before cleaning it up */ - private Integer connTimeOut = null; - - public ArcSDEConnectionConfig() throws IllegalArgumentException { - - } - - public String getServerName() { - return serverName; - } - - public void setServerName(String serverName) { - this.serverName = serverName; - } - - public Integer getPortNumber() { - return portNumber; - } - - public void setPortNumber(Integer portNumber) { - this.portNumber = portNumber; - } - - public String getDatabaseName() { - return databaseName; - } - - public void setDatabaseName(String databaseName) { - this.databaseName = databaseName; - } - - public String getUserName() { - return userName; - } - - public void setUserName(String userName) { - this.userName = userName; - } - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } - - public Integer getMinConnections() { - return minConnections; - } - - public void setMinConnections(Integer minConnections) { - this.minConnections = minConnections; - } - - public Integer getMaxConnections() { - return maxConnections; - } - - public void setMaxConnections(Integer maxConnections) { - this.maxConnections = maxConnections; - } - - public Integer getConnTimeOut() { - return connTimeOut; - } - - public void setConnTimeOut(Integer connTimeOut) { - this.connTimeOut = connTimeOut; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(getClass().getSimpleName()); - sb.append("[server=").append(serverName); - sb.append(", port=").append(portNumber); - sb.append(", database=").append(databaseName); - sb.append(", user=").append(userName); - sb.append(", minConnections=").append(minConnections); - sb.append(", maxConnections=").append(maxConnections); - sb.append(", timeout=").append(connTimeOut); - sb.append("]"); - - return sb.toString(); - } - - @Override - public boolean equals(final Object o) { - if (!(o instanceof ArcSDEConnectionConfig)) { - return false; - } - - ArcSDEConnectionConfig c = (ArcSDEConnectionConfig) o; - boolean equals = equals(serverName, c.serverName) && equals(portNumber, c.portNumber) - && equals(databaseName, c.databaseName) && equals(userName, c.userName) - && equals(password, c.password) && equals(minConnections, c.minConnections) - && equals(maxConnections, c.maxConnections) && equals(connTimeOut, c.connTimeOut); - - return equals; - } - - private static boolean equals(Object o1, Object o2) { - return o1 == null ? (o2 == null) : o1.equals(o2); - } - - @Override - public int hashCode() { - int prime = 17; - int hash = prime - * (hash(serverName) + hash(portNumber) + hash(databaseName) + hash(userName) - + hash(password) + hash(minConnections) + hash(maxConnections) + hash(connTimeOut)); - return hash; - } - - private static int hash(Object o) { - return o == null ? 1 : String.valueOf(o).hashCode(); - } - - public static ArcSDEConnectionConfig fromMap(final Map<String, String> map) { - ArcSDEConnectionConfig config = new ArcSDEConnectionConfig(); - config.setDatabaseName(map.get(INSTANCE_NAME_PARAM_NAME)); - config.setPassword(map.get(PASSWORD_PARAM_NAME)); - config.setPortNumber(Integer.valueOf(map.get(PORT_NUMBER_PARAM_NAME))); - config.setServerName(map.get(SERVER_NAME_PARAM_NAME)); - config.setUserName(map.get(USER_NAME_PARAM_NAME)); - - - config.setConnTimeOut(Integer.valueOf(String - .valueOf(map.get(CONNECTION_TIMEOUT_PARAM_NAME)))); - config.setMaxConnections(Integer.valueOf(String - .valueOf(map.get(MAX_CONNECTIONS_PARAM_NAME)))); - config.setMinConnections(Integer.valueOf(String - .valueOf(map.get(MIN_CONNECTIONS_PARAM_NAME)))); - - return config; - } -} Copied: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionConfig.java (from rev 33502, trunk/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionConfig.java) =================================================================== --- branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionConfig.java (rev 0) +++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionConfig.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -0,0 +1,207 @@ +/* + * 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.arcsde.session; + +import java.util.Map; + +/** + * Represents a set of ArcSDE database connection parameters. + * + * @author Gabriel Roldan + * @version $Id$ + */ +public class ArcSDEConnectionConfig { + /** ArcSDE server parameter name */ + public static final String SERVER_NAME_PARAM_NAME = "server"; + + /** ArcSDE server port parameter name */ + public static final String PORT_NUMBER_PARAM_NAME = "port"; + + /** ArcSDE databse name parameter name */ + public static final String INSTANCE_NAME_PARAM_NAME = "instance"; + + /** ArcSDE database user name parameter name */ + public static final String USER_NAME_PARAM_NAME = "user"; + + /** ArcSDE database user password parameter name */ + public static final String PASSWORD_PARAM_NAME = "password"; + + public static final String MIN_CONNECTIONS_PARAM_NAME = "pool.minConnections"; + + public static final String MAX_CONNECTIONS_PARAM_NAME = "pool.maxConnections"; + + public static final String CONNECTION_TIMEOUT_PARAM_NAME = "pool.timeOut"; + + /** name or IP of the ArcSDE server to connect to */ + private String serverName; + + /** port number where the ArcSDE instance listens for connections */ + private Integer portNumber; + + /** name of the ArcSDE database to connect to */ + private String databaseName; + + /** database user name to connect as */ + private String userName; + + /** database user password */ + private String password; + + /** minimum number of connection held in reserve, often 0 */ + private Integer minConnections = null; + + /** maximum number of connections */ + private Integer maxConnections = null; + + /** time to hold onto an idle connection before cleaning it up */ + private Integer connTimeOut = null; + + public ArcSDEConnectionConfig() throws IllegalArgumentException { + + } + + public String getServerName() { + return serverName; + } + + public void setServerName(String serverName) { + this.serverName = serverName; + } + + public Integer getPortNumber() { + return portNumber; + } + + public void setPortNumber(Integer portNumber) { + this.portNumber = portNumber; + } + + public String getDatabaseName() { + return databaseName; + } + + public void setDatabaseName(String databaseName) { + this.databaseName = databaseName; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public Integer getMinConnections() { + return minConnections; + } + + public void setMinConnections(Integer minConnections) { + this.minConnections = minConnections; + } + + public Integer getMaxConnections() { + return maxConnections; + } + + public void setMaxConnections(Integer maxConnections) { + this.maxConnections = maxConnections; + } + + public Integer getConnTimeOut() { + return connTimeOut; + } + + public void setConnTimeOut(Integer connTimeOut) { + this.connTimeOut = connTimeOut; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(getClass().getSimpleName()); + sb.append("[server=").append(serverName); + sb.append(", port=").append(portNumber); + sb.append(", database=").append(databaseName); + sb.append(", user=").append(userName); + sb.append(", minConnections=").append(minConnections); + sb.append(", maxConnections=").append(maxConnections); + sb.append(", timeout=").append(connTimeOut); + sb.append("]"); + + return sb.toString(); + } + + @Override + public boolean equals(final Object o) { + if (!(o instanceof ArcSDEConnectionConfig)) { + return false; + } + + ArcSDEConnectionConfig c = (ArcSDEConnectionConfig) o; + boolean equals = equals(serverName, c.serverName) && equals(portNumber, c.portNumber) + && equals(databaseName, c.databaseName) && equals(userName, c.userName) + && equals(password, c.password) && equals(minConnections, c.minConnections) + && equals(maxConnections, c.maxConnections) && equals(connTimeOut, c.connTimeOut); + + return equals; + } + + private static boolean equals(Object o1, Object o2) { + return o1 == null ? (o2 == null) : o1.equals(o2); + } + + @Override + public int hashCode() { + int prime = 17; + int hash = prime + * (hash(serverName) + hash(portNumber) + hash(databaseName) + hash(userName) + + hash(password) + hash(minConnections) + hash(maxConnections) + hash(connTimeOut)); + return hash; + } + + private static int hash(Object o) { + return o == null ? 1 : String.valueOf(o).hashCode(); + } + + public static ArcSDEConnectionConfig fromMap(final Map<String, String> map) { + ArcSDEConnectionConfig config = new ArcSDEConnectionConfig(); + config.setDatabaseName(map.get(INSTANCE_NAME_PARAM_NAME)); + config.setPassword(map.get(PASSWORD_PARAM_NAME)); + config.setPortNumber(Integer.valueOf(map.get(PORT_NUMBER_PARAM_NAME))); + config.setServerName(map.get(SERVER_NAME_PARAM_NAME)); + config.setUserName(map.get(USER_NAME_PARAM_NAME)); + + + config.setConnTimeOut(Integer.valueOf(String + .valueOf(map.get(CONNECTION_TIMEOUT_PARAM_NAME)))); + config.setMaxConnections(Integer.valueOf(String + .valueOf(map.get(MAX_CONNECTIONS_PARAM_NAME)))); + config.setMinConnections(Integer.valueOf(String + .valueOf(map.get(MIN_CONNECTIONS_PARAM_NAME)))); + + return config; + } +} Deleted: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionReference.java =================================================================== --- trunk/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionReference.java 2009-07-07 01:13:56 UTC (rev 33502) +++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionReference.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -1,65 +0,0 @@ -/* - * 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.arcsde.session; - -import java.io.IOException; - -/** - * This SessionPool makes a maximum of *one* Connection available to the calling application. - * <p> - * Why? ArcSDEConnections are both expensive to set up and expensive in cache. We still use an - * ObjectCache internally in order to control time out behavior. - * <p> - * The trick is this time that Transaction.AUTO_COMMIT is only treated as suggestion for read only - * code. The system will allow one transaction to be underway at any point, and will hand out that - * connection to code that knows how to ask. - * <p> - * This is an aggressive experiment designed to cut down the number of connections needed. - * <p> - * - * @author Jody Garnett - * @since 2.5 - */ -final class ArcSDEConnectionReference extends SessionPool { - /** - * Our "cached" session used to issue read only commands. - */ - ISession cached; - - protected ArcSDEConnectionReference(ArcSDEConnectionConfig config) throws IOException { - super(config); - if (config.getMaxConnections().intValue() != 1) { - throw new IllegalArgumentException( - "ConnectionReference is only allowed to manage one connection."); - } - } - - @Override - public ISession getSession() throws IOException, UnavailableArcSDEConnectionException { - if (cached == null) { - ISession session = super.getSession(); // this will block if session is already in use - this.cached = new SessionWrapper(session) { - @Override - public void dispose() { - // ignore - } - }; - } - return cached; - } -} Copied: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionReference.java (from rev 33502, trunk/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionReference.java) =================================================================== --- branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionReference.java (rev 0) +++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionReference.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -0,0 +1,65 @@ +/* + * 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.arcsde.session; + +import java.io.IOException; + +/** + * This SessionPool makes a maximum of *one* Connection available to the calling application. + * <p> + * Why? ArcSDEConnections are both expensive to set up and expensive in cache. We still use an + * ObjectCache internally in order to control time out behavior. + * <p> + * The trick is this time that Transaction.AUTO_COMMIT is only treated as suggestion for read only + * code. The system will allow one transaction to be underway at any point, and will hand out that + * connection to code that knows how to ask. + * <p> + * This is an aggressive experiment designed to cut down the number of connections needed. + * <p> + * + * @author Jody Garnett + * @since 2.5 + */ +final class ArcSDEConnectionReference extends SessionPool { + /** + * Our "cached" session used to issue read only commands. + */ + ISession cached; + + protected ArcSDEConnectionReference(ArcSDEConnectionConfig config) throws IOException { + super(config); + if (config.getMaxConnections().intValue() != 1) { + throw new IllegalArgumentException( + "ConnectionReference is only allowed to manage one connection."); + } + } + + @Override + public ISession getSession() throws IOException, UnavailableArcSDEConnectionException { + if (cached == null) { + ISession session = super.getSession(); // this will block if session is already in use + this.cached = new SessionWrapper(session) { + @Override + public void dispose() { + // ignore + } + }; + } + return cached; + } +} Deleted: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/Command.java =================================================================== --- trunk/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/Command.java 2009-07-07 01:13:56 UTC (rev 33502) +++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/Command.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -1,50 +0,0 @@ -/* - * 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.arcsde.session; - -import java.io.IOException; - -import com.esri.sde.sdk.client.SeConnection; -import com.esri.sde.sdk.client.SeException; - -/** - * Runnable used to interact with an ArcSDEConnection. - * <p> - * Instances of this class can the sent to {@link Session#issue(Command)} in order to be executed. - * An ArcSDERunnable has exclusive access to the Connection for the duration. This facility is used - * to prevent a series of complicated locks and try/catch/finally code. - * - * @author Jody Garnett - */ -public abstract class Command<R> { - /** - * Executed to operate on an SeConnection, a Command is scheduled for execution on a Session. - * <p> - * Please keep in mind that a Command should be short in duration; you are sharing this - * SeConnection with other threads. - * - * @param session - * the Session the command is being executed inside - * @param connection - * the session's connection, used to interact with ArcSDE - * @return the result of the command execution, or null if the command is not meant to return - * anything (a command meant to return something should fail if not able to) - */ - public abstract R execute(ISession session, SeConnection connection) throws SeException, - IOException; -} Copied: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/Command.java (from rev 33502, trunk/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/Command.java) =================================================================== --- branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/Command.java (rev 0) +++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/Command.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -0,0 +1,50 @@ +/* + * 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.arcsde.session; + +import java.io.IOException; + +import com.esri.sde.sdk.client.SeConnection; +import com.esri.sde.sdk.client.SeException; + +/** + * Runnable used to interact with an ArcSDEConnection. + * <p> + * Instances of this class can the sent to {@link Session#issue(Command)} in order to be executed. + * An ArcSDERunnable has exclusive access to the Connection for the duration. This facility is used + * to prevent a series of complicated locks and try/catch/finally code. + * + * @author Jody Garnett + */ +public abstract class Command<R> { + /** + * Executed to operate on an SeConnection, a Command is scheduled for execution on a Session. + * <p> + * Please keep in mind that a Command should be short in duration; you are sharing this + * SeConnection with other threads. + * + * @param session + * the Session the command is being executed inside + * @param connection + * the session's connection, used to interact with ArcSDE + * @return the result of the command execution, or null if the command is not meant to return + * anything (a command meant to return something should fail if not able to) + */ + public abstract R execute(ISession session, SeConnection connection) throws SeException, + IOException; +} Deleted: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/Commands.java =================================================================== --- trunk/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/Commands.java 2009-07-07 01:13:56 UTC (rev 33502) +++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/Commands.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -1,58 +0,0 @@ -package org.geotools.arcsde.session; - -import java.io.IOException; -import java.util.ArrayList; - -import org.geotools.arcsde.ArcSdeException; - -import com.esri.sde.sdk.client.SeConnection; -import com.esri.sde.sdk.client.SeException; -import com.esri.sde.sdk.client.SeVersion; - -public class Commands { - - /** - * Command to fetch a version. - * - * @author Gabriel Roldan - */ - public static final class GetVersionCommand extends Command<SeVersion> { - - private String versionName; - - public GetVersionCommand(final String versionName) { - this.versionName = versionName; - } - - @Override - public SeVersion execute(ISession session, SeConnection connection) throws SeException, - IOException { - - final SeVersion version; - try { - version = new SeVersion(connection, versionName); - } catch (SeException cause) { - - if (cause.getSeError().getSdeError() == -126) { - ArrayList<String> available = new ArrayList<String>(); - try { - SeVersion[] versionList = connection.getVersionList(null); - for (SeVersion v : versionList) { - available.add(v.getName()); - } - throw new ArcSdeException("Specified ArcSDE version does not exist: " - + versionName + ". Available versions are: " + available, cause); - } catch (SeException ignorable) { - // hum... ignore - throw new ArcSdeException("Specified ArcSDE version does not exist: " - + versionName, cause); - } - } else { - throw cause; - } - } - version.getInfo(); - return version; - } - } -} Copied: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/Commands.java (from rev 33502, trunk/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/Commands.java) =================================================================== --- branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/Commands.java (rev 0) +++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/Commands.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -0,0 +1,58 @@ +package org.geotools.arcsde.session; + +import java.io.IOException; +import java.util.ArrayList; + +import org.geotools.arcsde.ArcSdeException; + +import com.esri.sde.sdk.client.SeConnection; +import com.esri.sde.sdk.client.SeException; +import com.esri.sde.sdk.client.SeVersion; + +public class Commands { + + /** + * Command to fetch a version. + * + * @author Gabriel Roldan + */ + public static final class GetVersionCommand extends Command<SeVersion> { + + private String versionName; + + public GetVersionCommand(final String versionName) { + this.versionName = versionName; + } + + @Override + public SeVersion execute(ISession session, SeConnection connection) throws SeException, + IOException { + + final SeVersion version; + try { + version = new SeVersion(connection, versionName); + } catch (SeException cause) { + + if (cause.getSeError().getSdeError() == -126) { + ArrayList<String> available = new ArrayList<String>(); + try { + SeVersion[] versionList = connection.getVersionList(null); + for (SeVersion v : versionList) { + available.add(v.getName()); + } + throw new ArcSdeException("Specified ArcSDE version does not exist: " + + versionName + ". Available versions are: " + available, cause); + } catch (SeException ignorable) { + // hum... ignore + throw new ArcSdeException("Specified ArcSDE version does not exist: " + + versionName, cause); + } + } else { + throw cause; + } + } + version.getInfo(); + return version; + } + } +} Deleted: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ISession.java =================================================================== --- trunk/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ISession.java 2009-07-07 01:13:56 UTC (rev 33502) +++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ISession.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -1,237 +0,0 @@ -/* - * 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.arcsde.session; - -import java.io.IOException; -import java.util.List; - -import com.esri.sde.sdk.client.SeColumnDefinition; -import com.esri.sde.sdk.client.SeConnection; -import com.esri.sde.sdk.client.SeDBMSInfo; -import com.esri.sde.sdk.client.SeDelete; -import com.esri.sde.sdk.client.SeInsert; -import com.esri.sde.sdk.client.SeLayer; -import com.esri.sde.sdk.client.SeObjectId; -import com.esri.sde.sdk.client.SeQuery; -import com.esri.sde.sdk.client.SeRasterColumn; -import com.esri.sde.sdk.client.SeRegistration; -import com.esri.sde.sdk.client.SeRelease; -import com.esri.sde.sdk.client.SeRow; -import com.esri.sde.sdk.client.SeSqlConstruct; -import com.esri.sde.sdk.client.SeState; -import com.esri.sde.sdk.client.SeStreamOp; -import com.esri.sde.sdk.client.SeTable; -import com.esri.sde.sdk.client.SeUpdate; -import com.esri.sde.sdk.client.SeVersion; - -public interface ISession { - - /** - * Executes the given command and returns its result. - * - * @param command - * the command to execute - * @throws IOException - * if an exception occurs handling any ArcSDE resource while executing the command - */ - public abstract <T> T issue(final Command<T> command) throws IOException; - - /** - * Performs a session sanity check to avoid stale connections to be returned from the pool. - * - * @throws IOException - * @see {@link SeConnection#testServer(long)} - */ - public void testServer() throws IOException; - - public abstract boolean isClosed(); - - /** - * Returns whether this connection is on the connection pool domain or not. - * - * @return <code>true</code> if this connection has beed returned to the pool and thus cannot be - * used, <code>false</code> if its safe to keep using it. - */ - public abstract boolean isDisposed(); - - public abstract SeLayer getLayer(final String layerName) throws IOException; - - public abstract SeRasterColumn getRasterColumn(final String rasterName) throws IOException; - - public abstract SeTable getTable(final String tableName) throws IOException; - - /** - * Starts a transaction over the connection held by this Session - * <p> - * If this method succeeds, {@link #isTransactionActive()} will return true afterwards - * </p> - * - * @throws IOException - * @see {@link #issueStartTransaction(Session)} - */ - public abstract void startTransaction() throws IOException; - - /** - * Commits the current transaction. - * <p> - * This method shall only be called from inside a command - * </p> - * - * @throws IOException - */ - public abstract void commitTransaction() throws IOException; - - /** - * Returns whether a transaction is in progress over this connection - * <p> - * As for any other public method, this one can't be called if {@link #isDisposed()} is true. - * </p> - * - * @return - */ - public abstract boolean isTransactionActive(); - - /** - * Rolls back the current transaction - * <p> - * When this method returns it is guaranteed that {@link #isTransactionActive()} will return - * false, regardless of the success of the rollback operation. - * </p> - * - * @throws IOException - */ - public abstract void rollbackTransaction() throws IOException; - - /** - * Return to the pool (may not close the internal connection, depends on pool settings). - * - * @throws IllegalStateException - * if dispose() is called while a transaction is in progress - */ - public abstract void dispose() throws IllegalStateException; - - /** - * Compares for reference equality - */ - public abstract boolean equals(Object other); - - public abstract int hashCode(); - - /** - * Returns the live list of layers, not the cached ones, so it may pick up the differences in - * the database. - * - * @return - * @throws IOException - */ - public abstract List<SeLayer> getLayers() throws IOException; - - public abstract String getUser() throws IOException; - - public abstract SeRelease getRelease() throws IOException; - - public abstract String getDatabaseName() throws IOException; - - public abstract SeDBMSInfo getDBMSInfo() throws IOException; - - // - // Factory methods that make use of internal connection - // Q: How "long" are these objects good for? until the connection closes - - // or longer... - // - public abstract SeLayer createSeLayer() throws IOException; - - public abstract SeRegistration createSeRegistration(final String typeName) throws IOException; - - /** - * Creates an SeTable named - * <code>qualifiedName<code>; the layer does not need to exist on the server. - * - * @param qualifiedName - * @return - * @throws IOException - */ - public abstract SeTable createSeTable(final String qualifiedName) throws IOException; - - public abstract SeInsert createSeInsert() throws IOException; - - public abstract SeUpdate createSeUpdate() throws IOException; - - public abstract SeDelete createSeDelete() throws IOException; - - public abstract SeRasterColumn createSeRasterColumn() throws IOException; - - public abstract SeRasterColumn createSeRasterColumn(final SeObjectId rasterColumnId) - throws IOException; - - public abstract SeColumnDefinition[] describe(final String tableName) throws IOException; - - public abstract SeColumnDefinition[] describe(final SeTable table) throws IOException; - - /** - * Issues a command that fetches a row from an already executed SeQuery and returns the - * {@link SdeRow} object with its contents. - * <p> - * The point in returning an {@link SdeRow} instead of a plain {@link SeRow} is that the former - * prefetches the row values and this can be freely used outside a {@link Command}. Otherwise - * the SeRow should only be used inside a command as accessing its values implies using the - * connection. - * </p> - * - * @param query - * @return - * @throws IOException - */ - public abstract SdeRow fetch(final SeQuery query) throws IOException; - - public abstract SdeRow fetch(SeQuery seQuery, SdeRow currentRow) throws IOException; - - public abstract void close(final SeState state) throws IOException; - - public abstract void close(final SeStreamOp stream) throws IOException; - - public abstract SeState createState(final SeObjectId stateId) throws IOException; - - public abstract SeQuery createSeQuery() throws IOException; - - /** - * Creates an SeQuery to fetch the given propertyNames with the provided attribute based - * restrictions - * <p> - * This method shall only be called from inside a {@link Command} - * </p> - * - * @param propertyNames - * @param sql - * @return - * @throws IOException - */ - public abstract SeQuery createSeQuery(final String[] propertyNames, final SeSqlConstruct sql) - throws IOException; - - public abstract SeQuery createAndExecuteQuery(final String[] propertyNames, - final SeSqlConstruct sql) throws IOException; - - /** - * Returns the up to date information about the database default version - */ - public abstract SeVersion getDefaultVersion() throws IOException; - - public SeState createChildState(long parentStateId) throws IOException; - -} Copied: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ISession.java (from rev 33502, trunk/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ISession.java) =================================================================== --- branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ISession.java (rev 0) +++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ISession.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -0,0 +1,237 @@ +/* + * 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.arcsde.session; + +import java.io.IOException; +import java.util.List; + +import com.esri.sde.sdk.client.SeColumnDefinition; +import com.esri.sde.sdk.client.SeConnection; +import com.esri.sde.sdk.client.SeDBMSInfo; +import com.esri.sde.sdk.client.SeDelete; +import com.esri.sde.sdk.client.SeInsert; +import com.esri.sde.sdk.client.SeLayer; +import com.esri.sde.sdk.client.SeObjectId; +import com.esri.sde.sdk.client.SeQuery; +import com.esri.sde.sdk.client.SeRasterColumn; +import com.esri.sde.sdk.client.SeRegistration; +import com.esri.sde.sdk.client.SeRelease; +import com.esri.sde.sdk.client.SeRow; +import com.esri.sde.sdk.client.SeSqlConstruct; +import com.esri.sde.sdk.client.SeState; +import com.esri.sde.sdk.client.SeStreamOp; +import com.esri.sde.sdk.client.SeTable; +import com.esri.sde.sdk.client.SeUpdate; +import com.esri.sde.sdk.client.SeVersion; + +public interface ISession { + + /** + * Executes the given command and returns its result. + * + * @param command + * the command to execute + * @throws IOException + * if an exception occurs handling any ArcSDE resource while executing the command + */ + public abstract <T> T issue(final Command<T> command) throws IOException; + + /** + * Performs a session sanity check to avoid stale connections to be returned from the pool. + * + * @throws IOException + * @see {@link SeConnection#testServer(long)} + */ + public void testServer() throws IOException; + + public abstract boolean isClosed(); + + /** + * Returns whether this connection is on the connection pool domain or not. + * + * @return <code>true</code> if this connection has beed returned to the pool and thus cannot be + * used, <code>false</code> if its safe to keep using it. + */ + public abstract boolean isDisposed(); + + public abstract SeLayer getLayer(final String layerName) throws IOException; + + public abstract SeRasterColumn getRasterColumn(final String rasterName) throws IOException; + + public abstract SeTable getTable(final String tableName) throws IOException; + + /** + * Starts a transaction over the connection held by this Session + * <p> + * If this method succeeds, {@link #isTransactionActive()} will return true afterwards + * </p> + * + * @throws IOException + * @see {@link #issueStartTransaction(Session)} + */ + public abstract void startTransaction() throws IOException; + + /** + * Commits the current transaction. + * <p> + * This method shall only be called from inside a command + * </p> + * + * @throws IOException + */ + public abstract void commitTransaction() throws IOException; + + /** + * Returns whether a transaction is in progress over this connection + * <p> + * As for any other public method, this one can't be called if {@link #isDisposed()} is true. + * </p> + * + * @return + */ + public abstract boolean isTransactionActive(); + + /** + * Rolls back the current transaction + * <p> + * When this method returns it is guaranteed that {@link #isTransactionActive()} will return + * false, regardless of the success of the rollback operation. + * </p> + * + * @throws IOException + */ + public abstract void rollbackTransaction() throws IOException; + + /** + * Return to the pool (may not close the internal connection, depends on pool settings). + * + * @throws IllegalStateException + * if dispose() is called while a transaction is in progress + */ + public abstract void dispose() throws IllegalStateException; + + /** + * Compares for reference equality + */ + public abstract boolean equals(Object other); + + public abstract int hashCode(); + + /** + * Returns the live list of layers, not the cached ones, so it may pick up the differences in + * the database. + * + * @return + * @throws IOException + */ + public abstract List<SeLayer> getLayers() throws IOException; + + public abstract String getUser() throws IOException; + + public abstract SeRelease getRelease() throws IOException; + + public abstract String getDatabaseName() throws IOException; + + public abstract SeDBMSInfo getDBMSInfo() throws IOException; + + // + // Factory methods that make use of internal connection + // Q: How "long" are these objects good for? until the connection closes - + // or longer... + // + public abstract SeLayer createSeLayer() throws IOException; + + public abstract SeRegistration createSeRegistration(final String typeName) throws IOException; + + /** + * Creates an SeTable named + * <code>qualifiedName<code>; the layer does not need to exist on the server. + * + * @param qualifiedName + * @return + * @throws IOException + */ + public abstract SeTable createSeTable(final String qualifiedName) throws IOException; + + public abstract SeInsert createSeInsert() throws IOException; + + public abstract SeUpdate createSeUpdate() throws IOException; + + public abstract SeDelete createSeDelete() throws IOException; + + public abstract SeRasterColumn createSeRasterColumn() throws IOException; + + public abstract SeRasterColumn createSeRasterColumn(final SeObjectId rasterColumnId) + throws IOException; + + public abstract SeColumnDefinition[] describe(final String tableName) throws IOException; + + public abstract SeColumnDefinition[] describe(final SeTable table) throws IOException; + + /** + * Issues a command that fetches a row from an already executed SeQuery and returns the + * {@link SdeRow} object with its contents. + * <p> + * The point in returning an {@link SdeRow} instead of a plain {@link SeRow} is that the former + * prefetches the row values and this can be freely used outside a {@link Command}. Otherwise + * the SeRow should only be used inside a command as accessing its values implies using the + * connection. + * </p> + * + * @param query + * @return + * @throws IOException + */ + public abstract SdeRow fetch(final SeQuery query) throws IOException; + + public abstract SdeRow fetch(SeQuery seQuery, SdeRow currentRow) throws IOException; + + public abstract void close(final SeState state) throws IOException; + + public abstract void close(final SeStreamOp stream) throws IOException; + + public abstract SeState createState(final SeObjectId stateId) throws IOException; + + public abstract SeQuery createSeQuery() throws IOException; + + /** + * Creates an SeQuery to fetch the given propertyNames with the provided attribute based + * restrictions + * <p> + * This method shall only be called from inside a {@link Command} + * </p> + * + * @param propertyNames + * @param sql + * @return + * @throws IOException + */ + public abstract SeQuery createSeQuery(final String[] propertyNames, final SeSqlConstruct sql) + throws IOException; + + public abstract SeQuery createAndExecuteQuery(final String[] propertyNames, + final SeSqlConstruct sql) throws IOException; + + /** + * Returns the up to date information about the database default version + */ + public abstract SeVersion getDefaultVersion() throws IOException; + + public SeState createChildState(long parentStateId) throws IOException; + +} Deleted: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ISessionPool.java =================================================================== --- trunk/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ISessionPool.java 2009-07-07 01:13:56 UTC (rev 33502) +++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ISessionPool.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -1,73 +0,0 @@ -package org.geotools.arcsde.session; - -import java.io.IOException; - -/** - * Maintains <code>SeConnection</code>'s for a single set of connection properties (for instance: by - * server, port, user and password) in a pool to recycle used connections. - * <p> - * The expected optional parameters that you can set up in the argument Map for createDataStore are: - * <ul> - * <li>pool.minConnections Integer, tells the minimum number of open connections the pool will - * maintain opened</li> - * <li>pool.maxConnections Integer, tells the maximum number of open connections the pool will - * create and maintain opened</li> - * <li>pool.timeOut Integer, tells how many milliseconds a calling thread is guaranteed to wait - * before getConnection() throws an UnavailableArcSDEConnectionException</li> - * </ul> - * </p> - * - * @author Gabriel Roldan - * @version $Id$ - */ -public interface ISessionPool { - - /** - * returns the number of actual connections held by this connection pool. In other words, the - * sum of used and available connections, regardless - * - */ - int getPoolSize(); - - /** - * closes all connections in this pool. The first call closes all SeConnections, further calls - * have no effect. - */ - void close(); - - /** - * Returns whether this pool is closed - * - * @return - */ - boolean isClosed(); - - /** - * Returns the number of idle connections - */ - int getAvailableCount(); - - /** - * Number of active sessions. - * - * @return Number of active session; used to monitor the live pool. - */ - int getInUseCount(); - - /** - * Grab a session from the pool, this session is the responsibility of the calling code and must - * be closed after use. - * - * @return A Session, when close() is called it will be recycled into the pool - * @throws IOException - * If we could not get a connection - * @throws UnavailableArcSDEConnectionException - * If we are out of connections - * @throws IllegalStateException - * If pool has been closed. - */ - ISession getSession() throws IOException, UnavailableArcSDEConnectionException; - - ArcSDEConnectionConfig getConfig(); - -} \ No newline at end of file Copied: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ISessionPool.java (from rev 33502, trunk/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ISessionPool.java) =================================================================== --- branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ISessionPool.java (rev 0) +++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ISessionPool.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -0,0 +1,73 @@ +package org.geotools.arcsde.session; + +import java.io.IOException; + +/** + * Maintains <code>SeConnection</code>'s for a single set of connection properties (for instance: by + * server, port, user and password) in a pool to recycle used connections. + * <p> + * The expected optional parameters that you can set up in the argument Map for createDataStore are: + * <ul> + * <li>pool.minConnections Integer, tells the minimum number of open connections the pool will + * maintain opened</li> + * <li>pool.maxConnections Integer, tells the maximum number of open connections the pool will + * create and maintain opened</li> + * <li>pool.timeOut Integer, tells how many milliseconds a calling thread is guaranteed to wait + * before getConnection() throws an UnavailableArcSDEConnectionException</li> + * </ul> + * </p> + * + * @author Gabriel Roldan + * @version $Id$ + */ +public interface ISessionPool { + + /** + * returns the number of actual connections held by this connection pool. In other words, the + * sum of used and available connections, regardless + * + */ + int getPoolSize(); + + /** + * closes all connections in this pool. The first call closes all SeConnections, further calls + * have no effect. + */ + void close(); + + /** + * Returns whether this pool is closed + * + * @return + */ + boolean isClosed(); + + /** + * Returns the number of idle connections + */ + int getAvailableCount(); + + /** + * Number of active sessions. + * + * @return Number of active session; used to monitor the live pool. + */ + int getInUseCount(); + + /** + * Grab a session from the pool, this session is the responsibility of the calling code and must + * be closed after use. + * + * @return A Session, when close() is called it will be recycled into the pool + * @throws IOException + * If we could not get a connection + * @throws UnavailableArcSDEConnectionException + * If we are out of connections + * @throws IllegalStateException + * If pool has been closed. + */ + ISession getSession() throws IOException, UnavailableArcSDEConnectionException; + + ArcSDEConnectionConfig getConfig(); + +} \ No newline at end of file Deleted: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ISessionPoolFactory.java =================================================================== --- trunk/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ISessionPoolFactory.java 2009-07-07 01:13:56 UTC (rev 33502) +++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ISessionPoolFactory.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -1,49 +0,0 @@ -/* - * GeoTools - The Open Source Java GIS Toolkit - * http://geotools.org - * - * (C) 2002-2009, 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.arcsde.session; - -import java.io.IOException; - -import org.geotools.arcsde.jndi.ArcSDEConnectionFactory; - -/** - * Factory interface for {@link ISessionPool}. - * <p> - * A specific {@link ISessionPool} factory can be injected when using JNDI through the {@code - * sessionPoolFactory} parameter. See {@link ArcSDEConnectionFactory}. - * </p> - * - * @author Gabriel Roldan (OpenGeo) - * @version $Id$ - * @since 2.5.7 - */ -public interface ISessionPoolFactory { - - /** - * Creates a connection pool factory for the given connection parameters. - * - * @param config - * Â contains the connection parameters and pool preferences - * @return a pool for the given connection parameters, wether it already existed or had to be - * created. - * @throws IOException - * if the pool needs but can't be created - */ - ISessionPool createPool(ArcSDEConnectionConfig config) throws IOException; - -} \ No newline at end of file Copied: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ISessionPoolFactory.java (from rev 33502, trunk/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ISessionPoolFactory.java) =================================================================== --- branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ISessionPoolFactory.java (rev 0) +++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ISessionPoolFactory.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -0,0 +1,49 @@ +/* + * GeoTools - The Open Source Java GIS Toolkit + * http://geotools.org + * + * (C) 2002-2009, 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.arcsde.session; + +import java.io.IOException; + +import org.geotools.arcsde.jndi.ArcSDEConnectionFactory; + +/** + * Factory interface for {@link ISessionPool}. + * <p> + * A specific {@link ISessionPool} factory can be injected when using JNDI through the {@code + * sessionPoolFactory} parameter. See {@link ArcSDEConnectionFactory}. + * </p> + * + * @author Gabriel Roldan (OpenGeo) + * @version $Id$ + * @since 2.5.7 + */ +public interface ISessionPoolFactory { + + /** + * Creates a connection pool factory for the given connection parameters. + * + * @param config + * Â contains the connection parameters and pool preferences + * @return a pool for the given connection parameters, wether it already existed or had to be + * created. + * @throws IOException + * if the pool needs but can't be created + */ + ISessionPool createPool(ArcSDEConnectionConfig config) throws IOException; + +} \ No newline at end of file Deleted: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/SdeRow.java =================================================================== --- trunk/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/SdeRow.java 2009-07-07 01:13:56 UTC (rev 33502) +++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/SdeRow.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -1,240 +0,0 @@ -/* - * 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.arcsde.session; - -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.logging.Level; -import java.util.logging.Logger; - -import org.geotools.arcsde.ArcSdeException; - -import com.esri.sde.sdk.client.SeColumnDefinition; -import com.esri.sde.sdk.client.SeException; -import com.esri.sde.sdk.client.SeRow; -import com.esri.sde.sdk.client.SeShape; -import com.esri.sde.sdk.geom.GeometryFactory; - -/** - * Wrapper for an SeRow so it allows asking multiple times for the same property. - * - * @author Gabriel Roldan, Axios Engineering - * @version $Id$ - * @source $URL: - * http://svn.geotools.org/geotools/trunk/gt/modules/plugin/arcsde/datastore/src/main/java - * /org/geotools/arcsde/data/SdeRow.java $ - * @since 2.4.0 - */ -public class SdeRow { - /** Logger for ths class' package */ - private static final Logger LOGGER = Logger.getLogger(SdeRow.class.getName()); - - /** cached SeRow values */ - private Object[] values; - - private int[] colStatusIndicator; - - private int nCols; - - /** - * A possible non set SDE geometry factory that provides the means for geometry fetching other - * than SeRow.getShape(). That is, if this geometryFactory is non null, it will be used to fetch - * the geometric attributes. Otherwise SeRow.getShape():SeShape will be used - */ - private GeometryFactory geometryFactory; - - private int geometryIndex = -1; - - public SdeRow(GeometryFactory geometryFactory) { - this.geometryFactory = geometryFactory; - } - - public SdeRow(SeRow row) throws IOException { - this(row, null); - } - - public SdeRow(SeRow row, GeometryFactory geometryFactory) throws IOException { - this.geometryFactory = geometryFactory; - setRow(row); - } - - public void setRow(SeRow row) throws IOException { - final int ncols = row.getNumColumns(); - if (this.nCols != ncols) { - this.nCols = ncols; - values = new Object[nCols]; - colStatusIndicator = new int[nCols]; - } - - int i = 0; - int statusIndicator = 0; - - try { - for (i = 0; i < nCols; i++) { - statusIndicator = row.getIndicator(i); - colStatusIndicator[i] = statusIndicator; - - if (statusIndicator == SeRow.SE_IS_ALREADY_FETCHED - || statusIndicator == SeRow.SE_IS_REPEATED_FEATURE - || statusIndicator == SeRow.SE_IS_NULL_VALUE) { - // ignore, will use previous values - } else { - if (this.geometryFactory != null && this.geometryIndex == i) { - values[i] = row.getGeometry(geometryFactory, i); - } else { - values[i] = row.getObject(i); - } - /* - * ML: I'm adding checks here for the [n] clob object that are returned as null - * by getObject, but are reported as Strings. We can suck those out of - * ByteArrayStreams - */ - if (values[i] == null) { - ByteArrayInputStream clobIn = null; - BufferedReader reader = null; - try { - int type = row.getColumnDef(i).getType(); - if (type == SeColumnDefinition.TYPE_NCLOB) { - clobIn = row.getNClob(i); - } else if (type == SeColumnDefinition.TYPE_CLOB) { - /* - * Warning! this line throws an NPE with the 9.2 java api, but works - * with the 9.3 jars - */ - clobIn = row.getClob(i); - } - if (clobIn != null) { - reader = new BufferedReader(new InputStreamReader(clobIn, "UTF-16")); - StringBuffer buf = new StringBuffer(); - String snip = reader.readLine(); - while (snip != null) { - if (buf.length() != 0) - buf.append('\n'); - buf.append(snip); - snip = reader.readLine(); - } - if (buf.length() > 0) - values[i] = buf.toString(); - } - } catch (IOException e) { - LOGGER.log(Level.FINEST, - "Issue decoding CLOB/NCLOB into a String:" + e, e); - // value will remain null - } finally { - if (reader != null) { - try { - reader.close(); - } catch (IOException ignore) { - LOGGER.log(Level.FINEST, "Issue cleaning up after CLOB/NCLOB:" - + ignore, ignore); - } - } - } - } - } - } - } catch (SeException e) { - throw new ArcSdeException("getting property #" + i, e); - } - } - - public void setPreviousValues(Object[] previousValues) { - int statusIndicator; - for (int i = 0; i < nCols; i++) { - statusIndicator = colStatusIndicator[i]; - - if (statusIndicator == SeRow.SE_IS_ALREADY_FETCHED - || statusIndicator == SeRow.SE_IS_REPEATED_FEATURE) { - values[i] = previousValues[i]; - } - } - } - - /** - * DOCUMENT ME! - * - * @param index - * DOCUMENT ME! - * @return DOCUMENT ME! - * @throws IOException - * DOCUMENT ME! - */ - public Object getObject(int index) throws IOException { - return values[index]; - } - - /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! - */ - public Object[] getAll() { - return values; - } - - /** - * DOCUMENT ME! - * - * @param index - * DOCUMENT ME! - * @return DOCUMENT ME! - * @throws IOException - * DOCUMENT ME! - */ - public Long getLong(int index) throws IOException { - return (Long) getObject(index); - } - - /** - * DOCUMENT ME! - * - * @param index - * DOCUMENT ME! - * @return DOCUMENT ME! - * @throws IOException - * DOCUMENT ME! - */ - public SeShape getShape(int index) throws IOException { - return (SeShape) getObject(index); - } - - /** - * @param columnIndex - * @return one of {@link SeRow#SE_IS_ALREADY_FETCHED}, {@link SeRow#SE_IS_NOT_NULL_VALUE}, - * {@link SeRow#SE_IS_NULL_VALUE}, {@link SeRow#SE_IS_REPEATED_FEATURE} - */ - public int getIndicator(int columnIndex) { - return colStatusIndicator[columnIndex]; - } - - public Integer getInteger(int index) throws IOException { - return (Integer) getObject(index); - } - - /** - * @param geometryIndex - * a value >= 0 indicates which index in the row contains the geometry attribute. If - * not set, geometryFactory will be ignored - */ - public void setGeometryIndex(int geometryIndex) { - this.geometryIndex = geometryIndex; - } - -} Copied: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/SdeRow.java (from rev 33502, trunk/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/SdeRow.java) =================================================================== --- branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/SdeRow.java (rev 0) +++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/SdeRow.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -0,0 +1,240 @@ +/* + * 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.arcsde.session; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.geotools.arcsde.ArcSdeException; + +import com.esri.sde.sdk.client.SeColumnDefinition; +import com.esri.sde.sdk.client.SeException; +import com.esri.sde.sdk.client.SeRow; +import com.esri.sde.sdk.client.SeShape; +import com.esri.sde.sdk.geom.GeometryFactory; + +/** + * Wrapper for an SeRow so it allows asking multiple times for the same property. + * + * @author Gabriel Roldan, Axios Engineering + * @version $Id$ + * @source $URL: + * http://svn.geotools.org/geotools/trunk/gt/modules/plugin/arcsde/datastore/src/main/java + * /org/geotools/arcsde/data/SdeRow.java $ + * @since 2.4.0 + */ +public class SdeRow { + /** Logger for ths class' package */ + private static final Logger LOGGER = Logger.getLogger(SdeRow.class.getName()); + + /** cached SeRow values */ + private Object[] values; + + private int[] colStatusIndicator; + + private int nCols; + + /** + * A possible non set SDE geometry factory that provides the means for geometry fetching other + * than SeRow.getShape(). That is, if this geometryFactory is non null, it will be used to fetch + * the geometric attributes. Otherwise SeRow.getShape():SeShape will be used + */ + private GeometryFactory geometryFactory; + + private int geometryIndex = -1; + + public SdeRow(GeometryFactory geometryFactory) { + this.geometryFactory = geometryFactory; + } + + public SdeRow(SeRow row) throws IOException { + this(row, null); + } + + public SdeRow(SeRow row, GeometryFactory geometryFactory) throws IOException { + this.geometryFactory = geometryFactory; + setRow(row); + } + + public void setRow(SeRow row) throws IOException { + final int ncols = row.getNumColumns(); + if (this.nCols != ncols) { + this.nCols = ncols; + values = new Object[nCols]; + colStatusIndicator = new int[nCols]; + } + + int i = 0; + int statusIndicator = 0; + + try { + for (i = 0; i < nCols; i++) { + statusIndicator = row.getIndicator(i); + colStatusIndicator[i] = statusIndicator; + + if (statusIndicator == SeRow.SE_IS_ALREADY_FETCHED + || statusIndicator == SeRow.SE_IS_REPEATED_FEATURE + || statusIndicator == SeRow.SE_IS_NULL_VALUE) { + // ignore, will use previous values + } else { + if (this.geometryFactory != null && this.geometryIndex == i) { + values[i] = row.getGeometry(geometryFactory, i); + } else { + values[i] = row.getObject(i); + } + /* + * ML: I'm adding checks here for the [n] clob object that are returned as null + * by getObject, but are reported as Strings. We can suck those out of + * ByteArrayStreams + */ + if (values[i] == null) { + ByteArrayInputStream clobIn = null; + BufferedReader reader = null; + try { + int type = row.getColumnDef(i).getType(); + if (type == SeColumnDefinition.TYPE_NCLOB) { + clobIn = row.getNClob(i); + } else if (type == SeColumnDefinition.TYPE_CLOB) { + /* + * Warning! this line throws an NPE with the 9.2 java api, but works + * with the 9.3 jars + */ + clobIn = row.getClob(i); + } + if (clobIn != null) { + reader = new BufferedReader(new InputStreamReader(clobIn, "UTF-16")); + StringBuffer buf = new StringBuffer(); + String snip = reader.readLine(); + while (snip != null) { + if (buf.length() != 0) + buf.append('\n'); + buf.append(snip); + snip = reader.readLine(); + } + if (buf.length() > 0) + values[i] = buf.toString(); + } + } catch (IOException e) { + LOGGER.log(Level.FINEST, + "Issue decoding CLOB/NCLOB into a String:" + e, e); + // value will remain null + } finally { + if (reader != null) { + try { + reader.close(); + } catch (IOException ignore) { + LOGGER.log(Level.FINEST, "Issue cleaning up after CLOB/NCLOB:" + + ignore, ignore); + } + } + } + } + } + } + } catch (SeException e) { + throw new ArcSdeException("getting property #" + i, e); + } + } + + public void setPreviousValues(Object[] previousValues) { + int statusIndicator; + for (int i = 0; i < nCols; i++) { + statusIndicator = colStatusIndicator[i]; + + if (statusIndicator == SeRow.SE_IS_ALREADY_FETCHED + || statusIndicator == SeRow.SE_IS_REPEATED_FEATURE) { + values[i] = previousValues[i]; + } + } + } + + /** + * DOCUMENT ME! + * + * @param index + * DOCUMENT ME! + * @return DOCUMENT ME! + * @throws IOException + * DOCUMENT ME! + */ + public Object getObject(int index) throws IOException { + return values[index]; + } + + /** + * DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + public Object[] getAll() { + return values; + } + + /** + * DOCUMENT ME! + * + * @param index + * DOCUMENT ME! + * @return DOCUMENT ME! + * @throws IOException + * DOCUMENT ME! + */ + public Long getLong(int index) throws IOException { + return (Long) getObject(index); + } + + /** + * DOCUMENT ME! + * + * @param index + * DOCUMENT ME! + * @return DOCUMENT ME! + * @throws IOException + * DOCUMENT ME! + */ + public SeShape getShape(int index) throws IOException { + return (SeShape) getObject(index); + } + + /** + * @param columnIndex + * @return one of {@link SeRow#SE_IS_ALREADY_FETCHED}, {@link SeRow#SE_IS_NOT_NULL_VALUE}, + * {@link SeRow#SE_IS_NULL_VALUE}, {@link SeRow#SE_IS_REPEATED_FEATURE} + */ + public int getIndicator(int columnIndex) { + return colStatusIndicator[columnIndex]; + } + + public Integer getInteger(int index) throws IOException { + return (Integer) getObject(index); + } + + /** + * @param geometryIndex + * a value >= 0 indicates which index in the row contains the geometry attribute. If + * not set, geometryFactory will be ignored + */ + public void setGeometryIndex(int geometryIndex) { + this.geometryIndex = geometryIndex; + } + +} Deleted: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/Session.java =================================================================== --- trunk/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/Session.java 2009-07-07 01:13:56 UTC (rev 33502) +++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/Session.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -1,974 +0,0 @@ -/* - * 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.arcsde.session; - -import java.io.IOException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.NoSuchElementException; -import java.util.Vector; -import java.util.WeakHashMap; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.FutureTask; -import java.util.logging.Level; -import java.util.logging.Logger; - -import org.apache.commons.pool.ObjectPool; -import org.geotools.arcsde.ArcSdeException; -import org.geotools.arcsde.session.Commands.GetVersionCommand; - -import com.esri.sde.sdk.client.SeColumnDefinition; -import com.esri.sde.sdk.client.SeConnection; -import com.esri.sde.sdk.client.SeDBMSInfo; -import com.esri.sde.sdk.client.SeDelete; -import com.esri.sde.sdk.client.SeError; -import com.esri.sde.sdk.client.SeException; -import com.esri.sde.sdk.client.SeInsert; -import com.esri.sde.sdk.client.SeLayer; -import com.esri.sde.sdk.client.SeObjectId; -import com.esri.sde.sdk.client.SeQuery; -import com.esri.sde.sdk.client.SeRasterColumn; -import com.esri.sde.sdk.client.SeRegistration; -import com.esri.sde.sdk.client.SeRelease; -import com.esri.sde.sdk.client.SeRow; -import com.esri.sde.sdk.client.SeSqlConstruct; -import com.esri.sde.sdk.client.SeState; -import com.esri.sde.sdk.client.SeStreamOp; -import com.esri.sde.sdk.client.SeTable; -import com.esri.sde.sdk.client.SeUpdate; -import com.esri.sde.sdk.client.SeVersion; -import com.esri.sde.sdk.geom.GeometryFactory; - -/** - * Provides thread safe access to an SeConnection. - * <p> - * This class has become more and more magic over time! It no longer represents a Connection but - * provides "safe" access to a connection. - * <p> - * - * @author Gabriel Roldan - * @author Jody Garnett - * @version $Id$ - * @since 2.3.x - */ -class Session implements ISession { - - private static final Logger LOGGER = Logger.getLogger("org.geotools.arcsde.pool"); - - /** - * How many seconds must have elapsed since the last connection round trip to the server for - * {@link #testServer()} to actually check the connection's validity - */ - protected static final long TEST_SERVER_ROUNDTRIP_INTERVAL_SECONDS = 5; - - /** Actual SeConnection being protected */ - private final SeConnection connection; - - /** - * ObjectPool used to manage open connections (shared). - */ - private final ObjectPool pool; - - private final ArcSDEConnectionConfig config; - - private static int sessionCounter; - - private final int sessionId; - - private boolean transactionInProgress; - - private boolean isPassivated; - - private Map<String, SeTable> cachedTables = new WeakHashMap<String, SeTable>(); - - private Map<String, SeLayer> cachedLayers = new WeakHashMap<String, SeLayer>(); - - private Map<String, SeRasterColumn> cachedRasters = new HashMap<String, SeRasterColumn>(); - - /** - * The SeConnection bound task executor, ensures all operations against a given connection are - * performed in the same thread regardless of the thread the {@link #issue(Command)} is being - * called from. - */ - private final ExecutorService taskExecutor; - - /** - * Thread used by the taskExecutor; so we can detect recursion. - */ - private Thread commandThread; - - /** - * Provides safe access to an SeConnection. - * - * @param pool - * ObjectPool used to manage SeConnection - * @param config - * Used to set up a SeConnection - * @throws SeException - * If we cannot connect - */ - Session(final ObjectPool pool, final ArcSDEConnectionConfig config) throws IOException { - this.config = config; - this.pool = pool; - this.taskExecutor = Executors.newSingleThreadExecutor(); - - // grab command thread, held by taskExecutor - updateCommandThread(); - - /* - * This ensures the connection runs always on the same thread. Will fail if its accessed by - * different threads - */ - try { - this.connection = issue(new CreateSessionCommand(config)); - } catch (IOException e) { - // make sure a connection creation failure does not leave a stale thread - this.taskExecutor.shutdownNow(); - throw e; - } catch (RuntimeException shouldntHappen) { - this.taskExecutor.shutdownNow(); - throw shouldntHappen; - } - - synchronized (Session.class) { - sessionCounter++; - sessionId = sessionCounter; - } - } - - /** - * @see ISession#issue(org.geotools.arcsde.session.Command) - */ - public <T> T issue(final Command<T> command) throws IOException { - final Thread callingThread = Thread.currentThread(); - if (callingThread == commandThread) { - // Called command inside command - try { - return command.execute(this, connection); - } catch (SeException e) { - Throwable cause = e.getCause(); - if (cause instanceof IOException) { - throw (IOException) cause; - } - throw new ArcSdeException(e); - } - } else { - final FutureTask<T> task = new FutureTask<T>(new Callable<T>() { - public T call() throws Exception { - final Thread currentThread = Thread.currentThread(); - - if (commandThread != currentThread) { - LOGGER.fine("updating command thread from " + commandThread + " to " - + currentThread); - commandThread = currentThread; - - } - if (currentThread != commandThread) { - throw new IllegalStateException("currentThread != commandThread"); - } - try { - return command.execute(Session.this, connection); - } catch (Exception e) { - if (LOGGER.isLoggable(Level.FINEST)) { - LOGGER.log(Level.FINEST, "Command execution failed for Session " - + Session.this.sessionId + " in thread " - + currentThread.getId(), e); - } else if (LOGGER.isLoggable(Level.FINE)) { - LOGGER.fine("Command execution failed for Session " - + Session.this.sessionId + " in thread " - + currentThread.getId()); - } - - if (e instanceof SeException) { - throw new ArcSdeException((SeException) e); - } else if (e instanceof IOException) { - throw e; - } - throw new RuntimeException("Command execution failed for Session " - + Session.this.sessionId + " in thread " + currentThread.getId(), e); - } - } - }); - - T result; - synchronized (config) { - taskExecutor.execute(task); - try { - result = task.get(); - } catch (InterruptedException e) { - updateCommandThread(); - throw new RuntimeException("Command execution abruptly interrupted", e); - } catch (ExecutionException e) { - updateCommandThread(); - Throwable cause = e.getCause(); - if (cause instanceof IOException) { - throw (IOException) cause; - } else if (cause instanceof SeException) { - throw new ArcSdeException((SeException) cause); - } - throw (IOException) new IOException().initCause(cause); - } - - } - return result; - } - } - - private void updateCommandThread() { - final FutureTask<?> task = new FutureTask<Object>(new Callable<Object>() { - public Object call() throws Exception { - final Thread currentThread = Thread.currentThread(); - if (currentThread != commandThread) { - LOGGER.fine("updating command thread from " + commandThread + " to " - + currentThread); - commandThread = currentThread; - } - return null; - } - }); - // used to detect when thread has been - // restarted after error - taskExecutor.execute(task); - // block until task is executed - try { - task.get(); - } catch (Exception e) { - e.printStackTrace(); - throw new RuntimeException(e); - } - } - - /** - * @see ISession#testServer() - */ - public final void testServer() throws IOException { - /* - * This method is called often (every time a session is to be returned from the pool) to - * check if it's still valid. We can call getTimeSinceLastRT safely since it does not - * require a server roundtrip and hence there's no risk of violating thread safety. So we do - * it before issuing the command to avoid the perf penalty imposed by running the command if - * not needed. - */ - final long secondsSinceLastServerRoundTrip = this.connection.getTimeSinceLastRT(); - - if (TEST_SERVER_ROUNDTRIP_INTERVAL_SECONDS < secondsSinceLastServerRoundTrip) { - issue(new Command<Void>() { - @Override - public Void execute(final ISession session, final SeConnection connection) - throws SeException, IOException { - connection.testServer(TEST_SERVER_ROUNDTRIP_INTERVAL_SECONDS); - - return null; - } - }); - } - } - - /** - * @see ISession#isClosed() - */ - public final boolean isClosed() { - return this.connection.isClosed(); - } - - /** - * Marks the connection as being active (i.e. its out of the pool and ready to be used). - * <p> - * Shall be called just before being returned from the connection pool - * </p> - * - * @see #markInactive() - * @see #isPassivated - * @see #checkActive() - */ - void markActive() { - this.isPassivated = false; - } - - /** - * Marks the connection as being inactive (i.e. laying on the connection pool) - * <p> - * Shall be callled just before sending it back to the pool - * </p> - * - * @see #markActive() - * @see #isPassivated - * @see #checkActive() - */ - void markInactive() { - this.isPassivated = true; - } - - /** - * @see ISession#isPassivated() - */ - public boolean isDisposed() { - return isPassivated; - } - - /** - * Sanity check method called before every public operation delegates to the superclass. - * - * @throws IllegalStateException - * if {@link #isDisposed() isPassivated() == true} as this is a serious workflow - * breackage. - */ - private void checkActive() { - if (isDisposed()) { - throw new IllegalStateException("Unrecoverable error: " + toString() - + " is passivated, shall not be used!"); - } - } - - /** - * @see ISession#getLayer(java.lang.String) - */ - public SeLayer getLayer(final String layerName) throws IOException { - checkActive(); - return issue(new Command<SeLayer>() { - @Override - public SeLayer execute(final ISession session, final SeConnection connection) - throws SeException, IOException { - if (!cachedLayers.containsKey(layerName)) { - synchronized (Session.this) { - if (!cachedLayers.containsKey(layerName)) { - SeTable table = getTable(layerName); - String shapeColumn = getShapeColumn(table); - if (shapeColumn == null) { - return null; - } - SeLayer layer = new SeLayer(connection, layerName, shapeColumn); - cachedLayers.put(layerName, layer); - } - } - } - SeLayer seLayer = cachedLayers.get(layerName); - if (seLayer == null) { - throw new NoSuchElementException("Layer '" + layerName + "' not found"); - } - return seLayer; - } - }); - } - - private String getShapeColumn(SeTable table) throws ArcSdeException { - try { - for (SeColumnDefinition aDef : table.describe()) { - if (aDef.getType() == SeColumnDefinition.TYPE_SHAPE) { - return aDef.getName(); - } - } - } catch (SeException e) { - throw new ArcSdeException("Exception describing table " + table.getName(), e); - } - return null; - } - - /** - * @see ISession#getRasterColumn(java.lang.String) - */ - public synchronized SeRasterColumn getRasterColumn(final String rasterName) throws IOException { - checkActive(); - if (!cachedRasters.containsKey(rasterName)) { - try { - cacheRasters(); - } catch (SeException e) { - throw (IOException) new IOException("Can't obtain raster " + rasterName) - .initCause(e); - } - } - SeRasterColumn raster = cachedRasters.get(rasterName); - if (raster == null) { - throw new NoSuchElementException("Raster '" + rasterName + "' not found"); - } - return raster; - } - - /** - * @see ISession#getTable(java.lang.String) - */ - public SeTable getTable(final String tableName) throws IOException { - checkActive(); - return issue(new Command<SeTable>() { - @Override - public SeTable execute(final ISession session, final SeConnection connection) - throws SeException, IOException { - if (!cachedTables.containsKey(tableName)) { - synchronized (Session.this) { - if (!cachedTables.containsKey(tableName)) { - SeTable table = new SeTable(connection, tableName); - try { - table.describe(); - } catch (SeException e) { - throw new NoSuchElementException("Table '" + tableName - + "' not found"); - } - cachedTables.put(tableName, table); - } - } - } - SeTable seTable = (SeTable) cachedTables.get(tableName); - if (seTable == null) { - throw new NoSuchElementException("Table '" + tableName + "' not found"); - } - return seTable; - } - }); - } - - @SuppressWarnings("unchecked") - private void cacheRasters() throws SeException { - Vector<SeRasterColumn> rasters = this.connection.getRasterColumns(); - cachedRasters.clear(); - for (SeRasterColumn raster : rasters) { - cachedRasters.put(raster.getQualifiedTableName(), raster); - } - } - - /** - * @see ISession#startTransaction() - */ - public void startTransaction() throws IOException { - checkActive(); - issue(new Command<Void>() { - @Override - public Void execute(final ISession session, final SeConnection connection) - throws SeException, IOException { - connection.setTransactionAutoCommit(0); - connection.startTransaction(); - transactionInProgress = true; - return null; - } - }); - } - - /** - * @see ISession#commitTransaction() - */ - public void commitTransaction() throws IOException { - checkActive(); - issue(new Command<Void>() { - @Override - public Void execute(final ISession session, final SeConnection connection) - throws SeException, IOException { - connection.commitTransaction(); - return null; - } - }); - transactionInProgress = false; - } - - /** - * @see ISession#isTransactionActive() - */ - public boolean isTransactionActive() { - checkActive(); - return transactionInProgress; - } - - /** - * @see ISession#rollbackTransaction() - */ - public void rollbackTransaction() throws IOException { - checkActive(); - try { - issue(new Command<Void>() { - @Override - public Void execute(final ISession session, final SeConnection connection) - throws SeException, IOException { - connection.rollbackTransaction(); - return null; - } - }); - } finally { - transactionInProgress = false; - } - } - - /** - * @see ISession#dispose() - */ - public void dispose() throws IllegalStateException { - checkActive(); - if (transactionInProgress) { - throw new IllegalStateException( - "Transaction is in progress, should commit or rollback before closing"); - } - - try { - this.pool.returnObject(this); - if (LOGGER.isLoggable(Level.FINER)) { - LOGGER.finer("<-- " + toString() + " retured to pool. Active: " - + pool.getNumActive() + ", idle: " + pool.getNumIdle()); - } - } catch (Exception e) { - LOGGER.log(Level.SEVERE, e.getMessage(), e); - } - } - - @Override - public String toString() { - return "Session[" + sessionId + "]"; - } - - /** - * Actually closes the connection, called when the session is discarded from the pool - */ - void destroy() { - LOGGER.fine("Destroying connection " + toString()); - try { - issue(new Command<Void>() { - @Override - public Void execute(final ISession session, final SeConnection connection) - throws SeException, IOException { - connection.close(); - LOGGER.fine(session.toString() + " successfully closed"); - return null; - } - }); - } catch (Exception e) { - LOGGER.log(Level.FINE, "closing connection " + toString(), e); - } - } - - /** - * @see ISession#equals(java.lang.Object) - */ - @Override - public boolean equals(Object other) { - return other == this; - } - - /** - * @see ISession#hashCode() - */ - @Override - public int hashCode() { - return 17 ^ this.config.hashCode(); - } - - /** - * @see ISession#getLayers() - */ - @SuppressWarnings("unchecked") - public List<SeLayer> getLayers() throws IOException { - return issue(new Command<List<SeLayer>>() { - @Override - public List<SeLayer> execute(final ISession session, final SeConnection connection) - throws SeException, IOException { - return connection.getLayers(); - } - }); - } - - /** - * @see ISession#getUser() - */ - public String getUser() throws IOException { - return issue(new Command<String>() { - @Override - public String execute(final ISession session, final SeConnection connection) - throws SeException, IOException { - return connection.getUser(); - } - }); - } - - /** - * @see ISession#getRelease() - */ - public SeRelease getRelease() throws IOException { - return issue(new Command<SeRelease>() { - @Override - public SeRelease execute(final ISession session, final SeConnection connection) - throws SeException, IOException { - return connection.getRelease(); - } - }); - } - - /** - * @see ISession#getDatabaseName() - */ - public String getDatabaseName() throws IOException { - return issue(new Command<String>() { - @Override - public String execute(final ISession session, final SeConnection connection) - throws SeException, IOException { - return connection.getDatabaseName(); - } - }); - } - - public SeDBMSInfo getDBMSInfo() throws IOException { - return issue(new Command<SeDBMSInfo>() { - @Override - public SeDBMSInfo execute(final ISession session, final SeConnection connection) - throws SeException, IOException { - return connection.getDBMSInfo(); - } - }); - } - - // - // Factory methods that make use of internal connection - // Q: How "long" are these objects good for? until the connection closes - - // or longer... - // - /** - * @see ISession#createSeLayer() - */ - public SeLayer createSeLayer() throws IOException { - return issue(new Command<SeLayer>() { - @Override - public SeLayer execute(final ISession session, final SeConnection connection) - throws SeException, IOException { - return new SeLayer(connection); - } - }); - } - - /** - * @see ISession#createSeRegistration(java.lang.String) - */ - public SeRegistration createSeRegistration(final String typeName) throws IOException { - return issue(new Command<SeRegistration>() { - @Override - public SeRegistration execute(final ISession session, final SeConnection connection) - throws SeException, IOException { - return new SeRegistration(connection, typeName); - } - }); - } - - /** - * @see ISession#createSeTable(java.lang.String) - */ - public SeTable createSeTable(final String qualifiedName) throws IOException { - return issue(new Command<SeTable>() { - @Override - public SeTable execute(final ISession session, final SeConnection connection) - throws SeException, IOException { - return new SeTable(connection, qualifiedName); - } - }); - } - - /** - * @see ISession#createSeInsert() - */ - public SeInsert createSeInsert() throws IOException { - return issue(new Command<SeInsert>() { - @Override - public SeInsert execute(final ISession session, final SeConnection connection) - throws SeException, IOException { - return new SeInsert(connection); - } - }); - } - - /** - * @see ISession#createSeUpdate() - */ - public SeUpdate createSeUpdate() throws IOException { - return issue(new Command<SeUpdate>() { - @Override - public SeUpdate execute(final ISession session, final SeConnection connection) - throws SeException, IOException { - return new SeUpdate(connection); - } - }); - } - - /** - * @see ISession#createSeDelete() - */ - public SeDelete createSeDelete() throws IOException { - return issue(new Command<SeDelete>() { - @Override - public SeDelete execute(final ISession session, final SeConnection connection) - throws SeException, IOException { - return new SeDelete(connection); - } - }); - } - - /** - * @see ISession#createSeRasterColumn() - */ - public SeRasterColumn createSeRasterColumn() throws IOException { - return issue(new Command<SeRasterColumn>() { - @Override - public SeRasterColumn execute(final ISession session, final SeConnection connection) - throws SeException, IOException { - return new SeRasterColumn(connection); - } - }); - } - - /** - * @see ISession#createSeRasterColumn(com.esri.sde.sdk.client.SeObjectId) - */ - public SeRasterColumn createSeRasterColumn(final SeObjectId rasterColumnId) throws IOException { - return issue(new Command<SeRasterColumn>() { - @Override - public SeRasterColumn execute(final ISession session, final SeConnection connection) - throws SeException, IOException { - return new SeRasterColumn(connection, rasterColumnId); - } - }); - } - - /** - * @see ISession#describe(java.lang.String) - */ - public SeColumnDefinition[] describe(final String tableName) throws IOException { - final SeTable table = getTable(tableName); - return describe(table); - } - - /** - * @see ISession#describe(com.esri.sde.sdk.client.SeTable) - */ - public SeColumnDefinition[] describe(final SeTable table) throws IOException { - return issue(new Command<SeColumnDefinition[]>() { - @Override - public SeColumnDefinition[] execute(final ISession session, - final SeConnection connection) throws SeException, IOException { - return table.describe(); - } - }); - } - - /** - * @see ISession#fetch(com.esri.sde.sdk.client.SeQuery) - */ - public SdeRow fetch(final SeQuery query) throws IOException { - return fetch(query, new SdeRow((GeometryFactory) null)); - } - - public SdeRow fetch(final SeQuery query, final SdeRow currentRow) throws IOException { - return issue(new Command<SdeRow>() { - @Override - public SdeRow execute(final ISession session, final SeConnection connection) - throws SeException, IOException { - SeRow row = query.fetch(); - if (row == null) { - return null; - } else { - currentRow.setRow(row); - } - return currentRow; - } - }); - } - - /** - * @see ISession#close(com.esri.sde.sdk.client.SeState) - */ - public void close(final SeState state) throws IOException { - issue(new Command<Void>() { - @Override - public Void execute(final ISession session, final SeConnection connection) - throws SeException, IOException { - state.close(); - return null; - } - }); - } - - /** - * @see ISession#close(com.esri.sde.sdk.client.SeStreamOp) - */ - public void close(final SeStreamOp stream) throws IOException { - issue(new Command<Void>() { - @Override - public Void execute(final ISession session, final SeConnection connection) - throws SeException, IOException { - stream.close(); - return null; - } - }); - } - - /** - * @see ISession#createState(com.esri.sde.sdk.client.SeObjectId) - */ - public SeState createState(final SeObjectId stateId) throws IOException { - return issue(new Command<SeState>() { - @Override - public SeState execute(final ISession session, final SeConnection connection) - throws SeException, IOException { - return new SeState(connection, stateId); - } - }); - } - - /** - * @see ISession#createSeQuery() - */ - public SeQuery createSeQuery() throws IOException { - return issue(new Command<SeQuery>() { - @Override - public SeQuery execute(final ISession session, final SeConnection connection) - throws SeException, IOException { - return new SeQuery(connection); - } - }); - } - - /** - * @see ISession#createSeQuery(java.lang.String[], com.esri.sde.sdk.client.SeSqlConstruct) - */ - public SeQuery createSeQuery(final String[] propertyNames, final SeSqlConstruct sql) - throws IOException { - - return issue(new Command<SeQuery>() { - @Override - public SeQuery execute(final ISession session, final SeConnection connection) - throws SeException, IOException { - return new SeQuery(connection, propertyNames, sql); - } - }); - } - - /** - * @see ISession#createAndExecuteQuery(java.lang.String[], - * com.esri.sde.sdk.client.SeSqlConstruct) - */ - public SeQuery createAndExecuteQuery(final String[] propertyNames, final SeSqlConstruct sql) - throws IOException { - return issue(new Command<SeQuery>() { - @Override - public SeQuery execute(final ISession session, final SeConnection connection) - throws SeException, IOException { - SeQuery query = new SeQuery(connection, propertyNames, sql); - query.prepareQuery(); - query.execute(); - return query; - } - }); - } - - /** - * @see ISession#getDefaultVersion() - */ - public SeVersion getDefaultVersion() throws IOException { - return issue(new GetVersionCommand(SeVersion.SE_QUALIFIED_DEFAULT_VERSION_NAME)); - } - - /** - * Creates either a direct child state of parentStateId, or a sibling being an exact copy of - * parentStatId if either the state can't be closed because its in use or parentStateId does not - * belong to the current user. - */ - public SeState createChildState(final long parentStateId) throws IOException { - return issue(new Command<SeState>() { - @Override - public SeState execute(ISession session, SeConnection connection) throws SeException, - IOException { - SeState parentState = new SeState(connection, new SeObjectId(parentStateId)); - - SeState realParent = null; - - boolean mergeParentToRealParent = false; - - if (parentState.isOpen()) { - // only closed states can have child states - try { - parentState.close(); - realParent = parentState; - } catch (SeException e) { - final int errorCode = e.getSeError().getSdeError(); - if (SeError.SE_STATE_INUSE == errorCode - || SeError.SE_NO_PERMISSIONS == errorCode) { - // it's not our state or somebody's editing it so we - // need to clone the parent, - // starting from the parent of the parent - realParent = new SeState(connection, parentState.getParentId()); - mergeParentToRealParent = true; - } else { - throw e; - } - } - } else { - realParent = parentState; - } - - // create the new state - SeState newState = new SeState(connection); - newState.create(realParent.getId()); - - if (mergeParentToRealParent) { - // a sibling of parentStateId was created instead of a - // child, we need to merge the changes - // in parentStateId to the new state so they refer to the - // same content. - // SE_state_merge applies changes to a parent state to - // create a new merged state. - // The new state is the child of the parent state with the - // changes of the second state. - // Both input states must have the same parent state. - // When a row has been changed in both parent and second - // states, the row from the changes state is used. - // The parent and changes states must be open or owned by - // the current user unless the current user is the ArcSDE - // DBA. - newState.merge(realParent.getId(), parentState.getId()); - } - - return newState; - } - }); - } - - private static final class CreateSessionCommand extends Command<SeConnection> { - private final ArcSDEConnectionConfig config; - - private CreateSessionCommand(final ArcSDEConnectionConfig config) { - this.config = config; - } - - @Override - public SeConnection execute(final ISession session, final SeConnection connection) - throws SeException, IOException { - String serverName = config.getServerName(); - int portNumber = config.getPortNumber().intValue(); - String databaseName = config.getDatabaseName(); - String userName = config.getUserName(); - String userPassword = config.getPassword(); - - SeConnection conn; - try { - conn = new SeConnection(serverName, portNumber, databaseName, userName, - userPassword); - } catch (SeException e) { - throw new ArcSdeException("Can't create connection to " + serverName, e); - } catch (RuntimeException e) { - throw (IOException) new IOException("Can't create connection to " + serverName) - .initCause(e); - } - conn.setConcurrency(SeConnection.SE_ONE_THREAD_POLICY); - return conn; - } - } -} Copied: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/Session.java (from rev 33502, trunk/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/Session.java) =================================================================== --- branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/Session.java (rev 0) +++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/Session.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -0,0 +1,974 @@ +/* + * 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.arcsde.session; + +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Vector; +import java.util.WeakHashMap; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.FutureTask; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.apache.commons.pool.ObjectPool; +import org.geotools.arcsde.ArcSdeException; +import org.geotools.arcsde.session.Commands.GetVersionCommand; + +import com.esri.sde.sdk.client.SeColumnDefinition; +import com.esri.sde.sdk.client.SeConnection; +import com.esri.sde.sdk.client.SeDBMSInfo; +import com.esri.sde.sdk.client.SeDelete; +import com.esri.sde.sdk.client.SeError; +import com.esri.sde.sdk.client.SeException; +import com.esri.sde.sdk.client.SeInsert; +import com.esri.sde.sdk.client.SeLayer; +import com.esri.sde.sdk.client.SeObjectId; +import com.esri.sde.sdk.client.SeQuery; +import com.esri.sde.sdk.client.SeRasterColumn; +import com.esri.sde.sdk.client.SeRegistration; +import com.esri.sde.sdk.client.SeRelease; +import com.esri.sde.sdk.client.SeRow; +import com.esri.sde.sdk.client.SeSqlConstruct; +import com.esri.sde.sdk.client.SeState; +import com.esri.sde.sdk.client.SeStreamOp; +import com.esri.sde.sdk.client.SeTable; +import com.esri.sde.sdk.client.SeUpdate; +import com.esri.sde.sdk.client.SeVersion; +import com.esri.sde.sdk.geom.GeometryFactory; + +/** + * Provides thread safe access to an SeConnection. + * <p> + * This class has become more and more magic over time! It no longer represents a Connection but + * provides "safe" access to a connection. + * <p> + * + * @author Gabriel Roldan + * @author Jody Garnett + * @version $Id$ + * @since 2.3.x + */ +class Session implements ISession { + + private static final Logger LOGGER = Logger.getLogger("org.geotools.arcsde.pool"); + + /** + * How many seconds must have elapsed since the last connection round trip to the server for + * {@link #testServer()} to actually check the connection's validity + */ + protected static final long TEST_SERVER_ROUNDTRIP_INTERVAL_SECONDS = 5; + + /** Actual SeConnection being protected */ + private final SeConnection connection; + + /** + * ObjectPool used to manage open connections (shared). + */ + private final ObjectPool pool; + + private final ArcSDEConnectionConfig config; + + private static int sessionCounter; + + private final int sessionId; + + private boolean transactionInProgress; + + private boolean isPassivated; + + private Map<String, SeTable> cachedTables = new WeakHashMap<String, SeTable>(); + + private Map<String, SeLayer> cachedLayers = new WeakHashMap<String, SeLayer>(); + + private Map<String, SeRasterColumn> cachedRasters = new HashMap<String, SeRasterColumn>(); + + /** + * The SeConnection bound task executor, ensures all operations against a given connection are + * performed in the same thread regardless of the thread the {@link #issue(Command)} is being + * called from. + */ + private final ExecutorService taskExecutor; + + /** + * Thread used by the taskExecutor; so we can detect recursion. + */ + private Thread commandThread; + + /** + * Provides safe access to an SeConnection. + * + * @param pool + * ObjectPool used to manage SeConnection + * @param config + * Used to set up a SeConnection + * @throws SeException + * If we cannot connect + */ + Session(final ObjectPool pool, final ArcSDEConnectionConfig config) throws IOException { + this.config = config; + this.pool = pool; + this.taskExecutor = Executors.newSingleThreadExecutor(); + + // grab command thread, held by taskExecutor + updateCommandThread(); + + /* + * This ensures the connection runs always on the same thread. Will fail if its accessed by + * different threads + */ + try { + this.connection = issue(new CreateSessionCommand(config)); + } catch (IOException e) { + // make sure a connection creation failure does not leave a stale thread + this.taskExecutor.shutdownNow(); + throw e; + } catch (RuntimeException shouldntHappen) { + this.taskExecutor.shutdownNow(); + throw shouldntHappen; + } + + synchronized (Session.class) { + sessionCounter++; + sessionId = sessionCounter; + } + } + + /** + * @see ISession#issue(org.geotools.arcsde.session.Command) + */ + public <T> T issue(final Command<T> command) throws IOException { + final Thread callingThread = Thread.currentThread(); + if (callingThread == commandThread) { + // Called command inside command + try { + return command.execute(this, connection); + } catch (SeException e) { + Throwable cause = e.getCause(); + if (cause instanceof IOException) { + throw (IOException) cause; + } + throw new ArcSdeException(e); + } + } else { + final FutureTask<T> task = new FutureTask<T>(new Callable<T>() { + public T call() throws Exception { + final Thread currentThread = Thread.currentThread(); + + if (commandThread != currentThread) { + LOGGER.fine("updating command thread from " + commandThread + " to " + + currentThread); + commandThread = currentThread; + + } + if (currentThread != commandThread) { + throw new IllegalStateException("currentThread != commandThread"); + } + try { + return command.execute(Session.this, connection); + } catch (Exception e) { + if (LOGGER.isLoggable(Level.FINEST)) { + LOGGER.log(Level.FINEST, "Command execution failed for Session " + + Session.this.sessionId + " in thread " + + currentThread.getId(), e); + } else if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.fine("Command execution failed for Session " + + Session.this.sessionId + " in thread " + + currentThread.getId()); + } + + if (e instanceof SeException) { + throw new ArcSdeException((SeException) e); + } else if (e instanceof IOException) { + throw e; + } + throw new RuntimeException("Command execution failed for Session " + + Session.this.sessionId + " in thread " + currentThread.getId(), e); + } + } + }); + + T result; + synchronized (config) { + taskExecutor.execute(task); + try { + result = task.get(); + } catch (InterruptedException e) { + updateCommandThread(); + throw new RuntimeException("Command execution abruptly interrupted", e); + } catch (ExecutionException e) { + updateCommandThread(); + Throwable cause = e.getCause(); + if (cause instanceof IOException) { + throw (IOException) cause; + } else if (cause instanceof SeException) { + throw new ArcSdeException((SeException) cause); + } + throw (IOException) new IOException().initCause(cause); + } + + } + return result; + } + } + + private void updateCommandThread() { + final FutureTask<?> task = new FutureTask<Object>(new Callable<Object>() { + public Object call() throws Exception { + final Thread currentThread = Thread.currentThread(); + if (currentThread != commandThread) { + LOGGER.fine("updating command thread from " + commandThread + " to " + + currentThread); + commandThread = currentThread; + } + return null; + } + }); + // used to detect when thread has been + // restarted after error + taskExecutor.execute(task); + // block until task is executed + try { + task.get(); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } + + /** + * @see ISession#testServer() + */ + public final void testServer() throws IOException { + /* + * This method is called often (every time a session is to be returned from the pool) to + * check if it's still valid. We can call getTimeSinceLastRT safely since it does not + * require a server roundtrip and hence there's no risk of violating thread safety. So we do + * it before issuing the command to avoid the perf penalty imposed by running the command if + * not needed. + */ + final long secondsSinceLastServerRoundTrip = this.connection.getTimeSinceLastRT(); + + if (TEST_SERVER_ROUNDTRIP_INTERVAL_SECONDS < secondsSinceLastServerRoundTrip) { + issue(new Command<Void>() { + @Override + public Void execute(final ISession session, final SeConnection connection) + throws SeException, IOException { + connection.testServer(TEST_SERVER_ROUNDTRIP_INTERVAL_SECONDS); + + return null; + } + }); + } + } + + /** + * @see ISession#isClosed() + */ + public final boolean isClosed() { + return this.connection.isClosed(); + } + + /** + * Marks the connection as being active (i.e. its out of the pool and ready to be used). + * <p> + * Shall be called just before being returned from the connection pool + * </p> + * + * @see #markInactive() + * @see #isPassivated + * @see #checkActive() + */ + void markActive() { + this.isPassivated = false; + } + + /** + * Marks the connection as being inactive (i.e. laying on the connection pool) + * <p> + * Shall be callled just before sending it back to the pool + * </p> + * + * @see #markActive() + * @see #isPassivated + * @see #checkActive() + */ + void markInactive() { + this.isPassivated = true; + } + + /** + * @see ISession#isPassivated() + */ + public boolean isDisposed() { + return isPassivated; + } + + /** + * Sanity check method called before every public operation delegates to the superclass. + * + * @throws IllegalStateException + * if {@link #isDisposed() isPassivated() == true} as this is a serious workflow + * breackage. + */ + private void checkActive() { + if (isDisposed()) { + throw new IllegalStateException("Unrecoverable error: " + toString() + + " is passivated, shall not be used!"); + } + } + + /** + * @see ISession#getLayer(java.lang.String) + */ + public SeLayer getLayer(final String layerName) throws IOException { + checkActive(); + return issue(new Command<SeLayer>() { + @Override + public SeLayer execute(final ISession session, final SeConnection connection) + throws SeException, IOException { + if (!cachedLayers.containsKey(layerName)) { + synchronized (Session.this) { + if (!cachedLayers.containsKey(layerName)) { + SeTable table = getTable(layerName); + String shapeColumn = getShapeColumn(table); + if (shapeColumn == null) { + return null; + } + SeLayer layer = new SeLayer(connection, layerName, shapeColumn); + cachedLayers.put(layerName, layer); + } + } + } + SeLayer seLayer = cachedLayers.get(layerName); + if (seLayer == null) { + throw new NoSuchElementException("Layer '" + layerName + "' not found"); + } + return seLayer; + } + }); + } + + private String getShapeColumn(SeTable table) throws ArcSdeException { + try { + for (SeColumnDefinition aDef : table.describe()) { + if (aDef.getType() == SeColumnDefinition.TYPE_SHAPE) { + return aDef.getName(); + } + } + } catch (SeException e) { + throw new ArcSdeException("Exception describing table " + table.getName(), e); + } + return null; + } + + /** + * @see ISession#getRasterColumn(java.lang.String) + */ + public synchronized SeRasterColumn getRasterColumn(final String rasterName) throws IOException { + checkActive(); + if (!cachedRasters.containsKey(rasterName)) { + try { + cacheRasters(); + } catch (SeException e) { + throw (IOException) new IOException("Can't obtain raster " + rasterName) + .initCause(e); + } + } + SeRasterColumn raster = cachedRasters.get(rasterName); + if (raster == null) { + throw new NoSuchElementException("Raster '" + rasterName + "' not found"); + } + return raster; + } + + /** + * @see ISession#getTable(java.lang.String) + */ + public SeTable getTable(final String tableName) throws IOException { + checkActive(); + return issue(new Command<SeTable>() { + @Override + public SeTable execute(final ISession session, final SeConnection connection) + throws SeException, IOException { + if (!cachedTables.containsKey(tableName)) { + synchronized (Session.this) { + if (!cachedTables.containsKey(tableName)) { + SeTable table = new SeTable(connection, tableName); + try { + table.describe(); + } catch (SeException e) { + throw new NoSuchElementException("Table '" + tableName + + "' not found"); + } + cachedTables.put(tableName, table); + } + } + } + SeTable seTable = (SeTable) cachedTables.get(tableName); + if (seTable == null) { + throw new NoSuchElementException("Table '" + tableName + "' not found"); + } + return seTable; + } + }); + } + + @SuppressWarnings("unchecked") + private void cacheRasters() throws SeException { + Vector<SeRasterColumn> rasters = this.connection.getRasterColumns(); + cachedRasters.clear(); + for (SeRasterColumn raster : rasters) { + cachedRasters.put(raster.getQualifiedTableName(), raster); + } + } + + /** + * @see ISession#startTransaction() + */ + public void startTransaction() throws IOException { + checkActive(); + issue(new Command<Void>() { + @Override + public Void execute(final ISession session, final SeConnection connection) + throws SeException, IOException { + connection.setTransactionAutoCommit(0); + connection.startTransaction(); + transactionInProgress = true; + return null; + } + }); + } + + /** + * @see ISession#commitTransaction() + */ + public void commitTransaction() throws IOException { + checkActive(); + issue(new Command<Void>() { + @Override + public Void execute(final ISession session, final SeConnection connection) + throws SeException, IOException { + connection.commitTransaction(); + return null; + } + }); + transactionInProgress = false; + } + + /** + * @see ISession#isTransactionActive() + */ + public boolean isTransactionActive() { + checkActive(); + return transactionInProgress; + } + + /** + * @see ISession#rollbackTransaction() + */ + public void rollbackTransaction() throws IOException { + checkActive(); + try { + issue(new Command<Void>() { + @Override + public Void execute(final ISession session, final SeConnection connection) + throws SeException, IOException { + connection.rollbackTransaction(); + return null; + } + }); + } finally { + transactionInProgress = false; + } + } + + /** + * @see ISession#dispose() + */ + public void dispose() throws IllegalStateException { + checkActive(); + if (transactionInProgress) { + throw new IllegalStateException( + "Transaction is in progress, should commit or rollback before closing"); + } + + try { + this.pool.returnObject(this); + if (LOGGER.isLoggable(Level.FINER)) { + LOGGER.finer("<-- " + toString() + " retured to pool. Active: " + + pool.getNumActive() + ", idle: " + pool.getNumIdle()); + } + } catch (Exception e) { + LOGGER.log(Level.SEVERE, e.getMessage(), e); + } + } + + @Override + public String toString() { + return "Session[" + sessionId + "]"; + } + + /** + * Actually closes the connection, called when the session is discarded from the pool + */ + void destroy() { + LOGGER.fine("Destroying connection " + toString()); + try { + issue(new Command<Void>() { + @Override + public Void execute(final ISession session, final SeConnection connection) + throws SeException, IOException { + connection.close(); + LOGGER.fine(session.toString() + " successfully closed"); + return null; + } + }); + } catch (Exception e) { + LOGGER.log(Level.FINE, "closing connection " + toString(), e); + } + } + + /** + * @see ISession#equals(java.lang.Object) + */ + @Override + public boolean equals(Object other) { + return other == this; + } + + /** + * @see ISession#hashCode() + */ + @Override + public int hashCode() { + return 17 ^ this.config.hashCode(); + } + + /** + * @see ISession#getLayers() + */ + @SuppressWarnings("unchecked") + public List<SeLayer> getLayers() throws IOException { + return issue(new Command<List<SeLayer>>() { + @Override + public List<SeLayer> execute(final ISession session, final SeConnection connection) + throws SeException, IOException { + return connection.getLayers(); + } + }); + } + + /** + * @see ISession#getUser() + */ + public String getUser() throws IOException { + return issue(new Command<String>() { + @Override + public String execute(final ISession session, final SeConnection connection) + throws SeException, IOException { + return connection.getUser(); + } + }); + } + + /** + * @see ISession#getRelease() + */ + public SeRelease getRelease() throws IOException { + return issue(new Command<SeRelease>() { + @Override + public SeRelease execute(final ISession session, final SeConnection connection) + throws SeException, IOException { + return connection.getRelease(); + } + }); + } + + /** + * @see ISession#getDatabaseName() + */ + public String getDatabaseName() throws IOException { + return issue(new Command<String>() { + @Override + public String execute(final ISession session, final SeConnection connection) + throws SeException, IOException { + return connection.getDatabaseName(); + } + }); + } + + public SeDBMSInfo getDBMSInfo() throws IOException { + return issue(new Command<SeDBMSInfo>() { + @Override + public SeDBMSInfo execute(final ISession session, final SeConnection connection) + throws SeException, IOException { + return connection.getDBMSInfo(); + } + }); + } + + // + // Factory methods that make use of internal connection + // Q: How "long" are these objects good for? until the connection closes - + // or longer... + // + /** + * @see ISession#createSeLayer() + */ + public SeLayer createSeLayer() throws IOException { + return issue(new Command<SeLayer>() { + @Override + public SeLayer execute(final ISession session, final SeConnection connection) + throws SeException, IOException { + return new SeLayer(connection); + } + }); + } + + /** + * @see ISession#createSeRegistration(java.lang.String) + */ + public SeRegistration createSeRegistration(final String typeName) throws IOException { + return issue(new Command<SeRegistration>() { + @Override + public SeRegistration execute(final ISession session, final SeConnection connection) + throws SeException, IOException { + return new SeRegistration(connection, typeName); + } + }); + } + + /** + * @see ISession#createSeTable(java.lang.String) + */ + public SeTable createSeTable(final String qualifiedName) throws IOException { + return issue(new Command<SeTable>() { + @Override + public SeTable execute(final ISession session, final SeConnection connection) + throws SeException, IOException { + return new SeTable(connection, qualifiedName); + } + }); + } + + /** + * @see ISession#createSeInsert() + */ + public SeInsert createSeInsert() throws IOException { + return issue(new Command<SeInsert>() { + @Override + public SeInsert execute(final ISession session, final SeConnection connection) + throws SeException, IOException { + return new SeInsert(connection); + } + }); + } + + /** + * @see ISession#createSeUpdate() + */ + public SeUpdate createSeUpdate() throws IOException { + return issue(new Command<SeUpdate>() { + @Override + public SeUpdate execute(final ISession session, final SeConnection connection) + throws SeException, IOException { + return new SeUpdate(connection); + } + }); + } + + /** + * @see ISession#createSeDelete() + */ + public SeDelete createSeDelete() throws IOException { + return issue(new Command<SeDelete>() { + @Override + public SeDelete execute(final ISession session, final SeConnection connection) + throws SeException, IOException { + return new SeDelete(connection); + } + }); + } + + /** + * @see ISession#createSeRasterColumn() + */ + public SeRasterColumn createSeRasterColumn() throws IOException { + return issue(new Command<SeRasterColumn>() { + @Override + public SeRasterColumn execute(final ISession session, final SeConnection connection) + throws SeException, IOException { + return new SeRasterColumn(connection); + } + }); + } + + /** + * @see ISession#createSeRasterColumn(com.esri.sde.sdk.client.SeObjectId) + */ + public SeRasterColumn createSeRasterColumn(final SeObjectId rasterColumnId) throws IOException { + return issue(new Command<SeRasterColumn>() { + @Override + public SeRasterColumn execute(final ISession session, final SeConnection connection) + throws SeException, IOException { + return new SeRasterColumn(connection, rasterColumnId); + } + }); + } + + /** + * @see ISession#describe(java.lang.String) + */ + public SeColumnDefinition[] describe(final String tableName) throws IOException { + final SeTable table = getTable(tableName); + return describe(table); + } + + /** + * @see ISession#describe(com.esri.sde.sdk.client.SeTable) + */ + public SeColumnDefinition[] describe(final SeTable table) throws IOException { + return issue(new Command<SeColumnDefinition[]>() { + @Override + public SeColumnDefinition[] execute(final ISession session, + final SeConnection connection) throws SeException, IOException { + return table.describe(); + } + }); + } + + /** + * @see ISession#fetch(com.esri.sde.sdk.client.SeQuery) + */ + public SdeRow fetch(final SeQuery query) throws IOException { + return fetch(query, new SdeRow((GeometryFactory) null)); + } + + public SdeRow fetch(final SeQuery query, final SdeRow currentRow) throws IOException { + return issue(new Command<SdeRow>() { + @Override + public SdeRow execute(final ISession session, final SeConnection connection) + throws SeException, IOException { + SeRow row = query.fetch(); + if (row == null) { + return null; + } else { + currentRow.setRow(row); + } + return currentRow; + } + }); + } + + /** + * @see ISession#close(com.esri.sde.sdk.client.SeState) + */ + public void close(final SeState state) throws IOException { + issue(new Command<Void>() { + @Override + public Void execute(final ISession session, final SeConnection connection) + throws SeException, IOException { + state.close(); + return null; + } + }); + } + + /** + * @see ISession#close(com.esri.sde.sdk.client.SeStreamOp) + */ + public void close(final SeStreamOp stream) throws IOException { + issue(new Command<Void>() { + @Override + public Void execute(final ISession session, final SeConnection connection) + throws SeException, IOException { + stream.close(); + return null; + } + }); + } + + /** + * @see ISession#createState(com.esri.sde.sdk.client.SeObjectId) + */ + public SeState createState(final SeObjectId stateId) throws IOException { + return issue(new Command<SeState>() { + @Override + public SeState execute(final ISession session, final SeConnection connection) + throws SeException, IOException { + return new SeState(connection, stateId); + } + }); + } + + /** + * @see ISession#createSeQuery() + */ + public SeQuery createSeQuery() throws IOException { + return issue(new Command<SeQuery>() { + @Override + public SeQuery execute(final ISession session, final SeConnection connection) + throws SeException, IOException { + return new SeQuery(connection); + } + }); + } + + /** + * @see ISession#createSeQuery(java.lang.String[], com.esri.sde.sdk.client.SeSqlConstruct) + */ + public SeQuery createSeQuery(final String[] propertyNames, final SeSqlConstruct sql) + throws IOException { + + return issue(new Command<SeQuery>() { + @Override + public SeQuery execute(final ISession session, final SeConnection connection) + throws SeException, IOException { + return new SeQuery(connection, propertyNames, sql); + } + }); + } + + /** + * @see ISession#createAndExecuteQuery(java.lang.String[], + * com.esri.sde.sdk.client.SeSqlConstruct) + */ + public SeQuery createAndExecuteQuery(final String[] propertyNames, final SeSqlConstruct sql) + throws IOException { + return issue(new Command<SeQuery>() { + @Override + public SeQuery execute(final ISession session, final SeConnection connection) + throws SeException, IOException { + SeQuery query = new SeQuery(connection, propertyNames, sql); + query.prepareQuery(); + query.execute(); + return query; + } + }); + } + + /** + * @see ISession#getDefaultVersion() + */ + public SeVersion getDefaultVersion() throws IOException { + return issue(new GetVersionCommand(SeVersion.SE_QUALIFIED_DEFAULT_VERSION_NAME)); + } + + /** + * Creates either a direct child state of parentStateId, or a sibling being an exact copy of + * parentStatId if either the state can't be closed because its in use or parentStateId does not + * belong to the current user. + */ + public SeState createChildState(final long parentStateId) throws IOException { + return issue(new Command<SeState>() { + @Override + public SeState execute(ISession session, SeConnection connection) throws SeException, + IOException { + SeState parentState = new SeState(connection, new SeObjectId(parentStateId)); + + SeState realParent = null; + + boolean mergeParentToRealParent = false; + + if (parentState.isOpen()) { + // only closed states can have child states + try { + parentState.close(); + realParent = parentState; + } catch (SeException e) { + final int errorCode = e.getSeError().getSdeError(); + if (SeError.SE_STATE_INUSE == errorCode + || SeError.SE_NO_PERMISSIONS == errorCode) { + // it's not our state or somebody's editing it so we + // need to clone the parent, + // starting from the parent of the parent + realParent = new SeState(connection, parentState.getParentId()); + mergeParentToRealParent = true; + } else { + throw e; + } + } + } else { + realParent = parentState; + } + + // create the new state + SeState newState = new SeState(connection); + newState.create(realParent.getId()); + + if (mergeParentToRealParent) { + // a sibling of parentStateId was created instead of a + // child, we need to merge the changes + // in parentStateId to the new state so they refer to the + // same content. + // SE_state_merge applies changes to a parent state to + // create a new merged state. + // The new state is the child of the parent state with the + // changes of the second state. + // Both input states must have the same parent state. + // When a row has been changed in both parent and second + // states, the row from the changes state is used. + // The parent and changes states must be open or owned by + // the current user unless the current user is the ArcSDE + // DBA. + newState.merge(realParent.getId(), parentState.getId()); + } + + return newState; + } + }); + } + + private static final class CreateSessionCommand extends Command<SeConnection> { + private final ArcSDEConnectionConfig config; + + private CreateSessionCommand(final ArcSDEConnectionConfig config) { + this.config = config; + } + + @Override + public SeConnection execute(final ISession session, final SeConnection connection) + throws SeException, IOException { + String serverName = config.getServerName(); + int portNumber = config.getPortNumber().intValue(); + String databaseName = config.getDatabaseName(); + String userName = config.getUserName(); + String userPassword = config.getPassword(); + + SeConnection conn; + try { + conn = new SeConnection(serverName, portNumber, databaseName, userName, + userPassword); + } catch (SeException e) { + throw new ArcSdeException("Can't create connection to " + serverName, e); + } catch (RuntimeException e) { + throw (IOException) new IOException("Can't create connection to " + serverName) + .initCause(e); + } + conn.setConcurrency(SeConnection.SE_ONE_THREAD_POLICY); + return conn; + } + } +} Deleted: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/SessionPool.java =================================================================== --- trunk/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/SessionPool.java 2009-07-07 01:13:56 UTC (rev 33502) +++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/SessionPool.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -1,427 +0,0 @@ -/* - * 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.arcsde.session; - -import java.io.IOException; -import java.util.NoSuchElementException; -import java.util.logging.Level; -import java.util.logging.Logger; - -import org.apache.commons.pool.BasePoolableObjectFactory; -import org.apache.commons.pool.impl.GenericObjectPool; -import org.apache.commons.pool.impl.GenericObjectPool.Config; -import org.geotools.arcsde.ArcSdeException; - -import com.esri.sde.sdk.client.SeException; -import com.esri.sde.sdk.client.SeRelease; - -/** - * Maintains <code>SeConnection</code>'s for a single set of connection properties (for instance: by - * server, port, user and password) in a pool to recycle used connections. - * <p> - * We are making use of an Apache Commons ObjectPool to maintain connections. This connection pool - * is configurable in the sense that some parameters can be passed to establish the pooling policy. - * To pass parameters to the connection pool, you should set properties in the parameters Map passed - * to SdeDataStoreFactory.createDataStore, which will invoke SdeConnectionPoolFactory to get the SDE - * instance's pool singleton. That instance singleton will be created with the preferences passed - * the first time createDataStore is called for a given SDE instance/user, if subsequent calls - * change that preferences, they will be ignored. - * </p> - * <p> - * The expected optional parameters that you can set up in the argument Map for createDataStore are: - * <ul> - * <li>pool.minConnections Integer, tells the minimum number of open connections the pool will - * maintain opened</li> - * <li>pool.maxConnections Integer, tells the maximum number of open connections the pool will - * create and maintain opened</li> - * <li>pool.timeOut Integer, tells how many milliseconds a calling thread is guaranteed to wait - * before getConnection() throws an UnavailableArcSDEConnectionException</li> - * </ul> - * </p> - * - * @author Gabriel Roldan - * @version $Id$ - */ -class SessionPool implements ISessionPool { - /** package's logger */ - private static final Logger LOGGER = Logger.getLogger("org.geotools.arcsde.pool"); - - protected static final Level INFO_LOG_LEVEL = Level.WARNING; - - private SeConnectionFactory seConnectionFactory; - - /** this connection pool connection's parameters */ - protected ArcSDEConnectionConfig config; - - /** Apache commons-pool used to pool arcsde connections */ - protected GenericObjectPool pool; - - /** - * Creates a new SdeConnectionPool object with the connection parameters holded by - * <code>config</code> - * - * @param config - * holds connection options such as server, user and password, as well as tuning - * options as maximum number of connections allowed - * @throws IOException - * If connection could not be established - * @throws NullPointerException - * If config is null - */ - protected SessionPool(ArcSDEConnectionConfig config) throws IOException { - if (config == null) { - throw new NullPointerException("parameter config can't be null"); - } - - this.config = config; - LOGGER.fine("populating ArcSDE connection pool"); - - this.seConnectionFactory = createConnectionFactory(); - - final int minConnections = config.getMinConnections().intValue(); - final int maxConnections = config.getMaxConnections().intValue(); - if (minConnections > maxConnections) { - throw new IllegalArgumentException("pool.minConnections > pool.maxConnections"); - } - {// configure connection pool - - Config poolCfg = new Config(); - // pool upper limit - poolCfg.maxActive = config.getMaxConnections().intValue(); - - // minimum number of idle objects. MAKE SURE this is 0, otherwise the pool will start - // trying to create connections permanently even if there's a connection failure, - // ultimately leading to the exhaustion of resources - poolCfg.minIdle = 0; - - // how many connections may be idle at any time? -1 = no limit. We're running an - // eviction thread to take care of idle connections (see minEvictableIdleTimeMillis and - // timeBetweenEvictionRunsMillis) - poolCfg.maxIdle = -1; - - // When reached the pool upper limit, block and wait for an idle connection for maxWait - // milliseconds before failing - poolCfg.maxWait = config.getConnTimeOut().longValue(); - poolCfg.whenExhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_BLOCK; - - // check connection health at borrowObject()? - poolCfg.testOnBorrow = true; - // check connection health at returnObject()? - poolCfg.testOnReturn = false; - // check periodically the health of idle connections and discard them if can't be - // validated? - poolCfg.testWhileIdle = true; - - // check health of idle connections every 30 seconds - poolCfg.timeBetweenEvictionRunsMillis = 30000; - - // drop connections that have been idle for at least one minute - poolCfg.minEvictableIdleTimeMillis = 60000; - - pool = new GenericObjectPool(seConnectionFactory, poolCfg); - - LOGGER.fine("Created ArcSDE connection pool for " + config); - } - - ISession[] preload = new ISession[minConnections]; - - try { - for (int i = 0; i < minConnections; i++) { - preload[i] = (ISession) pool.borrowObject(); - if (i == 0) { - SeRelease seRelease = preload[i].getRelease(); - String sdeDesc = seRelease.getDesc(); - int major = seRelease.getMajor(); - int minor = seRelease.getMinor(); - int bugFix = seRelease.getBugFix(); - String desc = "ArcSDE " + major + "." + minor + "." + bugFix + " " + sdeDesc; - LOGGER.fine("Connected to " + desc); - } - } - - for (int i = 0; i < minConnections; i++) { - pool.returnObject(preload[i]); - } - } catch (Exception e) { - try { - pool.close(); - } catch (Exception closeEx) { - // ignore - } - if (e instanceof IOException) { - throw (IOException) e; - } - throw (IOException) new IOException().initCause(e); - } - } - - /** - * SeConnectionFactory used to create {@link ISession} instances for the pool. - * <p> - * Subclass may overide to customize this behaviour. - * </p> - * - * @return SeConnectionFactory. - */ - protected SeConnectionFactory createConnectionFactory() { - return new SeConnectionFactory(this.config); - } - - /* - * (non-Javadoc) - * - * @see org.geotools.arcsde.session.ISessionPool#getPoolSize() - */ - public int getPoolSize() { - checkOpen(); - synchronized (this.pool) { - return this.pool.getNumActive() + this.pool.getNumIdle(); - } - } - - /* - * (non-Javadoc) - * - * @see org.geotools.arcsde.session.ISessionPool#close() - */ - public void close() { - if (pool != null) { - try { - this.pool.close(); - pool = null; - LOGGER.fine("SDE connection pool closed. "); - } catch (Exception e) { - LOGGER.log(Level.WARNING, "Closing pool: " + e.getMessage(), e); - } - } - } - - /* - * (non-Javadoc) - * - * @see org.geotools.arcsde.session.ISessionPool#isClosed() - */ - public boolean isClosed() { - return pool == null; - } - - private void checkOpen() throws IllegalStateException { - if (isClosed()) { - throw new IllegalStateException("This session pool is closed"); - } - } - - /** - * Ensures proper closure of connection pool at this object's finalization stage. - */ - @Override - protected void finalize() { - close(); - } - - /* - * (non-Javadoc) - * - * @see org.geotools.arcsde.session.ISessionPool#getAvailableCount() - */ - public synchronized int getAvailableCount() { - checkOpen(); - return this.pool.getNumIdle(); - } - - /* - * (non-Javadoc) - * - * @see org.geotools.arcsde.session.ISessionPool#getInUseCount() - */ - public synchronized int getInUseCount() { - checkOpen(); - return this.pool.getNumActive(); - } - - /* - * (non-Javadoc) - * - * @see org.geotools.arcsde.session.ISessionPool#getSession() - */ - public ISession getSession() throws IOException, UnavailableArcSDEConnectionException { - checkOpen(); - try { - Session connection = (Session) this.pool.borrowObject(); - - if (LOGGER.isLoggable(Level.FINER)) { - LOGGER.finer("-->" + connection + " out of connection pool. Active: " - + pool.getNumActive() + ", idle: " + pool.getNumIdle()); - } - - connection.markActive(); - return connection; - } catch (NoSuchElementException e) { - LOGGER.log(Level.WARNING, "Out of connections: " + e.getMessage() + ". Config: " - + this.config); - throw new UnavailableArcSDEConnectionException(this.pool.getNumActive(), this.config); - } catch (SeException se) { - ArcSdeException sdee = new ArcSdeException(se); - LOGGER.log(Level.WARNING, "ArcSDE error getting connection for " + config, sdee); - throw sdee; - } catch (Exception e) { - LOGGER.log(Level.WARNING, "Unknown problem getting connection: " + e.getMessage(), e); - throw (IOException) new IOException( - "Unknown problem fetching connection from connection pool").initCause(e); - } - } - - /* - * (non-Javadoc) - * - * @see org.geotools.arcsde.session.ISessionPool#getConfig() - */ - public ArcSDEConnectionConfig getConfig() { - return this.config; - } - - /** - * PoolableObjectFactory intended to be used by a Jakarta's commons-pool objects pool, that - * provides ArcSDE's SeConnections. - * - * @author Gabriel Roldan, Axios Engineering - * @version $Id$ - */ - protected final class SeConnectionFactory extends BasePoolableObjectFactory { - - private ArcSDEConnectionConfig config; - - /** - * Creates a new SeConnectionFactory object. - * - * @param config - */ - public SeConnectionFactory(ArcSDEConnectionConfig config) { - super(); - this.config = config; - } - - /** - * Called whenever a new instance is needed. - * - * @return a newly created <code>SeConnection</code> - * @throws SeException - * if the connection can't be created - */ - @Override - public Object makeObject() throws IOException { - NegativeArraySizeException cause = null; - for (int i = 0; i < 3; i++) { - try { - ISession seConn = new Session(SessionPool.this.pool, config); - return seConn; - } catch (NegativeArraySizeException nase) { - LOGGER.warning("Strange failed ArcSDE connection error. Trying again (try " - + (i + 1) + " of 3)"); - cause = nase; - } - } - throw (IOException) new IOException( - "Couldn't create ArcSDE Session because of strange SDE internal exception. " - + " Tried 3 times, giving up.").initCause(cause); - } - - /** - * is invoked on every instance before it is returned from the pool. - * - * @param obj - */ - @Override - public void activateObject(Object obj) { - final Session conn = (Session) obj; - conn.markActive(); - LOGGER.finest(" activating connection " + obj); - } - - @Override - public void passivateObject(Object obj) { - LOGGER.finest(" passivating connection " + obj); - final Session conn = (Session) obj; - conn.markInactive(); - } - - /** - * is invoked in an implementation-specific fashion to determine if an instance is still - * valid to be returned by the pool. It will only be invoked on an "activated" instance. - * - * @param an - * instance of {@link Session} maintained by this pool. - * @return <code>true</code> if the connection is still alive and operative (checked by - * asking its user name), <code>false</code> otherwise. - */ - @Override - public boolean validateObject(Object obj) { - ISession session = (ISession) obj; - boolean valid = !session.isClosed(); - // MAKE PROPER VALIDITY CHECK HERE as for GEOT-1273 - if (valid) { - try { - if (LOGGER.isLoggable(Level.FINEST)) { - LOGGER.finest(" Validating SDE Connection " + session); - } - /* - * Validate the connection's health with testServer instead of getUser. The - * former is lighter weight, getUser() forced a server round trip and under - * heavy concurrency ate about 30% the time - */ - session.testServer(); - } catch (IOException e) { - LOGGER.info("Can't validate SeConnection, discarding it: " + session - + ". Reason: " + e.getMessage()); - valid = false; - } - } - return valid; - } - - /** - * is invoked on every instance when it is being "dropped" from the pool (whether due to the - * response from validateObject, or for reasons specific to the pool implementation.) - * - * @param obj - * an instance of {@link Session} maintained by this pool. - */ - @Override - public void destroyObject(Object obj) { - Session conn = (Session) obj; - conn.destroy(); - } - } - - @Override - public String toString() { - StringBuilder ret = new StringBuilder(getClass().getSimpleName()); - ret.append("[config=").append(getConfig()); - if (pool == null) { - ret.append("[Session pool is disposed]"); - } else { - ret.append("[ACTIVE: "); - ret.append(pool.getNumActive() + "/" + ((GenericObjectPool) pool).getMaxActive()); - ret.append(" INACTIVE: "); - ret.append(pool.getNumIdle() + "/" + ((GenericObjectPool) pool).getMaxIdle() + "]"); - } - ret.append("]"); - return ret.toString(); - } - -} Copied: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/SessionPool.java (from rev 33502, trunk/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/SessionPool.java) =================================================================== --- branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/SessionPool.java (rev 0) +++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/SessionPool.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -0,0 +1,427 @@ +/* + * 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.arcsde.session; + +import java.io.IOException; +import java.util.NoSuchElementException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.apache.commons.pool.BasePoolableObjectFactory; +import org.apache.commons.pool.impl.GenericObjectPool; +import org.apache.commons.pool.impl.GenericObjectPool.Config; +import org.geotools.arcsde.ArcSdeException; + +import com.esri.sde.sdk.client.SeException; +import com.esri.sde.sdk.client.SeRelease; + +/** + * Maintains <code>SeConnection</code>'s for a single set of connection properties (for instance: by + * server, port, user and password) in a pool to recycle used connections. + * <p> + * We are making use of an Apache Commons ObjectPool to maintain connections. This connection pool + * is configurable in the sense that some parameters can be passed to establish the pooling policy. + * To pass parameters to the connection pool, you should set properties in the parameters Map passed + * to SdeDataStoreFactory.createDataStore, which will invoke SdeConnectionPoolFactory to get the SDE + * instance's pool singleton. That instance singleton will be created with the preferences passed + * the first time createDataStore is called for a given SDE instance/user, if subsequent calls + * change that preferences, they will be ignored. + * </p> + * <p> + * The expected optional parameters that you can set up in the argument Map for createDataStore are: + * <ul> + * <li>pool.minConnections Integer, tells the minimum number of open connections the pool will + * maintain opened</li> + * <li>pool.maxConnections Integer, tells the maximum number of open connections the pool will + * create and maintain opened</li> + * <li>pool.timeOut Integer, tells how many milliseconds a calling thread is guaranteed to wait + * before getConnection() throws an UnavailableArcSDEConnectionException</li> + * </ul> + * </p> + * + * @author Gabriel Roldan + * @version $Id$ + */ +class SessionPool implements ISessionPool { + /** package's logger */ + private static final Logger LOGGER = Logger.getLogger("org.geotools.arcsde.pool"); + + protected static final Level INFO_LOG_LEVEL = Level.WARNING; + + private SeConnectionFactory seConnectionFactory; + + /** this connection pool connection's parameters */ + protected ArcSDEConnectionConfig config; + + /** Apache commons-pool used to pool arcsde connections */ + protected GenericObjectPool pool; + + /** + * Creates a new SdeConnectionPool object with the connection parameters holded by + * <code>config</code> + * + * @param config + * holds connection options such as server, user and password, as well as tuning + * options as maximum number of connections allowed + * @throws IOException + * If connection could not be established + * @throws NullPointerException + * If config is null + */ + protected SessionPool(ArcSDEConnectionConfig config) throws IOException { + if (config == null) { + throw new NullPointerException("parameter config can't be null"); + } + + this.config = config; + LOGGER.fine("populating ArcSDE connection pool"); + + this.seConnectionFactory = createConnectionFactory(); + + final int minConnections = config.getMinConnections().intValue(); + final int maxConnections = config.getMaxConnections().intValue(); + if (minConnections > maxConnections) { + throw new IllegalArgumentException("pool.minConnections > pool.maxConnections"); + } + {// configure connection pool + + Config poolCfg = new Config(); + // pool upper limit + poolCfg.maxActive = config.getMaxConnections().intValue(); + + // minimum number of idle objects. MAKE SURE this is 0, otherwise the pool will start + // trying to create connections permanently even if there's a connection failure, + // ultimately leading to the exhaustion of resources + poolCfg.minIdle = 0; + + // how many connections may be idle at any time? -1 = no limit. We're running an + // eviction thread to take care of idle connections (see minEvictableIdleTimeMillis and + // timeBetweenEvictionRunsMillis) + poolCfg.maxIdle = -1; + + // When reached the pool upper limit, block and wait for an idle connection for maxWait + // milliseconds before failing + poolCfg.maxWait = config.getConnTimeOut().longValue(); + poolCfg.whenExhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_BLOCK; + + // check connection health at borrowObject()? + poolCfg.testOnBorrow = true; + // check connection health at returnObject()? + poolCfg.testOnReturn = false; + // check periodically the health of idle connections and discard them if can't be + // validated? + poolCfg.testWhileIdle = true; + + // check health of idle connections every 30 seconds + poolCfg.timeBetweenEvictionRunsMillis = 30000; + + // drop connections that have been idle for at least one minute + poolCfg.minEvictableIdleTimeMillis = 60000; + + pool = new GenericObjectPool(seConnectionFactory, poolCfg); + + LOGGER.fine("Created ArcSDE connection pool for " + config); + } + + ISession[] preload = new ISession[minConnections]; + + try { + for (int i = 0; i < minConnections; i++) { + preload[i] = (ISession) pool.borrowObject(); + if (i == 0) { + SeRelease seRelease = preload[i].getRelease(); + String sdeDesc = seRelease.getDesc(); + int major = seRelease.getMajor(); + int minor = seRelease.getMinor(); + int bugFix = seRelease.getBugFix(); + String desc = "ArcSDE " + major + "." + minor + "." + bugFix + " " + sdeDesc; + LOGGER.fine("Connected to " + desc); + } + } + + for (int i = 0; i < minConnections; i++) { + pool.returnObject(preload[i]); + } + } catch (Exception e) { + try { + pool.close(); + } catch (Exception closeEx) { + // ignore + } + if (e instanceof IOException) { + throw (IOException) e; + } + throw (IOException) new IOException().initCause(e); + } + } + + /** + * SeConnectionFactory used to create {@link ISession} instances for the pool. + * <p> + * Subclass may overide to customize this behaviour. + * </p> + * + * @return SeConnectionFactory. + */ + protected SeConnectionFactory createConnectionFactory() { + return new SeConnectionFactory(this.config); + } + + /* + * (non-Javadoc) + * + * @see org.geotools.arcsde.session.ISessionPool#getPoolSize() + */ + public int getPoolSize() { + checkOpen(); + synchronized (this.pool) { + return this.pool.getNumActive() + this.pool.getNumIdle(); + } + } + + /* + * (non-Javadoc) + * + * @see org.geotools.arcsde.session.ISessionPool#close() + */ + public void close() { + if (pool != null) { + try { + this.pool.close(); + pool = null; + LOGGER.fine("SDE connection pool closed. "); + } catch (Exception e) { + LOGGER.log(Level.WARNING, "Closing pool: " + e.getMessage(), e); + } + } + } + + /* + * (non-Javadoc) + * + * @see org.geotools.arcsde.session.ISessionPool#isClosed() + */ + public boolean isClosed() { + return pool == null; + } + + private void checkOpen() throws IllegalStateException { + if (isClosed()) { + throw new IllegalStateException("This session pool is closed"); + } + } + + /** + * Ensures proper closure of connection pool at this object's finalization stage. + */ + @Override + protected void finalize() { + close(); + } + + /* + * (non-Javadoc) + * + * @see org.geotools.arcsde.session.ISessionPool#getAvailableCount() + */ + public synchronized int getAvailableCount() { + checkOpen(); + return this.pool.getNumIdle(); + } + + /* + * (non-Javadoc) + * + * @see org.geotools.arcsde.session.ISessionPool#getInUseCount() + */ + public synchronized int getInUseCount() { + checkOpen(); + return this.pool.getNumActive(); + } + + /* + * (non-Javadoc) + * + * @see org.geotools.arcsde.session.ISessionPool#getSession() + */ + public ISession getSession() throws IOException, UnavailableArcSDEConnectionException { + checkOpen(); + try { + Session connection = (Session) this.pool.borrowObject(); + + if (LOGGER.isLoggable(Level.FINER)) { + LOGGER.finer("-->" + connection + " out of connection pool. Active: " + + pool.getNumActive() + ", idle: " + pool.getNumIdle()); + } + + connection.markActive(); + return connection; + } catch (NoSuchElementException e) { + LOGGER.log(Level.WARNING, "Out of connections: " + e.getMessage() + ". Config: " + + this.config); + throw new UnavailableArcSDEConnectionException(this.pool.getNumActive(), this.config); + } catch (SeException se) { + ArcSdeException sdee = new ArcSdeException(se); + LOGGER.log(Level.WARNING, "ArcSDE error getting connection for " + config, sdee); + throw sdee; + } catch (Exception e) { + LOGGER.log(Level.WARNING, "Unknown problem getting connection: " + e.getMessage(), e); + throw (IOException) new IOException( + "Unknown problem fetching connection from connection pool").initCause(e); + } + } + + /* + * (non-Javadoc) + * + * @see org.geotools.arcsde.session.ISessionPool#getConfig() + */ + public ArcSDEConnectionConfig getConfig() { + return this.config; + } + + /** + * PoolableObjectFactory intended to be used by a Jakarta's commons-pool objects pool, that + * provides ArcSDE's SeConnections. + * + * @author Gabriel Roldan, Axios Engineering + * @version $Id$ + */ + protected final class SeConnectionFactory extends BasePoolableObjectFactory { + + private ArcSDEConnectionConfig config; + + /** + * Creates a new SeConnectionFactory object. + * + * @param config + */ + public SeConnectionFactory(ArcSDEConnectionConfig config) { + super(); + this.config = config; + } + + /** + * Called whenever a new instance is needed. + * + * @return a newly created <code>SeConnection</code> + * @throws SeException + * if the connection can't be created + */ + @Override + public Object makeObject() throws IOException { + NegativeArraySizeException cause = null; + for (int i = 0; i < 3; i++) { + try { + ISession seConn = new Session(SessionPool.this.pool, config); + return seConn; + } catch (NegativeArraySizeException nase) { + LOGGER.warning("Strange failed ArcSDE connection error. Trying again (try " + + (i + 1) + " of 3)"); + cause = nase; + } + } + throw (IOException) new IOException( + "Couldn't create ArcSDE Session because of strange SDE internal exception. " + + " Tried 3 times, giving up.").initCause(cause); + } + + /** + * is invoked on every instance before it is returned from the pool. + * + * @param obj + */ + @Override + public void activateObject(Object obj) { + final Session conn = (Session) obj; + conn.markActive(); + LOGGER.finest(" activating connection " + obj); + } + + @Override + public void passivateObject(Object obj) { + LOGGER.finest(" passivating connection " + obj); + final Session conn = (Session) obj; + conn.markInactive(); + } + + /** + * is invoked in an implementation-specific fashion to determine if an instance is still + * valid to be returned by the pool. It will only be invoked on an "activated" instance. + * + * @param an + * instance of {@link Session} maintained by this pool. + * @return <code>true</code> if the connection is still alive and operative (checked by + * asking its user name), <code>false</code> otherwise. + */ + @Override + public boolean validateObject(Object obj) { + ISession session = (ISession) obj; + boolean valid = !session.isClosed(); + // MAKE PROPER VALIDITY CHECK HERE as for GEOT-1273 + if (valid) { + try { + if (LOGGER.isLoggable(Level.FINEST)) { + LOGGER.finest(" Validating SDE Connection " + session); + } + /* + * Validate the connection's health with testServer instead of getUser. The + * former is lighter weight, getUser() forced a server round trip and under + * heavy concurrency ate about 30% the time + */ + session.testServer(); + } catch (IOException e) { + LOGGER.info("Can't validate SeConnection, discarding it: " + session + + ". Reason: " + e.getMessage()); + valid = false; + } + } + return valid; + } + + /** + * is invoked on every instance when it is being "dropped" from the pool (whether due to the + * response from validateObject, or for reasons specific to the pool implementation.) + * + * @param obj + * an instance of {@link Session} maintained by this pool. + */ + @Override + public void destroyObject(Object obj) { + Session conn = (Session) obj; + conn.destroy(); + } + } + + @Override + public String toString() { + StringBuilder ret = new StringBuilder(getClass().getSimpleName()); + ret.append("[config=").append(getConfig()); + if (pool == null) { + ret.append("[Session pool is disposed]"); + } else { + ret.append("[ACTIVE: "); + ret.append(pool.getNumActive() + "/" + ((GenericObjectPool) pool).getMaxActive()); + ret.append(" INACTIVE: "); + ret.append(pool.getNumIdle() + "/" + ((GenericObjectPool) pool).getMaxIdle() + "]"); + } + ret.append("]"); + return ret.toString(); + } + +} Deleted: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/SessionPoolFactory.java =================================================================== --- trunk/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/SessionPoolFactory.java 2009-07-07 01:13:56 UTC (rev 33502) +++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/SessionPoolFactory.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -1,69 +0,0 @@ -/* - * 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.arcsde.session; - -import java.io.IOException; - -/** - * {@link SessionPool} factory. - * - * @author Gabriel Roldan - * @source $URL: - * http://svn.geotools.org/geotools/trunk/gt/modules/unsupported/arcsde/datastore/src/main - * /java/org/geotools/arcsde/pool/SessionPoolFactory.java $ - * @version $Id$ - */ -public class SessionPoolFactory implements ISessionPoolFactory { - - /** singleton pool factory */ - private static final ISessionPoolFactory singleton = new SessionPoolFactory(); - - /** - * Creates a new SdeConnectionPoolFactory object. - */ - private SessionPoolFactory() { - // intentionally blank - } - - /** - * Returns a connection pool factory instance - * - * @return the connection pool factory singleton - */ - public synchronized static ISessionPoolFactory getInstance() { - return singleton; - } - - /* (non-Javadoc) - * @see org.geotools.arcsde.session.ISessionPoolFactory#createPool(org.geotools.arcsde.session.ArcSDEConnectionConfig) - */ - public synchronized ISessionPool createPool(ArcSDEConnectionConfig config) throws IOException { - ISessionPool pool; - - // the new pool will be populated with config.minConnections - // connections - if (config.getMaxConnections() != null && config.getMaxConnections() == 1) { - // engage experimental single connection mode! - pool = new ArcSDEConnectionReference(config); - } else { - pool = new SessionPool(config); - } - - return pool; - } -} Copied: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/SessionPoolFactory.java (from rev 33502, trunk/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/SessionPoolFactory.java) =================================================================== --- branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/SessionPoolFactory.java (rev 0) +++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/SessionPoolFactory.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -0,0 +1,69 @@ +/* + * 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.arcsde.session; + +import java.io.IOException; + +/** + * {@link SessionPool} factory. + * + * @author Gabriel Roldan + * @source $URL: + * http://svn.geotools.org/geotools/trunk/gt/modules/unsupported/arcsde/datastore/src/main + * /java/org/geotools/arcsde/pool/SessionPoolFactory.java $ + * @version $Id$ + */ +public class SessionPoolFactory implements ISessionPoolFactory { + + /** singleton pool factory */ + private static final ISessionPoolFactory singleton = new SessionPoolFactory(); + + /** + * Creates a new SdeConnectionPoolFactory object. + */ + private SessionPoolFactory() { + // intentionally blank + } + + /** + * Returns a connection pool factory instance + * + * @return the connection pool factory singleton + */ + public synchronized static ISessionPoolFactory getInstance() { + return singleton; + } + + /* (non-Javadoc) + * @see org.geotools.arcsde.session.ISessionPoolFactory#createPool(org.geotools.arcsde.session.ArcSDEConnectionConfig) + */ + public synchronized ISessionPool createPool(ArcSDEConnectionConfig config) throws IOException { + ISessionPool pool; + + // the new pool will be populated with config.minConnections + // connections + if (config.getMaxConnections() != null && config.getMaxConnections() == 1) { + // engage experimental single connection mode! + pool = new ArcSDEConnectionReference(config); + } else { + pool = new SessionPool(config); + } + + return pool; + } +} Deleted: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/SessionWrapper.java =================================================================== --- trunk/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/SessionWrapper.java 2009-07-07 01:13:56 UTC (rev 33502) +++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/SessionWrapper.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -1,317 +0,0 @@ -/* - * 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.arcsde.session; - -import java.io.IOException; -import java.util.List; - -import com.esri.sde.sdk.client.SeColumnDefinition; -import com.esri.sde.sdk.client.SeDBMSInfo; -import com.esri.sde.sdk.client.SeDelete; -import com.esri.sde.sdk.client.SeInsert; -import com.esri.sde.sdk.client.SeLayer; -import com.esri.sde.sdk.client.SeObjectId; -import com.esri.sde.sdk.client.SeQuery; -import com.esri.sde.sdk.client.SeRasterColumn; -import com.esri.sde.sdk.client.SeRegistration; -import com.esri.sde.sdk.client.SeRelease; -import com.esri.sde.sdk.client.SeSqlConstruct; -import com.esri.sde.sdk.client.SeState; -import com.esri.sde.sdk.client.SeStreamOp; -import com.esri.sde.sdk.client.SeTable; -import com.esri.sde.sdk.client.SeUpdate; -import com.esri.sde.sdk.client.SeVersion; - -/** - * A pure session wrapper to aid in creating session decorators by extending this class. - * - * @author Gabriel Roldan (TOPP) - * @version $Id$ - * @since 2.5.x - * @source $URL: - * http://svn.geotools.org/trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools - * /arcsde/pool/SessionWrapper.java $ - */ -public class SessionWrapper implements ISession { - - protected final ISession wrapped; - - public SessionWrapper(final ISession wrapped) { - this.wrapped = wrapped; - } - - /** - * @see org.geotools.arcsde.session.ISession#testServer() - */ - public void testServer() throws IOException { - this.wrapped.testServer(); - } - - /** - * @see org.geotools.arcsde.session.ISession#close(com.esri.sde.sdk.client.SeState) - */ - public void close(SeState state) throws IOException { - wrapped.close(state); - } - - /** - * @see org.geotools.arcsde.session.ISession#close(com.esri.sde.sdk.client.SeStreamOp) - */ - public void close(SeStreamOp stream) throws IOException { - wrapped.close(stream); - } - - /** - * @see org.geotools.arcsde.session.ISession#commitTransaction() - */ - public void commitTransaction() throws IOException { - wrapped.commitTransaction(); - } - - /** - * @see org.geotools.arcsde.session.ISession#createAndExecuteQuery(java.lang.String[], - * com.esri.sde.sdk.client.SeSqlConstruct) - */ - public SeQuery createAndExecuteQuery(String[] propertyNames, SeSqlConstruct sql) - throws IOException { - return wrapped.createAndExecuteQuery(propertyNames, sql); - } - - /** - * @see org.geotools.arcsde.session.ISession#createSeDelete() - */ - public SeDelete createSeDelete() throws IOException { - return wrapped.createSeDelete(); - } - - /** - * @see org.geotools.arcsde.session.ISession#createSeInsert() - */ - public SeInsert createSeInsert() throws IOException { - return wrapped.createSeInsert(); - } - - /** - * @see org.geotools.arcsde.session.ISession#createSeLayer() - */ - public SeLayer createSeLayer() throws IOException { - return wrapped.createSeLayer(); - } - - /** - * @see org.geotools.arcsde.session.ISession#createSeQuery() - */ - public SeQuery createSeQuery() throws IOException { - return wrapped.createSeQuery(); - } - - /** - * @see org.geotools.arcsde.session.ISession#createSeQuery(java.lang.String[], - * com.esri.sde.sdk.client.SeSqlConstruct) - */ - public SeQuery createSeQuery(String[] propertyNames, SeSqlConstruct sql) throws IOException { - return wrapped.createSeQuery(propertyNames, sql); - } - - /** - * @see org.geotools.arcsde.session.ISession#createSeRasterColumn() - */ - public SeRasterColumn createSeRasterColumn() throws IOException { - return wrapped.createSeRasterColumn(); - } - - /** - * @see org.geotools.arcsde.session.ISession#createSeRasterColumn(com.esri.sde.sdk.client.SeObjectId) - */ - public SeRasterColumn createSeRasterColumn(SeObjectId rasterColumnId) throws IOException { - return wrapped.createSeRasterColumn(rasterColumnId); - } - - /** - * @see org.geotools.arcsde.session.ISession#createSeRegistration(java.lang.String) - */ - public SeRegistration createSeRegistration(String typeName) throws IOException { - return wrapped.createSeRegistration(typeName); - } - - /** - * @see org.geotools.arcsde.session.ISession#createSeTable(java.lang.String) - */ - public SeTable createSeTable(String qualifiedName) throws IOException { - return wrapped.createSeTable(qualifiedName); - } - - /** - * @see org.geotools.arcsde.session.ISession#createSeUpdate() - */ - public SeUpdate createSeUpdate() throws IOException { - return wrapped.createSeUpdate(); - } - - /** - * @see org.geotools.arcsde.session.ISession#createState(com.esri.sde.sdk.client.SeObjectId) - */ - public SeState createState(SeObjectId stateId) throws IOException { - return wrapped.createState(stateId); - } - - /** - * @see org.geotools.arcsde.session.ISession#describe(java.lang.String) - */ - public SeColumnDefinition[] describe(String tableName) throws IOException { - return wrapped.describe(tableName); - } - - /** - * @see org.geotools.arcsde.session.ISession#describe(com.esri.sde.sdk.client.SeTable) - */ - public SeColumnDefinition[] describe(SeTable table) throws IOException { - return wrapped.describe(table); - } - - /** - * @see org.geotools.arcsde.session.ISession#dispose() - */ - public void dispose() throws IllegalStateException { - wrapped.dispose(); - } - - /** - * @see org.geotools.arcsde.session.ISession#fetch(com.esri.sde.sdk.client.SeQuery) - */ - public SdeRow fetch(SeQuery query) throws IOException { - return wrapped.fetch(query); - } - - /** - * @see org.geotools.arcsde.session.ISession#fetch(SeQuery, SdeRow) - */ - public SdeRow fetch(SeQuery query, SdeRow currentRow) throws IOException { - return wrapped.fetch(query, currentRow); - } - - /** - * @see org.geotools.arcsde.session.ISession#getDatabaseName() - */ - public String getDatabaseName() throws IOException { - return wrapped.getDatabaseName(); - } - - /** - * @see org.geotools.arcsde.session.ISession#getDBMSInfo() - */ - public SeDBMSInfo getDBMSInfo() throws IOException { - return wrapped.getDBMSInfo(); - } - - /** - * @see org.geotools.arcsde.session.ISession#getLayer(java.lang.String) - */ - public SeLayer getLayer(String layerName) throws IOException { - return wrapped.getLayer(layerName); - } - - /** - * @see org.geotools.arcsde.session.ISession#getLayers() - */ - public List<SeLayer> getLayers() throws IOException { - return wrapped.getLayers(); - } - - /** - * @see org.geotools.arcsde.session.ISession#getRasterColumn(java.lang.String) - */ - public SeRasterColumn getRasterColumn(String rasterName) throws IOException { - return wrapped.getRasterColumn(rasterName); - } - - /** - * @see org.geotools.arcsde.session.ISession#getRelease() - */ - public SeRelease getRelease() throws IOException { - return wrapped.getRelease(); - } - - /** - * @see org.geotools.arcsde.session.ISession#getTable(java.lang.String) - */ - public SeTable getTable(String tableName) throws IOException { - return wrapped.getTable(tableName); - } - - /** - * @see org.geotools.arcsde.session.ISession#getUser() - */ - public String getUser() throws IOException { - return wrapped.getUser(); - } - - /** - * @see org.geotools.arcsde.session.ISession#isClosed() - */ - public boolean isClosed() { - return wrapped.isClosed(); - } - - /** - * @see org.geotools.arcsde.session.ISession#isDisposed() - */ - public boolean isDisposed() { - return wrapped.isDisposed(); - } - - /** - * @see org.geotools.arcsde.session.ISession#isTransactionActive() - */ - public boolean isTransactionActive() { - return wrapped.isTransactionActive(); - } - - /** - * @see org.geotools.arcsde.session.ISession#issue(org.geotools.arcsde.session.Command) - */ - public <T> T issue(Command<T> command) throws IOException { - return wrapped.issue(command); - } - - /** - * @see org.geotools.arcsde.session.ISession#rollbackTransaction() - */ - public void rollbackTransaction() throws IOException { - wrapped.rollbackTransaction(); - } - - /** - * @see org.geotools.arcsde.session.ISession#startTransaction() - */ - public void startTransaction() throws IOException { - wrapped.startTransaction(); - } - - /** - * @see ISession#getDefaultVersion() - */ - public SeVersion getDefaultVersion() throws IOException { - return wrapped.getDefaultVersion(); - } - - public SeState createChildState(long parentStateId) throws IOException { - return wrapped.createChildState(parentStateId); - } - -} Copied: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/SessionWrapper.java (from rev 33502, trunk/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/SessionWrapper.java) =================================================================== --- branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/SessionWrapper.java (rev 0) +++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/SessionWrapper.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -0,0 +1,317 @@ +/* + * 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.arcsde.session; + +import java.io.IOException; +import java.util.List; + +import com.esri.sde.sdk.client.SeColumnDefinition; +import com.esri.sde.sdk.client.SeDBMSInfo; +import com.esri.sde.sdk.client.SeDelete; +import com.esri.sde.sdk.client.SeInsert; +import com.esri.sde.sdk.client.SeLayer; +import com.esri.sde.sdk.client.SeObjectId; +import com.esri.sde.sdk.client.SeQuery; +import com.esri.sde.sdk.client.SeRasterColumn; +import com.esri.sde.sdk.client.SeRegistration; +import com.esri.sde.sdk.client.SeRelease; +import com.esri.sde.sdk.client.SeSqlConstruct; +import com.esri.sde.sdk.client.SeState; +import com.esri.sde.sdk.client.SeStreamOp; +import com.esri.sde.sdk.client.SeTable; +import com.esri.sde.sdk.client.SeUpdate; +import com.esri.sde.sdk.client.SeVersion; + +/** + * A pure session wrapper to aid in creating session decorators by extending this class. + * + * @author Gabriel Roldan (TOPP) + * @version $Id$ + * @since 2.5.x + * @source $URL: + * http://svn.geotools.org/trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools + * /arcsde/pool/SessionWrapper.java $ + */ +public class SessionWrapper implements ISession { + + protected final ISession wrapped; + + public SessionWrapper(final ISession wrapped) { + this.wrapped = wrapped; + } + + /** + * @see org.geotools.arcsde.session.ISession#testServer() + */ + public void testServer() throws IOException { + this.wrapped.testServer(); + } + + /** + * @see org.geotools.arcsde.session.ISession#close(com.esri.sde.sdk.client.SeState) + */ + public void close(SeState state) throws IOException { + wrapped.close(state); + } + + /** + * @see org.geotools.arcsde.session.ISession#close(com.esri.sde.sdk.client.SeStreamOp) + */ + public void close(SeStreamOp stream) throws IOException { + wrapped.close(stream); + } + + /** + * @see org.geotools.arcsde.session.ISession#commitTransaction() + */ + public void commitTransaction() throws IOException { + wrapped.commitTransaction(); + } + + /** + * @see org.geotools.arcsde.session.ISession#createAndExecuteQuery(java.lang.String[], + * com.esri.sde.sdk.client.SeSqlConstruct) + */ + public SeQuery createAndExecuteQuery(String[] propertyNames, SeSqlConstruct sql) + throws IOException { + return wrapped.createAndExecuteQuery(propertyNames, sql); + } + + /** + * @see org.geotools.arcsde.session.ISession#createSeDelete() + */ + public SeDelete createSeDelete() throws IOException { + return wrapped.createSeDelete(); + } + + /** + * @see org.geotools.arcsde.session.ISession#createSeInsert() + */ + public SeInsert createSeInsert() throws IOException { + return wrapped.createSeInsert(); + } + + /** + * @see org.geotools.arcsde.session.ISession#createSeLayer() + */ + public SeLayer createSeLayer() throws IOException { + return wrapped.createSeLayer(); + } + + /** + * @see org.geotools.arcsde.session.ISession#createSeQuery() + */ + public SeQuery createSeQuery() throws IOException { + return wrapped.createSeQuery(); + } + + /** + * @see org.geotools.arcsde.session.ISession#createSeQuery(java.lang.String[], + * com.esri.sde.sdk.client.SeSqlConstruct) + */ + public SeQuery createSeQuery(String[] propertyNames, SeSqlConstruct sql) throws IOException { + return wrapped.createSeQuery(propertyNames, sql); + } + + /** + * @see org.geotools.arcsde.session.ISession#createSeRasterColumn() + */ + public SeRasterColumn createSeRasterColumn() throws IOException { + return wrapped.createSeRasterColumn(); + } + + /** + * @see org.geotools.arcsde.session.ISession#createSeRasterColumn(com.esri.sde.sdk.client.SeObjectId) + */ + public SeRasterColumn createSeRasterColumn(SeObjectId rasterColumnId) throws IOException { + return wrapped.createSeRasterColumn(rasterColumnId); + } + + /** + * @see org.geotools.arcsde.session.ISession#createSeRegistration(java.lang.String) + */ + public SeRegistration createSeRegistration(String typeName) throws IOException { + return wrapped.createSeRegistration(typeName); + } + + /** + * @see org.geotools.arcsde.session.ISession#createSeTable(java.lang.String) + */ + public SeTable createSeTable(String qualifiedName) throws IOException { + return wrapped.createSeTable(qualifiedName); + } + + /** + * @see org.geotools.arcsde.session.ISession#createSeUpdate() + */ + public SeUpdate createSeUpdate() throws IOException { + return wrapped.createSeUpdate(); + } + + /** + * @see org.geotools.arcsde.session.ISession#createState(com.esri.sde.sdk.client.SeObjectId) + */ + public SeState createState(SeObjectId stateId) throws IOException { + return wrapped.createState(stateId); + } + + /** + * @see org.geotools.arcsde.session.ISession#describe(java.lang.String) + */ + public SeColumnDefinition[] describe(String tableName) throws IOException { + return wrapped.describe(tableName); + } + + /** + * @see org.geotools.arcsde.session.ISession#describe(com.esri.sde.sdk.client.SeTable) + */ + public SeColumnDefinition[] describe(SeTable table) throws IOException { + return wrapped.describe(table); + } + + /** + * @see org.geotools.arcsde.session.ISession#dispose() + */ + public void dispose() throws IllegalStateException { + wrapped.dispose(); + } + + /** + * @see org.geotools.arcsde.session.ISession#fetch(com.esri.sde.sdk.client.SeQuery) + */ + public SdeRow fetch(SeQuery query) throws IOException { + return wrapped.fetch(query); + } + + /** + * @see org.geotools.arcsde.session.ISession#fetch(SeQuery, SdeRow) + */ + public SdeRow fetch(SeQuery query, SdeRow currentRow) throws IOException { + return wrapped.fetch(query, currentRow); + } + + /** + * @see org.geotools.arcsde.session.ISession#getDatabaseName() + */ + public String getDatabaseName() throws IOException { + return wrapped.getDatabaseName(); + } + + /** + * @see org.geotools.arcsde.session.ISession#getDBMSInfo() + */ + public SeDBMSInfo getDBMSInfo() throws IOException { + return wrapped.getDBMSInfo(); + } + + /** + * @see org.geotools.arcsde.session.ISession#getLayer(java.lang.String) + */ + public SeLayer getLayer(String layerName) throws IOException { + return wrapped.getLayer(layerName); + } + + /** + * @see org.geotools.arcsde.session.ISession#getLayers() + */ + public List<SeLayer> getLayers() throws IOException { + return wrapped.getLayers(); + } + + /** + * @see org.geotools.arcsde.session.ISession#getRasterColumn(java.lang.String) + */ + public SeRasterColumn getRasterColumn(String rasterName) throws IOException { + return wrapped.getRasterColumn(rasterName); + } + + /** + * @see org.geotools.arcsde.session.ISession#getRelease() + */ + public SeRelease getRelease() throws IOException { + return wrapped.getRelease(); + } + + /** + * @see org.geotools.arcsde.session.ISession#getTable(java.lang.String) + */ + public SeTable getTable(String tableName) throws IOException { + return wrapped.getTable(tableName); + } + + /** + * @see org.geotools.arcsde.session.ISession#getUser() + */ + public String getUser() throws IOException { + return wrapped.getUser(); + } + + /** + * @see org.geotools.arcsde.session.ISession#isClosed() + */ + public boolean isClosed() { + return wrapped.isClosed(); + } + + /** + * @see org.geotools.arcsde.session.ISession#isDisposed() + */ + public boolean isDisposed() { + return wrapped.isDisposed(); + } + + /** + * @see org.geotools.arcsde.session.ISession#isTransactionActive() + */ + public boolean isTransactionActive() { + return wrapped.isTransactionActive(); + } + + /** + * @see org.geotools.arcsde.session.ISession#issue(org.geotools.arcsde.session.Command) + */ + public <T> T issue(Command<T> command) throws IOException { + return wrapped.issue(command); + } + + /** + * @see org.geotools.arcsde.session.ISession#rollbackTransaction() + */ + public void rollbackTransaction() throws IOException { + wrapped.rollbackTransaction(); + } + + /** + * @see org.geotools.arcsde.session.ISession#startTransaction() + */ + public void startTransaction() throws IOException { + wrapped.startTransaction(); + } + + /** + * @see ISession#getDefaultVersion() + */ + public SeVersion getDefaultVersion() throws IOException { + return wrapped.getDefaultVersion(); + } + + public SeState createChildState(long parentStateId) throws IOException { + return wrapped.createChildState(parentStateId); + } + +} Deleted: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/UnavailableArcSDEConnectionException.java =================================================================== --- trunk/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/UnavailableArcSDEConnectionException.java 2009-07-07 01:13:56 UTC (rev 33502) +++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/UnavailableArcSDEConnectionException.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -1,50 +0,0 @@ -/* - * 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.arcsde.session; - -import java.io.IOException; - -/** - * Exception thrown when a free SDE connection can't be obtained after the calling thread was - * waiting an available connection for <code>SdeConnectionPool instance's getMaxWaitTime()</code> milliseconds - * - * @author Gabriel Roldan - * @source $URL: - * http://svn.geotools.org/geotools/trunk/gt/modules/plugin/arcsde/datastore/src/main/java - * /org/geotools/arcsde/pool/UnavailableArcSDEConnectionException.java $ - * @version $Id$ - */ -public class UnavailableArcSDEConnectionException extends IOException { - /** - * serial version id - */ - private static final long serialVersionUID = -7964603239735118491L; - - /** - * Creates a new UnavailableArcSDEConnectionException object. - * - * @param usedConnections - * DOCUMENT ME! - * @param config - * DOCUMENT ME! - */ - public UnavailableArcSDEConnectionException(int usedConnections, ArcSDEConnectionConfig config) { - super("The maximun of " + usedConnections + " to " + config.toString() - + " has been reached"); - } -} Copied: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/UnavailableArcSDEConnectionException.java (from rev 33502, trunk/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/UnavailableArcSDEConnectionException.java) =================================================================== --- branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/UnavailableArcSDEConnectionException.java (rev 0) +++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/UnavailableArcSDEConnectionException.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -0,0 +1,50 @@ +/* + * 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.arcsde.session; + +import java.io.IOException; + +/** + * Exception thrown when a free SDE connection can't be obtained after the calling thread was + * waiting an available connection for <code>SdeConnectionPool instance's getMaxWaitTime()</code> milliseconds + * + * @author Gabriel Roldan + * @source $URL: + * http://svn.geotools.org/geotools/trunk/gt/modules/plugin/arcsde/datastore/src/main/java + * /org/geotools/arcsde/pool/UnavailableArcSDEConnectionException.java $ + * @version $Id$ + */ +public class UnavailableArcSDEConnectionException extends IOException { + /** + * serial version id + */ + private static final long serialVersionUID = -7964603239735118491L; + + /** + * Creates a new UnavailableArcSDEConnectionException object. + * + * @param usedConnections + * DOCUMENT ME! + * @param config + * DOCUMENT ME! + */ + public UnavailableArcSDEConnectionException(int usedConnections, ArcSDEConnectionConfig config) { + super("The maximun of " + usedConnections + " to " + config.toString() + + " has been reached"); + } +} Deleted: branches/2.5.x/modules/plugin/arcsde/common/src/test/java/org/geotools/arcsde/jndi/ArcSDEConnectionFactoryTest.java =================================================================== --- trunk/modules/plugin/arcsde/common/src/test/java/org/geotools/arcsde/jndi/ArcSDEConnectionFactoryTest.java 2009-07-07 01:13:56 UTC (rev 33502) +++ branches/2.5.x/modules/plugin/arcsde/common/src/test/java/org/geotools/arcsde/jndi/ArcSDEConnectionFactoryTest.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -1,254 +0,0 @@ -/* - * GeoTools - The Open Source Java GIS Toolkit - * http://geotools.org - * - * (C) 2002-2009, 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.arcsde.jndi; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.io.IOException; -import java.util.Hashtable; - -import javax.naming.Context; -import javax.naming.Name; -import javax.naming.Reference; -import javax.naming.StringRefAddr; - -import org.geotools.arcsde.session.ArcSDEConnectionConfig; -import org.geotools.arcsde.session.ISession; -import org.geotools.arcsde.session.ISessionPool; -import org.geotools.arcsde.session.ISessionPoolFactory; -import org.geotools.arcsde.session.UnavailableArcSDEConnectionException; -import org.junit.Before; -import org.junit.Test; - -/** - * Unit test suite for {@link ArcSDEConnectionFactory} - * - * @author Gabriel Roldan (OpenGeo) - * @version $Id$ - * @since 2.5.7 - */ -public class ArcSDEConnectionFactoryTest { - - private ArcSDEConnectionFactory factory; - - @Before - public void setUp() throws Exception { - factory = new ArcSDEConnectionFactory(); - } - - @Test - public void getObjectInstance_NotASupportedType() throws Exception { - String className = "not.a.supported.Class"; - String factoryName = ArcSDEConnectionFactory.class.getName(); - String factoryLocation = null; - Reference ref = createRef(className, factoryName, factoryLocation); - - Name name = null; - Context nameCtx = null; - Hashtable<?, ?> environment = null; - - Object object = factory.getObjectInstance(ref, name, nameCtx, environment); - assertNull(object); - } - - @Test - public void getObjectInstance_MandatoryParams() throws Exception { - String className = ArcSDEConnectionConfig.class.getName(); - String factoryName = ArcSDEConnectionFactory.class.getName(); - String factoryLocation = null; - Reference ref = new Reference(className, factoryName, factoryLocation); - - Name name = null; - Context nameCtx = null; - Hashtable<?, ?> environment = null; - - assertMandatory(ref, name, nameCtx, environment); - - ref.add(new StringRefAddr(ArcSDEConnectionConfig.SERVER_NAME_PARAM_NAME, "localhost")); - assertMandatory(ref, name, nameCtx, environment); - - ref.add(new StringRefAddr(ArcSDEConnectionConfig.PORT_NUMBER_PARAM_NAME, "5151")); - assertMandatory(ref, name, nameCtx, environment); - - ref.add(new StringRefAddr(ArcSDEConnectionConfig.USER_NAME_PARAM_NAME, "me")); - assertMandatory(ref, name, nameCtx, environment); - - ref.add(new StringRefAddr(ArcSDEConnectionConfig.PASSWORD_PARAM_NAME, "mine")); - - Object object = factory.getObjectInstance(ref, name, nameCtx, environment); - assertNotNull("We're done with mandatory params, should have worked!", object); - } - - private void assertMandatory(Reference ref, Name name, Context nameCtx, - Hashtable<?, ?> environment) throws Exception { - try { - factory.getObjectInstance(ref, name, nameCtx, environment); - fail("Expected IAE"); - } catch (IllegalArgumentException e) { - assertTrue(true); - } - } - - @Test - public void getObjectInstance_ArcSDEConnectionConfig_Minimum() throws Exception { - String className = ArcSDEConnectionConfig.class.getName(); - String factoryName = ArcSDEConnectionFactory.class.getName(); - String factoryLocation = null; - Reference ref = createRef(className, factoryName, factoryLocation); - - Name name = null; - Context nameCtx = null; - Hashtable<?, ?> environment = null; - - Object object = factory.getObjectInstance(ref, name, nameCtx, environment); - assertNotNull(object); - assertTrue(object instanceof ArcSDEConnectionConfig); - - Object object2 = factory.getObjectInstance(ref, name, nameCtx, environment); - - assertFalse(object == object2); - assertEquals(object, object2); - ArcSDEConnectionConfig config = (ArcSDEConnectionConfig) object; - assertEquals("localhost", config.getServerName()); - assertEquals(Integer.valueOf(5151), config.getPortNumber()); - assertEquals("sde", config.getDatabaseName()); - assertEquals("sdeusr", config.getUserName()); - assertEquals("s3cr3t", config.getPassword()); - } - - @Test - public void getObjectInstance_ArcSDEConnectionConfig_Full() throws Exception { - String className = ArcSDEConnectionConfig.class.getName(); - String factoryName = ArcSDEConnectionFactory.class.getName(); - String factoryLocation = null; - Reference ref = createRef(className, factoryName, factoryLocation); - // add the non mandatory params - ref.add(new StringRefAddr(ArcSDEConnectionConfig.MIN_CONNECTIONS_PARAM_NAME, "2")); - ref.add(new StringRefAddr(ArcSDEConnectionConfig.MAX_CONNECTIONS_PARAM_NAME, "6")); - ref.add(new StringRefAddr(ArcSDEConnectionConfig.CONNECTION_TIMEOUT_PARAM_NAME, "2000")); - - Name name = null; - Context nameCtx = null; - Hashtable<?, ?> environment = null; - - Object object = factory.getObjectInstance(ref, name, nameCtx, environment); - assertNotNull(object); - assertTrue(object instanceof ArcSDEConnectionConfig); - - Object object2 = factory.getObjectInstance(ref, name, nameCtx, environment); - - assertFalse(object == object2); - assertEquals(object, object2); - - ArcSDEConnectionConfig config = (ArcSDEConnectionConfig) object; - assertEquals(Integer.valueOf(2), config.getMinConnections()); - assertEquals(Integer.valueOf(6), config.getMaxConnections()); - assertEquals(Integer.valueOf(2000), config.getConnTimeOut()); - - } - - @Test - public void getObjectInstance_ISessionPool() throws Exception { - String className = ISessionPool.class.getName(); - String factoryName = ArcSDEConnectionFactory.class.getName(); - String factoryLocation = null; - Reference ref = createRef(className, factoryName, factoryLocation); - - Name name = null; - Context nameCtx = null; - Hashtable<?, ?> environment = null; - - factory.setClosableSessionPoolFactory(new MockSessionPoolFactory()); - - Object object = factory.getObjectInstance(ref, name, nameCtx, environment); - assertNotNull(object); - assertTrue(object instanceof SharedSessionPool); - ArcSDEConnectionConfig config = ((SharedSessionPool) object).getConfig(); - assertNotNull(config); - assertEquals("localhost", config.getServerName()); - - Reference ref2 = createRef(className, factoryName, factoryLocation); - Object object2 = factory.getObjectInstance(ref2, name, nameCtx, environment); - assertSame(object, object2); - } - - private Reference createRef(String className, String factoryName, String factoryLocation) { - Reference ref = new Reference(className, factoryName, factoryLocation); - ref.add(new StringRefAddr(ArcSDEConnectionConfig.SERVER_NAME_PARAM_NAME, "localhost")); - ref.add(new StringRefAddr(ArcSDEConnectionConfig.PORT_NUMBER_PARAM_NAME, "5151")); - ref.add(new StringRefAddr(ArcSDEConnectionConfig.INSTANCE_NAME_PARAM_NAME, "sde")); - ref.add(new StringRefAddr(ArcSDEConnectionConfig.USER_NAME_PARAM_NAME, "sdeusr")); - ref.add(new StringRefAddr(ArcSDEConnectionConfig.PASSWORD_PARAM_NAME, "s3cr3t")); - return ref; - } - - private static class MockSessionPoolFactory implements ISessionPoolFactory { - - public ISessionPool createPool(ArcSDEConnectionConfig config) throws IOException { - return new MockSessionPool(config); - } - } - - private static class MockSessionPool implements ISessionPool { - - private ArcSDEConnectionConfig config; - - public MockSessionPool(ArcSDEConnectionConfig config) { - this.config = config; - } - - public ArcSDEConnectionConfig getConfig() { - return config; - } - - public void close() { - // TODO Auto-generated method stub - } - - public int getAvailableCount() { - // TODO Auto-generated method stub - return 0; - } - - public int getInUseCount() { - // TODO Auto-generated method stub - return 0; - } - - public int getPoolSize() { - // TODO Auto-generated method stub - return 0; - } - - public ISession getSession() throws IOException, UnavailableArcSDEConnectionException { - // TODO Auto-generated method stub - return null; - } - - public boolean isClosed() { - // TODO Auto-generated method stub - return false; - } - } -} Copied: branches/2.5.x/modules/plugin/arcsde/common/src/test/java/org/geotools/arcsde/jndi/ArcSDEConnectionFactoryTest.java (from rev 33502, trunk/modules/plugin/arcsde/common/src/test/java/org/geotools/arcsde/jndi/ArcSDEConnectionFactoryTest.java) =================================================================== --- branches/2.5.x/modules/plugin/arcsde/common/src/test/java/org/geotools/arcsde/jndi/ArcSDEConnectionFactoryTest.java (rev 0) +++ branches/2.5.x/modules/plugin/arcsde/common/src/test/java/org/geotools/arcsde/jndi/ArcSDEConnectionFactoryTest.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -0,0 +1,254 @@ +/* + * GeoTools - The Open Source Java GIS Toolkit + * http://geotools.org + * + * (C) 2002-2009, 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.arcsde.jndi; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; +import java.util.Hashtable; + +import javax.naming.Context; +import javax.naming.Name; +import javax.naming.Reference; +import javax.naming.StringRefAddr; + +import org.geotools.arcsde.session.ArcSDEConnectionConfig; +import org.geotools.arcsde.session.ISession; +import org.geotools.arcsde.session.ISessionPool; +import org.geotools.arcsde.session.ISessionPoolFactory; +import org.geotools.arcsde.session.UnavailableArcSDEConnectionException; +import org.junit.Before; +import org.junit.Test; + +/** + * Unit test suite for {@link ArcSDEConnectionFactory} + * + * @author Gabriel Roldan (OpenGeo) + * @version $Id$ + * @since 2.5.7 + */ +public class ArcSDEConnectionFactoryTest { + + private ArcSDEConnectionFactory factory; + + @Before + public void setUp() throws Exception { + factory = new ArcSDEConnectionFactory(); + } + + @Test + public void getObjectInstance_NotASupportedType() throws Exception { + String className = "not.a.supported.Class"; + String factoryName = ArcSDEConnectionFactory.class.getName(); + String factoryLocation = null; + Reference ref = createRef(className, factoryName, factoryLocation); + + Name name = null; + Context nameCtx = null; + Hashtable<?, ?> environment = null; + + Object object = factory.getObjectInstance(ref, name, nameCtx, environment); + assertNull(object); + } + + @Test + public void getObjectInstance_MandatoryParams() throws Exception { + String className = ArcSDEConnectionConfig.class.getName(); + String factoryName = ArcSDEConnectionFactory.class.getName(); + String factoryLocation = null; + Reference ref = new Reference(className, factoryName, factoryLocation); + + Name name = null; + Context nameCtx = null; + Hashtable<?, ?> environment = null; + + assertMandatory(ref, name, nameCtx, environment); + + ref.add(new StringRefAddr(ArcSDEConnectionConfig.SERVER_NAME_PARAM_NAME, "localhost")); + assertMandatory(ref, name, nameCtx, environment); + + ref.add(new StringRefAddr(ArcSDEConnectionConfig.PORT_NUMBER_PARAM_NAME, "5151")); + assertMandatory(ref, name, nameCtx, environment); + + ref.add(new StringRefAddr(ArcSDEConnectionConfig.USER_NAME_PARAM_NAME, "me")); + assertMandatory(ref, name, nameCtx, environment); + + ref.add(new StringRefAddr(ArcSDEConnectionConfig.PASSWORD_PARAM_NAME, "mine")); + + Object object = factory.getObjectInstance(ref, name, nameCtx, environment); + assertNotNull("We're done with mandatory params, should have worked!", object); + } + + private void assertMandatory(Reference ref, Name name, Context nameCtx, + Hashtable<?, ?> environment) throws Exception { + try { + factory.getObjectInstance(ref, name, nameCtx, environment); + fail("Expected IAE"); + } catch (IllegalArgumentException e) { + assertTrue(true); + } + } + + @Test + public void getObjectInstance_ArcSDEConnectionConfig_Minimum() throws Exception { + String className = ArcSDEConnectionConfig.class.getName(); + String factoryName = ArcSDEConnectionFactory.class.getName(); + String factoryLocation = null; + Reference ref = createRef(className, factoryName, factoryLocation); + + Name name = null; + Context nameCtx = null; + Hashtable<?, ?> environment = null; + + Object object = factory.getObjectInstance(ref, name, nameCtx, environment); + assertNotNull(object); + assertTrue(object instanceof ArcSDEConnectionConfig); + + Object object2 = factory.getObjectInstance(ref, name, nameCtx, environment); + + assertFalse(object == object2); + assertEquals(object, object2); + ArcSDEConnectionConfig config = (ArcSDEConnectionConfig) object; + assertEquals("localhost", config.getServerName()); + assertEquals(Integer.valueOf(5151), config.getPortNumber()); + assertEquals("sde", config.getDatabaseName()); + assertEquals("sdeusr", config.getUserName()); + assertEquals("s3cr3t", config.getPassword()); + } + + @Test + public void getObjectInstance_ArcSDEConnectionConfig_Full() throws Exception { + String className = ArcSDEConnectionConfig.class.getName(); + String factoryName = ArcSDEConnectionFactory.class.getName(); + String factoryLocation = null; + Reference ref = createRef(className, factoryName, factoryLocation); + // add the non mandatory params + ref.add(new StringRefAddr(ArcSDEConnectionConfig.MIN_CONNECTIONS_PARAM_NAME, "2")); + ref.add(new StringRefAddr(ArcSDEConnectionConfig.MAX_CONNECTIONS_PARAM_NAME, "6")); + ref.add(new StringRefAddr(ArcSDEConnectionConfig.CONNECTION_TIMEOUT_PARAM_NAME, "2000")); + + Name name = null; + Context nameCtx = null; + Hashtable<?, ?> environment = null; + + Object object = factory.getObjectInstance(ref, name, nameCtx, environment); + assertNotNull(object); + assertTrue(object instanceof ArcSDEConnectionConfig); + + Object object2 = factory.getObjectInstance(ref, name, nameCtx, environment); + + assertFalse(object == object2); + assertEquals(object, object2); + + ArcSDEConnectionConfig config = (ArcSDEConnectionConfig) object; + assertEquals(Integer.valueOf(2), config.getMinConnections()); + assertEquals(Integer.valueOf(6), config.getMaxConnections()); + assertEquals(Integer.valueOf(2000), config.getConnTimeOut()); + + } + + @Test + public void getObjectInstance_ISessionPool() throws Exception { + String className = ISessionPool.class.getName(); + String factoryName = ArcSDEConnectionFactory.class.getName(); + String factoryLocation = null; + Reference ref = createRef(className, factoryName, factoryLocation); + + Name name = null; + Context nameCtx = null; + Hashtable<?, ?> environment = null; + + factory.setClosableSessionPoolFactory(new MockSessionPoolFactory()); + + Object object = factory.getObjectInstance(ref, name, nameCtx, environment); + assertNotNull(object); + assertTrue(object instanceof SharedSessionPool); + ArcSDEConnectionConfig config = ((SharedSessionPool) object).getConfig(); + assertNotNull(config); + assertEquals("localhost", config.getServerName()); + + Reference ref2 = createRef(className, factoryName, factoryLocation); + Object object2 = factory.getObjectInstance(ref2, name, nameCtx, environment); + assertSame(object, object2); + } + + private Reference createRef(String className, String factoryName, String factoryLocation) { + Reference ref = new Reference(className, factoryName, factoryLocation); + ref.add(new StringRefAddr(ArcSDEConnectionConfig.SERVER_NAME_PARAM_NAME, "localhost")); + ref.add(new StringRefAddr(ArcSDEConnectionConfig.PORT_NUMBER_PARAM_NAME, "5151")); + ref.add(new StringRefAddr(ArcSDEConnectionConfig.INSTANCE_NAME_PARAM_NAME, "sde")); + ref.add(new StringRefAddr(ArcSDEConnectionConfig.USER_NAME_PARAM_NAME, "sdeusr")); + ref.add(new StringRefAddr(ArcSDEConnectionConfig.PASSWORD_PARAM_NAME, "s3cr3t")); + return ref; + } + + private static class MockSessionPoolFactory implements ISessionPoolFactory { + + public ISessionPool createPool(ArcSDEConnectionConfig config) throws IOException { + return new MockSessionPool(config); + } + } + + private static class MockSessionPool implements ISessionPool { + + private ArcSDEConnectionConfig config; + + public MockSessionPool(ArcSDEConnectionConfig config) { + this.config = config; + } + + public ArcSDEConnectionConfig getConfig() { + return config; + } + + public void close() { + // TODO Auto-generated method stub + } + + public int getAvailableCount() { + // TODO Auto-generated method stub + return 0; + } + + public int getInUseCount() { + // TODO Auto-generated method stub + return 0; + } + + public int getPoolSize() { + // TODO Auto-generated method stub + return 0; + } + + public ISession getSession() throws IOException, UnavailableArcSDEConnectionException { + // TODO Auto-generated method stub + return null; + } + + public boolean isClosed() { + // TODO Auto-generated method stub + return false; + } + } +} Modified: branches/2.5.x/modules/plugin/arcsde/datastore/pom.xml =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/pom.xml 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/pom.xml 2009-07-07 15:55:29 UTC (rev 33511) @@ -1,253 +1,241 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- ======================================================================= - Maven Project Configuration File - - The Geotools Project - http://www.geotools.org/ - - Version: $Id$ - ======================================================================= --> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 + <!-- + ======================================================================= + Maven Project Configuration File The Geotools Project + http://www.geotools.org/ Version: $Id: pom.xml 33423 2009-07-01 + 17:13:45Z groldan $ + ======================================================================= + --> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> - <modelVersion>4.0.0</modelVersion> - <parent> - <groupId>org.geotools</groupId> - <artifactId>arcsde-plugin</artifactId> - <version>2.5-SNAPSHOT</version> - </parent> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.geotools</groupId> + <artifactId>arcsde-plugin</artifactId> + <version>2.5-SNAPSHOT</version> + </parent> - <!-- =========================================================== --> - <!-- Module Description --> - <!-- =========================================================== --> - <groupId>org.geotools</groupId> - <artifactId>gt-arcsde</artifactId> - <packaging>jar</packaging> - <name>ArcSDE DataStore plugin</name> - + <!-- =========================================================== --> + <!-- Module Description --> + <!-- =========================================================== --> + <groupId>org.geotools</groupId> + <artifactId>gt-arcsde</artifactId> + <packaging>jar</packaging> + <name>ArcSDE DataStore plugin</name> - <scm> - <connection> - scm:svn:http://svn.osgeo.org/geotools/branches/2.5.x/modules/plugin/arcsde/datastore/ + + <scm> + <connection> + scm:svn:http://svn.osgeo.org/geotools/trunk/modules/plugin/arcsde/datastore/ </connection> - <url>http://svn.osgeo.org/geotools/branches/2.5.x/modules/plugin/arcsde/datastore/</url> - </scm> + <url>http://svn.osgeo.org/geotools/trunk/modules/plugin/arcsde/datastore/</url> + </scm> - <description> ArcSDE DataStore plugin. </description> - <licenses> - <license> - <name>Lesser General Public License (LGPL)</name> - <url>http://www.gnu.org/copyleft/lesser.txt</url> - <distribution>repo</distribution> - </license> - </licenses> + <description> ArcSDE DataStore plugin. </description> + <licenses> + <license> + <name>Lesser General Public License (LGPL)</name> + <url>http://www.gnu.org/copyleft/lesser.txt</url> + <distribution>repo</distribution> + </license> + </licenses> - <!-- =========================================================== --> - <!-- Developers and Contributors --> - <!-- =========================================================== --> - <developers> - <developer> - <name>Gabriel Roldan</name> - <id>groldan</id> - <email>[hidden email]</email> - <organization>OpenGeo</organization> - <organizationUrl>http://opengeo.org</organizationUrl> - <roles> - <role>Module Maintainer</role> - <role>Java Developer</role> - </roles> - </developer> - <developer> - <name>Jody Garnett</name> - <id>jgarnett</id> - <email>[hidden email]</email> - <organization>LISAsoft</organization> - <organizationUrl>http://www.lisasoft.com</organizationUrl> - <roles> - <role>Java Developer</role> - </roles> - </developer> - </developers> - <contributors> - <contributor> - <name>Saul Farber</name> - <email>[hidden email]</email> - <roles> - <role>Former co-module maintainer and Java Developer</role> - </roles> - </contributor> - <contributor> - <name>Chris Dillard</name> - <email>[hidden email]</email> - <organization>Polexis</organization> - <roles> - <role>Java Developer</role> - </roles> - </contributor> - <contributor> - <name>Jake Fear</name> - <email>[hidden email]</email> - <organization>Polexis</organization> - <roles> - <role>Java Developer</role> - </roles> - </contributor> - </contributors> + <!-- =========================================================== --> + <!-- Developers and Contributors --> + <!-- =========================================================== --> + <developers> + <developer> + <name>Gabriel Roldan</name> + <id>groldan</id> + <email>[hidden email]</email> + <organization>OpenGeo</organization> + <organizationUrl>http://opengeo.org</organizationUrl> + <roles> + <role>Module Maintainer</role> + <role>Java Developer</role> + </roles> + </developer> + <developer> + <name>Jody Garnett</name> + <id>jgarnett</id> + <email>[hidden email]</email> + <organization>LISAsoft</organization> + <organizationUrl>http://www.lisasoft.com</organizationUrl> + <roles> + <role>Java Developer</role> + </roles> + </developer> + </developers> + <contributors> + <contributor> + <name>Saul Farber</name> + <email>[hidden email]</email> + <roles> + <role>Former co-module maintainer and Java Developer</role> + </roles> + </contributor> + <contributor> + <name>Chris Dillard</name> + <email>[hidden email]</email> + <organization>Polexis</organization> + <roles> + <role>Java Developer</role> + </roles> + </contributor> + <contributor> + <name>Jake Fear</name> + <email>[hidden email]</email> + <organization>Polexis</organization> + <roles> + <role>Java Developer</role> + </roles> + </contributor> + </contributors> - <!-- =========================================================== --> - <!-- Dependency Management --> - <!-- =========================================================== --> - <dependencies> - <dependency> - <groupId>jsqlparser</groupId> - <artifactId>jsqlparser</artifactId> - <version>0.3.14</version> - </dependency> - <dependency> - <groupId>org.geotools</groupId> - <artifactId>gt-jdbc</artifactId> - <version>${project.version}</version> - </dependency> - <dependency> - <groupId>commons-pool</groupId> - <artifactId>commons-pool</artifactId> - </dependency> - <dependency> - <groupId>org.geotools</groupId> - <artifactId>gt-coverage</artifactId> - <version>${project.version}</version> - </dependency> - <dependency> - <groupId>org.geotools</groupId> - <artifactId>gt-sample-data</artifactId> - <version>${project.version}</version> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.geotools</groupId> - <artifactId>gt-cql</artifactId> - <version>${project.version}</version> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.geotools</groupId> - <artifactId>gt-epsg-wkt</artifactId> - <version>${project.version}</version> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.geotools</groupId> - <artifactId>gt-render</artifactId> - <version>${project.version}</version> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.geotools</groupId> - <artifactId>gt-geotiff</artifactId> - <version>${project.version}</version> - <scope>test</scope> - </dependency> - <dependency> - <groupId>javax.media</groupId> - <artifactId>jai_core</artifactId> - <scope>provided</scope> - </dependency> - <dependency> - <groupId>javax.media</groupId> - <artifactId>jai_codec</artifactId> - <scope>provided</scope> - </dependency> - <dependency> - <groupId>javax.media</groupId> - <artifactId>jai_imageio</artifactId> - <scope>provided</scope> - </dependency> - </dependencies> + <!-- =========================================================== --> + <!-- Dependency Management --> + <!-- =========================================================== --> + <dependencies> + <dependency> + <groupId>org.geotools</groupId> + <artifactId>gt-arcsde-common</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>jsqlparser</groupId> + <artifactId>jsqlparser</artifactId> + <version>0.3.14</version> + </dependency> + <dependency> + <groupId>org.geotools</groupId> + <artifactId>gt-jdbc</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.geotools</groupId> + <artifactId>gt-coverage</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>javax.media</groupId> + <artifactId>jai_core</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>javax.media</groupId> + <artifactId>jai_codec</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>javax.media</groupId> + <artifactId>jai_imageio</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.geotools</groupId> + <artifactId>gt-sample-data</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.geotools</groupId> + <artifactId>gt-render</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.geotools</groupId> + <artifactId>gt-geotiff</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.geotools</groupId> + <artifactId>gt-cql</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>simple-jndi</groupId> + <artifactId>simple-jndi</artifactId> + <scope>test</scope> + </dependency> + </dependencies> + <profiles> + <profile> + <id>autoSDEDummyJars</id> + <activation> + <activeByDefault>true</activeByDefault> + </activation> + <dependencies> + <dependency> + <groupId>org.geotools</groupId> + <artifactId>gt-sde-dummy</artifactId> + <version>${project.version}</version> + <scope>provided</scope> + </dependency> + </dependencies> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <!-- if we're using the dummy api, we should disable all tests --> + <excludes> + <exclude>**/*.java</exclude> + </excludes> + </configuration> + </plugin> + </plugins> + </build> + </profile> + <profile> + <id>arcsde</id> + <dependencies> + <dependency> + <groupId>com.esri</groupId> + <artifactId>jsde_sdk</artifactId> + <version>${sde.version}</version> + </dependency> + <dependency> + <groupId>com.esri</groupId> + <artifactId>jsde_jpe_sdk</artifactId> + <version>${sde.version}</version> + </dependency> + <dependency> + <groupId>com.ibm.icu</groupId> + <artifactId>icu4j</artifactId> + </dependency> + </dependencies> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <!-- + You need two things to run these tests successfully 1) The esri + ArcSDE jars installed. Either the 9.2 or 9.3 ones from your + ArcSDE Java SDK installation. 2) A properly configured + testparams.properties file. Make sure it correctly references + your SDE server with usernames and passwords in there correctly. - - <!-- =========================================================== --> - <!-- Profile Configuration --> - <!-- =========================================================== --> - <profiles> - <profile> - <id>autoSDEDummyJars</id> - <activation> - <activeByDefault>true</activeByDefault> - <property> - <name>haveSDEJars</name> - <value>false</value> - </property> - </activation> - <dependencies> - <dependency> - <groupId>org.geotools</groupId> - <artifactId>gt-sde-dummy</artifactId> - <version>${project.version}</version> - <scope>provided</scope> - </dependency> - </dependencies> - <build> - <plugins> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-surefire-plugin</artifactId> - <configuration> - <!-- if we're using the dummy api, we should disable all tests --> - <excludes> - <exclude>**/*.java</exclude> - </excludes> - </configuration> - </plugin> - </plugins> - </build> - </profile> - <profile> - <id>arcsde</id> - <dependencies> - <dependency> - <groupId>com.esri</groupId> - <artifactId>jsde_sdk</artifactId> - <version>${sde.version}</version> - </dependency> - <dependency> - <groupId>com.esri</groupId> - <artifactId>jsde_jpe_sdk</artifactId> - <version>${sde.version}</version> - </dependency> - <dependency> - <groupId>com.ibm.icu</groupId> - <artifactId>icu4j</artifactId> - </dependency> - </dependencies> - <build> - <plugins> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-surefire-plugin</artifactId> - <configuration> - <!-- You need two things to run these tests successfully - 1) The esri ArcSDE jars installed. The 9.0 jars are freely available - so as long as you have #2, you can rely on those ones. If you have - jsde jars other than 9.0 you need to inject them into - maven manually and set the sde.version property in the parent pom - or on the command line. - 2) A properly configured testparams.properties file. Make - sure it correctly references your SDE server with usernames and passwords - in there correctly. - - Since if you're building with the *real* SDE jars from SVN, I'd suggest - you enable these tests, just to make sure the SDE plugin is actually - correctly working right now! - --> - <includes> - <include>**/*Test.java</include> - </includes> - </configuration> - </plugin> - </plugins> - </build> - </profile> - </profiles> + Since if you're building with the *real* SDE jars from SVN, I'd + suggest you enable these tests, just to make sure the SDE plugin + is actually correctly working right now! + --> + <includes> + <include>**/*Test.java</include> + </includes> + </configuration> + </plugin> + </plugins> + </build> + </profile> + </profiles> </project> Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/ArcSDEDataStoreFactory.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/ArcSDEDataStoreFactory.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/ArcSDEDataStoreFactory.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -17,6 +17,20 @@ */ package org.geotools.arcsde; +import static org.geotools.arcsde.data.ArcSDEDataStoreConfig.ALLOW_NON_SPATIAL_TABLES_PARAM_NAME; +import static org.geotools.arcsde.data.ArcSDEDataStoreConfig.DBTYPE_PARAM_NAME; +import static org.geotools.arcsde.data.ArcSDEDataStoreConfig.NAMESPACE_PARAM_NAME; +import static org.geotools.arcsde.data.ArcSDEDataStoreConfig.VERSION_PARAM_NAME; +import static org.geotools.arcsde.session.ArcSDEConnectionConfig.CONNECTION_TIMEOUT_PARAM_NAME; +import static org.geotools.arcsde.session.ArcSDEConnectionConfig.INSTANCE_NAME_PARAM_NAME; +import static org.geotools.arcsde.session.ArcSDEConnectionConfig.MAX_CONNECTIONS_PARAM_NAME; +import static org.geotools.arcsde.session.ArcSDEConnectionConfig.MIN_CONNECTIONS_PARAM_NAME; +import static org.geotools.arcsde.session.ArcSDEConnectionConfig.PASSWORD_PARAM_NAME; +import static org.geotools.arcsde.session.ArcSDEConnectionConfig.PORT_NUMBER_PARAM_NAME; +import static org.geotools.arcsde.session.ArcSDEConnectionConfig.SERVER_NAME_PARAM_NAME; +import static org.geotools.arcsde.session.ArcSDEConnectionConfig.USER_NAME_PARAM_NAME; + +import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -24,17 +38,18 @@ import java.util.logging.Logger; import org.geotools.arcsde.data.ArcSDEDataStore; +import org.geotools.arcsde.data.ArcSDEDataStoreConfig; import org.geotools.arcsde.data.ViewRegisteringFactoryHelper; -import org.geotools.arcsde.pool.ArcSDEConnectionConfig; -import org.geotools.arcsde.pool.Commands; -import org.geotools.arcsde.pool.ISession; -import org.geotools.arcsde.pool.SessionPool; -import org.geotools.arcsde.pool.SessionPoolFactory; +import org.geotools.arcsde.session.Commands; +import org.geotools.arcsde.session.ISession; +import org.geotools.arcsde.session.ISessionPool; +import org.geotools.arcsde.session.ISessionPoolFactory; +import org.geotools.arcsde.session.SessionPoolFactory; +import org.geotools.arcsde.session.UnavailableArcSDEConnectionException; import org.geotools.data.DataSourceException; import org.geotools.data.DataStore; import org.geotools.data.DataStoreFactorySpi; import org.geotools.data.Parameter; -import org.geotools.data.Transaction; import org.geotools.util.SimpleInternationalString; import org.geotools.util.logging.Logging; @@ -53,7 +68,7 @@ * @version $Id$ */ @SuppressWarnings("unchecked") -public class ArcSDEDataStoreFactory implements DataStoreFactorySpi { +public final class ArcSDEDataStoreFactory implements DataStoreFactorySpi { /** package's logger */ protected static final Logger LOGGER = Logging .getLogger(ArcSDEDataStoreFactory.class.getName()); @@ -74,46 +89,52 @@ private static int JSDE_CLIENT_VERSION; - static { - Param NAMESPACE_PARAM = new Param(ArcSDEConnectionConfig.NAMESPACE_PARAM, String.class, - "namespace associated to this data store", false); - Param DBTYPE_PARAM = new Param(ArcSDEConnectionConfig.DBTYPE_PARAM, String.class, - "fixed value. Must be \"arcsde\"", true, "arcsde"); - Param SERVER_PARAM = new Param(ArcSDEConnectionConfig.SERVER_NAME_PARAM, String.class, - "sever name where the ArcSDE gateway is running", true); - Param PORT_PARAM = new Param( - ArcSDEConnectionConfig.PORT_NUMBER_PARAM, - Integer.class, - "port number in wich the ArcSDE server is listening for connections.Generally it's 5151", - true, Integer.valueOf(5151)); - Param INSTANCE_PARAM = new Param(ArcSDEConnectionConfig.INSTANCE_NAME_PARAM, String.class, - "the specific database to connect to. Only applicable to " - + "certain databases. Value ignored if not applicable.", false); - Param USER_PARAM = new Param(ArcSDEConnectionConfig.USER_NAME_PARAM, String.class, - "name of a valid database user account.", true); - Param PASSWORD_PARAM = new Param(ArcSDEConnectionConfig.PASSWORD_PARAM, String.class, - new SimpleInternationalString("the database user's password."), false, null, - Collections.singletonMap(Parameter.IS_PASSWORD, Boolean.TRUE)); - Param MIN_CONNECTIONS_PARAM = new Param(ArcSDEConnectionConfig.MIN_CONNECTIONS_PARAM, - Integer.class, "Minimun number of open connections", false, Integer - .valueOf(SessionPool.DEFAULT_CONNECTIONS)); + static final Param NAMESPACE_PARAM = new Param(NAMESPACE_PARAM_NAME, String.class, + "namespace associated to this data store", false); - Param MAX_CONNECTIONS_PARAM = new Param(ArcSDEConnectionConfig.MAX_CONNECTIONS_PARAM, - Integer.class, "Maximun number of open connections (will not work if < 2)", false, - Integer.valueOf(SessionPool.DEFAULT_MAX_CONNECTIONS)); + static final Param DBTYPE_PARAM = new Param(DBTYPE_PARAM_NAME, String.class, + "fixed value. Must be \"arcsde\"", true, "arcsde"); - Param TIMEOUT_PARAM = new Param(ArcSDEConnectionConfig.CONNECTION_TIMEOUT_PARAM, - Integer.class, - "Milliseconds to wait for an available connection before failing to connect", - false, Integer.valueOf(SessionPool.DEFAULT_MAX_WAIT_TIME)); + static final Param SERVER_PARAM = new Param(SERVER_NAME_PARAM_NAME, String.class, + "sever name where the ArcSDE gateway is running", true); - Param VERSION_PARAM = new Param(ArcSDEConnectionConfig.VERSION_PARAM, String.class, - "The ArcSDE database version to use.", false); + static final Param PORT_PARAM = new Param( + PORT_NUMBER_PARAM_NAME, + Integer.class, + "port number in wich the ArcSDE server is listening for connections.Generally it's 5151", + true, Integer.valueOf(5151)); - Param ALLOW_NON_SPATIAL_PARAM = new Param( - ArcSDEConnectionConfig.ALLOW_NON_SPATIAL_TABLES_PARAM, Boolean.class, - "If enabled, registered non-spatial tables are also published.", false); + static final Param INSTANCE_PARAM = new Param(INSTANCE_NAME_PARAM_NAME, String.class, + "the specific database to connect to. Only applicable to " + + "certain databases. Value ignored if not applicable.", false); + static final Param USER_PARAM = new Param(USER_NAME_PARAM_NAME, String.class, + "name of a valid database user account.", true); + + static final Param PASSWORD_PARAM = new Param(PASSWORD_PARAM_NAME, String.class, + new SimpleInternationalString("the database user's password."), false, null, + Collections.singletonMap(Parameter.IS_PASSWORD, Boolean.TRUE)); + + static final Param MIN_CONNECTIONS_PARAM = new Param(MIN_CONNECTIONS_PARAM_NAME, Integer.class, + "Minimun number of open connections", false, Integer + .valueOf(ArcSDEDataStoreConfig.DEFAULT_CONNECTIONS)); + + static final Param MAX_CONNECTIONS_PARAM = new Param(MAX_CONNECTIONS_PARAM_NAME, Integer.class, + "Maximun number of open connections (will not work if < 2)", false, Integer + .valueOf(ArcSDEDataStoreConfig.DEFAULT_MAX_CONNECTIONS)); + + static final Param TIMEOUT_PARAM = new Param(CONNECTION_TIMEOUT_PARAM_NAME, Integer.class, + "Milliseconds to wait for an available connection before failing to connect", false, + Integer.valueOf(ArcSDEDataStoreConfig.DEFAULT_MAX_WAIT_TIME)); + + static final Param VERSION_PARAM = new Param(VERSION_PARAM_NAME, String.class, + "The ArcSDE database version to use.", false); + + static final Param ALLOW_NON_SPATIAL_PARAM = new Param(ALLOW_NON_SPATIAL_TABLES_PARAM_NAME, + Boolean.class, "If enabled, registered non-spatial tables are also published.", false, + Boolean.FALSE); + + static { paramMetadata.add(NAMESPACE_PARAM); paramMetadata.add(DBTYPE_PARAM); paramMetadata.add(SERVER_PARAM); @@ -166,7 +187,7 @@ } /** factory of connection pools to different SDE databases */ - private static final SessionPoolFactory poolFactory = SessionPoolFactory.getInstance(); + private static final ISessionPoolFactory poolFactory = SessionPoolFactory.getInstance(); /** * empty constructor @@ -221,17 +242,32 @@ * @throws java.io.IOException * if something goes wrong creating the datastore. */ - public DataStore createDataStore(Map params) throws java.io.IOException { + public DataStore createDataStore(final Map params) throws java.io.IOException { if (JSDE_CLIENT_VERSION == JSDE_VERSION_DUMMY) { throw new DataSourceException("Can't connect to ArcSDE with the dummy jar."); } ArcSDEDataStore sdeDStore = null; - ArcSDEConnectionConfig config = new ArcSDEConnectionConfig(params); + ArcSDEDataStoreConfig config = new ArcSDEDataStoreConfig(params); + sdeDStore = createDataStore(config); + + ViewRegisteringFactoryHelper.registerSqlViews(sdeDStore, params); + + return sdeDStore; + } + + final ArcSDEDataStore createDataStore(ArcSDEDataStoreConfig config) throws IOException { + ArcSDEDataStore sdeDStore; // create a new session pool to be used only by this datastore - final SessionPool connPool = poolFactory.createPool(config); + final ISessionPool connPool = poolFactory.createPool(config.getSessionConfig()); - final ISession session = connPool.getSession(Transaction.AUTO_COMMIT); + return createDataStore(config, connPool); + } + + final ArcSDEDataStore createDataStore(ArcSDEDataStoreConfig config, final ISessionPool connPool) + throws IOException, UnavailableArcSDEConnectionException { + ArcSDEDataStore sdeDStore; + final ISession session = connPool.getSession(); try { // check to see if our sdk is compatible with this arcsde instance SeRelease releaseInfo = session.getRelease(); @@ -278,9 +314,6 @@ } boolean allowNonSpatialTables = config.isAllowNonSpatialTables(); sdeDStore = new ArcSDEDataStore(connPool, namespaceUri, versionName, allowNonSpatialTables); - - ViewRegisteringFactoryHelper.registerSqlViews(sdeDStore, params); - return sdeDStore; } @@ -314,7 +347,7 @@ boolean canProcess = true; try { - new ArcSDEConnectionConfig(params); + new ArcSDEDataStoreConfig(params); } catch (NullPointerException ex) { canProcess = false; } catch (IllegalArgumentException ex) { Copied: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/ArcSDEJNDIDataStoreFactory.java (from rev 33502, trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/ArcSDEJNDIDataStoreFactory.java) =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/ArcSDEJNDIDataStoreFactory.java (rev 0) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/ArcSDEJNDIDataStoreFactory.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -0,0 +1,309 @@ +/* + * GeoTools - The Open Source Java GIS Toolkit + * http://geotools.org + * + * (C) 2002-2009, 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.arcsde; + +import static org.geotools.arcsde.ArcSDEDataStoreFactory.ALLOW_NON_SPATIAL_PARAM; +import static org.geotools.arcsde.ArcSDEDataStoreFactory.NAMESPACE_PARAM; +import static org.geotools.arcsde.ArcSDEDataStoreFactory.VERSION_PARAM; + +import java.awt.RenderingHints.Key; +import java.io.IOException; +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Logger; + +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; + +import org.geotools.arcsde.data.ArcSDEDataStore; +import org.geotools.arcsde.data.ArcSDEDataStoreConfig; +import org.geotools.arcsde.jndi.ArcSDEConnectionFactory; +import org.geotools.arcsde.session.ArcSDEConnectionConfig; +import org.geotools.arcsde.session.ISessionPool; +import org.geotools.arcsde.session.SessionPoolFactory; +import org.geotools.data.DataSourceException; +import org.geotools.data.DataStore; +import org.geotools.data.DataStoreFactorySpi; +import org.geotools.util.logging.Logging; + +/** + * A GeoTools {@link DataStore} factory to access an ArcSDE database by grabbing either the + * connection parameters or the connection pool from a JNDI reference. + * <p> + * This DataStore factory expects the arcsde connection information to be given as a JNDI resource + * path through the {@link #JNDI_REFNAME jndiRefName} parameter at {@link #createDataStore(Map)}. + * The resource provided by the JNDI context at that location may be either: + * <ul> + * <li>a {@code java.util.Map<String, String>} with the connection parameters from + * {@link ArcSDEConnectionConfig}</li> + * <li>an {@link ArcSDEConnectionConfig} instance itself</li> + * <li>a {@link ISessionPool} instance</li> + * </ul> + * </p> + * <p> + * If not an {@code ISessionPool}, the object will be used to get one from + * {@link ArcSDEConnectionFactory}. Whether the resulting session (connection) pool is shared among + * {@link ArcSDEDataStore} instances is dependent on how the JNDI resource is externally configured. + * For example, on the J2EE container, it will depend on if the JNDI resource is globally configured + * or not, and the required jar files are on a J2EE container shared libraries folder or not. + * </p> + * + * @author Gabriel Roldan (OpenGeo) + * @version $Id$ + * @since 2.5.7 + */ +public class ArcSDEJNDIDataStoreFactory implements DataStoreFactorySpi { + + private static final Logger LOGGER = Logging.getLogger("org.geotools.arcsde"); + + private final ArcSDEDataStoreFactory delegateFactory; + + /** + * JNDI context path name + */ + public static final Param JNDI_REFNAME = new Param("jndiReferenceName", String.class, + "JNDI context path", true, "java:comp/env/geotools/arcsde"); + + private static final String J2EERootContext = "java:comp/env/"; + + public ArcSDEJNDIDataStoreFactory() { + this.delegateFactory = new ArcSDEDataStoreFactory(); + } + + /** + * Creates and {@link ArcSDEDataStore} from the provided {@code params}, where the connection + * pool is provided by JNDI. + * <p> + * See {@link #getParametersInfo()} to check which datastore creation parameters are expected by + * this factory method. + * </p> + * + * @see org.geotools.data.DataStoreFactorySpi#createDataStore(java.util.Map) + */ + public DataStore createDataStore(Map<String, Serializable> params) throws IOException { + final String jndiName = (String) JNDI_REFNAME.lookUp(params); + + final Object lookup = lookupJndiResource(jndiName); + + final ISessionPool sessionPool = getSessionPool(jndiName, lookup); + + final String nsUri = (String) NAMESPACE_PARAM.lookUp(params); + final String version = (String) VERSION_PARAM.lookUp(params); + final boolean nonSpatial; + { + final Boolean allowNonSpatialTables = (Boolean) ALLOW_NON_SPATIAL_PARAM.lookUp(params); + nonSpatial = allowNonSpatialTables == null ? false : allowNonSpatialTables + .booleanValue(); + } + + final ArcSDEConnectionConfig connectionConfig = sessionPool.getConfig(); + final ArcSDEDataStoreConfig dsConfig; + dsConfig = new ArcSDEDataStoreConfig(connectionConfig, nsUri, version, nonSpatial); + + LOGGER.info("Creating ArcSDE JNDI DataStore with shared session pool for " + dsConfig); + final ArcSDEDataStore dataStore = delegateFactory.createDataStore(dsConfig, sessionPool); + + return dataStore; + } + + @SuppressWarnings("unchecked") + private ISessionPool getSessionPool(final String jndiName, final Object lookup) + throws IOException, DataSourceException { + + final ISessionPool sessionPool; + + if (lookup instanceof ArcSDEConnectionConfig) { + + LOGGER.info("Creating JNDI ArcSDE DataStore with own session pool for " + lookup); + final ArcSDEConnectionConfig connectionConfig = (ArcSDEConnectionConfig) lookup; + sessionPool = SessionPoolFactory.getInstance().createPool(connectionConfig); + + } else if (lookup instanceof ISessionPool) { + + LOGGER.info("Creating JNDI ArcSDE DataStore with shared session pool for " + lookup); + sessionPool = (ISessionPool) lookup; + + } else if (lookup instanceof Map) { + Map<String, String> map = new HashMap<String, String>(); + { + Map<Object, Object> props = (Map<Object, Object>) lookup; + String key; + Object value; + for (Map.Entry<Object, Object> e : props.entrySet()) { + key = String.valueOf(e.getKey()); + value = e.getValue(); + map.put(key, value == null ? null : String.valueOf(e.getValue())); + } + } + // use the JNDI factory to grab the shared pool + ArcSDEConnectionFactory factory = new ArcSDEConnectionFactory(); + sessionPool = factory.getInstance(map); + + } else { + throw new DataSourceException("Unknown JNDI resource on path " + jndiName + + ". Expected one of [" + ArcSDEConnectionConfig.class.getName() + ", " + + ISessionPool.class.getName() + "] but got " + lookup.getClass().getName() + + " (" + lookup + ")"); + } + return sessionPool; + } + + /** + * Looks up and returns the JNDI resource addressed by {@code jndiName} + * + * @param jndiName + * @return the resource mapped at {@code jndiName}, which shall be either a {@code + * java.util.Map<String, String>}, an {@link ArcSDEConnectionConfig} or a + * {@link ISessionPool}. + * @throws IOException + * if a resource is not found at {@code jndiName} + */ + private Object lookupJndiResource(final String jndiName) throws IOException { + if (jndiName == null) { + throw new IOException("Missing " + JNDI_REFNAME.description); + } + + final Context ctx; + + try { + Context initialContext = new InitialContext(); + ctx = (Context) initialContext.lookup("java:comp/env"); + } catch (NamingException e) { + throw new RuntimeException(e); + } + + Object lookup = null; + try { + lookup = ctx.lookup(jndiName); + } catch (NamingException e1) { + // check if the user did not specify "java:comp/env" + // and this code is running in a J2EE environment + try { + if (jndiName.startsWith(J2EERootContext) == false) { + lookup = ctx.lookup(J2EERootContext + jndiName); + // success --> issue a waring + LOGGER.warning("Using " + J2EERootContext + jndiName + " instead of " + + jndiName + " would avoid an unnecessary JNDI lookup"); + } + } catch (NamingException e2) { + // do nothing, was only a try + } + } + + if (lookup == null) { + throw new IOException("Cannot find JNDI data source: " + jndiName); + } + return lookup; + } + + /** + * Returns whether this factory <i>could</i> process the given parameters. That is, it does not + * check the validity of the parameter, it only asserts the {@link #JNDI_REFNAME} parameter is + * present. That is so so any failure is handled by {@link #createDataStore(Map)} instead of + * getting client code silently failing (as this method does not throw an exception) + * + * @see org.geotools.data.DataAccessFactory#canProcess(java.util.Map) + */ + public boolean canProcess(Map<String, Serializable> params) { + if (params == null) { + return false; + } + String lookUpKey; + try { + lookUpKey = (String) JNDI_REFNAME.lookUp(params); + } catch (IOException e) { + return false; + } + if (lookUpKey == null) { + return false; + } + return true; + } + + /** + * @see org.geotools.data.DataAccessFactory#getDescription() + */ + public String getDescription() { + return delegateFactory.getDescription() + " (JNDI)"; + } + + /** + * @see org.geotools.data.DataAccessFactory#getDisplayName() + */ + public String getDisplayName() { + return delegateFactory.getDisplayName() + " (JNDI)"; + } + + /** + * Provides the datastore creation parameter metadata for this factory. + * <p> + * The returned parameters are: + * <ul> + * <li>{@link #JNDI_REFNAME jndiReferenceName}: the JNDI path to the {@link ISessionPool + * connection pool} + * <li> {@link ArcSDEDataStoreConfig#NAMESPACE_PARAM_NAME namespace}: the namespace uri the + * datastore should create feature types in + * <li> {@link ArcSDEDataStoreConfig#VERSION_PARAM_NAME database.version} the arcsde database + * version the datastore shall work upon. If non provided or empty, the DEFAULT version will be + * used. + * <li> {@link ArcSDEDataStoreConfig#ALLOW_NON_SPATIAL_TABLES_PARAM_NAME + * datastore.allowNonSpatialTables} whether to publish non spatial registered tables (aka, + * Object Classes). Defaults to {@code false}. + * </ul> + * </p> + * + * @see org.geotools.data.DataAccessFactory#getParametersInfo() + */ + public Param[] getParametersInfo() { + return new Param[] { JNDI_REFNAME, NAMESPACE_PARAM, VERSION_PARAM, ALLOW_NON_SPATIAL_PARAM }; + } + + /** + * Determines if the datastore is available. + * <p> + * Check in an Initial Context is available, that is all what can be done Checking for the right + * jdbc jars in the classpath is not possible here + * </p> + * + * @see org.geotools.data.DataAccessFactory#isAvailable() + */ + public boolean isAvailable() { + try { + new InitialContext(); + } catch (NamingException e) { + return false; + } + return delegateFactory.isAvailable(); + } + + /** + * @see org.geotools.factory.Factory#getImplementationHints() + */ + @SuppressWarnings("unchecked") + public Map<Key, ?> getImplementationHints() { + return delegateFactory.getImplementationHints(); + } + + /** + * @see org.geotools.data.DataStoreFactorySpi#createNewDataStore(java.util.Map) + */ + public DataStore createNewDataStore(Map<String, Serializable> params) throws IOException { + throw new UnsupportedOperationException("ArcSDE PlugIn does not support createNewDataStore"); + } +} Deleted: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/ArcSdeException.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/ArcSdeException.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/ArcSdeException.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -1,120 +0,0 @@ -/* - * 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.arcsde; - -import org.geotools.data.DataSourceException; - -import com.esri.sde.sdk.client.SeError; -import com.esri.sde.sdk.client.SeException; - -/** - * An IOException that wraps an {@link SeException} in order to report the {@link SeError} messages - * that otherwise get hidden in a normal stack trace. - * - * @author Gabriel Roldan (TOPP) - * @version $Id$ - * @since 2.5 - * @URL $URL: - * http://svn.geotools.org/geotools/trunk/gt/modules/plugin/arcsde/datastore/src/main/java - * /org/geotools/arcsde/ArcSdeException.java $ - */ -public class ArcSdeException extends DataSourceException { - - private static final long serialVersionUID = -1392514883217797825L; - - public ArcSdeException(SeException cause) { - this("", cause); - } - - public ArcSdeException(String msg, SeException cause) { - super(msg, cause); - } - - @Override - public SeException getCause() { - return (SeException) super.getCause(); - } - - @Override - public String getMessage() { - String message = super.getMessage(); - SeError error = getSeError(); - StringBuffer sb = new StringBuffer(); - if (message != null) { - sb.append(message); - } - if (error != null) { - int sdeError = error.getSdeError(); - String sdeErrMsg = error.getSdeErrMsg(); - String extErrMsg = error.getExtErrMsg(); - String errDesc = error.getErrDesc(); - - sb.append("[SDE error ").append(sdeError); - if (sdeErrMsg != null && !"".equals(sdeErrMsg)) { - sb.append(" ").append(sdeErrMsg); - } - sb.append("]"); - if (errDesc != null && !"".equals(errDesc)) { - sb.append("[Error desc=").append(errDesc).append("]"); - } - if (extErrMsg != null && !"".equals(extErrMsg)) { - sb.append("[Extended desc=").append(extErrMsg).append("]"); - } - } - return sb.toString(); - } - - public SeError getSeError() { - SeException ex = getCause(); - if (ex == null) { - return null; - } - return ex.getSeError(); - } - - /** - * SeException is pretty sad (Caused by: com.esri.sde.sdk.client.SeException: ) leaving you to - * hunt and peck at the SeError for a good description of what went bad. - * <p> - * This class tries to grab as much information as possible form SeError. - * - * @return String describing the message from SeException. - */ - public static String toMessage(SeException e) { - StringBuffer buf = new StringBuffer(); - if (e.getSeError() != null) { - SeError error = e.getSeError(); - buf.append("SDE Error "); - buf.append(error.getSdeError()); - buf.append(" "); - buf.append(error.getSdeErrMsg()); - if (error.getExtErrMsg() != null) { - buf.append("\n"); - buf.append(error.getExtErrMsg()); - } - if (error.getErrDesc() != null) { - buf.append("\n"); - buf.append(error.getErrDesc()); - } - } - if (e.getMessage() != null) { - buf.append("\n"); - buf.append(e.getMessage()); - } - return buf.toString(); - } -} Property changes on: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data ___________________________________________________________________ Deleted: svn:mergeinfo - /trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data:31091-33383,33392 Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSDEAdapter.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSDEAdapter.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSDEAdapter.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -32,8 +32,8 @@ import net.sf.jsqlparser.statement.select.PlainSelect; import org.geotools.arcsde.ArcSdeException; -import org.geotools.arcsde.pool.Command; -import org.geotools.arcsde.pool.ISession; +import org.geotools.arcsde.session.Command; +import org.geotools.arcsde.session.ISession; import org.geotools.data.DataSourceException; import org.geotools.feature.AttributeTypeBuilder; import org.geotools.feature.simple.SimpleFeatureTypeBuilder; Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSDEAttributeReader.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSDEAttributeReader.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSDEAttributeReader.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -21,7 +21,8 @@ import java.util.logging.Logger; import org.geotools.arcsde.ArcSdeException; -import org.geotools.arcsde.pool.ISession; +import org.geotools.arcsde.session.ISession; +import org.geotools.arcsde.session.SdeRow; import org.geotools.data.AttributeReader; import org.geotools.data.DataSourceException; import org.geotools.util.logging.Logging; Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSDEDataStore.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSDEDataStore.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSDEDataStore.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -35,9 +35,9 @@ import org.geotools.arcsde.data.versioning.AutoCommitVersionHandler; import org.geotools.arcsde.data.view.QueryInfoParser; import org.geotools.arcsde.data.view.SelectQualifier; -import org.geotools.arcsde.pool.ISession; -import org.geotools.arcsde.pool.SessionPool; -import org.geotools.arcsde.pool.SessionWrapper; +import org.geotools.arcsde.session.ISession; +import org.geotools.arcsde.session.ISessionPool; +import org.geotools.arcsde.session.SessionWrapper; import org.geotools.data.DataAccess; import org.geotools.data.DataSourceException; import org.geotools.data.DataStore; @@ -76,7 +76,7 @@ /** * DataStore implementation to work upon an ArcSDE spatial database gateway. * <p> - * Takes ownership of the provided {@link SessionPool} so make sure to call {@link #dispose()} in + * Takes ownership of the provided {@link ISessionPool} so make sure to call {@link #dispose()} in * order to release resources (ArcSDE connections). * </p> * @@ -102,7 +102,7 @@ */ final FeatureListenerManager listenerManager = new FeatureListenerManager(); - final SessionPool connectionPool; + final ISessionPool connectionPool; final FeatureTypeInfoCache typeInfoCache; @@ -120,7 +120,7 @@ * pool of {@link Session} this datastore works upon. * @throws IOException */ - public ArcSDEDataStore(final SessionPool connPool) throws IOException { + public ArcSDEDataStore(final ISessionPool connPool) throws IOException { this(connPool, null, null, false); } @@ -139,7 +139,7 @@ * whether ArcSDE registered, non-spatial tables are to be published * @throws IOException */ - public ArcSDEDataStore(final SessionPool connPool, final String namespaceUri, + public ArcSDEDataStore(final ISessionPool connPool, final String namespaceUri, final String versionName, final boolean allowNonSpatialTables) throws IOException { this.connectionPool = connPool; this.version = versionName == null ? SeVersion.SE_QUALIFIED_DEFAULT_VERSION_NAME @@ -148,13 +148,29 @@ DEFAULT_LAYER_NAMES_CACHE_UPDATE_FREQ_SECS, allowNonSpatialTables); } - public ISession getSession(final Transaction transaction) throws IOException { + /** + * Retrieve the connection for the provided transaction. + * <p> + * The connection is held open until while the transaction is underway. A a Transaction.State is + * registered for this SessionPool in order to hold the session. + * </p> + * + * @param transaction + * @return the session associated with the transaction + */ + public ISession getSession(Transaction transaction) throws IOException { if (transaction == null) { throw new NullPointerException( "transaction can't be null. Did you mean Transaction.AUTO_COMMIT?"); } - final ISession session = connectionPool.getSession(transaction); - + final ISession session; + if (Transaction.AUTO_COMMIT.equals(transaction)) { + session = connectionPool.getSession(); + } else { + SessionTransactionState state; + state = SessionTransactionState.getState(transaction, this.connectionPool); + session = state.getConnection(); + } return session; } @@ -164,7 +180,7 @@ } ArcTransactionState state = (ArcTransactionState) transaction.getState(this); if (state == null) { - state = new ArcTransactionState(this.connectionPool, listenerManager); + state = new ArcTransactionState(this, listenerManager); transaction.putState(this, state); } return state; Copied: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSDEDataStoreConfig.java (from rev 33502, trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSDEDataStoreConfig.java) =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSDEDataStoreConfig.java (rev 0) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSDEDataStoreConfig.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -0,0 +1,388 @@ +/* + * 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.arcsde.data; + +import static org.geotools.arcsde.session.ArcSDEConnectionConfig.CONNECTION_TIMEOUT_PARAM_NAME; +import static org.geotools.arcsde.session.ArcSDEConnectionConfig.INSTANCE_NAME_PARAM_NAME; +import static org.geotools.arcsde.session.ArcSDEConnectionConfig.MAX_CONNECTIONS_PARAM_NAME; +import static org.geotools.arcsde.session.ArcSDEConnectionConfig.MIN_CONNECTIONS_PARAM_NAME; +import static org.geotools.arcsde.session.ArcSDEConnectionConfig.PASSWORD_PARAM_NAME; +import static org.geotools.arcsde.session.ArcSDEConnectionConfig.PORT_NUMBER_PARAM_NAME; +import static org.geotools.arcsde.session.ArcSDEConnectionConfig.SERVER_NAME_PARAM_NAME; +import static org.geotools.arcsde.session.ArcSDEConnectionConfig.USER_NAME_PARAM_NAME; + +import java.util.Map; +import java.util.logging.Logger; + +import org.geotools.arcsde.session.ArcSDEConnectionConfig; + +/** + * Represents a set of ArcSDE database connection parameters. Instances of this class are used to + * validate ArcSDE connection params as in <code>DataSourceFactory.canProcess(java.util.Map)</code> + * and serves as keys for maintaining single <code>SdeConnectionPool</code>'s by each set of + * connection properties + * + * @author Gabriel Roldan + * @source $URL: + * http://svn.geotools.org/geotools/trunk/gt/modules/plugin/arcsde/datastore/src/main/java + * /org/geotools/arcsde/pool/ArcSDEConnectionConfig.java $ + * @version $Id$ + */ +@SuppressWarnings("unchecked") +public class ArcSDEDataStoreConfig { + /* + * ArcSDEDataStoreConfige's logger + */ + private static final Logger LOGGER = org.geotools.util.logging.Logging + .getLogger("org.geotools.arcsde.pool"); + + /** + * message of the exception thrown if a mandatory parameter is not supplied + */ + private static final String NULL_ARGUMENTS_MSG = "Illegal arguments. At least one of them was null. Check to pass " + + "correct values to dbtype, server, port, database, user and password parameters"; + + private static final String ILLEGAL_ARGUMENT_MSG = " is not valid for parameter "; + + /** must equals to <code>"arcsde"</code> */ + public static final String DBTYPE_PARAM_NAME = "dbtype"; + + /** constant to pass "arcsde" as DBTYPE_PARAM */ + public static final String DBTYPE_PARAM_VALUE = "arcsde"; + + /** namespace URI assigned to datastore instance */ + public static final String NAMESPACE_PARAM_NAME = "namespace"; + + public static final String VERSION_PARAM_NAME = "database.version"; + + public static final String ALLOW_NON_SPATIAL_TABLES_PARAM_NAME = "datastore.allowNonSpatialTables"; + + /** default number of connections a pool creates at first population */ + public static final int DEFAULT_CONNECTIONS = 2; + + /** default number of maximum allowable connections a pool can hold */ + public static final int DEFAULT_MAX_CONNECTIONS = 6; + + public static final int DEFAULT_MAX_WAIT_TIME = 500; + + /** namespace URI assigned to datastore */ + private String namespaceUri; + + /** ArcSDE database version name, or null for DEFAULT version */ + private String version; + + /** whether to publish arcsde registered, non-spatial tables */ + private boolean allowNonSpatialTables; + + private ArcSDEConnectionConfig sessionConfig = new ArcSDEConnectionConfig(); + + public ArcSDEConnectionConfig getSessionConfig() { + return sessionConfig; + } + + /** + * Configure arcsde connection information from supplied connection parameters. + * + * @param params + * Connection parameters + * @throws NullPointerException + * if at least one mandatory parameter is null + * @throws IllegalArgumentException + * if at least one mandatory parameter is present but does not have a "valid" value. + */ + public ArcSDEDataStoreConfig(Map params) throws IllegalArgumentException { + init(params); + } + + public ArcSDEDataStoreConfig(ArcSDEConnectionConfig sessionConfig, final String namespace, + final String versionName, final boolean allowNonSpatialTables) { + + this.sessionConfig = sessionConfig; + this.namespaceUri = namespace; + this.allowNonSpatialTables = allowNonSpatialTables; + this.version = versionName; + } + + /** + * Extra connection parameters from the provided map. + * + * @param params + * Connection parameters + * @throws NumberFormatException + * If port could not be parsed into a number + * @throws IllegalArgumentException + * If any of the parameters are invalid + */ + private void init(Map params) throws NumberFormatException, IllegalArgumentException { + String dbtype = (String) params.get(DBTYPE_PARAM_NAME); + String server = (String) params.get(SERVER_NAME_PARAM_NAME); + String port = String.valueOf(params.get(PORT_NUMBER_PARAM_NAME)); + String instance = (String) params.get(INSTANCE_NAME_PARAM_NAME); + String user = (String) params.get(USER_NAME_PARAM_NAME); + String pwd = (String) params.get(PASSWORD_PARAM_NAME); + Integer _port = checkParams(dbtype, server, port, instance, user, pwd); + sessionConfig.setServerName(server); + sessionConfig.setPortNumber(_port); + sessionConfig.setDatabaseName(instance); + sessionConfig.setUserName(user); + sessionConfig.setPassword(pwd); + setUpOptionalParams(params); + } + + /** + * Handle optional parameters; most are focused on connection pool use. + * + * @param params + * Connection parameters + * @throws IllegalArgumentException + * If any of the optional prameters are invlaid. + */ + private void setUpOptionalParams(Map params) throws IllegalArgumentException { + String exceptionMsg = ""; + Object ns = params.get(NAMESPACE_PARAM_NAME); + + this.namespaceUri = ns == null ? null : String.valueOf(ns); + + Integer minConnections = getInt(params.get(MIN_CONNECTIONS_PARAM_NAME), DEFAULT_CONNECTIONS); + Integer maxConnections = getInt(params.get(MAX_CONNECTIONS_PARAM_NAME), + DEFAULT_MAX_CONNECTIONS); + Integer connTimeOut = getInt(params.get(CONNECTION_TIMEOUT_PARAM_NAME), + DEFAULT_MAX_WAIT_TIME); + + this.version = (String) params.get(VERSION_PARAM_NAME); + + Object nonSpatial = params.get(ALLOW_NON_SPATIAL_TABLES_PARAM_NAME); + this.allowNonSpatialTables = nonSpatial == null ? false : Boolean.valueOf(String + .valueOf(nonSpatial)); + + if (minConnections.intValue() <= 0) { + exceptionMsg += MIN_CONNECTIONS_PARAM_NAME + " must be a positive integer. "; + } + + if (maxConnections.intValue() <= 0) { + exceptionMsg += MAX_CONNECTIONS_PARAM_NAME + " must be a positive integer. "; + } + + if (connTimeOut.intValue() <= 0) { + exceptionMsg += CONNECTION_TIMEOUT_PARAM_NAME + " must be a positive integer. "; + } + + if (minConnections.intValue() > maxConnections.intValue()) { + exceptionMsg += MIN_CONNECTIONS_PARAM_NAME + " must be lower than " + + MAX_CONNECTIONS_PARAM_NAME + "."; + } + + if (exceptionMsg.length() != 0) { + throw new IllegalArgumentException(exceptionMsg); + } + + sessionConfig.setMinConnections(minConnections); + sessionConfig.setMaxConnections(maxConnections); + sessionConfig.setConnTimeOut(connTimeOut); + } + + /** + * Convert value to an Integer, or use the default value + * + * @param value + * Object to convert to int + * @param defaultValue + * Default value if conversion fails + * @return value as an interger, or default value if that is not possible + */ + private static final Integer getInt(Object value, int defaultValue) { + if (value == null) { + return Integer.valueOf(defaultValue); + } + + String sVal = String.valueOf(value); + + try { + return Integer.valueOf(sVal); + } catch (NumberFormatException ex) { + return Integer.valueOf(defaultValue); + } + } + + private static Integer checkParams(String dbType, String serverName, String portNumber, + String databaseName, String userName, String userPassword) + throws IllegalArgumentException, NullPointerException { + // check if dbtype is 'arcsde' + if (!(DBTYPE_PARAM_VALUE.equals(dbType))) { + throw new IllegalArgumentException("parameter dbtype must be " + DBTYPE_PARAM_VALUE); + } + + // check for nullity + if ((serverName == null) || (portNumber == null) || (userName == null) + || (userPassword == null)) { + throw new NullPointerException(NULL_ARGUMENTS_MSG); + } + + if (serverName.length() == 0) { + throwIllegal(SERVER_NAME_PARAM_NAME, serverName); + } + + if (databaseName == null || databaseName.length() == 0) { + LOGGER.fine("No database name specified"); + } + + if (userName.length() == 0) { + throwIllegal(USER_NAME_PARAM_NAME, userName); + } + + if (userPassword.length() == 0) { + throwIllegal(PASSWORD_PARAM_NAME, userPassword); + } + + Integer port = null; + + try { + port = Integer.valueOf(portNumber); + } catch (NumberFormatException ex) { + throwIllegal(PORT_NUMBER_PARAM_NAME, portNumber); + } + + return port; + } + + /** + * DOCUMENT ME! + * + * @param paramName + * DOCUMENT ME! + * @param paramValue + * DOCUMENT ME! + * @throws IllegalArgumentException + * DOCUMENT ME! + */ + private static void throwIllegal(String paramName, String paramValue) + throws IllegalArgumentException { + throw new IllegalArgumentException("'" + paramValue + "'" + ILLEGAL_ARGUMENT_MSG + + paramName); + } + + public String getNamespaceUri() { + return namespaceUri; + } + + public String getDatabaseName() { + return sessionConfig.getDatabaseName(); + } + + public Integer getPortNumber() { + return sessionConfig.getPortNumber(); + } + + public String getServerName() { + return sessionConfig.getServerName(); + } + + public String getUserName() { + return sessionConfig.getUserName(); + } + + public String getUserPassword() { + return sessionConfig.getPassword(); + } + + @Override + public int hashCode() { + int hash = 37; + hash *= getServerName().hashCode(); + hash *= getPortNumber().hashCode(); + hash *= getUserName().hashCode(); + return hash; + } + + /** + * Checks for equality over another <code>ArcSDEConnectionConfig</code>, taking into account the + * values of database name, user name, and port number. + * + * @param o + * DOCUMENT ME! + * @return DOCUMENT ME! + */ + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + + if (!(o instanceof ArcSDEDataStoreConfig)) { + return false; + } + + ArcSDEDataStoreConfig config = (ArcSDEDataStoreConfig) o; + + return config.getServerName().equals(getServerName()) + && config.getPortNumber().equals(getPortNumber()) + && config.getUserName().equals(getUserName()); + } + + public Integer getConnTimeOut() { + return sessionConfig.getConnTimeOut(); + } + + public Integer getMaxConnections() { + return sessionConfig.getMaxConnections(); + } + + public Integer getMinConnections() { + return sessionConfig.getMinConnections(); + } + + /** + * @return the ArcSDE version name to connect to + */ + public String getVersion() { + return version; + } + + /** + * @return whether to publish ArcSDE registered, non-spatial tables + */ + public boolean isAllowNonSpatialTables() { + return allowNonSpatialTables; + } + + /** + * @return a human friendly description of this parameter holder contents (password is masked), + * mostly usefull for stack traces + */ + @Override + public String toString() { + StringBuffer sb = new StringBuffer(getClass().getName() + "["); + sb.append("dbtype=").append(ArcSDEDataStoreConfig.DBTYPE_PARAM_VALUE); + sb.append(", server=").append(getServerName()); + sb.append(", port=").append(getPortNumber()); + sb.append(", instance=").append(getDatabaseName()); + sb.append(", user=").append(getUserName()); + // hidding password as the result of this method + // is probably going to end up in a stack trace + sb.append(", password=*****"); + sb.append(", version='").append(version == null ? "[DEFAULT]" : version).append("'"); + sb.append(", non-spatial:").append(allowNonSpatialTables); + sb.append(", minConnections=").append(getMinConnections()); + sb.append(", maxConnections=").append(getMaxConnections()); + sb.append(", connTimeOut=").append(getConnTimeOut()); + sb.append("]"); + + return sb.toString(); + } + +} Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSDEQuery.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSDEQuery.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSDEQuery.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -33,8 +33,9 @@ import org.geotools.arcsde.filter.FilterToSQLSDE; import org.geotools.arcsde.filter.GeometryEncoderException; import org.geotools.arcsde.filter.GeometryEncoderSDE; -import org.geotools.arcsde.pool.Command; -import org.geotools.arcsde.pool.ISession; +import org.geotools.arcsde.session.Command; +import org.geotools.arcsde.session.ISession; +import org.geotools.arcsde.session.SdeRow; import org.geotools.data.DataSourceException; import org.geotools.data.DataUtilities; import org.geotools.data.DefaultQuery; Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSdeFeatureSource.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSdeFeatureSource.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSdeFeatureSource.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -23,7 +23,7 @@ import java.util.logging.Logger; import org.geotools.arcsde.data.versioning.ArcSdeVersionHandler; -import org.geotools.arcsde.pool.ISession; +import org.geotools.arcsde.session.ISession; import org.geotools.data.DataSourceException; import org.geotools.data.DefaultQuery; import org.geotools.data.FeatureListener; Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSdeFeatureStore.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSdeFeatureStore.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSdeFeatureStore.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -21,8 +21,8 @@ import java.util.List; import java.util.logging.Logger; -import org.geotools.arcsde.pool.Command; -import org.geotools.arcsde.pool.ISession; +import org.geotools.arcsde.session.Command; +import org.geotools.arcsde.session.ISession; import org.geotools.data.DataSourceException; import org.geotools.data.FeatureReader; import org.geotools.data.FeatureStore; Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSdeFeatureWriter.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSdeFeatureWriter.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSdeFeatureWriter.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -31,8 +31,8 @@ import org.geotools.arcsde.ArcSdeException; import org.geotools.arcsde.data.versioning.ArcSdeVersionHandler; -import org.geotools.arcsde.pool.Command; -import org.geotools.arcsde.pool.ISession; +import org.geotools.arcsde.session.Command; +import org.geotools.arcsde.session.ISession; import org.geotools.data.DataSourceException; import org.geotools.data.FeatureListenerManager; import org.geotools.data.FeatureReader; Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcTransactionState.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcTransactionState.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcTransactionState.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -25,9 +25,8 @@ import org.geotools.arcsde.data.versioning.ArcSdeVersionHandler; import org.geotools.arcsde.data.versioning.TransactionVersionHandler; -import org.geotools.arcsde.pool.Command; -import org.geotools.arcsde.pool.ISession; -import org.geotools.arcsde.pool.SessionPool; +import org.geotools.arcsde.session.Command; +import org.geotools.arcsde.session.ISession; import org.geotools.data.FeatureListenerManager; import org.geotools.data.Transaction; import org.geotools.util.logging.Logging; @@ -52,12 +51,12 @@ private static final Logger LOGGER = Logging.getLogger(ArcTransactionState.class.getName()); /** - * ConnectionPool we can use to look up a Session for our Transaction. + * ArcSDEDataStore we can use to look up a Session for our Transaction. * <p> * The ConnectionPool will hold this connection open for us until commit(), rollback() or * close() is called. */ - private SessionPool pool; + private ArcSDEDataStore dataStore; private Transaction transaction; @@ -80,12 +79,12 @@ * Creates a new ArcTransactionState object. * * @param listenerManager - * @param pool + * @param arcSDEDataStore * connection pool where to grab a connection and hold it while there's a transaction * open (signaled by any use of {@link #getConnection()} */ - ArcTransactionState(SessionPool pool, final FeatureListenerManager listenerManager) { - this.pool = pool; + ArcTransactionState(ArcSDEDataStore dataStore, final FeatureListenerManager listenerManager) { + this.dataStore = dataStore; this.listenerManager = listenerManager; } @@ -241,7 +240,7 @@ * if the transaction state has been closed. */ private void failIfClosed() throws IllegalStateException { - if (pool == null) { + if (dataStore == null) { throw new IllegalStateException("This transaction state has already been closed"); } } @@ -250,10 +249,10 @@ * Releases resources and invalidates this state (signaled by setting the connection to null) */ private void close() { - if (pool == null) { + if (dataStore == null) { return; } - pool = null; + dataStore = null; } /** @@ -266,7 +265,7 @@ ISession getConnection() throws IOException { failIfClosed(); // the pool is keeping track of connection according to transaction for us - return pool.getSession(transaction); + return dataStore.getSession(transaction); } public Transaction getTransaction() { Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/AutoCommitFeatureWriter.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/AutoCommitFeatureWriter.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/AutoCommitFeatureWriter.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -20,7 +20,7 @@ import java.util.NoSuchElementException; import org.geotools.arcsde.data.versioning.ArcSdeVersionHandler; -import org.geotools.arcsde.pool.ISession; +import org.geotools.arcsde.session.ISession; import org.geotools.data.FeatureEvent; import org.geotools.data.FeatureListenerManager; import org.geotools.data.FeatureReader; Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/FIDReader.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/FIDReader.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/FIDReader.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -22,8 +22,9 @@ import java.util.List; import org.geotools.arcsde.ArcSdeException; -import org.geotools.arcsde.pool.Command; -import org.geotools.arcsde.pool.ISession; +import org.geotools.arcsde.session.Command; +import org.geotools.arcsde.session.ISession; +import org.geotools.arcsde.session.SdeRow; import org.opengis.feature.simple.SimpleFeatureType; import org.opengis.feature.type.AttributeDescriptor; Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/FeatureTypeInfoCache.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/FeatureTypeInfoCache.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/FeatureTypeInfoCache.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -33,11 +33,10 @@ import net.sf.jsqlparser.statement.select.PlainSelect; -import org.geotools.arcsde.pool.Command; -import org.geotools.arcsde.pool.ISession; -import org.geotools.arcsde.pool.SessionPool; +import org.geotools.arcsde.session.Command; +import org.geotools.arcsde.session.ISession; +import org.geotools.arcsde.session.ISessionPool; import org.geotools.data.DataSourceException; -import org.geotools.data.Transaction; import org.geotools.feature.NameImpl; import org.geotools.util.logging.Logging; import org.opengis.feature.type.FeatureType; @@ -87,7 +86,7 @@ */ private final Map<String, FeatureTypeInfo> inProcessFeatureTypeInfos; - private final SessionPool sessionPool; + private final ISessionPool sessionPool; /** * list of available featureclasses in the database. Does not contain in-process view type @@ -118,7 +117,7 @@ /** * Creates a FeatureTypeInfoCache * <p> - * The provided {@link SessionPool} is used to grab an {@link ISession} when the list of + * The provided {@link ISessionPool} is used to grab an {@link ISession} when the list of * available layers needs to be updated. This update happens at this class' construction time * and, optionally, every {@code cacheUpdateFreqSecs} seconds. * </p> @@ -132,7 +131,7 @@ * whether non spatial table names are requested * @throws IOException */ - public FeatureTypeInfoCache(final SessionPool sessionPool, final String namespace, + public FeatureTypeInfoCache(final ISessionPool sessionPool, final String namespace, final int cacheUpdateFreqSecs, boolean allowNonSpatialTables) throws IOException { availableLayerNames = new TreeSet<String>(); @@ -221,7 +220,7 @@ return typeInfo; } - ISession session = sessionPool.getSession(Transaction.AUTO_COMMIT); + ISession session = sessionPool.getSession(); try { typeInfo = getFeatureTypeInfo(typeName, session); } finally { @@ -340,7 +339,7 @@ private List<String> fetchRegistrations() throws Exception { final List<String> typeNames; - final ISession session = sessionPool.getSession(Transaction.AUTO_COMMIT); + final ISession session = sessionPool.getSession(); try { typeNames = session.issue(new FetchRegistrationsCommand(allowNonSpatialTables)); } finally { Deleted: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/SdeRow.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/SdeRow.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/SdeRow.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -1,241 +0,0 @@ -/* - * 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.arcsde.data; - -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.logging.Level; -import java.util.logging.Logger; - -import org.geotools.arcsde.ArcSdeException; -import org.geotools.util.logging.Logging; - -import com.esri.sde.sdk.client.SeColumnDefinition; -import com.esri.sde.sdk.client.SeException; -import com.esri.sde.sdk.client.SeRow; -import com.esri.sde.sdk.client.SeShape; -import com.esri.sde.sdk.geom.GeometryFactory; - -/** - * Wrapper for an SeRow so it allows asking multiple times for the same property. - * - * @author Gabriel Roldan, Axios Engineering - * @version $Id$ - * @source $URL: - * http://svn.geotools.org/geotools/trunk/gt/modules/plugin/arcsde/datastore/src/main/java - * /org/geotools/arcsde/data/SdeRow.java $ - * @since 2.4.0 - */ -public class SdeRow { - /** Logger for ths class' package */ - private static final Logger LOGGER = Logging.getLogger(SdeRow.class.getName()); - - /** cached SeRow values */ - private Object[] values; - - private int[] colStatusIndicator; - - private int nCols; - - /** - * A possible non set SDE geometry factory that provides the means for geometry fetching other - * than SeRow.getShape(). That is, if this geometryFactory is non null, it will be used to fetch - * the geometric attributes. Otherwise SeRow.getShape():SeShape will be used - */ - private GeometryFactory geometryFactory; - - private int geometryIndex = -1; - - public SdeRow(GeometryFactory geometryFactory) { - this.geometryFactory = geometryFactory; - } - - public SdeRow(SeRow row) throws IOException { - this(row, null); - } - - public SdeRow(SeRow row, GeometryFactory geometryFactory) throws IOException { - this.geometryFactory = geometryFactory; - setRow(row); - } - - public void setRow(SeRow row) throws IOException { - final int ncols = row.getNumColumns(); - if (this.nCols != ncols) { - this.nCols = ncols; - values = new Object[nCols]; - colStatusIndicator = new int[nCols]; - } - - int i = 0; - int statusIndicator = 0; - - try { - for (i = 0; i < nCols; i++) { - statusIndicator = row.getIndicator(i); - colStatusIndicator[i] = statusIndicator; - - if (statusIndicator == SeRow.SE_IS_ALREADY_FETCHED - || statusIndicator == SeRow.SE_IS_REPEATED_FEATURE - || statusIndicator == SeRow.SE_IS_NULL_VALUE) { - // ignore, will use previous values - } else { - if (this.geometryFactory != null && this.geometryIndex == i) { - values[i] = row.getGeometry(geometryFactory, i); - } else { - values[i] = row.getObject(i); - } - /* - * ML: I'm adding checks here for the [n] clob object that are returned as null - * by getObject, but are reported as Strings. We can suck those out of - * ByteArrayStreams - */ - if (values[i] == null) { - ByteArrayInputStream clobIn = null; - BufferedReader reader = null; - try { - int type = row.getColumnDef(i).getType(); - if (type == SeColumnDefinition.TYPE_NCLOB) { - clobIn = row.getNClob(i); - } else if (type == SeColumnDefinition.TYPE_CLOB) { - /* - * Warning! this line throws an NPE with the 9.2 java api, but works - * with the 9.3 jars - */ - clobIn = row.getClob(i); - } - if (clobIn != null) { - reader = new BufferedReader(new InputStreamReader(clobIn, "UTF-16")); - StringBuffer buf = new StringBuffer(); - String snip = reader.readLine(); - while (snip != null) { - if (buf.length() != 0) - buf.append('\n'); - buf.append(snip); - snip = reader.readLine(); - } - if (buf.length() > 0) - values[i] = buf.toString(); - } - } catch (IOException e) { - LOGGER.log(Level.FINEST, - "Issue decoding CLOB/NCLOB into a String:" + e, e); - // value will remain null - } finally { - if (reader != null) { - try { - reader.close(); - } catch (IOException ignore) { - LOGGER.log(Level.FINEST, "Issue cleaning up after CLOB/NCLOB:" - + ignore, ignore); - } - } - } - } - } - } - } catch (SeException e) { - throw new ArcSdeException("getting property #" + i, e); - } - } - - public void setPreviousValues(Object[] previousValues) { - int statusIndicator; - for (int i = 0; i < nCols; i++) { - statusIndicator = colStatusIndicator[i]; - - if (statusIndicator == SeRow.SE_IS_ALREADY_FETCHED - || statusIndicator == SeRow.SE_IS_REPEATED_FEATURE) { - values[i] = previousValues[i]; - } - } - } - - /** - * DOCUMENT ME! - * - * @param index - * DOCUMENT ME! - * @return DOCUMENT ME! - * @throws IOException - * DOCUMENT ME! - */ - public Object getObject(int index) throws IOException { - return values[index]; - } - - /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! - */ - public Object[] getAll() { - return values; - } - - /** - * DOCUMENT ME! - * - * @param index - * DOCUMENT ME! - * @return DOCUMENT ME! - * @throws IOException - * DOCUMENT ME! - */ - public Long getLong(int index) throws IOException { - return (Long) getObject(index); - } - - /** - * DOCUMENT ME! - * - * @param index - * DOCUMENT ME! - * @return DOCUMENT ME! - * @throws IOException - * DOCUMENT ME! - */ - public SeShape getShape(int index) throws IOException { - return (SeShape) getObject(index); - } - - /** - * @param columnIndex - * @return one of {@link SeRow#SE_IS_ALREADY_FETCHED}, {@link SeRow#SE_IS_NOT_NULL_VALUE}, - * {@link SeRow#SE_IS_NULL_VALUE}, {@link SeRow#SE_IS_REPEATED_FEATURE} - */ - public int getIndicator(int columnIndex) { - return colStatusIndicator[columnIndex]; - } - - public Integer getInteger(int index) throws IOException { - return (Integer) getObject(index); - } - - /** - * @param geometryIndex - * a value >= 0 indicates which index in the row contains the geometry attribute. If - * not set, geometryFactory will be ignored - */ - public void setGeometryIndex(int geometryIndex) { - this.geometryIndex = geometryIndex; - } - -} Copied: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/SessionTransactionState.java (from rev 33502, trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/SessionTransactionState.java) =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/SessionTransactionState.java (rev 0) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/SessionTransactionState.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -0,0 +1,320 @@ +/* + * 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.arcsde.data; + +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.geotools.arcsde.session.Command; +import org.geotools.arcsde.session.ISession; +import org.geotools.arcsde.session.ISessionPool; +import org.geotools.arcsde.session.SessionWrapper; +import org.geotools.arcsde.session.UnavailableArcSDEConnectionException; +import org.geotools.data.DataSourceException; +import org.geotools.data.Transaction; + +import com.esri.sde.sdk.client.SeConnection; +import com.esri.sde.sdk.client.SeException; + +/** + * Store the transaction state needed for a <code>Session</code> instances. + * <p> + * This transaction state is used to hold the SeConnection needed for a Session. + * </p> + * + * @author Jake Fear + * @author Gabriel Roldan + * @source $URL: + * http://svn.geotools.org/geotools/trunk/gt/modules/plugin/arcsde/datastore/src/main/java + * /org/geotools/arcsde/data/ArcTransactionState.java $ + * @version $Id$ + */ +final class SessionTransactionState implements Transaction.State { + private static final Logger LOGGER = org.geotools.util.logging.Logging + .getLogger(SessionTransactionState.class.getPackage().getName()); + + /** + * The session being managed, it will be held open until commit(), rollback() or close() is + * called. + */ + private TransactionSession session; + + /** + * The transaction that is holding on to this Transaction.State + */ + private Transaction transaction; + + /** + * Creates a new ArcTransactionState object. + * + * @param listenerManager + * @param pool + * connection pool where to grab a connection and hold it while there's a transaction + * open (signaled by any use of {@link #getConnection()} + */ + private SessionTransactionState(final ISession session) { + if (!session.isTransactionActive()) { + throw new IllegalArgumentException("session shall be in transactional mode"); + } + this.session = new TransactionSession(session); + } + + /** + * Commits the transaction and returns the connection to the pool. A new one will be grabbed + * when needed. + * <p> + * Preconditions: + * <ul> + * <li>{@link #setTransaction(Transaction)} already called with non <code>null</code> argument. + * <li> + * </ul> + * </p> + */ + public void commit() throws IOException { + failIfClosed(); + final ISession session = this.session; + + final Command<Void> commitCommand = new Command<Void>() { + @Override + public Void execute(ISession session, SeConnection connection) throws SeException, + IOException { + + try { + session.commitTransaction(); + session.startTransaction(); + } catch (IOException se) { + LOGGER.log(Level.WARNING, se.getMessage(), se); + throw se; + } + return null; + } + }; + + try { + session.issue(commitCommand); + } catch (IOException e) { + throw e; + } + } + + /** + * + */ + public void rollback() throws IOException { + failIfClosed(); + final ISession session = this.session; + try { + session.issue(new Command<Void>() { + @Override + public Void execute(ISession session, SeConnection connection) throws SeException, + IOException { + session.rollbackTransaction(); + // and keep editing + session.startTransaction(); + return null; + } + }); + } catch (IOException se) { + close(); + LOGGER.log(Level.WARNING, se.getMessage(), se); + throw se; + } + } + + /** + * + */ + public void addAuthorization(String authId) { + // intentionally blank we are not making use of ArcSDE locking + } + + /** + * Transaction start/end. + * <p> + * If the provided transaction is non null we are being added to the Transaction. If the + * provided transaction is null we are being shutdown. + * </p> + * + * @see Transaction.State#setTransaction(Transaction) + * @param transaction + * transaction information, <code>null</code> signals this state lifecycle end. + * @throws IllegalStateException + * if close() is called while a transaction is in progress + */ + public void setTransaction(final Transaction transaction) { + if (Transaction.AUTO_COMMIT.equals(transaction)) { + throw new IllegalArgumentException("Cannot use Transaction.AUTO_COMMIT here"); + } + if (transaction == null) { + // this is a call to free resources (ugly, but that's what the API says) + close(); + } else if (this.transaction != null) { + // assert this assumption + throw new IllegalStateException( + "Once a transaction is set, it is " + + "illegal to call Transaction.State.setTransaction with anything other than null: " + + transaction); + } + this.transaction = transaction; + } + + /** + * If this state has been closed throws an unchecked exception as its clearly a broken workflow. + * + * @throws IllegalStateException + * if the transaction state has been closed. + */ + private void failIfClosed() throws IllegalStateException { + if (session == null) { + throw new IllegalStateException("This transaction state has already been closed"); + } + } + + /** + * Releases resources and invalidates this state (signaled by setting the connection to null) + */ + private void close() { + if (session == null) { + return; + } + // can't even try to use this state in any way from now on + // may throw ISE if transaction is still in progress + try { + // release current transaction before returning the + // connection to the pool + try { + session.rollbackTransaction(); + // connection.setConcurrency(SeConnection.SE_UNPROTECTED_POLICY); + } catch (IOException e) { + // TODO: this shouldn't happen, but if it does + // we should somehow invalidate the connection? + LOGGER.log(Level.SEVERE, "Unexpected exception at close(): " + e.getMessage(), e); + } + // now its safe to return it to the pool + session.dispose(); + } catch (IllegalStateException workflowError) { + // fail fast but put the connection in a healthy state first + try { + session.rollbackTransaction(); + } catch (IOException e) { + // well, it's totally messed up, just log though + LOGGER.log(Level.SEVERE, "rolling back connection " + session, e); + session.dispose(); + } + throw workflowError; + } finally { + session = null; + } + } + + /** + * Used only within the package to provide access to a single connection on which this + * transaction is being conducted. + * + * @return connection + * @throws UnavailableArcSDEConnectionException + * @throws DataSourceException + * @throws SeException + */ + ISession getConnection() throws DataSourceException, UnavailableArcSDEConnectionException { + failIfClosed(); + return session; + } + + public Transaction getTransaction() { + return transaction; + } + + /** + * Grab the SessionTransactionState (when not using AUTO_COMMIT). + * <p> + * As of GeoTools 2.5 we store the TransactionState using the connection pool as a key. + * </p> + * + * @return the SessionTransactionState stored in the transaction with + * <code>connectionPool</code> as key. + */ + public static SessionTransactionState getState(final Transaction transaction, + final ISessionPool pool) throws IOException { + SessionTransactionState state; + + if (transaction == Transaction.AUTO_COMMIT) { + LOGGER.log(Level.SEVERE, + "Should not request ArcTransactionState when using AUTO_COMMITback connection"); + return null; + } + + synchronized (SessionTransactionState.class) { + state = (SessionTransactionState) transaction.getState(pool); + if (state == null) { + // start a transaction + final ISession session = pool.getSession(); + try { + session.startTransaction(); + } catch (IOException e) { + try { + session.rollbackTransaction(); + } finally { + session.dispose(); + } + throw new DataSourceException("Exception initiating transaction on " + session, + e); + } + state = new SessionTransactionState(session); + transaction.putState(pool, state); + } + } + return state; + } + + /** + * A session wrapper that does not disposes if a transaction is active. + * <p> + * This wrapper provides for client code to follow de acquire/use/dispose workflow without + * worrying if it should or should not actually dispose the session depending on a transaction + * being in progress or not. + * </p> + * + * @author Gabriel Roldan (TOPP) + * @version $Id$ + * @since 2.5.x + * @source $URL: + * http://svn.geotools.org/trunk/modules/plugin/arcsde/datastore/src/main/java/org/ + * geotools/arcsde/pool/SessionTransactionState.java $ + */ + private static final class TransactionSession extends SessionWrapper { + + public TransactionSession(final ISession session) { + super(session); + } + + /** + * Does not returns the session to the pool while a transaction is active. + */ + @Override + public void dispose() throws IllegalStateException { + if (isTransactionActive()) { + LOGGER.finer("Ignoring Session.close, transaction is active..."); + } else { + wrapped.dispose(); + } + } + } + +} Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/versioning/ArcSdeVersionHandler.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/versioning/ArcSdeVersionHandler.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/versioning/ArcSdeVersionHandler.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -18,7 +18,7 @@ import java.io.IOException; -import org.geotools.arcsde.pool.ISession; +import org.geotools.arcsde.session.ISession; import com.esri.sde.sdk.client.SeStreamOp; Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/versioning/AutoCommitVersionHandler.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/versioning/AutoCommitVersionHandler.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/versioning/AutoCommitVersionHandler.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -20,9 +20,9 @@ import java.util.logging.Level; import java.util.logging.Logger; -import org.geotools.arcsde.pool.Command; -import org.geotools.arcsde.pool.ISession; -import org.geotools.arcsde.pool.Commands.GetVersionCommand; +import org.geotools.arcsde.session.Command; +import org.geotools.arcsde.session.ISession; +import org.geotools.arcsde.session.Commands.GetVersionCommand; import org.geotools.util.logging.Logging; import com.esri.sde.sdk.client.SeConnection; Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/versioning/TransactionVersionHandler.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/versioning/TransactionVersionHandler.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/versioning/TransactionVersionHandler.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -21,9 +21,9 @@ import java.util.logging.Logger; import org.geotools.arcsde.ArcSdeException; -import org.geotools.arcsde.pool.Command; -import org.geotools.arcsde.pool.ISession; -import org.geotools.arcsde.pool.Commands.GetVersionCommand; +import org.geotools.arcsde.session.Command; +import org.geotools.arcsde.session.ISession; +import org.geotools.arcsde.session.Commands.GetVersionCommand; import org.geotools.util.logging.Logging; import com.esri.sde.sdk.client.SeConnection; Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/view/ColumnQualifier.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/view/ColumnQualifier.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/view/ColumnQualifier.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -22,7 +22,7 @@ import net.sf.jsqlparser.schema.Column; import net.sf.jsqlparser.schema.Table; -import org.geotools.arcsde.pool.ISession; +import org.geotools.arcsde.session.ISession; /** * Qualifies a column name with the ArcSDE "table.user." prefix as required by the ArcSDE java api Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/view/ColumnReferenceQualifier.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/view/ColumnReferenceQualifier.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/view/ColumnReferenceQualifier.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -24,7 +24,7 @@ import net.sf.jsqlparser.statement.select.ColumnReference; import net.sf.jsqlparser.statement.select.ColumnReferenceVisitor; -import org.geotools.arcsde.pool.ISession; +import org.geotools.arcsde.session.ISession; /** * Qualifies a column reference (aliased) the ArcSDE "table.user." prefix as required by the ArcSDE Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/view/ExpressionQualifier.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/view/ExpressionQualifier.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/view/ExpressionQualifier.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -59,7 +59,7 @@ import net.sf.jsqlparser.schema.Column; import net.sf.jsqlparser.statement.select.SubSelect; -import org.geotools.arcsde.pool.ISession; +import org.geotools.arcsde.session.ISession; /** * Qualifies the column references (aliased or not) the ArcSDE "table.user." prefix as required by Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/view/FromItemQualifier.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/view/FromItemQualifier.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/view/FromItemQualifier.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -22,7 +22,7 @@ import net.sf.jsqlparser.statement.select.FromItemVisitor; import net.sf.jsqlparser.statement.select.SubSelect; -import org.geotools.arcsde.pool.ISession; +import org.geotools.arcsde.session.ISession; /** * Fully qualifies a table names. Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/view/ItemsListQualifier.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/view/ItemsListQualifier.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/view/ItemsListQualifier.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -28,7 +28,7 @@ import net.sf.jsqlparser.expression.operators.relational.ItemsListVisitor; import net.sf.jsqlparser.statement.select.SubSelect; -import org.geotools.arcsde.pool.ISession; +import org.geotools.arcsde.session.ISession; /** * Seems to visit a list and update the entries and fill in the blanks qualifying them. Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/view/OrderByElementQualifier.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/view/OrderByElementQualifier.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/view/OrderByElementQualifier.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -23,7 +23,7 @@ import net.sf.jsqlparser.statement.select.OrderByElement; import net.sf.jsqlparser.statement.select.OrderByVisitor; -import org.geotools.arcsde.pool.ISession; +import org.geotools.arcsde.session.ISession; /** * Qualifies a column reference in an order by clause Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/view/QueryInfoParser.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/view/QueryInfoParser.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/view/QueryInfoParser.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -33,7 +33,7 @@ import net.sf.jsqlparser.statement.select.SelectExpressionItem; import net.sf.jsqlparser.statement.select.SelectItem; -import org.geotools.arcsde.pool.ISession; +import org.geotools.arcsde.session.ISession; import com.esri.sde.sdk.client.SeColumnDefinition; import com.esri.sde.sdk.client.SeException; Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/view/SelectItemQualifier.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/view/SelectItemQualifier.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/view/SelectItemQualifier.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -31,7 +31,7 @@ import net.sf.jsqlparser.statement.select.SelectExpressionItem; import net.sf.jsqlparser.statement.select.SelectItem; -import org.geotools.arcsde.pool.ISession; +import org.geotools.arcsde.session.ISession; import com.esri.sde.sdk.client.SeColumnDefinition; Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/view/SelectQualifier.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/view/SelectQualifier.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/view/SelectQualifier.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -31,7 +31,7 @@ import net.sf.jsqlparser.statement.select.SelectItem; import net.sf.jsqlparser.statement.select.Union; -import org.geotools.arcsde.pool.ISession; +import org.geotools.arcsde.session.ISession; /** * Visitor on a PlainSelect that produces another one but with all the table names and field names Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/view/SubSelectQualifier.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/view/SubSelectQualifier.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/view/SubSelectQualifier.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -21,7 +21,7 @@ import net.sf.jsqlparser.statement.select.SelectBody; import net.sf.jsqlparser.statement.select.SubSelect; -import org.geotools.arcsde.pool.ISession; +import org.geotools.arcsde.session.ISession; /** * Qualifies a column reference in a subselect clause. Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/view/TableQualifier.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/view/TableQualifier.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/view/TableQualifier.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -21,7 +21,7 @@ import net.sf.jsqlparser.schema.Table; -import org.geotools.arcsde.pool.ISession; +import org.geotools.arcsde.session.ISession; /** * Utility used to qualify table names Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/ArcSDEGridCoverage2DReaderJAI.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/ArcSDEGridCoverage2DReaderJAI.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/ArcSDEGridCoverage2DReaderJAI.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -53,8 +53,8 @@ import javax.media.jai.operator.MosaicDescriptor; import org.geotools.arcsde.ArcSdeException; -import org.geotools.arcsde.pool.ArcSDEConnectionPool; -import org.geotools.arcsde.pool.ArcSDEPooledConnection; +import org.geotools.arcsde.session.ArcSDEConnectionPool; +import org.geotools.arcsde.session.ArcSDEPooledConnection; import org.geotools.coverage.CoverageFactoryFinder; import org.geotools.coverage.GridSampleDimension; import org.geotools.coverage.TypeMap; Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/ArcSDERasterFormat.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/ArcSDERasterFormat.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/ArcSDERasterFormat.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -17,13 +17,13 @@ */ package org.geotools.arcsde.gce; -import static org.geotools.arcsde.pool.ArcSDEConnectionConfig.DBTYPE_PARAM; -import static org.geotools.arcsde.pool.ArcSDEConnectionConfig.DBTYPE_PARAM_VALUE; -import static org.geotools.arcsde.pool.ArcSDEConnectionConfig.INSTANCE_NAME_PARAM; -import static org.geotools.arcsde.pool.ArcSDEConnectionConfig.PASSWORD_PARAM; -import static org.geotools.arcsde.pool.ArcSDEConnectionConfig.PORT_NUMBER_PARAM; -import static org.geotools.arcsde.pool.ArcSDEConnectionConfig.SERVER_NAME_PARAM; -import static org.geotools.arcsde.pool.ArcSDEConnectionConfig.USER_NAME_PARAM; +import static org.geotools.arcsde.data.ArcSDEDataStoreConfig.DBTYPE_PARAM_NAME; +import static org.geotools.arcsde.data.ArcSDEDataStoreConfig.DBTYPE_PARAM_VALUE; +import static org.geotools.arcsde.session.ArcSDEConnectionConfig.INSTANCE_NAME_PARAM_NAME; +import static org.geotools.arcsde.session.ArcSDEConnectionConfig.PASSWORD_PARAM_NAME; +import static org.geotools.arcsde.session.ArcSDEConnectionConfig.PORT_NUMBER_PARAM_NAME; +import static org.geotools.arcsde.session.ArcSDEConnectionConfig.SERVER_NAME_PARAM_NAME; +import static org.geotools.arcsde.session.ArcSDEConnectionConfig.USER_NAME_PARAM_NAME; import java.awt.geom.Point2D; import java.awt.image.DataBuffer; @@ -45,11 +45,12 @@ import java.util.logging.Logger; import org.geotools.arcsde.ArcSdeException; -import org.geotools.arcsde.pool.ArcSDEConnectionConfig; -import org.geotools.arcsde.pool.ArcSDEConnectionPool; -import org.geotools.arcsde.pool.ArcSDEConnectionPoolFactory; -import org.geotools.arcsde.pool.ArcSDEPooledConnection; -import org.geotools.arcsde.pool.UnavailableArcSDEConnectionException; +import org.geotools.arcsde.data.ArcSDEDataStoreConfig; +import org.geotools.arcsde.session.ArcSDEConnectionConfig; +import org.geotools.arcsde.session.ArcSDEConnectionPool; +import org.geotools.arcsde.session.ArcSDEConnectionPoolFactory; +import org.geotools.arcsde.session.ArcSDEPooledConnection; +import org.geotools.arcsde.session.UnavailableArcSDEConnectionException; import org.geotools.arcsde.util.ArcSDEUtils; import org.geotools.coverage.grid.io.AbstractGridCoverage2DReader; import org.geotools.coverage.grid.io.AbstractGridFormat; @@ -106,7 +107,7 @@ */ private static final Map<String, RasterDatasetInfo> rasterInfos = new WeakHashMap<String, RasterDatasetInfo>(); - private static final Map<String, ArcSDEConnectionConfig> connectionConfigs = new WeakHashMap<String, ArcSDEConnectionConfig>(); + private static final Map<String, ArcSDEDataStoreConfig> connectionConfigs = new WeakHashMap<String, ArcSDEDataStoreConfig>(); private static final ArcSDERasterFormat instance = new ArcSDERasterFormat(); @@ -209,7 +210,7 @@ } private ArcSDEConnectionConfig getConnectionConfig(final String coverageUrl) { - ArcSDEConnectionConfig sdeConfig; + ArcSDEDataStoreConfig sdeConfig; sdeConfig = connectionConfigs.get(coverageUrl); if (sdeConfig == null) { synchronized (connectionConfigs) { @@ -220,7 +221,7 @@ } } } - return sdeConfig; + return sdeConfig.getSessionConfig(); } /** @@ -361,7 +362,7 @@ * 'sde://user:pass@sdehost:[port]/[dbname] * @return a ConnectionConfig object representing these parameters */ - static ArcSDEConnectionConfig sdeURLToConnectionConfig(StringBuffer sdeUrl) { + static ArcSDEDataStoreConfig sdeURLToConnectionConfig(StringBuffer sdeUrl) { // annoyingly, geoserver currently stores the user-entered SDE string as // a File, and passes us the // File object. The File object strips the 'sde://user...' into a @@ -430,14 +431,14 @@ sdeUrl.delete(0, idx); Map<String, String> params = new HashMap<String, String>(); - params.put(DBTYPE_PARAM, DBTYPE_PARAM_VALUE); - params.put(SERVER_NAME_PARAM, sdeHost); - params.put(PORT_NUMBER_PARAM, String.valueOf(sdePort)); - params.put(INSTANCE_NAME_PARAM, sdeDBName); - params.put(USER_NAME_PARAM, sdeUser); - params.put(PASSWORD_PARAM, sdePass); + params.put(DBTYPE_PARAM_NAME, DBTYPE_PARAM_VALUE); + params.put(SERVER_NAME_PARAM_NAME, sdeHost); + params.put(PORT_NUMBER_PARAM_NAME, String.valueOf(sdePort)); + params.put(INSTANCE_NAME_PARAM_NAME, sdeDBName); + params.put(USER_NAME_PARAM_NAME, sdeUser); + params.put(PASSWORD_PARAM_NAME, sdePass); - return new ArcSDEConnectionConfig(params); + return new ArcSDEDataStoreConfig(params); } /** Deleted: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionPool.java =================================================================== --- trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionPool.java 2009-07-07 01:13:56 UTC (rev 33502) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionPool.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -1,451 +0,0 @@ -/* - * 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.arcsde.session; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.NoSuchElementException; -import java.util.logging.Level; -import java.util.logging.Logger; - -import org.apache.commons.pool.BasePoolableObjectFactory; -import org.apache.commons.pool.ObjectPool; -import org.apache.commons.pool.impl.GenericObjectPool; -import org.geotools.arcsde.ArcSdeException; -import org.geotools.data.DataSourceException; - -import com.esri.sde.sdk.client.SeConnection; -import com.esri.sde.sdk.client.SeException; -import com.esri.sde.sdk.client.SeLayer; -import com.esri.sde.sdk.client.SeRelease; - -/** - * Maintains <code>SeConnection</code>'s for a single set of connection properties (for instance: by - * server, port, user and password) in a pooled way - * - * <p> - * Since sde connections are not jdbc connections, I can't use Sean's excellent connection pool. So - * I'll borrow most of it. - * </p> - * - * <p> - * This connection pool is configurable in the sense that some parameters can be passed to establish - * the pooling policy. To pass parameters to the connection pool, you should set some properties in - * the parameters Map passed to SdeDataStoreFactory.createDataStore, wich will invoke - * SdeConnectionPoolFactory to get the SDE instance's pool singleton. That instance singleton will - * be created with the preferences passed the first time createDataStore is called for a given SDE - * instance/user, if subsecuent calls change that preferences, they will be ignored. - * </p> - * - * <p> - * The expected optional parameters that you can set up in the argument Map for createDataStore are: - * - * <ul> - * <li>pool.minConnections Integer, tells the minimun number of open connections the pool will - * maintain opened</li> - * <li>pool.maxConnections Integer, tells the maximun number of open connections the pool will - * create and maintain opened</li> - * <li>pool.timeOut Integer, tells how many milliseconds a calling thread is guaranteed to wait - * before getConnection() throws an UnavailableArcSDEConnectionException</li> - * </ul> - * </p> - * - * @author Gabriel Roldan, Axios Engineering - * @version $Id$ - * @deprecated still here waiting for gce to switch to {@link SessionPool} - */ -@SuppressWarnings("unchecked") -public class ArcSDEConnectionPool { - /** package's logger */ - private static final Logger LOGGER = org.geotools.util.logging.Logging - .getLogger("org.geotools.arcsde.pool"); - - /** DOCUMENT ME! */ - protected static final Level INFO_LOG_LEVEL = Level.WARNING; - - /** default number of connections a pool creates at first population */ - public static final int DEFAULT_CONNECTIONS = 2; - - /** default number of maximun allowable connections a pool can hold */ - public static final int DEFAULT_MAX_CONNECTIONS = 6; - - public static final int DEFAULT_MAX_WAIT_TIME = 500; - - /** DOCUMENT ME! */ - private SeConnectionFactory seConnectionFactory; - - /** this connection pool connection's parameters */ - private ArcSDEConnectionConfig config; - - /** Apache commons-pool used to pool arcsde connections */ - private ObjectPool pool; - - /** - * Creates a new SdeConnectionPool object with the connection parameters holded by - * <code>config</code> - * - * @param config - * holds connection options such as server, user and password, as well as tuning - * options as maximun number of connections allowed - * - * @throws DataSourceException - * DOCUMENT ME! - * @throws NullPointerException - * DOCUMENT ME! - */ - protected ArcSDEConnectionPool(ArcSDEConnectionConfig config) throws DataSourceException { - if (config == null) { - throw new NullPointerException("parameter config can't be null"); - } - - this.config = config; - LOGGER.fine("populating ArcSDE connection pool"); - - this.seConnectionFactory = new SeConnectionFactory(this.config); - - int minConnections = config.getMinConnections().intValue(); - int maxConnections = config.getMaxConnections().intValue(); - // byte exhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_GROW; - byte exhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_BLOCK; - long maxWait = config.getConnTimeOut().longValue(); - - this.pool = new GenericObjectPool(seConnectionFactory, maxConnections, exhaustedAction, - maxWait, true, true); - LOGGER.info("Created ArcSDE connection pool for " + config); - - ArcSDEPooledConnection[] preload = new ArcSDEPooledConnection[minConnections]; - - try { - for (int i = 0; i < minConnections; i++) { - preload[i] = (ArcSDEPooledConnection) this.pool.borrowObject(); - if (i == 0) { - SeRelease seRelease = preload[i].getRelease(); - String sdeDesc = seRelease.getDesc(); - int major = seRelease.getMajor(); - int minor = seRelease.getMinor(); - int bugFix = seRelease.getBugFix(); - String desc = "ArcSDE " + major + "." + minor + "." + bugFix + " " + sdeDesc; - LOGGER.info("Connected to " + desc); - } - } - - for (int i = 0; i < minConnections; i++) { - this.pool.returnObject(preload[i]); - } - } catch (Exception e) { - LOGGER.log(Level.WARNING, "can't connect to " + config, e); - throw new DataSourceException(e); - } - } - - /** - * returns the number of actual connections holded by this connection pool. In other words, the - * sum of used and available connections, regardless - * - * @return DOCUMENT ME! - */ - public int getPoolSize() { - synchronized (this.pool) { - return this.pool.getNumActive() + this.pool.getNumIdle(); - } - } - - /** - * closes all connections in this pool - */ - public void close() { - if (pool != null) { - try { - this.pool.close(); - pool = null; - LOGGER.fine("SDE connection pool closed. "); - } catch (Exception e) { - LOGGER.log(Level.WARNING, "Closing pool: " + e.getMessage(), e); - } - } - } - - public boolean isClosed() { - return pool == null; - } - - /** - * Ensures proper closure of connection pool at this object's finalization stage. - */ - // //@Override - protected void finalize() { - close(); - } - - /** - * TODO: Document this method! - * - * @return DOCUMENT ME! - */ - public synchronized int getAvailableCount() { - return this.pool.getNumIdle(); - } - - /** - * TODO: Document this method! - * - * @return DOCUMENT ME! - */ - public synchronized int getInUseCount() { - return this.pool.getNumActive(); - } - - /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! - * - * @throws DataSourceException - * DOCUMENT ME! - * @throws UnavailableArcSDEConnectionException - * @throws IllegalStateException - * DOCUMENT ME! - */ - public ArcSDEPooledConnection getConnection() throws DataSourceException, - UnavailableArcSDEConnectionException { - if (pool == null) { - throw new IllegalStateException("The ConnectionPool has been closed."); - } - - try { - // String caller = null; - // if (LOGGER.isLoggable(Level.FINER)) { - // StackTraceElement[] stackTrace = - // Thread.currentThread().getStackTrace(); - // caller = stackTrace[3].getClassName() + "." + - // stackTrace[3].getMethodName(); - // } - - ArcSDEPooledConnection connection = (ArcSDEPooledConnection) this.pool.borrowObject(); - - if (LOGGER.isLoggable(Level.FINER)) { - // System.err.println("-> " + caller + " got " + connection); - LOGGER.finer(connection + " out of connection pool"); - } - - connection.markActive(); - return connection; - } catch (NoSuchElementException e) { - LOGGER.log(Level.WARNING, "Out of connections: " + e.getMessage(), e); - throw new UnavailableArcSDEConnectionException(this.pool.getNumActive(), this.config); - } catch (SeException se) { - LOGGER.log(Level.WARNING, "ArcSDE error getting connection: " - + se.getSeError().getErrDesc(), se); - throw new DataSourceException("ArcSDE Error Message: " + se.getSeError().getErrDesc(), - se); - } catch (Exception e) { - LOGGER.log(Level.WARNING, "Unknown problem getting connection: " + e.getMessage(), e); - throw new DataSourceException( - "Unknown problem fetching connection from connection pool", e); - } - } - - /** - * Sometimes (and largely without reason) ArcSDEPooledConnections (really their underlying - * SeConnection objects) just poop out. They start behaving strangely, or not behaving at all. - * You can tell the pool that a particular SeConnection has 'Failed' using this method, and it - * will do its best to get it out of the pool as soon as you release your hold on it. - * - * @param conn - */ - public synchronized void markConnectionAsFailed(ArcSDEPooledConnection conn) { - LOGGER.warning("ArcSDE connection '" + conn - + "' has been marked as failed. Current pool state is " + getAvailableCount() - + " avail/" + this.getPoolSize() + " total"); - seConnectionFactory.markObjectInvalid(conn); - } - - /** - * Gets the list of available layer names on the database - * - * @return a <code>List<String></code> with the registered featureclasses on the ArcSDE - * database - * - * @throws DataSourceException - */ - // //@SuppressWarnings("unchecked") - public List/* <String> */getAvailableLayerNames() throws DataSourceException { - ArcSDEPooledConnection conn = null; - - List/* <String> */layerNames = new LinkedList/* <String> */(); - try { - conn = getConnection(); - for (Iterator/* <SeLayer> */it = conn.getLayers().iterator(); it.hasNext();) { - layerNames.add(((SeLayer) it.next()).getQualifiedName()); - } - } catch (SeException ex) { - throw new DataSourceException("Error querying the layers list" - + ex.getSeError().getSdeError() + " (" + ex.getSeError().getErrDesc() + ") ", - ex); - } catch (UnavailableArcSDEConnectionException ex) { - throw new DataSourceException("No free connection found to query the layers list", ex); - } finally { - if (conn != null) - conn.close(); - } - return layerNames; - } - - /** - * DOCUMENT ME! - * - * @return DOCUMENT ME! - */ - public ArcSDEConnectionConfig getConfig() { - return this.config; - } - - /** - * PoolableObjectFactory intended to be used by a Jakarta's commons-pool objects pool, that - * provides ArcSDE's SeConnections. - * - * @author Gabriel Roldan, Axios Engineering - * @version $Id$ - */ - class SeConnectionFactory extends BasePoolableObjectFactory { - /** DOCUMENT ME! */ - private ArcSDEConnectionConfig config; - - private List/* <SeConnection> */invalidConnections = new ArrayList/* <SeConnection> */(2); - - /** - * Creates a new SeConnectionFactory object. - * - * @param config - * DOCUMENT ME! - */ - public SeConnectionFactory(ArcSDEConnectionConfig config) { - super(); - this.config = config; - } - - public void markObjectInvalid(Object o) { - invalidConnections.add((SeConnection) o); - } - - /** - * Called whenever a new instance is needed. - * - * @return a newly created <code>SeConnection</code> - * - * @throws SeException - * if the connection can't be created - */ - // //@Override - public Object makeObject() throws IOException { - NegativeArraySizeException cause = null; - for (int i = 0; i < 3; i++) { - try { - ArcSDEPooledConnection seConn = new ArcSDEPooledConnection( - ArcSDEConnectionPool.this.pool, config); - return seConn; - } catch (NegativeArraySizeException nase) { - LOGGER.warning("Strange failed ArcSDE connection error. Trying again (try " - + (i + 1) + " of 3)"); - cause = nase; - } catch (SeException e) { - throw new ArcSdeException(e); - } - } - throw new DataSourceException( - "Couldn't create ArcSDEPooledConnection because of strange SDE internal exception. Tried 3 times, giving up.", - cause); - } - - /** - * is invoked on every instance before it is returned from the pool. - * - * @param obj - */ - // //@Override - public void activateObject(Object obj) { - final ArcSDEPooledConnection conn = (ArcSDEPooledConnection) obj; - conn.markActive(); - LOGGER.finest("activating connection " + obj); - } - - // //@Override - public void passivateObject(Object obj) { - LOGGER.finest("passivating connection " + obj); - final ArcSDEPooledConnection conn = (ArcSDEPooledConnection) obj; - conn.markInactive(); - } - - /** - * is invoked in an implementation-specific fashion to determine if an instance is still - * valid to be returned by the pool. It will only be invoked on an "activated" instance. - * - * @param an - * instance of {@link ArcSDEPooledConnection} maintained by this pool. - * - * @return <code>true</code> if the connection is still alive and operative (checked by - * asking its user name), <code>false</code> otherwise. - */ - // //@Override - public boolean validateObject(Object obj) { - ArcSDEPooledConnection conn = (ArcSDEPooledConnection) obj; - boolean valid = !conn.isClosed(); - // MAKE PROPER VALIDITY CHECK HERE as for GEOT-1273 - if (valid) { - if (invalidConnections.contains(obj)) - valid = false; - - try { - LOGGER.finest("Validating SDE Connection"); - String user = conn.getUser(); - LOGGER.finer("Connection validated, returned user " + user); - } catch (SeException e) { - LOGGER.info("Can't validate SeConnection, discarding it: " + conn); - valid = false; - } - } - return valid; - } - - /** - * is invoked on every instance when it is being "dropped" from the pool (whether due to the - * response from validateObject, or for reasons specific to the pool implementation.) - * - * @param obj - * an instance of {@link ArcSDEPooledConnection} maintained by this pool. - */ - // //@Override - public void destroyObject(Object obj) { - ArcSDEPooledConnection conn = (ArcSDEPooledConnection) obj; - conn.destroy(); - } - } - - // //@Override - public String toString() { - StringBuffer ret = new StringBuffer(); - ret.append("[ACTIVE: "); - ret.append(pool.getNumActive() + "/" + ((GenericObjectPool) pool).getMaxActive()); - ret.append(" INACTIVE: "); - ret.append(pool.getNumIdle() + "/" + ((GenericObjectPool) pool).getMaxIdle() + "]"); - return ret.toString(); - } -} \ No newline at end of file Copied: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionPool.java (from rev 33502, trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionPool.java) =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionPool.java (rev 0) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionPool.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -0,0 +1,451 @@ +/* + * 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.arcsde.session; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.apache.commons.pool.BasePoolableObjectFactory; +import org.apache.commons.pool.ObjectPool; +import org.apache.commons.pool.impl.GenericObjectPool; +import org.geotools.arcsde.ArcSdeException; +import org.geotools.data.DataSourceException; + +import com.esri.sde.sdk.client.SeConnection; +import com.esri.sde.sdk.client.SeException; +import com.esri.sde.sdk.client.SeLayer; +import com.esri.sde.sdk.client.SeRelease; + +/** + * Maintains <code>SeConnection</code>'s for a single set of connection properties (for instance: by + * server, port, user and password) in a pooled way + * + * <p> + * Since sde connections are not jdbc connections, I can't use Sean's excellent connection pool. So + * I'll borrow most of it. + * </p> + * + * <p> + * This connection pool is configurable in the sense that some parameters can be passed to establish + * the pooling policy. To pass parameters to the connection pool, you should set some properties in + * the parameters Map passed to SdeDataStoreFactory.createDataStore, wich will invoke + * SdeConnectionPoolFactory to get the SDE instance's pool singleton. That instance singleton will + * be created with the preferences passed the first time createDataStore is called for a given SDE + * instance/user, if subsecuent calls change that preferences, they will be ignored. + * </p> + * + * <p> + * The expected optional parameters that you can set up in the argument Map for createDataStore are: + * + * <ul> + * <li>pool.minConnections Integer, tells the minimun number of open connections the pool will + * maintain opened</li> + * <li>pool.maxConnections Integer, tells the maximun number of open connections the pool will + * create and maintain opened</li> + * <li>pool.timeOut Integer, tells how many milliseconds a calling thread is guaranteed to wait + * before getConnection() throws an UnavailableArcSDEConnectionException</li> + * </ul> + * </p> + * + * @author Gabriel Roldan, Axios Engineering + * @version $Id$ + * @deprecated still here waiting for gce to switch to {@link SessionPool} + */ +@SuppressWarnings("unchecked") +public class ArcSDEConnectionPool { + /** package's logger */ + private static final Logger LOGGER = org.geotools.util.logging.Logging + .getLogger("org.geotools.arcsde.pool"); + + /** DOCUMENT ME! */ + protected static final Level INFO_LOG_LEVEL = Level.WARNING; + + /** default number of connections a pool creates at first population */ + public static final int DEFAULT_CONNECTIONS = 2; + + /** default number of maximun allowable connections a pool can hold */ + public static final int DEFAULT_MAX_CONNECTIONS = 6; + + public static final int DEFAULT_MAX_WAIT_TIME = 500; + + /** DOCUMENT ME! */ + private SeConnectionFactory seConnectionFactory; + + /** this connection pool connection's parameters */ + private ArcSDEConnectionConfig config; + + /** Apache commons-pool used to pool arcsde connections */ + private ObjectPool pool; + + /** + * Creates a new SdeConnectionPool object with the connection parameters holded by + * <code>config</code> + * + * @param config + * holds connection options such as server, user and password, as well as tuning + * options as maximun number of connections allowed + * + * @throws DataSourceException + * DOCUMENT ME! + * @throws NullPointerException + * DOCUMENT ME! + */ + protected ArcSDEConnectionPool(ArcSDEConnectionConfig config) throws DataSourceException { + if (config == null) { + throw new NullPointerException("parameter config can't be null"); + } + + this.config = config; + LOGGER.fine("populating ArcSDE connection pool"); + + this.seConnectionFactory = new SeConnectionFactory(this.config); + + int minConnections = config.getMinConnections().intValue(); + int maxConnections = config.getMaxConnections().intValue(); + // byte exhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_GROW; + byte exhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_BLOCK; + long maxWait = config.getConnTimeOut().longValue(); + + this.pool = new GenericObjectPool(seConnectionFactory, maxConnections, exhaustedAction, + maxWait, true, true); + LOGGER.info("Created ArcSDE connection pool for " + config); + + ArcSDEPooledConnection[] preload = new ArcSDEPooledConnection[minConnections]; + + try { + for (int i = 0; i < minConnections; i++) { + preload[i] = (ArcSDEPooledConnection) this.pool.borrowObject(); + if (i == 0) { + SeRelease seRelease = preload[i].getRelease(); + String sdeDesc = seRelease.getDesc(); + int major = seRelease.getMajor(); + int minor = seRelease.getMinor(); + int bugFix = seRelease.getBugFix(); + String desc = "ArcSDE " + major + "." + minor + "." + bugFix + " " + sdeDesc; + LOGGER.info("Connected to " + desc); + } + } + + for (int i = 0; i < minConnections; i++) { + this.pool.returnObject(preload[i]); + } + } catch (Exception e) { + LOGGER.log(Level.WARNING, "can't connect to " + config, e); + throw new DataSourceException(e); + } + } + + /** + * returns the number of actual connections holded by this connection pool. In other words, the + * sum of used and available connections, regardless + * + * @return DOCUMENT ME! + */ + public int getPoolSize() { + synchronized (this.pool) { + return this.pool.getNumActive() + this.pool.getNumIdle(); + } + } + + /** + * closes all connections in this pool + */ + public void close() { + if (pool != null) { + try { + this.pool.close(); + pool = null; + LOGGER.fine("SDE connection pool closed. "); + } catch (Exception e) { + LOGGER.log(Level.WARNING, "Closing pool: " + e.getMessage(), e); + } + } + } + + public boolean isClosed() { + return pool == null; + } + + /** + * Ensures proper closure of connection pool at this object's finalization stage. + */ + // //@Override + protected void finalize() { + close(); + } + + /** + * TODO: Document this method! + * + * @return DOCUMENT ME! + */ + public synchronized int getAvailableCount() { + return this.pool.getNumIdle(); + } + + /** + * TODO: Document this method! + * + * @return DOCUMENT ME! + */ + public synchronized int getInUseCount() { + return this.pool.getNumActive(); + } + + /** + * DOCUMENT ME! + * + * @return DOCUMENT ME! + * + * @throws DataSourceException + * DOCUMENT ME! + * @throws UnavailableArcSDEConnectionException + * @throws IllegalStateException + * DOCUMENT ME! + */ + public ArcSDEPooledConnection getConnection() throws DataSourceException, + UnavailableArcSDEConnectionException { + if (pool == null) { + throw new IllegalStateException("The ConnectionPool has been closed."); + } + + try { + // String caller = null; + // if (LOGGER.isLoggable(Level.FINER)) { + // StackTraceElement[] stackTrace = + // Thread.currentThread().getStackTrace(); + // caller = stackTrace[3].getClassName() + "." + + // stackTrace[3].getMethodName(); + // } + + ArcSDEPooledConnection connection = (ArcSDEPooledConnection) this.pool.borrowObject(); + + if (LOGGER.isLoggable(Level.FINER)) { + // System.err.println("-> " + caller + " got " + connection); + LOGGER.finer(connection + " out of connection pool"); + } + + connection.markActive(); + return connection; + } catch (NoSuchElementException e) { + LOGGER.log(Level.WARNING, "Out of connections: " + e.getMessage(), e); + throw new UnavailableArcSDEConnectionException(this.pool.getNumActive(), this.config); + } catch (SeException se) { + LOGGER.log(Level.WARNING, "ArcSDE error getting connection: " + + se.getSeError().getErrDesc(), se); + throw new DataSourceException("ArcSDE Error Message: " + se.getSeError().getErrDesc(), + se); + } catch (Exception e) { + LOGGER.log(Level.WARNING, "Unknown problem getting connection: " + e.getMessage(), e); + throw new DataSourceException( + "Unknown problem fetching connection from connection pool", e); + } + } + + /** + * Sometimes (and largely without reason) ArcSDEPooledConnections (really their underlying + * SeConnection objects) just poop out. They start behaving strangely, or not behaving at all. + * You can tell the pool that a particular SeConnection has 'Failed' using this method, and it + * will do its best to get it out of the pool as soon as you release your hold on it. + * + * @param conn + */ + public synchronized void markConnectionAsFailed(ArcSDEPooledConnection conn) { + LOGGER.warning("ArcSDE connection '" + conn + + "' has been marked as failed. Current pool state is " + getAvailableCount() + + " avail/" + this.getPoolSize() + " total"); + seConnectionFactory.markObjectInvalid(conn); + } + + /** + * Gets the list of available layer names on the database + * + * @return a <code>List<String></code> with the registered featureclasses on the ArcSDE + * database + * + * @throws DataSourceException + */ + // //@SuppressWarnings("unchecked") + public List/* <String> */getAvailableLayerNames() throws DataSourceException { + ArcSDEPooledConnection conn = null; + + List/* <String> */layerNames = new LinkedList/* <String> */(); + try { + conn = getConnection(); + for (Iterator/* <SeLayer> */it = conn.getLayers().iterator(); it.hasNext();) { + layerNames.add(((SeLayer) it.next()).getQualifiedName()); + } + } catch (SeException ex) { + throw new DataSourceException("Error querying the layers list" + + ex.getSeError().getSdeError() + " (" + ex.getSeError().getErrDesc() + ") ", + ex); + } catch (UnavailableArcSDEConnectionException ex) { + throw new DataSourceException("No free connection found to query the layers list", ex); + } finally { + if (conn != null) + conn.close(); + } + return layerNames; + } + + /** + * DOCUMENT ME! + * + * @return DOCUMENT ME! + */ + public ArcSDEConnectionConfig getConfig() { + return this.config; + } + + /** + * PoolableObjectFactory intended to be used by a Jakarta's commons-pool objects pool, that + * provides ArcSDE's SeConnections. + * + * @author Gabriel Roldan, Axios Engineering + * @version $Id$ + */ + class SeConnectionFactory extends BasePoolableObjectFactory { + /** DOCUMENT ME! */ + private ArcSDEConnectionConfig config; + + private List/* <SeConnection> */invalidConnections = new ArrayList/* <SeConnection> */(2); + + /** + * Creates a new SeConnectionFactory object. + * + * @param config + * DOCUMENT ME! + */ + public SeConnectionFactory(ArcSDEConnectionConfig config) { + super(); + this.config = config; + } + + public void markObjectInvalid(Object o) { + invalidConnections.add((SeConnection) o); + } + + /** + * Called whenever a new instance is needed. + * + * @return a newly created <code>SeConnection</code> + * + * @throws SeException + * if the connection can't be created + */ + // //@Override + public Object makeObject() throws IOException { + NegativeArraySizeException cause = null; + for (int i = 0; i < 3; i++) { + try { + ArcSDEPooledConnection seConn = new ArcSDEPooledConnection( + ArcSDEConnectionPool.this.pool, config); + return seConn; + } catch (NegativeArraySizeException nase) { + LOGGER.warning("Strange failed ArcSDE connection error. Trying again (try " + + (i + 1) + " of 3)"); + cause = nase; + } catch (SeException e) { + throw new ArcSdeException(e); + } + } + throw new DataSourceException( + "Couldn't create ArcSDEPooledConnection because of strange SDE internal exception. Tried 3 times, giving up.", + cause); + } + + /** + * is invoked on every instance before it is returned from the pool. + * + * @param obj + */ + // //@Override + public void activateObject(Object obj) { + final ArcSDEPooledConnection conn = (ArcSDEPooledConnection) obj; + conn.markActive(); + LOGGER.finest("activating connection " + obj); + } + + // //@Override + public void passivateObject(Object obj) { + LOGGER.finest("passivating connection " + obj); + final ArcSDEPooledConnection conn = (ArcSDEPooledConnection) obj; + conn.markInactive(); + } + + /** + * is invoked in an implementation-specific fashion to determine if an instance is still + * valid to be returned by the pool. It will only be invoked on an "activated" instance. + * + * @param an + * instance of {@link ArcSDEPooledConnection} maintained by this pool. + * + * @return <code>true</code> if the connection is still alive and operative (checked by + * asking its user name), <code>false</code> otherwise. + */ + // //@Override + public boolean validateObject(Object obj) { + ArcSDEPooledConnection conn = (ArcSDEPooledConnection) obj; + boolean valid = !conn.isClosed(); + // MAKE PROPER VALIDITY CHECK HERE as for GEOT-1273 + if (valid) { + if (invalidConnections.contains(obj)) + valid = false; + + try { + LOGGER.finest("Validating SDE Connection"); + String user = conn.getUser(); + LOGGER.finer("Connection validated, returned user " + user); + } catch (SeException e) { + LOGGER.info("Can't validate SeConnection, discarding it: " + conn); + valid = false; + } + } + return valid; + } + + /** + * is invoked on every instance when it is being "dropped" from the pool (whether due to the + * response from validateObject, or for reasons specific to the pool implementation.) + * + * @param obj + * an instance of {@link ArcSDEPooledConnection} maintained by this pool. + */ + // //@Override + public void destroyObject(Object obj) { + ArcSDEPooledConnection conn = (ArcSDEPooledConnection) obj; + conn.destroy(); + } + } + + // //@Override + public String toString() { + StringBuffer ret = new StringBuffer(); + ret.append("[ACTIVE: "); + ret.append(pool.getNumActive() + "/" + ((GenericObjectPool) pool).getMaxActive()); + ret.append(" INACTIVE: "); + ret.append(pool.getNumIdle() + "/" + ((GenericObjectPool) pool).getMaxIdle() + "]"); + return ret.toString(); + } +} \ No newline at end of file Deleted: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionPoolFactory.java =================================================================== --- trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionPoolFactory.java 2009-07-07 01:13:56 UTC (rev 33502) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionPoolFactory.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -1,120 +0,0 @@ -/* - * 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.arcsde.session; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.logging.Logger; - -import org.geotools.arcsde.data.ArcSDEDataStoreConfig; -import org.geotools.data.DataSourceException; - -/** - * Singleton factory that maintains a single {@link ArcSDEConnectionPool connection pool} per set of - * {@link ArcSDEDataStoreConfig connection parameters}. - * - * @author Gabriel Roldan - * @source $URL: - * http://svn.geotools.org/geotools/trunk/gt/modules/unsupported/arcsde/datastore/src/main - * /java/org/geotools/arcsde/pool/ArcSDEConnectionPoolFactory.java $ - * @version $Id$ - * @deprecated sill here waiting for gce to switch to {@link SessionPoolFactory} - */ -public class ArcSDEConnectionPoolFactory { - /** package logger */ - private static final Logger LOGGER = org.geotools.util.logging.Logging - .getLogger("org.geotools.arcsde.pool"); - - /** singleton pool factory */ - private static final ArcSDEConnectionPoolFactory singleton = new ArcSDEConnectionPoolFactory(); - - /** - * Map{ArcSDEConnectionConfig,ArcSDEConnectionPool} with per config connection pool - */ - private final Map currentPools = new HashMap(); - - /** - * Creates a new SdeConnectionPoolFactory object. - */ - private ArcSDEConnectionPoolFactory() { - // intentionally blank - } - - /** - * Returns a connection pool factory instance - * - * @return the connection pool factory singleton - */ - public synchronized static ArcSDEConnectionPoolFactory getInstance() { - return singleton; - } - - /** - * Creates a connection pool factory for the given connection parameters, or returns the - * existing one if there already exists one for that set of connection params. - * - * @param config - * Â contains the connection parameters and pool preferences - * - * @return a pool for the given connection parameters, wether it already existed or had to be - * created. - * - * @throws DataSourceException - * if the pool needs but can't be created - */ - public synchronized ArcSDEConnectionPool createPool(ArcSDEConnectionConfig config) - throws DataSourceException { - ArcSDEConnectionPool pool = (ArcSDEConnectionPool) this.currentPools.get(config); - - if (pool == null || pool.isClosed()) { - // the new pool will be populated with config.minConnections - // connections - pool = new ArcSDEConnectionPool(config); - this.currentPools.put(config, pool); - } - - return pool; - } - - /** - * Closes and removes all the existing connection pools - */ - public void clear() { - closeAll(); - this.currentPools.clear(); - LOGGER.fine("sde connection pools creared"); - } - - /** - * loses all the available connection pools - */ - private void closeAll() { - for (Iterator it = this.currentPools.values().iterator(); it.hasNext();) { - ((ArcSDEConnectionPool) it.next()).close(); - } - } - - /** - * Ensures proper closure of connection pools at this object's finalization stage. - */ - // //@Override - protected void finalize() { - closeAll(); - } -} Copied: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionPoolFactory.java (from rev 33502, trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionPoolFactory.java) =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionPoolFactory.java (rev 0) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionPoolFactory.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -0,0 +1,120 @@ +/* + * 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.arcsde.session; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.logging.Logger; + +import org.geotools.arcsde.data.ArcSDEDataStoreConfig; +import org.geotools.data.DataSourceException; + +/** + * Singleton factory that maintains a single {@link ArcSDEConnectionPool connection pool} per set of + * {@link ArcSDEDataStoreConfig connection parameters}. + * + * @author Gabriel Roldan + * @source $URL: + * http://svn.geotools.org/geotools/trunk/gt/modules/unsupported/arcsde/datastore/src/main + * /java/org/geotools/arcsde/pool/ArcSDEConnectionPoolFactory.java $ + * @version $Id$ + * @deprecated sill here waiting for gce to switch to {@link SessionPoolFactory} + */ +public class ArcSDEConnectionPoolFactory { + /** package logger */ + private static final Logger LOGGER = org.geotools.util.logging.Logging + .getLogger("org.geotools.arcsde.pool"); + + /** singleton pool factory */ + private static final ArcSDEConnectionPoolFactory singleton = new ArcSDEConnectionPoolFactory(); + + /** + * Map{ArcSDEConnectionConfig,ArcSDEConnectionPool} with per config connection pool + */ + private final Map currentPools = new HashMap(); + + /** + * Creates a new SdeConnectionPoolFactory object. + */ + private ArcSDEConnectionPoolFactory() { + // intentionally blank + } + + /** + * Returns a connection pool factory instance + * + * @return the connection pool factory singleton + */ + public synchronized static ArcSDEConnectionPoolFactory getInstance() { + return singleton; + } + + /** + * Creates a connection pool factory for the given connection parameters, or returns the + * existing one if there already exists one for that set of connection params. + * + * @param config + * Â contains the connection parameters and pool preferences + * + * @return a pool for the given connection parameters, wether it already existed or had to be + * created. + * + * @throws DataSourceException + * if the pool needs but can't be created + */ + public synchronized ArcSDEConnectionPool createPool(ArcSDEConnectionConfig config) + throws DataSourceException { + ArcSDEConnectionPool pool = (ArcSDEConnectionPool) this.currentPools.get(config); + + if (pool == null || pool.isClosed()) { + // the new pool will be populated with config.minConnections + // connections + pool = new ArcSDEConnectionPool(config); + this.currentPools.put(config, pool); + } + + return pool; + } + + /** + * Closes and removes all the existing connection pools + */ + public void clear() { + closeAll(); + this.currentPools.clear(); + LOGGER.fine("sde connection pools creared"); + } + + /** + * loses all the available connection pools + */ + private void closeAll() { + for (Iterator it = this.currentPools.values().iterator(); it.hasNext();) { + ((ArcSDEConnectionPool) it.next()).close(); + } + } + + /** + * Ensures proper closure of connection pools at this object's finalization stage. + */ + // //@Override + protected void finalize() { + closeAll(); + } +} Deleted: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/session/ArcSDEPooledConnection.java =================================================================== --- trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/session/ArcSDEPooledConnection.java 2009-07-07 01:13:56 UTC (rev 33502) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/session/ArcSDEPooledConnection.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -1,292 +0,0 @@ -/* - * 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.arcsde.session; - -import java.util.HashMap; -import java.util.Map; -import java.util.NoSuchElementException; -import java.util.Vector; -import java.util.logging.Level; -import java.util.logging.Logger; - -import org.apache.commons.pool.ObjectPool; -import org.geotools.data.DataSourceException; - -import com.esri.sde.sdk.client.SeConnection; -import com.esri.sde.sdk.client.SeException; -import com.esri.sde.sdk.client.SeLayer; -import com.esri.sde.sdk.client.SeRasterColumn; -import com.esri.sde.sdk.client.SeTable; - -/** - * An SeConnection that returns itself to the connection pool instead of closing on each call to - * close(). - * - * @author Gabriel Roldan (TOPP) - * @version $Id$ - * @since 2.3.x - * - * @deprecated still here waiting for gce to switch to {@link ISession} - */ -public class ArcSDEPooledConnection extends SeConnection { - - private static final Logger LOGGER = org.geotools.util.logging.Logging - .getLogger("org.geotools.arcsde.pool"); - - private ObjectPool pool; - - private ArcSDEConnectionConfig config; - - private static int connectionCounter; - - private int connectionId; - - private boolean transactionInProgress; - - private boolean isPassivated; - - private Map<String, SeLayer> cachedLayers = new HashMap<String, SeLayer>(); - - private Map<String, SeRasterColumn> cachedRasters = new HashMap<String, SeRasterColumn>(); - - public ArcSDEPooledConnection(ObjectPool pool, ArcSDEConnectionConfig config) - throws SeException { - super(config.getServerName(), config.getPortNumber().intValue(), config.getDatabaseName(), - config.getUserName(), config.getPassword()); - this.config = config; - this.pool = pool; - this.setConcurrency(SeConnection.SE_UNPROTECTED_POLICY); - synchronized (ArcSDEPooledConnection.class) { - connectionCounter++; - connectionId = connectionCounter; - } - } - - @Override - public final boolean isClosed() { - return super.isClosed(); - } - - /** - * Marks the connection as being active (i.e. its out of the pool and ready to be used). - * <p> - * Shall be called just before being returned from the connection pool - * </p> - * - * @see #markInactive() - * @see #isPassivated - * @see #checkActive() - */ - void markActive() { - this.isPassivated = false; - } - - /** - * Marks the connection as being inactive (i.e. laying on the connection pool) - * <p> - * Shall be callled just before sending it back to the pool - * </p> - * - * @see #markActive() - * @see #isPassivated - * @see #checkActive() - */ - void markInactive() { - this.isPassivated = true; - } - - /** - * Returns whether this connection is on the connection pool domain or not. - * - * @return <code>true</code> if this connection has beed returned to the pool and thus cannot be - * used, <code>false</code> if its safe to keep using it. - */ - public boolean isPassivated() { - return isPassivated; - } - - /** - * Sanity check method called before every public operation delegates to the superclass. - * - * @throws IllegalStateException - * if {@link #isPassivated() isPassivated() == true} as this is a serious workflow - * breackage. - */ - private void checkActive() { - if (isPassivated()) { - throw new IllegalStateException("Unrecoverable error: " + toString() - + " is passivated, shall not be used!"); - } - } - - public synchronized SeLayer getLayer(final String layerName) throws DataSourceException { - checkActive(); - if (!cachedLayers.containsKey(layerName)) { - try { - cacheLayers(); - } catch (SeException e) { - throw new DataSourceException("Can't obtain layer " + layerName, e); - } - } - SeLayer seLayer = cachedLayers.get(layerName); - if (seLayer == null) { - throw new NoSuchElementException("Layer '" + layerName + "' not found"); - } - return seLayer; - } - - public synchronized SeRasterColumn getRasterColumn(final String rasterName) - throws DataSourceException { - checkActive(); - if (!cachedRasters.containsKey(rasterName)) { - try { - cacheRasters(); - } catch (SeException e) { - throw new DataSourceException("Can't obtain raster " + rasterName, e); - } - } - SeRasterColumn raster = cachedRasters.get(rasterName); - if (raster == null) { - throw new NoSuchElementException("Raster '" + rasterName + "' not found"); - } - return raster; - } - - public synchronized SeTable getTable(final String tableName) throws DataSourceException { - checkActive(); - try { - return new SeTable(this, tableName); - } catch (SeException e) { - throw new DataSourceException("Can't access table " + tableName, e); - } - } - - @SuppressWarnings("unchecked") - private void cacheLayers() throws SeException { - Vector<SeLayer> layers = this.getLayers(); - cachedLayers.clear(); - for (SeLayer layer : layers) { - cachedLayers.put(layer.getQualifiedName(), layer); - } - } - - @SuppressWarnings("unchecked") - private void cacheRasters() throws SeException { - Vector<SeRasterColumn> rasters = this.getRasterColumns(); - cachedRasters.clear(); - for (SeRasterColumn raster : rasters) { - cachedRasters.put(raster.getQualifiedTableName(), raster); - } - } - - @Override - public void startTransaction() throws SeException { - checkActive(); - super.startTransaction(); - transactionInProgress = true; - } - - @Override - public void commitTransaction() throws SeException { - checkActive(); - super.commitTransaction(); - transactionInProgress = false; - } - - /** - * Returns whether a transaction is in progress over this connection - * <p> - * As for any other public method, this one can't be called if {@link #isPassivated()} is true. - * </p> - * - * @return - */ - public boolean isTransactionActive() { - checkActive(); - return transactionInProgress; - } - - @Override - public void rollbackTransaction() throws SeException { - checkActive(); - super.rollbackTransaction(); - transactionInProgress = false; - } - - /** - * Doesn't close the connection, but returns itself to the connection pool. - * - * @throws IllegalStateException - * if close() is called while a transaction is in progress - * @see #destroy() - */ - @Override - public void close() throws IllegalStateException { - checkActive(); - if (transactionInProgress) { - throw new IllegalStateException( - "Transaction is in progress, should commit or rollback before closing"); - } - - try { - if (LOGGER.isLoggable(Level.FINER)) { - // StackTraceElement[] stackTrace = - // Thread.currentThread().getStackTrace(); - // String caller = stackTrace[3].getClassName() + "." + - // stackTrace[3].getMethodName(); - // System.err.println("<- " + caller + " returning " + - // toString() + " to pool"); - - LOGGER.finer("<- returning " + toString() + " to pool"); - } - this.pool.returnObject(this); - } catch (Exception e) { - LOGGER.log(Level.SEVERE, e.getMessage(), e); - } - } - - @Override - public String toString() { - return "ArcSDEPooledConnection[" + connectionId + "]"; - } - - /** - * Actually closes the connection - */ - void destroy() { - try { - super.close(); - } catch (SeException e) { - LOGGER.info("closing connection: " + e.getMessage()); - } - } - - /** - * Compares for reference equality - */ - @Override - public boolean equals(Object other) { - return other == this; - } - - @Override - public int hashCode() { - return 17 ^ this.config.hashCode(); - } - -} Copied: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/session/ArcSDEPooledConnection.java (from rev 33502, trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/session/ArcSDEPooledConnection.java) =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/session/ArcSDEPooledConnection.java (rev 0) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/session/ArcSDEPooledConnection.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -0,0 +1,292 @@ +/* + * 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.arcsde.session; + +import java.util.HashMap; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Vector; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.apache.commons.pool.ObjectPool; +import org.geotools.data.DataSourceException; + +import com.esri.sde.sdk.client.SeConnection; +import com.esri.sde.sdk.client.SeException; +import com.esri.sde.sdk.client.SeLayer; +import com.esri.sde.sdk.client.SeRasterColumn; +import com.esri.sde.sdk.client.SeTable; + +/** + * An SeConnection that returns itself to the connection pool instead of closing on each call to + * close(). + * + * @author Gabriel Roldan (TOPP) + * @version $Id$ + * @since 2.3.x + * + * @deprecated still here waiting for gce to switch to {@link ISession} + */ +public class ArcSDEPooledConnection extends SeConnection { + + private static final Logger LOGGER = org.geotools.util.logging.Logging + .getLogger("org.geotools.arcsde.pool"); + + private ObjectPool pool; + + private ArcSDEConnectionConfig config; + + private static int connectionCounter; + + private int connectionId; + + private boolean transactionInProgress; + + private boolean isPassivated; + + private Map<String, SeLayer> cachedLayers = new HashMap<String, SeLayer>(); + + private Map<String, SeRasterColumn> cachedRasters = new HashMap<String, SeRasterColumn>(); + + public ArcSDEPooledConnection(ObjectPool pool, ArcSDEConnectionConfig config) + throws SeException { + super(config.getServerName(), config.getPortNumber().intValue(), config.getDatabaseName(), + config.getUserName(), config.getPassword()); + this.config = config; + this.pool = pool; + this.setConcurrency(SeConnection.SE_UNPROTECTED_POLICY); + synchronized (ArcSDEPooledConnection.class) { + connectionCounter++; + connectionId = connectionCounter; + } + } + + @Override + public final boolean isClosed() { + return super.isClosed(); + } + + /** + * Marks the connection as being active (i.e. its out of the pool and ready to be used). + * <p> + * Shall be called just before being returned from the connection pool + * </p> + * + * @see #markInactive() + * @see #isPassivated + * @see #checkActive() + */ + void markActive() { + this.isPassivated = false; + } + + /** + * Marks the connection as being inactive (i.e. laying on the connection pool) + * <p> + * Shall be callled just before sending it back to the pool + * </p> + * + * @see #markActive() + * @see #isPassivated + * @see #checkActive() + */ + void markInactive() { + this.isPassivated = true; + } + + /** + * Returns whether this connection is on the connection pool domain or not. + * + * @return <code>true</code> if this connection has beed returned to the pool and thus cannot be + * used, <code>false</code> if its safe to keep using it. + */ + public boolean isPassivated() { + return isPassivated; + } + + /** + * Sanity check method called before every public operation delegates to the superclass. + * + * @throws IllegalStateException + * if {@link #isPassivated() isPassivated() == true} as this is a serious workflow + * breackage. + */ + private void checkActive() { + if (isPassivated()) { + throw new IllegalStateException("Unrecoverable error: " + toString() + + " is passivated, shall not be used!"); + } + } + + public synchronized SeLayer getLayer(final String layerName) throws DataSourceException { + checkActive(); + if (!cachedLayers.containsKey(layerName)) { + try { + cacheLayers(); + } catch (SeException e) { + throw new DataSourceException("Can't obtain layer " + layerName, e); + } + } + SeLayer seLayer = cachedLayers.get(layerName); + if (seLayer == null) { + throw new NoSuchElementException("Layer '" + layerName + "' not found"); + } + return seLayer; + } + + public synchronized SeRasterColumn getRasterColumn(final String rasterName) + throws DataSourceException { + checkActive(); + if (!cachedRasters.containsKey(rasterName)) { + try { + cacheRasters(); + } catch (SeException e) { + throw new DataSourceException("Can't obtain raster " + rasterName, e); + } + } + SeRasterColumn raster = cachedRasters.get(rasterName); + if (raster == null) { + throw new NoSuchElementException("Raster '" + rasterName + "' not found"); + } + return raster; + } + + public synchronized SeTable getTable(final String tableName) throws DataSourceException { + checkActive(); + try { + return new SeTable(this, tableName); + } catch (SeException e) { + throw new DataSourceException("Can't access table " + tableName, e); + } + } + + @SuppressWarnings("unchecked") + private void cacheLayers() throws SeException { + Vector<SeLayer> layers = this.getLayers(); + cachedLayers.clear(); + for (SeLayer layer : layers) { + cachedLayers.put(layer.getQualifiedName(), layer); + } + } + + @SuppressWarnings("unchecked") + private void cacheRasters() throws SeException { + Vector<SeRasterColumn> rasters = this.getRasterColumns(); + cachedRasters.clear(); + for (SeRasterColumn raster : rasters) { + cachedRasters.put(raster.getQualifiedTableName(), raster); + } + } + + @Override + public void startTransaction() throws SeException { + checkActive(); + super.startTransaction(); + transactionInProgress = true; + } + + @Override + public void commitTransaction() throws SeException { + checkActive(); + super.commitTransaction(); + transactionInProgress = false; + } + + /** + * Returns whether a transaction is in progress over this connection + * <p> + * As for any other public method, this one can't be called if {@link #isPassivated()} is true. + * </p> + * + * @return + */ + public boolean isTransactionActive() { + checkActive(); + return transactionInProgress; + } + + @Override + public void rollbackTransaction() throws SeException { + checkActive(); + super.rollbackTransaction(); + transactionInProgress = false; + } + + /** + * Doesn't close the connection, but returns itself to the connection pool. + * + * @throws IllegalStateException + * if close() is called while a transaction is in progress + * @see #destroy() + */ + @Override + public void close() throws IllegalStateException { + checkActive(); + if (transactionInProgress) { + throw new IllegalStateException( + "Transaction is in progress, should commit or rollback before closing"); + } + + try { + if (LOGGER.isLoggable(Level.FINER)) { + // StackTraceElement[] stackTrace = + // Thread.currentThread().getStackTrace(); + // String caller = stackTrace[3].getClassName() + "." + + // stackTrace[3].getMethodName(); + // System.err.println("<- " + caller + " returning " + + // toString() + " to pool"); + + LOGGER.finer("<- returning " + toString() + " to pool"); + } + this.pool.returnObject(this); + } catch (Exception e) { + LOGGER.log(Level.SEVERE, e.getMessage(), e); + } + } + + @Override + public String toString() { + return "ArcSDEPooledConnection[" + connectionId + "]"; + } + + /** + * Actually closes the connection + */ + void destroy() { + try { + super.close(); + } catch (SeException e) { + LOGGER.info("closing connection: " + e.getMessage()); + } + } + + /** + * Compares for reference equality + */ + @Override + public boolean equals(Object other) { + return other == this; + } + + @Override + public int hashCode() { + return 17 ^ this.config.hashCode(); + } + +} Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/resources/META-INF/services/org.geotools.data.DataStoreFactorySpi =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/resources/META-INF/services/org.geotools.data.DataStoreFactorySpi 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/resources/META-INF/services/org.geotools.data.DataStoreFactorySpi 2009-07-07 15:55:29 UTC (rev 33511) @@ -1 +1,2 @@ -org.geotools.arcsde.ArcSDEDataStoreFactory \ No newline at end of file +org.geotools.arcsde.ArcSDEDataStoreFactory +org.geotools.arcsde.ArcSDEJNDIDataStoreFactory \ No newline at end of file Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/ArcSDEDataStoreFactoryTest.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/ArcSDEDataStoreFactoryTest.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/ArcSDEDataStoreFactoryTest.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -17,7 +17,7 @@ */ package org.geotools.arcsde; -import static org.geotools.arcsde.pool.ArcSDEConnectionConfig.VERSION_PARAM; +import static org.geotools.arcsde.data.ArcSDEDataStoreConfig.VERSION_PARAM_NAME; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @@ -31,10 +31,11 @@ import java.util.Map; import org.geotools.arcsde.data.ArcSDEDataStore; +import org.geotools.arcsde.data.ArcSDEDataStoreConfig; import org.geotools.arcsde.data.InProcessViewSupportTestData; import org.geotools.arcsde.data.TestData; -import org.geotools.arcsde.pool.ArcSDEConnectionConfig; -import org.geotools.arcsde.pool.ISession; +import org.geotools.arcsde.session.ArcSDEConnectionConfig; +import org.geotools.arcsde.session.ISession; import org.geotools.data.DataAccessFactory; import org.geotools.data.DataAccessFinder; import org.geotools.data.DataSourceException; @@ -94,10 +95,10 @@ workingParams = testData.getConProps(); nonWorkingParams = new HashMap(workingParams); - nonWorkingParams.put(ArcSDEConnectionConfig.SERVER_NAME_PARAM, "non-existent-server"); + nonWorkingParams.put(ArcSDEConnectionConfig.SERVER_NAME_PARAM_NAME, "non-existent-server"); illegalParams = new HashMap(workingParams); - illegalParams.put(ArcSDEConnectionConfig.DBTYPE_PARAM, "non-existent-db-type"); + illegalParams.put(ArcSDEDataStoreConfig.DBTYPE_PARAM_NAME, "non-existent-db-type"); dsFactory = new ArcSDEDataStoreFactory(); } @@ -236,7 +237,7 @@ Map paramsWithVersion = new HashMap(workingParams); try { - paramsWithVersion.put(VERSION_PARAM, "Non existent version name"); + paramsWithVersion.put(VERSION_PARAM_NAME, "Non existent version name"); dsFactory.createDataStore(paramsWithVersion); } catch (IOException e) { assertTrue(e.getMessage(), e.getMessage().startsWith( @@ -256,26 +257,26 @@ } Map paramsWithVersion = new HashMap(workingParams); - paramsWithVersion.put(VERSION_PARAM, versionName); + paramsWithVersion.put(VERSION_PARAM_NAME, versionName); DataStore ds = dsFactory.createDataStore(paramsWithVersion); assertNotNull(ds); ds.dispose(); String qualifiedVersionName = session.getUser() + "." + versionName; - paramsWithVersion.put(VERSION_PARAM, qualifiedVersionName); + paramsWithVersion.put(VERSION_PARAM_NAME, qualifiedVersionName); ds = dsFactory.createDataStore(paramsWithVersion); assertNotNull(ds); ds.dispose(); // version name should be case insensitive qualifiedVersionName = qualifiedVersionName.toUpperCase(); - paramsWithVersion.put(VERSION_PARAM, qualifiedVersionName); + paramsWithVersion.put(VERSION_PARAM_NAME, qualifiedVersionName); ds = dsFactory.createDataStore(paramsWithVersion); assertNotNull(ds); ds.dispose(); qualifiedVersionName = qualifiedVersionName.toLowerCase(); - paramsWithVersion.put(VERSION_PARAM, qualifiedVersionName); + paramsWithVersion.put(VERSION_PARAM_NAME, qualifiedVersionName); ds = dsFactory.createDataStore(paramsWithVersion); assertNotNull(ds); ds.dispose(); Copied: branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/ArcSDEJNDIDataStoreFactoryTest.java (from rev 33502, trunk/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/ArcSDEJNDIDataStoreFactoryTest.java) =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/ArcSDEJNDIDataStoreFactoryTest.java (rev 0) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/ArcSDEJNDIDataStoreFactoryTest.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -0,0 +1,189 @@ +/** + * + */ +package org.geotools.arcsde; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.File; +import java.io.IOException; +import java.io.Serializable; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.logging.Logger; + +import javax.naming.InitialContext; +import javax.naming.NamingException; + +import org.geotools.arcsde.data.ArcSDEDataStore; +import org.geotools.arcsde.data.TestData; +import org.geotools.arcsde.session.ArcSDEConnectionConfig; +import org.geotools.arcsde.session.ISession; +import org.geotools.data.DataAccessFactory; +import org.geotools.data.DataAccessFinder; +import org.geotools.data.DataStoreFactorySpi; +import org.geotools.data.DataStoreFinder; +import org.geotools.data.Transaction; +import org.geotools.data.DataAccessFactory.Param; +import org.geotools.factory.GeoTools; +import org.geotools.util.logging.Logging; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * @author groldan + * + */ +public class ArcSDEJNDIDataStoreFactoryTest { + + private static final Logger LOGGER = Logging.getLogger("org.geotools.arcsde"); + + private static ArcSDEJNDIDataStoreFactory factory; + + private static TestData testData; + + /** + * @throws java.lang.Exception + */ + @BeforeClass + public static void setUpBeforeClass() throws Exception { + factory = new ArcSDEJNDIDataStoreFactory(); + setupJNDIEnvironment(); + testData = new TestData(); + testData.setUp(); + testData.getConProps(); + } + + @Test + public void testDataStoreFinderFindsIt() throws IOException { + Iterator<DataStoreFactorySpi> allFactories = DataStoreFinder.getAllDataStores(); + ArcSDEJNDIDataStoreFactory sdeFac = null; + while (allFactories.hasNext()) { + DataAccessFactory next = allFactories.next(); + if (next instanceof ArcSDEJNDIDataStoreFactory) { + sdeFac = (ArcSDEJNDIDataStoreFactory) next; + break; + } + } + assertNotNull(sdeFac); + } + + @Test + public void testDataAccessFinderFindsIt() throws IOException { + Iterator<DataAccessFactory> allFactories = DataAccessFinder.getAllDataStores(); + ArcSDEJNDIDataStoreFactory sdeFac = null; + while (allFactories.hasNext()) { + DataAccessFactory next = allFactories.next(); + if (next instanceof ArcSDEJNDIDataStoreFactory) { + sdeFac = (ArcSDEJNDIDataStoreFactory) next; + break; + } + } + assertNotNull(sdeFac); + } + + /** + * Test method for {@link ArcSDEJNDIDataStoreFactory#createDataStore(java.util.Map)}. + * + * @throws IOException + */ + @Test + public void testCreateDataStore() throws IOException { + String jndiRef = "java:comp/env/MyArcSdeResource"; + Map<String, Serializable> params = new HashMap<String, Serializable>(); + params.put(ArcSDEJNDIDataStoreFactory.JNDI_REFNAME.key, jndiRef); + + ArcSDEConnectionConfig config = testData.getConnectionPool().getConfig(); + try { + InitialContext initialContext = GeoTools.getInitialContext(GeoTools.getDefaultHints()); + initialContext.createSubcontext("java:comp/env").bind(jndiRef, config); + } catch (NamingException e) { + throw new RuntimeException(e); + } + + ArcSDEDataStore dataStore = (ArcSDEDataStore) factory.createDataStore(params); + assertNotNull(dataStore); + ISession session = dataStore.getSession(Transaction.AUTO_COMMIT); + assertNotNull(session); + try { + assertEquals(config.getUserName().toUpperCase(), session.getUser().toUpperCase()); + } finally { + session.dispose(); + } + } + + /** + * Test method for {@link ArcSDEJNDIDataStoreFactory#canProcess(java.util.Map)}. + */ + @Test + public void testCanProcess() { + assertFalse(factory.canProcess(null)); + Map<String, Serializable> params = new HashMap<String, Serializable>(); + assertFalse(factory.canProcess(params)); + String jndiRef = "java:comp/env/MyArcSdeResource"; + params.put(ArcSDEJNDIDataStoreFactory.JNDI_REFNAME.key, jndiRef); + assertTrue(factory.canProcess(params)); + } + + /** + * Test method for {@link ArcSDEJNDIDataStoreFactory#getParametersInfo()}. + */ + @Test + public void testGetParametersInfo() { + Param[] parametersInfo = factory.getParametersInfo(); + assertNotNull(parametersInfo); + assertEquals(4, parametersInfo.length); + assertSame(ArcSDEJNDIDataStoreFactory.JNDI_REFNAME, parametersInfo[0]); + assertSame(ArcSDEDataStoreFactory.NAMESPACE_PARAM, parametersInfo[1]); + assertSame(ArcSDEDataStoreFactory.VERSION_PARAM, parametersInfo[2]); + assertSame(ArcSDEDataStoreFactory.ALLOW_NON_SPATIAL_PARAM, parametersInfo[3]); + } + + /** + * Test method for {@link ArcSDEJNDIDataStoreFactory#createNewDataStore(java.util.Map)}. + * + * @throws IOException + */ + @Test + public void testCreateNewDataStore() throws IOException { + try { + factory.createNewDataStore(new HashMap<String, Serializable>()); + fail("Expected UnsupportedOperationException"); + } catch (UnsupportedOperationException e) { + assertTrue(true); + } + } + + private static void setupJNDIEnvironment() throws IOException { + + File jndi = new File("target/jndi"); + jndi.mkdirs(); + + final String IC_FACTORY_PROPERTY = "java.naming.factory.initial"; + final String JNDI_ROOT = "org.osjava.sj.root"; + final String JNDI_DELIM = "org.osjava.jndi.delimiter"; + + if (System.getProperty(IC_FACTORY_PROPERTY) == null) { + System.setProperty(IC_FACTORY_PROPERTY, "org.osjava.sj.SimpleContextFactory"); + } + + if (System.getProperty(JNDI_ROOT) == null) { + System.setProperty(JNDI_ROOT, jndi.getAbsolutePath()); + } + + if (System.getProperty(JNDI_DELIM) == null) { + System.setProperty(JNDI_DELIM, "/"); + } + + LOGGER.fine(IC_FACTORY_PROPERTY + " = " + System.getProperty(IC_FACTORY_PROPERTY)); + LOGGER.fine(JNDI_ROOT + " = " + System.getProperty(JNDI_ROOT)); + LOGGER.fine(JNDI_DELIM + " = " + System.getProperty(JNDI_DELIM)); + } + +} Property changes on: branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data ___________________________________________________________________ Deleted: svn:mergeinfo - /trunk/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data:31091-33383,33392 Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ArcSDEClobTest.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ArcSDEClobTest.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ArcSDEClobTest.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -6,7 +6,8 @@ import java.io.IOException; import org.geotools.arcsde.data.versioning.ArcSdeVersionHandler; -import org.geotools.arcsde.pool.ISession; +import org.geotools.arcsde.session.ISession; +import org.geotools.arcsde.session.SdeRow; import org.geotools.data.Query; import org.geotools.data.Transaction; import org.junit.After; Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ArcSDEDataStoreNonSpatialTest.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ArcSDEDataStoreNonSpatialTest.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ArcSDEDataStoreNonSpatialTest.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -29,10 +29,10 @@ import java.util.Collections; import java.util.List; -import org.geotools.arcsde.pool.Command; -import org.geotools.arcsde.pool.ISession; -import org.geotools.arcsde.pool.SessionPool; -import org.geotools.arcsde.pool.UnavailableArcSDEConnectionException; +import org.geotools.arcsde.session.Command; +import org.geotools.arcsde.session.ISession; +import org.geotools.arcsde.session.ISessionPool; +import org.geotools.arcsde.session.UnavailableArcSDEConnectionException; import org.geotools.data.DataSourceException; import org.geotools.data.DataStore; import org.geotools.data.DataUtilities; @@ -106,7 +106,7 @@ seRowidSdeTable = baseTypeName + "_ROWID_SDE"; seRowidUserTable = baseTypeName + "_ROWID_USER"; - SessionPool sessionPool = testData.getConnectionPool(); + ISessionPool sessionPool = testData.getConnectionPool(); ISession session = sessionPool.getSession(); try { SeDBMSInfo dbInfo = session.getDBMSInfo(); @@ -148,7 +148,7 @@ @Before public void setUp() throws Exception { - SessionPool sessionPool = testData.newSessionPool(); + ISessionPool sessionPool = testData.newSessionPool(); final boolean allowNonSpatialTables = true; ds = new ArcSDEDataStore(sessionPool, null, null, allowNonSpatialTables); } Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ArcSDEDataStoreTest.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ArcSDEDataStoreTest.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ArcSDEDataStoreTest.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -30,8 +30,8 @@ import java.util.Map; import java.util.logging.Logger; -import org.geotools.arcsde.pool.ISession; -import org.geotools.arcsde.pool.SessionPool; +import org.geotools.arcsde.session.ISession; +import org.geotools.arcsde.session.ISessionPool; import org.geotools.data.DataAccess; import org.geotools.data.DataAccessFinder; import org.geotools.data.DataStore; @@ -295,7 +295,7 @@ public void testCreateSchema() throws IOException, SchemaException, SeException { final String typeName; { - SessionPool connectionPool = testData.getConnectionPool(); + ISessionPool connectionPool = testData.getConnectionPool(); ISession session = connectionPool.getSession(); final String user; user = session.getUser(); Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ArcSDEDataStoreVersioningTest.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ArcSDEDataStoreVersioningTest.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ArcSDEDataStoreVersioningTest.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -24,8 +24,7 @@ import java.util.Map; import org.geotools.arcsde.ArcSDEDataStoreFactory; -import org.geotools.arcsde.pool.ArcSDEConnectionConfig; -import org.geotools.arcsde.pool.ISession; +import org.geotools.arcsde.session.ISession; import org.geotools.data.DataSourceException; import org.geotools.data.DataStore; import org.geotools.data.DefaultTransaction; @@ -113,10 +112,10 @@ ArcSDEDataStoreFactory factory = new ArcSDEDataStoreFactory(); defaultVersionDataStore = factory.createDataStore(params); - params.put(ArcSDEConnectionConfig.VERSION_PARAM, version1); + params.put(ArcSDEDataStoreConfig.VERSION_PARAM_NAME, version1); version1DataStore = factory.createDataStore(params); - params.put(ArcSDEConnectionConfig.VERSION_PARAM, version2); + params.put(ArcSDEDataStoreConfig.VERSION_PARAM_NAME, version2); version2DataStore = factory.createDataStore(params); } Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ArcSDEFeatureSourceTest.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ArcSDEFeatureSourceTest.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ArcSDEFeatureSourceTest.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -36,7 +36,7 @@ import java.util.concurrent.FutureTask; import java.util.logging.Logger; -import org.geotools.arcsde.pool.SessionPool; +import org.geotools.arcsde.session.ISessionPool; import org.geotools.data.DataStore; import org.geotools.data.DefaultQuery; import org.geotools.data.FeatureReader; @@ -595,7 +595,7 @@ ArcSDEDataStore ds = testData.getDataStore(); - SessionPool pool = testData.getConnectionPool(); + ISessionPool pool = testData.getConnectionPool(); final int initialAvailableCount = pool.getAvailableCount(); final int initialPoolSize = pool.getPoolSize(); Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ArcSDEFeatureStoreTest.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ArcSDEFeatureStoreTest.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ArcSDEFeatureStoreTest.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -39,9 +39,10 @@ import junit.framework.AssertionFailedError; import org.geotools.arcsde.ArcSdeException; -import org.geotools.arcsde.pool.Command; -import org.geotools.arcsde.pool.ISession; -import org.geotools.arcsde.pool.SessionPool; +import org.geotools.arcsde.session.Command; +import org.geotools.arcsde.session.ISession; +import org.geotools.arcsde.session.ISessionPool; +import org.geotools.arcsde.session.SdeRow; import org.geotools.data.BatchFeatureEvent; import org.geotools.data.DataStore; import org.geotools.data.DataUtilities; @@ -377,7 +378,7 @@ } } - SessionPool connectionPool = testData.getConnectionPool(); + ISessionPool connectionPool = testData.getConnectionPool(); ISession session = connectionPool.getSession(); SeQuery seQuery; try { Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ArcSDEFeatureStoreVersionedTest.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ArcSDEFeatureStoreVersionedTest.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ArcSDEFeatureStoreVersionedTest.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -25,7 +25,7 @@ import java.util.logging.Logger; import org.geotools.arcsde.ArcSdeException; -import org.geotools.arcsde.pool.ISession; +import org.geotools.arcsde.session.ISession; import org.geotools.data.DataStoreFinder; import org.geotools.data.DataUtilities; import org.geotools.data.DefaultTransaction; Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ArcSDEJavaApiTest.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ArcSDEJavaApiTest.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ArcSDEJavaApiTest.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -28,10 +28,11 @@ import java.util.logging.Logger; import org.geotools.arcsde.ArcSdeException; -import org.geotools.arcsde.pool.Command; -import org.geotools.arcsde.pool.ISession; -import org.geotools.arcsde.pool.SessionPool; -import org.geotools.arcsde.pool.UnavailableArcSDEConnectionException; +import org.geotools.arcsde.session.Command; +import org.geotools.arcsde.session.ISession; +import org.geotools.arcsde.session.ISessionPool; +import org.geotools.arcsde.session.SdeRow; +import org.geotools.arcsde.session.UnavailableArcSDEConnectionException; import org.geotools.data.DataSourceException; import org.junit.After; import org.junit.AfterClass; @@ -85,7 +86,7 @@ private ISession session; - private SessionPool pool; + private ISessionPool pool; @BeforeClass public static void oneTimeSetUp() throws Exception { @@ -1082,7 +1083,7 @@ testData.truncateTempTable(); { - final SessionPool connPool = testData.getConnectionPool(); + final ISessionPool connPool = testData.getConnectionPool(); transSession = connPool.getSession(); // start a transaction on transConn transSession.startTransaction(); Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ArcSDEQueryTest.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ArcSDEQueryTest.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ArcSDEQueryTest.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -32,7 +32,7 @@ import org.geotools.arcsde.data.ArcSDEQuery.FilterSet; import org.geotools.arcsde.data.versioning.ArcSdeVersionHandler; import org.geotools.arcsde.data.versioning.AutoCommitVersionHandler; -import org.geotools.arcsde.pool.ISession; +import org.geotools.arcsde.session.ISession; import org.geotools.data.DefaultQuery; import org.geotools.data.FeatureReader; import org.geotools.data.FeatureSource; Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ClobTestData.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ClobTestData.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ClobTestData.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -7,12 +7,12 @@ import java.util.logging.Logger; import org.geotools.arcsde.ArcSDEDataStoreFactory; -import org.geotools.arcsde.pool.ArcSDEConnectionConfig; -import org.geotools.arcsde.pool.Command; -import org.geotools.arcsde.pool.ISession; -import org.geotools.arcsde.pool.SessionPool; -import org.geotools.arcsde.pool.SessionPoolFactory; -import org.geotools.arcsde.pool.UnavailableArcSDEConnectionException; +import org.geotools.arcsde.session.Command; +import org.geotools.arcsde.session.ISession; +import org.geotools.arcsde.session.ISessionPool; +import org.geotools.arcsde.session.ISessionPoolFactory; +import org.geotools.arcsde.session.SessionPoolFactory; +import org.geotools.arcsde.session.UnavailableArcSDEConnectionException; import org.geotools.referencing.crs.DefaultGeographicCRS; import com.esri.sde.sdk.client.SeColumnDefinition; @@ -63,7 +63,7 @@ /** the configuration keyword to use when creating layers and tables */ private String configKeyword; - private SessionPool _pool; + private ISessionPool _pool; /** * Creates a new TestData object. @@ -121,7 +121,7 @@ deleteTempTable(); } if (cleanPool) { - SessionPoolFactory pfac = SessionPoolFactory.getInstance(); + ISessionPoolFactory pfac = SessionPoolFactory.getInstance(); } } @@ -144,17 +144,17 @@ * DOCUMENT ME! */ public ArcSDEDataStore getDataStore() throws IOException { - SessionPool pool = getConnectionPool(); + ISessionPool pool = getConnectionPool(); ArcSDEDataStore dataStore = new ArcSDEDataStore(pool); return dataStore; } - public SessionPool getConnectionPool() throws IOException { + public ISessionPool getConnectionPool() throws IOException { if (this._pool == null) { - SessionPoolFactory pfac = SessionPoolFactory.getInstance(); - ArcSDEConnectionConfig config = new ArcSDEConnectionConfig(this.conProps); - this._pool = pfac.createPool(config); + ISessionPoolFactory pfac = SessionPoolFactory.getInstance(); + ArcSDEDataStoreConfig config = new ArcSDEDataStoreConfig(this.conProps); + this._pool = pfac.createPool(config.getSessionConfig()); } return this._pool; } @@ -220,7 +220,7 @@ public void deleteTable(final String typeName) throws IOException, UnavailableArcSDEConnectionException { - SessionPool connectionPool = getConnectionPool(); + ISessionPool connectionPool = getConnectionPool(); deleteTable(connectionPool, typeName); } @@ -231,7 +231,7 @@ * @param connPool * to get the connection to use in deleting {@link #getTempTableName()} */ - public void deleteTempTable(SessionPool connPool) { + public void deleteTempTable(ISessionPool connPool) { try { deleteTable(connPool, getTempTableName()); } catch (Exception e) { @@ -239,7 +239,7 @@ } } - private static void deleteTable(final SessionPool connPool, final String tableName) + private static void deleteTable(final ISessionPool connPool, final String tableName) throws IOException, UnavailableArcSDEConnectionException { final ISession session = connPool.getSession(); @@ -285,7 +285,7 @@ * for any error */ public void createTempTable(final boolean insertTestData) throws Exception { - SessionPool connPool = getConnectionPool(); + ISessionPool connPool = getConnectionPool(); deleteTempTable(connPool); @@ -331,7 +331,7 @@ */ public void insertTestData() throws Exception { truncateTempTable(); - SessionPool connPool = getConnectionPool(); + ISessionPool connPool = getConnectionPool(); ISession session = connPool.getSession(); try { SeLayer tempTableLayer = getTempLayer(session); @@ -342,7 +342,7 @@ } public void truncateTempTable() throws IOException { - final SessionPool connPool = getConnectionPool(); + final ISessionPool connPool = getConnectionPool(); final ISession session = connPool.getSession(); final String tempTableName = getTempTableName(session); Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/FIDReaderTest.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/FIDReaderTest.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/FIDReaderTest.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -24,7 +24,7 @@ import java.io.IOException; -import org.geotools.arcsde.pool.ISession; +import org.geotools.arcsde.session.ISession; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; @@ -86,7 +86,7 @@ /** * Test method for - * {@link org.geotools.arcsde.data.FIDReader#getFidReader(org.geotools.arcsde.pool.ISession, com.esri.sde.sdk.client.SeTable, com.esri.sde.sdk.client.SeLayer, com.esri.sde.sdk.client.SeRegistration)} + * {@link org.geotools.arcsde.data.FIDReader#getFidReader(org.geotools.arcsde.session.ISession, com.esri.sde.sdk.client.SeTable, com.esri.sde.sdk.client.SeLayer, com.esri.sde.sdk.client.SeRegistration)} * . * * @throws IOException Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/GeometryBuilderTest.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/GeometryBuilderTest.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/GeometryBuilderTest.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -26,7 +26,8 @@ import java.util.logging.Level; import java.util.logging.Logger; -import org.geotools.arcsde.pool.ISession; +import org.geotools.arcsde.session.ISession; +import org.geotools.arcsde.session.SdeRow; import org.geotools.data.DataSourceException; import org.junit.After; import org.junit.Assert; Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/InProcessViewSupportTestData.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/InProcessViewSupportTestData.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/InProcessViewSupportTestData.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -22,9 +22,9 @@ import java.util.Map; import java.util.logging.Logger; -import org.geotools.arcsde.pool.Command; -import org.geotools.arcsde.pool.ISession; -import org.geotools.arcsde.pool.UnavailableArcSDEConnectionException; +import org.geotools.arcsde.session.Command; +import org.geotools.arcsde.session.ISession; +import org.geotools.arcsde.session.UnavailableArcSDEConnectionException; import org.geotools.referencing.crs.DefaultGeographicCRS; import org.opengis.referencing.crs.CoordinateReferenceSystem; Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/SDEJavaApiJoinTest.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/SDEJavaApiJoinTest.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/SDEJavaApiJoinTest.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -32,8 +32,9 @@ import net.sf.jsqlparser.statement.select.PlainSelect; import net.sf.jsqlparser.statement.select.SelectBody; -import org.geotools.arcsde.pool.Command; -import org.geotools.arcsde.pool.ISession; +import org.geotools.arcsde.session.Command; +import org.geotools.arcsde.session.ISession; +import org.geotools.arcsde.session.SdeRow; import org.geotools.data.DefaultQuery; import org.geotools.data.FeatureSource; import org.geotools.data.Query; Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/TestData.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/TestData.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/TestData.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -30,14 +30,14 @@ import org.geotools.arcsde.ArcSDEDataStoreFactory; import org.geotools.arcsde.ArcSdeException; -import org.geotools.arcsde.pool.ArcSDEConnectionConfig; -import org.geotools.arcsde.pool.Command; -import org.geotools.arcsde.pool.Commands; -import org.geotools.arcsde.pool.ISession; -import org.geotools.arcsde.pool.SessionPool; -import org.geotools.arcsde.pool.SessionPoolFactory; -import org.geotools.arcsde.pool.UnavailableArcSDEConnectionException; -import org.geotools.arcsde.pool.Commands.GetVersionCommand; +import org.geotools.arcsde.session.Command; +import org.geotools.arcsde.session.Commands; +import org.geotools.arcsde.session.ISession; +import org.geotools.arcsde.session.ISessionPool; +import org.geotools.arcsde.session.ISessionPoolFactory; +import org.geotools.arcsde.session.SessionPoolFactory; +import org.geotools.arcsde.session.UnavailableArcSDEConnectionException; +import org.geotools.arcsde.session.Commands.GetVersionCommand; import org.geotools.data.DataSourceException; import org.geotools.feature.FeatureCollection; import org.geotools.feature.FeatureCollections; @@ -110,7 +110,7 @@ /** the configuration keyword to use when creating layers and tables */ private String configKeyword; - private SessionPool _pool; + private ISessionPool _pool; /** * Creates a new TestData object. @@ -192,23 +192,23 @@ * DOCUMENT ME! */ public ArcSDEDataStore getDataStore() throws IOException { - SessionPool pool = newSessionPool(); + ISessionPool pool = newSessionPool(); ArcSDEDataStore dataStore = new ArcSDEDataStore(pool); return dataStore; } - public SessionPool getConnectionPool() throws IOException { + public ISessionPool getConnectionPool() throws IOException { if (this._pool == null) { this._pool = newSessionPool(); } return this._pool; } - public SessionPool newSessionPool() throws IOException { - SessionPoolFactory pfac = SessionPoolFactory.getInstance(); - ArcSDEConnectionConfig config = new ArcSDEConnectionConfig(this.conProps); - return pfac.createPool(config); + public ISessionPool newSessionPool() throws IOException { + ISessionPoolFactory pfac = SessionPoolFactory.getInstance(); + ArcSDEDataStoreConfig config = new ArcSDEDataStoreConfig(this.conProps); + return pfac.createPool(config.getSessionConfig()); } /** @@ -275,7 +275,7 @@ public void deleteTable(final String typeName, final boolean ignoreFailure) throws IOException, UnavailableArcSDEConnectionException { - SessionPool connectionPool = getConnectionPool(); + ISessionPool connectionPool = getConnectionPool(); deleteTable(connectionPool, typeName, ignoreFailure); } @@ -285,11 +285,11 @@ * @param connPool * to get the connection to use in deleting {@link #getTempTableName()} */ - public void deleteTempTable(SessionPool connPool) throws IOException { + public void deleteTempTable(ISessionPool connPool) throws IOException { deleteTable(connPool, getTempTableName(), true); } - private static void deleteTable(final SessionPool connPool, final String tableName, + private static void deleteTable(final ISessionPool connPool, final String tableName, final boolean ignoreFailure) throws IOException, UnavailableArcSDEConnectionException { final ISession session = connPool.getSession(); @@ -337,7 +337,7 @@ * for any error */ public void createTempTable(final boolean insertTestData) throws Exception { - SessionPool connPool = getConnectionPool(); + ISessionPool connPool = getConnectionPool(); deleteTempTable(connPool); @@ -383,7 +383,7 @@ */ public void insertTestData() throws Exception { truncateTempTable(); - SessionPool connPool = getConnectionPool(); + ISessionPool connPool = getConnectionPool(); ISession session = connPool.getSession(); try { SeLayer tempTableLayer = getTempLayer(session); @@ -401,7 +401,7 @@ public void truncateTestTable(final String tempTableName) throws IOException, DataSourceException, UnavailableArcSDEConnectionException { - final SessionPool connPool = getConnectionPool(); + final ISessionPool connPool = getConnectionPool(); final ISession session = connPool.getSession(); try { @@ -918,7 +918,7 @@ } private void deleteSampleLayers(final int numLayersToCreate) throws IOException { - final SessionPool connectionPool = getConnectionPool(); + final ISessionPool connectionPool = getConnectionPool(); final ISession session = connectionPool.getSession(); final NumberFormat formatter = NumberFormat.getInstance(); formatter.setMinimumIntegerDigits(4); @@ -951,7 +951,7 @@ */ private void createSampleLayers(final int numLayersToCreate, final int startFrom) throws IOException { - final SessionPool connectionPool = getConnectionPool(); + final ISessionPool connectionPool = getConnectionPool(); final ISession session = connectionPool.getSession(); String tableName; @@ -1000,7 +1000,7 @@ } public void createSimpleTestTables() throws IOException { - final SessionPool connectionPool = getConnectionPool(); + final ISessionPool connectionPool = getConnectionPool(); final ISession session = connectionPool.getSession(); String tableName; Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/gce/ArcSDEGridCoverage2DReaderJAILegacyOnlineTest.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/gce/ArcSDEGridCoverage2DReaderJAILegacyOnlineTest.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/gce/ArcSDEGridCoverage2DReaderJAILegacyOnlineTest.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -22,7 +22,7 @@ import javax.media.jai.PlanarImage; import org.geotools.arcsde.ArcSDERasterFormatFactory; -import org.geotools.arcsde.pool.ArcSDEConnectionConfig; +import org.geotools.arcsde.session.ArcSDEConnectionConfig; import org.geotools.coverage.grid.GridCoverage2D; import org.geotools.coverage.grid.GridEnvelope2D; import org.geotools.coverage.grid.GridGeometry2D; @@ -416,8 +416,8 @@ private AbstractGridCoverage2DReader getReader() throws DataSourceException { final ArcSDEConnectionConfig config = rasterTestData.getConnectionPool().getConfig(); - final String rgbUrl = "sde://" + config.getUserName() + ":" + config.getUserPassword() - + "@" + config.getServerName() + ":" + config.getPortNumber() + "/" + final String rgbUrl = "sde://" + config.getUserName() + ":" + config.getPassword() + "@" + + config.getServerName() + ":" + config.getPortNumber() + "/" + config.getDatabaseName() + "#" + tableName; final ArcSDERasterFormat format = new ArcSDERasterFormatFactory().createFormat(); Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/gce/ArcSDEGridCoverage2DReaderJAIOnlineTest.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/gce/ArcSDEGridCoverage2DReaderJAIOnlineTest.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/gce/ArcSDEGridCoverage2DReaderJAIOnlineTest.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -36,7 +36,7 @@ import javax.media.jai.operator.FormatDescriptor; import org.geotools.arcsde.ArcSDERasterFormatFactory; -import org.geotools.arcsde.pool.ArcSDEConnectionConfig; +import org.geotools.arcsde.session.ArcSDEConnectionConfig; import org.geotools.coverage.grid.GridCoverage2D; import org.geotools.coverage.grid.GridEnvelope2D; import org.geotools.coverage.grid.GridGeometry2D; @@ -697,8 +697,8 @@ private AbstractGridCoverage2DReader getReader() throws DataSourceException { final ArcSDEConnectionConfig config = rasterTestData.getConnectionPool().getConfig(); - final String rgbUrl = "sde://" + config.getUserName() + ":" + config.getUserPassword() - + "@" + config.getServerName() + ":" + config.getPortNumber() + "/" + final String rgbUrl = "sde://" + config.getUserName() + ":" + config.getPassword() + "@" + + config.getServerName() + ":" + config.getPortNumber() + "/" + config.getDatabaseName() + "#" + tableName; final ArcSDERasterFormat format = new ArcSDERasterFormatFactory().createFormat(); Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/gce/RasterInfoTest.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/gce/RasterInfoTest.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/gce/RasterInfoTest.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -24,7 +24,7 @@ import java.awt.geom.Point2D.Double; import org.geotools.arcsde.ArcSdeException; -import org.geotools.arcsde.pool.ArcSDEConnectionPool; +import org.geotools.arcsde.session.ArcSDEConnectionPool; import org.geotools.geometry.jts.ReferencedEnvelope; import org.geotools.referencing.CRS; import org.geotools.referencing.crs.DefaultEngineeringCRS; Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/gce/RasterTestData.java =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/gce/RasterTestData.java 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/gce/RasterTestData.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -59,16 +59,17 @@ import javax.imageio.ImageIO; import org.geotools.arcsde.ArcSdeException; +import org.geotools.arcsde.data.ArcSDEDataStoreConfig; import org.geotools.arcsde.data.TestData; import org.geotools.arcsde.gce.producer.ArcSDERasterFloatProducerImpl; import org.geotools.arcsde.gce.producer.ArcSDERasterOneBitPerBandProducerImpl; import org.geotools.arcsde.gce.producer.ArcSDERasterOneBytePerBandProducerImpl; import org.geotools.arcsde.gce.producer.ArcSDERasterProducer; -import org.geotools.arcsde.pool.ArcSDEConnectionConfig; -import org.geotools.arcsde.pool.ArcSDEConnectionPool; -import org.geotools.arcsde.pool.ArcSDEConnectionPoolFactory; -import org.geotools.arcsde.pool.ArcSDEPooledConnection; -import org.geotools.arcsde.pool.UnavailableArcSDEConnectionException; +import org.geotools.arcsde.session.ArcSDEConnectionConfig; +import org.geotools.arcsde.session.ArcSDEConnectionPool; +import org.geotools.arcsde.session.ArcSDEConnectionPoolFactory; +import org.geotools.arcsde.session.ArcSDEPooledConnection; +import org.geotools.arcsde.session.UnavailableArcSDEConnectionException; import org.geotools.data.DataSourceException; import org.geotools.util.logging.Logging; @@ -133,7 +134,8 @@ public ArcSDEConnectionPool getConnectionPool() throws DataSourceException { if (this._pool == null) { ArcSDEConnectionPoolFactory pfac = ArcSDEConnectionPoolFactory.getInstance(); - ArcSDEConnectionConfig config = new ArcSDEConnectionConfig(testData.getConProps()); + ArcSDEConnectionConfig config = new ArcSDEDataStoreConfig(testData.getConProps()) + .getSessionConfig(); this._pool = pfac.createPool(config); } return this._pool; @@ -171,7 +173,7 @@ public String createCoverageUrl(final String rasterTableName) throws IOException { final ArcSDEConnectionConfig config = getConnectionPool().getConfig(); - String url = "sde://" + config.getUserName() + ":" + config.getUserPassword() + "@" + String url = "sde://" + config.getUserName() + ":" + config.getPassword() + "@" + config.getServerName() + ":" + config.getPortNumber() + "/" + config.getDatabaseName() + "#" + rasterTableName; return url; Deleted: branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/session/SessionPoolTest.java =================================================================== --- trunk/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/session/SessionPoolTest.java 2009-07-07 01:13:56 UTC (rev 33502) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/session/SessionPoolTest.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -1,309 +0,0 @@ -/* - * 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.arcsde.session; - -import static org.geotools.arcsde.session.ArcSDEConnectionConfig.INSTANCE_NAME_PARAM_NAME; -import static org.geotools.arcsde.session.ArcSDEConnectionConfig.MAX_CONNECTIONS_PARAM_NAME; -import static org.geotools.arcsde.session.ArcSDEConnectionConfig.MIN_CONNECTIONS_PARAM_NAME; -import static org.geotools.arcsde.session.ArcSDEConnectionConfig.SERVER_NAME_PARAM_NAME; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; -import java.util.logging.Logger; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -/** - * Tests the functionality of a pool of ArcSDE connection objects over a live ArcSDE database - * - * @author Gabriel Roldan - * @source $URL: - * http://svn.geotools.org/geotools/trunk/gt/modules/plugin/arcsde/datastore/src/test/java - * /org/geotools/arcsde/pool/SessionPoolTest.java $ - * @version $Id$ - */ -@SuppressWarnings("unchecked") -public class SessionPoolTest { - - private static Logger LOGGER = Logger.getLogger("org.geotools.data.sde"); - - private Map<String, String> connectionParameters; - - private ArcSDEConnectionConfig connectionConfig = null; - - private ISessionPool pool = null; - - /** - * loads {@code test-data/testparams.properties} to get connection parameters and sets up a - * ArcSDEConnectionConfig with them for tests to set up SessionPool's as required - * - * @throws Exception - * - * @throws IllegalStateException - */ - @Before - public void setUp() throws Exception { - - Properties conProps = new Properties(); - String propsFile = "testparams.properties"; - URL conParamsSource = org.geotools.test.TestData.url(null, propsFile); - - LOGGER.fine("loading connection parameters from " + conParamsSource.toExternalForm()); - - InputStream in = conParamsSource.openStream(); - - if (in == null) { - throw new IllegalStateException("cannot find test params: " - + conParamsSource.toExternalForm()); - } - - conProps.load(in); - in.close(); - connectionParameters = new HashMap<String, String>(); - for (Map.Entry e : conProps.entrySet()) { - connectionParameters.put((String) e.getKey(), (String) e.getValue()); - } - - // test that mandatory connection parameters are set - try { - connectionConfig = ArcSDEConnectionConfig.fromMap(connectionParameters); - } catch (Exception ex) { - throw new IllegalStateException("No valid connection parameters found in " - + conParamsSource.toExternalForm() + ": " + ex.getMessage()); - } - } - - /** - * closes the connection pool if it's still open - * - * @throws Exception - */ - @After - public void tearDown() throws Exception { - connectionConfig = null; - - if (pool != null) { - pool.close(); - } - - pool = null; - } - - /** - * Sets up a new SessionPool with the connection parameters stored in <code>connParams</code> - * and throws an exception if something goes wrong - * - * @param connParams - * a set of connection parameters from where the new SessionPool will connect to the - * SDE database and create connections - * @return - * @throws IllegalArgumentException - * if the set of connection parameters are not propperly set - * @throws NullPointerException - * if <code>connParams</code> is null - * @throws IOException - * if the pool can't create the connections with the passed arguments (i.e. can't - * connect to SDE database) - */ - private ISessionPool createPool(Map<String, String> connParams) - throws IllegalArgumentException, NullPointerException, IOException { - this.connectionConfig = ArcSDEConnectionConfig.fromMap(connParams); - LOGGER.fine("creating a new SessionPool with " + connectionConfig); - - if (this.pool != null) { - LOGGER.fine("pool already created, closing it"); - this.pool.close(); - } - - this.pool = new SessionPool(connectionConfig); - LOGGER.fine("pool created"); - - return this.pool; - } - - /** - * tests that a connection to a live ArcSDE database can be established with the parameters - * defined int testparams.properties, and a SessionPool can be properly setted up - * - * @throws IOException - */ - @Test - public void testConnect() throws IOException { - LOGGER.fine("testing connection to the sde database"); - - ISessionPoolFactory pf = SessionPoolFactory.getInstance(); - ArcSDEConnectionConfig config = ArcSDEConnectionConfig.fromMap(connectionParameters); - - ISessionPool connPool = null; - - connPool = pf.createPool(config); - LOGGER.fine("connection succeed " + connPool.getPoolSize() + " connections ready"); - connPool.close(); - } - - @Test - public void testConnectFailure() throws IOException { - - connectionParameters.put(SERVER_NAME_PARAM_NAME, "unreacheable-server-name"); - ArcSDEConnectionConfig config = ArcSDEConnectionConfig.fromMap(connectionParameters); - - try { - ISessionPool connPool = new SessionPool(config); - connPool.close(); - fail("Expected IOE for unreachable server"); - } catch (IOException e) { - assertTrue(true); - } - - } - - /** - * Checks that after creation the pool has the specified initial number of connections. - * - * @throws IOException - * - * @throws UnavailableArcSDEConnectionException - */ - @Test - public void testInitialCount() throws IOException, UnavailableArcSDEConnectionException { - int MIN_CONNECTIONS = 2; - int MAX_CONNECTIONS = 6; - - // override pool.minConnections and pool.maxConnections from - // the configured parameters to test the connections' pool - // availability - Map params = new HashMap(this.connectionParameters); - params.put(MIN_CONNECTIONS_PARAM_NAME, Integer.valueOf(MIN_CONNECTIONS)); - params.put(MAX_CONNECTIONS_PARAM_NAME, Integer.valueOf(MAX_CONNECTIONS)); - - createPool(params); - - // check that after creation, the pool contains the minimun number - // of connections specified - assertEquals( - "after creation, the pool must contain the minimun number of connections specified", - MIN_CONNECTIONS, this.pool.getPoolSize()); - } - - /** - * Tests that the pool creation fails if a wrong set of parameters is passed (i.e. - * maxConnections is lower than minConnections) - * - * @throws IOException - * @throws UnavailableArcSDEConnectionException - */ - @Test - public void testChecksLimits() throws IOException, UnavailableArcSDEConnectionException { - int MIN_CONNECTIONS = 2; - - // override pool.minConnections and pool.maxConnections from - // the configured parameters to test the connections' pool - // availability - Map params = new HashMap(this.connectionParameters); - params.put(MIN_CONNECTIONS_PARAM_NAME, Integer.valueOf(MIN_CONNECTIONS)); - params.put(MAX_CONNECTIONS_PARAM_NAME, Integer.valueOf(1)); - - // this MUST fail, since maxConnections is lower than minConnections - try { - LOGGER.fine("testing parameters' sanity check at pool creation time"); - ISessionPool pool = createPool(params); - pool.close(); - fail("the connection pool creation must have failed since a wrong set of arguments was passed"); - } catch (IllegalArgumentException ex) { - // it's ok, it is what's expected - LOGGER.fine("pramams assertion passed"); - } - } - - /** - * tests that no more than pool.maxConnections connections can be created, and once one - * connection is freed, it is ready to be used again. - * - * @throws Exception - */ - @Test - public void testMaxConnections() throws Exception { - final int MIN_CONNECTIONS = 2; - final int MAX_CONNECTIONS = 2; - - Map params = new HashMap(this.connectionParameters); - params.put(MIN_CONNECTIONS_PARAM_NAME, Integer.valueOf(MIN_CONNECTIONS)); - params.put(MAX_CONNECTIONS_PARAM_NAME, Integer.valueOf(MAX_CONNECTIONS)); - - createPool(params); - - ISession[] sessions = new ISession[MAX_CONNECTIONS]; - // try to get the maximun number of connections specified, and do not - // release anyone - for (int i = 0; i < MAX_CONNECTIONS; i++) { - sessions[i] = pool.getSession(); - } - - // now that the max number of connections is reached, the pool - // should throw an UnavailableArcSDEConnectionException - try { - this.pool.getSession(); - fail("since the max number of connections was reached, the pool should have throwed an UnavailableArcSDEConnectionException"); - } catch (UnavailableArcSDEConnectionException ex) { - LOGGER - .fine("maximun number of connections reached, got an UnavailableArcSDEConnectionException, it's OK"); - } - - // now, free one and check the same conection is returned on the - // next call to getConnection() - ISession expected = sessions[0]; - expected.dispose(); - - Thread.currentThread().sleep(1000); - ISession session = this.pool.getSession(); - assertEquals(expected, session); - } - - /** - * a null database name should not be an impediment to create the pool - * - * @throws IOException - */ - @Test - public void testCreateWithNullDBName() throws IOException { - Map params = new HashMap(this.connectionParameters); - params.remove(INSTANCE_NAME_PARAM_NAME); - createPool(params); - } - - /** - * an empty database name should not be an impediment to create the pool - * - * @throws IOException - */ - @Test - public void testCreateWithEmptyDBName() throws IOException { - Map params = new HashMap(this.connectionParameters); - params.put(INSTANCE_NAME_PARAM_NAME, ""); - createPool(params); - } -} Copied: branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/session/SessionPoolTest.java (from rev 33502, trunk/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/session/SessionPoolTest.java) =================================================================== --- branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/session/SessionPoolTest.java (rev 0) +++ branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/session/SessionPoolTest.java 2009-07-07 15:55:29 UTC (rev 33511) @@ -0,0 +1,309 @@ +/* + * 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.arcsde.session; + +import static org.geotools.arcsde.session.ArcSDEConnectionConfig.INSTANCE_NAME_PARAM_NAME; +import static org.geotools.arcsde.session.ArcSDEConnectionConfig.MAX_CONNECTIONS_PARAM_NAME; +import static org.geotools.arcsde.session.ArcSDEConnectionConfig.MIN_CONNECTIONS_PARAM_NAME; +import static org.geotools.arcsde.session.ArcSDEConnectionConfig.SERVER_NAME_PARAM_NAME; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.logging.Logger; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * Tests the functionality of a pool of ArcSDE connection objects over a live ArcSDE database + * + * @author Gabriel Roldan + * @source $URL: + * http://svn.geotools.org/geotools/trunk/gt/modules/plugin/arcsde/datastore/src/test/java + * /org/geotools/arcsde/pool/SessionPoolTest.java $ + * @version $Id$ + */ +@SuppressWarnings("unchecked") +public class SessionPoolTest { + + private static Logger LOGGER = Logger.getLogger("org.geotools.data.sde"); + + private Map<String, String> connectionParameters; + + private ArcSDEConnectionConfig connectionConfig = null; + + private ISessionPool pool = null; + + /** + * loads {@code test-data/testparams.properties} to get connection parameters and sets up a + * ArcSDEConnectionConfig with them for tests to set up SessionPool's as required + * + * @throws Exception + * + * @throws IllegalStateException + */ + @Before + public void setUp() throws Exception { + + Properties conProps = new Properties(); + String propsFile = "testparams.properties"; + URL conParamsSource = org.geotools.test.TestData.url(null, propsFile); + + LOGGER.fine("loading connection parameters from " + conParamsSource.toExternalForm()); + + InputStream in = conParamsSource.openStream(); + + if (in == null) { + throw new IllegalStateException("cannot find test params: " + + conParamsSource.toExternalForm()); + } + + conProps.load(in); + in.close(); + connectionParameters = new HashMap<String, String>(); + for (Map.Entry e : conProps.entrySet()) { + connectionParameters.put((String) e.getKey(), (String) e.getValue()); + } + + // test that mandatory connection parameters are set + try { + connectionConfig = ArcSDEConnectionConfig.fromMap(connectionParameters); + } catch (Exception ex) { + throw new IllegalStateException("No valid connection parameters found in " + + conParamsSource.toExternalForm() + ": " + ex.getMessage()); + } + } + + /** + * closes the connection pool if it's still open + * + * @throws Exception + */ + @After + public void tearDown() throws Exception { + connectionConfig = null; + + if (pool != null) { + pool.close(); + } + + pool = null; + } + + /** + * Sets up a new SessionPool with the connection parameters stored in <code>connParams</code> + * and throws an exception if something goes wrong + * + * @param connParams + * a set of connection parameters from where the new SessionPool will connect to the + * SDE database and create connections + * @return + * @throws IllegalArgumentException + * if the set of connection parameters are not propperly set + * @throws NullPointerException + * if <code>connParams</code> is null + * @throws IOException + * if the pool can't create the connections with the passed arguments (i.e. can't + * connect to SDE database) + */ + private ISessionPool createPool(Map<String, String> connParams) + throws IllegalArgumentException, NullPointerException, IOException { + this.connectionConfig = ArcSDEConnectionConfig.fromMap(connParams); + LOGGER.fine("creating a new SessionPool with " + connectionConfig); + + if (this.pool != null) { + LOGGER.fine("pool already created, closing it"); + this.pool.close(); + } + + this.pool = new SessionPool(connectionConfig); + LOGGER.fine("pool created"); + + return this.pool; + } + + /** + * tests that a connection to a live ArcSDE database can be established with the parameters + * defined int testparams.properties, and a SessionPool can be properly setted up + * + * @throws IOException + */ + @Test + public void testConnect() throws IOException { + LOGGER.fine("testing connection to the sde database"); + + ISessionPoolFactory pf = SessionPoolFactory.getInstance(); + ArcSDEConnectionConfig config = ArcSDEConnectionConfig.fromMap(connectionParameters); + + ISessionPool connPool = null; + + connPool = pf.createPool(config); + LOGGER.fine("connection succeed " + connPool.getPoolSize() + " connections ready"); + connPool.close(); + } + + @Test + public void testConnectFailure() throws IOException { + + connectionParameters.put(SERVER_NAME_PARAM_NAME, "unreacheable-server-name"); + ArcSDEConnectionConfig config = ArcSDEConnectionConfig.fromMap(connectionParameters); + + try { + ISessionPool connPool = new SessionPool(config); + connPool.close(); + fail("Expected IOE for unreachable server"); + } catch (IOException e) { + assertTrue(true); + } + + } + + /** + * Checks that after creation the pool has the specified initial number of connections. + * + * @throws IOException + * + * @throws UnavailableArcSDEConnectionException + */ + @Test + public void testInitialCount() throws IOException, UnavailableArcSDEConnectionException { + int MIN_CONNECTIONS = 2; + int MAX_CONNECTIONS = 6; + + // override pool.minConnections and pool.maxConnections from + // the configured parameters to test the connections' pool + // availability + Map params = new HashMap(this.connectionParameters); + params.put(MIN_CONNECTIONS_PARAM_NAME, Integer.valueOf(MIN_CONNECTIONS)); + params.put(MAX_CONNECTIONS_PARAM_NAME, Integer.valueOf(MAX_CONNECTIONS)); + + createPool(params); + + // check that after creation, the pool contains the minimun number + // of connections specified + assertEquals( + "after creation, the pool must contain the minimun number of connections specified", + MIN_CONNECTIONS, this.pool.getPoolSize()); + } + + /** + * Tests that the pool creation fails if a wrong set of parameters is passed (i.e. + * maxConnections is lower than minConnections) + * + * @throws IOException + * @throws UnavailableArcSDEConnectionException + */ + @Test + public void testChecksLimits() throws IOException, UnavailableArcSDEConnectionException { + int MIN_CONNECTIONS = 2; + + // override pool.minConnections and pool.maxConnections from + // the configured parameters to test the connections' pool + // availability + Map params = new HashMap(this.connectionParameters); + params.put(MIN_CONNECTIONS_PARAM_NAME, Integer.valueOf(MIN_CONNECTIONS)); + params.put(MAX_CONNECTIONS_PARAM_NAME, Integer.valueOf(1)); + + // this MUST fail, since maxConnections is lower than minConnections + try { + LOGGER.fine("testing parameters' sanity check at pool creation time"); + ISessionPool pool = createPool(params); + pool.close(); + fail("the connection pool creation must have failed since a wrong set of arguments was passed"); + } catch (IllegalArgumentException ex) { + // it's ok, it is what's expected + LOGGER.fine("pramams assertion passed"); + } + } + + /** + * tests that no more than pool.maxConnections connections can be created, and once one + * connection is freed, it is ready to be used again. + * + * @throws Exception + */ + @Test + public void testMaxConnections() throws Exception { + final int MIN_CONNECTIONS = 2; + final int MAX_CONNECTIONS = 2; + + Map params = new HashMap(this.connectionParameters); + params.put(MIN_CONNECTIONS_PARAM_NAME, Integer.valueOf(MIN_CONNECTIONS)); + params.put(MAX_CONNECTIONS_PARAM_NAME, Integer.valueOf(MAX_CONNECTIONS)); + + createPool(params); + + ISession[] sessions = new ISession[MAX_CONNECTIONS]; + // try to get the maximun number of connections specified, and do not + // release anyone + for (int i = 0; i < MAX_CONNECTIONS; i++) { + sessions[i] = pool.getSession(); + } + + // now that the max number of connections is reached, the pool + // should throw an UnavailableArcSDEConnectionException + try { + this.pool.getSession(); + fail("since the max number of connections was reached, the pool should have throwed an UnavailableArcSDEConnectionException"); + } catch (UnavailableArcSDEConnectionException ex) { + LOGGER + .fine("maximun number of connections reached, got an UnavailableArcSDEConnectionException, it's OK"); + } + + // now, free one and check the same conection is returned on the + // next call to getConnection() + ISession expected = sessions[0]; + expected.dispose(); + + Thread.currentThread().sleep(1000); + ISession session = this.pool.getSession(); + assertEquals(expected, session); + } + + /** + * a null database name should not be an impediment to create the pool + * + * @throws IOException + */ + @Test + public void testCreateWithNullDBName() throws IOException { + Map params = new HashMap(this.connectionParameters); + params.remove(INSTANCE_NAME_PARAM_NAME); + createPool(params); + } + + /** + * an empty database name should not be an impediment to create the pool + * + * @throws IOException + */ + @Test + public void testCreateWithEmptyDBName() throws IOException { + Map params = new HashMap(this.connectionParameters); + params.put(INSTANCE_NAME_PARAM_NAME, ""); + createPool(params); + } +} Modified: branches/2.5.x/modules/plugin/arcsde/pom.xml =================================================================== --- branches/2.5.x/modules/plugin/arcsde/pom.xml 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/pom.xml 2009-07-07 15:55:29 UTC (rev 33511) @@ -99,6 +99,7 @@ <!-- Modules included in the build --> <!-- =========================================================== --> <modules> + <module>common</module> <module>datastore</module> </modules> Modified: branches/2.5.x/modules/plugin/arcsde/sde-dummy/pom.xml =================================================================== --- branches/2.5.x/modules/plugin/arcsde/sde-dummy/pom.xml 2009-07-07 15:14:19 UTC (rev 33510) +++ branches/2.5.x/modules/plugin/arcsde/sde-dummy/pom.xml 2009-07-07 15:55:29 UTC (rev 33511) @@ -31,9 +31,9 @@ <scm> <connection> - scm:svn:http://svn.osgeo.org/geotools/branches/2.5.x/modules/plugin/arcsde/sde-dummy/ + scm:svn:http://svn.osgeo.org/geotools/trunk/modules/plugin/arcsde/sde-dummy/ </connection> - <url>http://svn.osgeo.org/geotools/branches/2.5.x/modules/plugin/arcsde/sde-dummy/</url> + <url>http://svn.osgeo.org/geotools/trunk/modules/plugin/arcsde/sde-dummy/</url> </scm> <description> ------------------------------------------------------------------------------ Enter the BlackBerry Developer Challenge This is your chance to win up to $100,000 in prizes! For a limited time, vendors submitting new applications to BlackBerry App World(TM) will have the opportunity to enter the BlackBerry Developer Challenge. See full prize details at: http://p.sf.net/sfu/blackberry _______________________________________________ GeoTools-commits mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/geotools-commits |
||||||||||||||||
| Free Embeddable Forum Powered by Nabble | Help |