libspring-java-3.0.6.RELEASE/0000755000175000017500000000000011623223526015405 5ustar drazzibdrazziblibspring-java-3.0.6.RELEASE/projects/0000755000175000017500000000000011623223530017231 5ustar drazzibdrazziblibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/0000755000175000017500000000000011623223530024140 5ustar drazzibdrazziblibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/template.mf0000644000175000017500000000333511623223526026310 0ustar drazzibdrazzibBundle-SymbolicName: org.springframework.jdbc Bundle-Name: Spring JDBC Bundle-Vendor: SpringSource Bundle-ManifestVersion: 2 Import-Package: com.ibm.websphere.rsadapter;version="0";resolution:=optional, com.ibm.ws.rsadapter.jdbc;version="0";resolution:=optional, oracle.jdbc;version="0";resolution:=optional, oracle.sql;version="0";resolution:=optional, org.h2;version="[1.8.0, 2.0.0)";resolution:=optional, org.hsqldb;version="[1.0.0, 2.0.0)";resolution:=optional, org.jboss.resource.adapter.jdbc;version="0";resolution:=optional, weblogic.jdbc.extensions;version="0";resolution:=optional Import-Template: com.mchange.v2.c3p0.*;version="[0.9.1, 2.0.0)";resolution:=optional, com.sun.rowset.*;version="[1.0.1, 2.0.0)";resolution:=optional, javax.naming.*;version="0";resolution:=optional, javax.sql.*;version="0", javax.transaction.*;version="[1.0.1, 2.0.0)";resolution:=optional, javax.xml.*;version="0";resolution:=optional, org.h2.*;version="[1.0.0, 2.0.0)";resolution:=optional, org.hsqldb.*;version="[1.8.0, 2.0.0)";resolution:=optional, org.apache.derby.*;version="[10.5.0, 11.0.0)";resolution:=optional, org.apache.commons.logging.*;version="[1.1.1, 2.0.0)", org.springframework.beans.*;version=${spring.osgi.range}, org.springframework.core.*;version=${spring.osgi.range}, org.springframework.context.*;version=${spring.osgi.range}, org.springframework.dao.*;version=${spring.osgi.range}, org.springframework.jndi.*;version=${spring.osgi.range};resolution:=optional, org.springframework.transaction.*;version=${spring.osgi.range}, org.springframework.util.*;version=${spring.osgi.range}, org.w3c.dom.*;version="0";resolution:=optional Ignored-Existing-Headers: Bnd-LastModified, Import-Package, Export-Package, Tool libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/pom.xml0000644000175000017500000000642711623223526025473 0ustar drazzibdrazzib 4.0.0 org.springframework spring-jdbc jar 3.0.6.RELEASE org.springframework spring-parent ../org.springframework.spring-parent 3.0.6.RELEASE c3p0 c3p0 0.9.1.2 true org.apache.geronimo.specs geronimo-jta_1.1_spec 1.1 provided org.springframework spring-beans ${project.version} compile org.springframework spring-context ${project.version} true org.springframework spring-core ${project.version} compile org.springframework spring-tx ${project.version} compile hsqldb hsqldb 1.8.0.7 compile true com.h2database h2 1.0.71 compile true org.apache.derby com.springsource.org.apache.derby 10.5.1000001.764942 compile true org.apache.derby com.springsource.org.apache.derby.client 10.5.1000001.764942 compile true junit junit test org.easymock easymock test src/test/resources **/*.sql **/*.xml libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/build.xml0000644000175000017500000000051411623223530025761 0ustar drazzibdrazzib libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/ivy.xml0000644000175000017500000000536111623223530025476 0ustar drazzibdrazzib libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/.classpath0000644000175000017500000000567711623223530026142 0ustar drazzibdrazzib libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/.project0000644000175000017500000000057711623223526025625 0ustar drazzibdrazzib org.springframework.jdbc org.eclipse.jdt.core.javabuilder org.eclipse.jdt.core.javanature libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/jdbc.iml0000644000175000017500000001042611623223530025550 0ustar drazzibdrazzib libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/0000755000175000017500000000000011623223526024734 5ustar drazzibdrazziblibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/0000755000175000017500000000000011623223526025660 5ustar drazzibdrazziblibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/resources/0000755000175000017500000000000011623223526027672 5ustar drazzibdrazziblibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/resources/META-INF/0000755000175000017500000000000011623223530031025 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000015200000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/resources/META-INF/spring.toolinglibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/resources/META-INF/spring.to0000644000175000017500000000041611623223526032701 0ustar drazzibdrazzib# Tooling related information for the jdbc namespace http\://www.springframework.org/schema/jdbc@name=jdbc Namespace http\://www.springframework.org/schema/jdbc@prefix=jdbc http\://www.springframework.org/schema/jdbc@icon=org/springframework/jdbc/config/spring-jdbc.gif ././@LongLink0000000000000000000000000000015200000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/resources/META-INF/spring.schemaslibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/resources/META-INF/spring.sc0000644000175000017500000000034311623223530032656 0ustar drazzibdrazzibhttp\://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd=org/springframework/jdbc/config/spring-jdbc-3.0.xsd http\://www.springframework.org/schema/jdbc/spring-jdbc.xsd=org/springframework/jdbc/config/spring-jdbc-3.0.xsd././@LongLink0000000000000000000000000000015300000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/resources/META-INF/spring.handlerslibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/resources/META-INF/spring.ha0000644000175000017500000000014011623223526032641 0ustar drazzibdrazzibhttp\://www.springframework.org/schema/jdbc=org.springframework.jdbc.config.JdbcNamespaceHandlerlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/resources/org/0000755000175000017500000000000011623223526030461 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/resources/org/springframework/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/resources/org/springframewor0000755000175000017500000000000011623223526033447 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000015400000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/resources/org/springframework/jdbc/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/resources/org/springframewor0000755000175000017500000000000011623223526033447 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000016300000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/resources/org/springframework/jdbc/config/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/resources/org/springframewor0000755000175000017500000000000011623223530033442 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000020200000000000011557 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/resources/org/springframework/jdbc/config/spring-jdbc.giflibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/resources/org/springframewor0000644000175000017500000000110511623223526033446 0ustar drazzibdrazzibGIF89a)B/IBB`Ih)X;hXտ󖫿Xz5h`qqʖq썫֠V-Gbє{KPSsk9i8`2]1f7yU+ʠpmI%qM'qM)aޢeb?dA pI&b8ט`ٜdqLjE(`lI.Ւ]c_DŽTuP7tŀUn@'V9}SfEuPƀX}\j>'tStTh<'kNnXlZeVXL\QTRQP!_,_  !  *./)B8",N6+"?Y3=P4!-7'0FEDOI1X>(;\RQ@ݜ#]GK&SZUHݣ 2ATW%VMCu((;././@LongLink0000000000000000000000000000020600000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/resources/org/springframework/jdbc/config/spring-jdbc-3.0.xsdlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/resources/org/springframewor0000644000175000017500000001260611623223530033451 0ustar drazzibdrazzib elements. ]]> Is this bean "enabled", meaning the scripts will be executed? Defaults to true, but can be used to switch on and off the initialization depending on the environment. Should failed SQL statements be ignored during initialization? ././@LongLink0000000000000000000000000000016400000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/resources/org/springframework/jdbc/support/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/resources/org/springframewor0000755000175000017500000000000011623223526033447 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000020700000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/resources/org/springframework/jdbc/support/sql-error-codes.xmllibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/resources/org/springframewor0000644000175000017500000001710311623223526033453 0ustar drazzibdrazzib DB2* -007,-029,-097,-104,-109,-115,-128,-199,-204,-206,-301,-408,-441,-491 -803 -407,-530,-531,-532,-543,-544,-545,-603,-667 -904,-971 -1035,-1218,-30080,-30081 -911,-913 Apache Derby true 42802,42821,42X01,42X02,42X03,42X04,42X05,42X06,42X07,42X08 23505 22001,22005,23502,23503,23513,X0Y32 04501,08004,42Y07 40XL1 40001 42000,42001,42101,42102,42111,42112,42121,42122,42132 23001 22003,22012,22025,23000 90046,90100,90117,90121,90126 50200 HSQL Database Engine -22,-28 -104 -9 -80 Informix Dynamic Server -201,-217,-696 -239,-268,-6017 -692,-11030 Microsoft SQL Server 156,170,207,208 229 2601,2627 544,8114,8115 4060 1222 1205 1054,1064,1146 1062 630,839,840,893,1169,1215,1216,1217,1451,1452,1557 1 1205 1213 900,903,904,917,936,942,17006 17003 1 1400,1722,2291,2292 17002,17447 54 8177 60 true 03000,42000,42601,42602,42622,42804,42P01 23505 23000,23502,23503,23514 53000,53100,53200,53300 55P03 40001 40P01 Sybase SQL Server SQL Server Adaptive Server Enterprise ASE sql server 101,102,103,104,105,106,107,108,109,110,111,112,113,116,120,121,123,207,208,213,257,512 2601 233,423,511,515,530,547,2615,2714 921,1105 1205 libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/0000755000175000017500000000000011623223530026574 5ustar drazzibdrazziblibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/overview.html0000644000175000017500000000021511623223530031326 0ustar drazzibdrazzib

Spring's JDBC support package. Includes DataSource setup support as well as JDBC access support.

libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/0000755000175000017500000000000011623223526027370 5ustar drazzibdrazziblibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/0000755000175000017500000000000011623223526032610 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000755000175000017500000000000011623223530033263 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000017700000000000011572 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/SQLWarningException.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000315711623223530033273 0ustar drazzibdrazzib/* * Copyright 2002-2006 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc; import java.sql.SQLWarning; import org.springframework.dao.UncategorizedDataAccessException; /** * Exception thrown when we're not ignoring {@link java.sql.SQLWarning SQLWarnings}. * *

If a SQLWarning is reported, the operation completed, so we will need * to explicitly roll it back if we're not happy when looking at the warning. * We might choose to ignore (and log) the warning, or to wrap and throw it * in the shape of this SQLWarningException instead. * * @author Rod Johnson * @author Juergen Hoeller * @see org.springframework.jdbc.core.JdbcTemplate#setIgnoreWarnings */ public class SQLWarningException extends UncategorizedDataAccessException { /** * Constructor for SQLWarningException. * @param msg the detail message * @param ex the JDBC warning */ public SQLWarningException(String msg, SQLWarning ex) { super(msg, ex); } /** * Return the underlying SQLWarning. */ public SQLWarning SQLWarning() { return (SQLWarning) getCause(); } } ././@LongLink0000000000000000000000000000022200000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/IncorrectResultSetColumnCountException.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000423011623223530033264 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc; import org.springframework.dao.DataRetrievalFailureException; /** * Data access exception thrown when a result set did not have the correct column count, * for example when expecting a single column but getting 0 or more than 1 columns. * * @author Juergen Hoeller * @since 2.0 * @see org.springframework.dao.IncorrectResultSizeDataAccessException */ public class IncorrectResultSetColumnCountException extends DataRetrievalFailureException { private int expectedCount; private int actualCount; /** * Constructor for IncorrectResultSetColumnCountException. * @param expectedCount the expected column count * @param actualCount the actual column count */ public IncorrectResultSetColumnCountException(int expectedCount, int actualCount) { super("Incorrect column count: expected " + expectedCount + ", actual " + actualCount); this.expectedCount = expectedCount; this.actualCount = actualCount; } /** * Constructor for IncorrectResultCountDataAccessException. * @param msg the detail message * @param expectedCount the expected column count * @param actualCount the actual column count */ public IncorrectResultSetColumnCountException(String msg, int expectedCount, int actualCount) { super(msg); this.expectedCount = expectedCount; this.actualCount = actualCount; } /** * Return the expected column count. */ public int getExpectedCount() { return this.expectedCount; } /** * Return the actual column count. */ public int getActualCount() { return this.actualCount; } } ././@LongLink0000000000000000000000000000017000000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/package-info.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000165111623223530033270 0ustar drazzibdrazzib /** * * The classes in this package make JDBC easier to use and * reduce the likelihood of common errors. In particular, they: *

* *

This package and related packages are discussed in Chapter 9 of * Expert One-On-One J2EE Design and Development * by Rod Johnson (Wrox, 2002). * */ package org.springframework.jdbc; ././@LongLink0000000000000000000000000000016200000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000755000175000017500000000000011623223530033263 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000017300000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000755000175000017500000000000011623223530033263 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000021400000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/package-info.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000021711623223530033265 0ustar drazzibdrazzib /** * * Provides extensible support for creating embedded database instances. * */ package org.springframework.jdbc.datasource.embedded; ././@LongLink0000000000000000000000000000023300000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseFactoryBean.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000360111623223530033265 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource.embedded; import javax.sql.DataSource; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.InitializingBean; /** * A subclass of {@link EmbeddedDatabaseFactory} that implements {@link FactoryBean} for registration as a Spring bean. * Returns the actual {@link DataSource} that provides connectivity to the embedded database to Spring. * *

The target DataSource is returned instead of a {@link EmbeddedDatabase} proxy since the FactoryBean * will manage the initialization and destruction lifecycle of the database instance. * *

Implements DisposableBean to shutdown the embedded database when the managing Spring container is shutdown. * * @author Keith Donald * @since 3.0 */ public class EmbeddedDatabaseFactoryBean extends EmbeddedDatabaseFactory implements FactoryBean, InitializingBean, DisposableBean { public void afterPropertiesSet() { initDatabase(); } public DataSource getObject() { return getDataSource(); } public Class getObjectType() { return DataSource.class; } public boolean isSingleton() { return true; } public void destroy() { shutdownDatabase(); } } ././@LongLink0000000000000000000000000000022400000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseType.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000205711623223526033276 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource.embedded; /** * A supported embedded database type. * * @author Keith Donald * @author Oliver Gierke * @since 3.0 */ public enum EmbeddedDatabaseType { /** The Hypersonic Embedded Java SQL Database (http://hsqldb.org) */ HSQL, /** The H2 Embedded Java SQL Database Engine (http://h2database.com) */ H2, /** The Apache Derby Embedded SQL Database (http://db.apache.org/derby) */ DERBY } ././@LongLink0000000000000000000000000000022700000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseFactory.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001652711623223526033305 0ustar drazzibdrazzib/* * Copyright 2002-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource.embedded; import java.io.PrintWriter; import java.sql.Connection; import java.sql.SQLException; import javax.sql.DataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.jdbc.datasource.init.DatabasePopulator; import org.springframework.util.Assert; /** * Creates a {@link EmbeddedDatabase} instance. Callers are guaranteed that the returned database has been fully * initialized and populated. * *

Can be configured:
* Call {@link #setDatabaseName(String)} to change the name of the database.
* Call {@link #setDatabaseType(EmbeddedDatabaseType)} to set the database type if you wish to use one of the supported types.
* Call {@link #setDatabaseConfigurer(EmbeddedDatabaseConfigurer)} to configure support for your own embedded database type.
* Call {@link #setDatabasePopulator(DatabasePopulator)} to change the algorithm used to populate the database.
* Call {@link #setDataSourceFactory(DataSourceFactory)} to change the type of DataSource used to connect to the database.
* Call {@link #getDatabase()} to get the {@link EmbeddedDatabase} instance.
* * @author Keith Donald * @author Juergen Hoeller * @since 3.0 */ public class EmbeddedDatabaseFactory { private static Log logger = LogFactory.getLog(EmbeddedDatabaseFactory.class); private String databaseName = "testdb"; private DataSourceFactory dataSourceFactory = new SimpleDriverDataSourceFactory(); private EmbeddedDatabaseConfigurer databaseConfigurer; private DatabasePopulator databasePopulator; private DataSource dataSource; /** * Set the name of the database. Defaults to "testdb". * @param databaseName name of the test database */ public void setDatabaseName(String databaseName) { Assert.notNull(databaseName, "Database name is required"); this.databaseName = databaseName; } /** * Set the factory to use to create the DataSource instance that connects to the embedded database. * Defaults to {@link SimpleDriverDataSourceFactory}. * @param dataSourceFactory the data source factory */ public void setDataSourceFactory(DataSourceFactory dataSourceFactory) { Assert.notNull(dataSourceFactory, "DataSourceFactory is required"); this.dataSourceFactory = dataSourceFactory; } /** * Set the type of embedded database to use. Call this when you wish to configure * one of the pre-supported types. Defaults to HSQL. * @param type the test database type */ public void setDatabaseType(EmbeddedDatabaseType type) { this.databaseConfigurer = EmbeddedDatabaseConfigurerFactory.getConfigurer(type); } /** * Set the strategy that will be used to configure the embedded database instance. * Call this when you wish to use an embedded database type not already supported. * @param configurer the embedded database configurer */ public void setDatabaseConfigurer(EmbeddedDatabaseConfigurer configurer) { this.databaseConfigurer = configurer; } /** * Set the strategy that will be used to populate the embedded database. Defaults to null. * @param populator the database populator */ public void setDatabasePopulator(DatabasePopulator populator) { this.databasePopulator = populator; } /** * Factory method that returns the embedded database instance. */ public EmbeddedDatabase getDatabase() { if (this.dataSource == null) { initDatabase(); } return new EmbeddedDataSourceProxy(this.dataSource); } /** * Hook to initialize the embedded database. Subclasses may call to force initialization. After calling this method, * {@link #getDataSource()} returns the DataSource providing connectivity to the db. */ protected void initDatabase() { // Create the embedded database source first if (logger.isInfoEnabled()) { logger.info("Creating embedded database '" + this.databaseName + "'"); } if (this.databaseConfigurer == null) { this.databaseConfigurer = EmbeddedDatabaseConfigurerFactory.getConfigurer(EmbeddedDatabaseType.HSQL); } this.databaseConfigurer.configureConnectionProperties( this.dataSourceFactory.getConnectionProperties(), this.databaseName); this.dataSource = this.dataSourceFactory.getDataSource(); // Now populate the database if (this.databasePopulator != null) { try { populateDatabase(); } catch (RuntimeException ex) { // failed to populate, so leave it as not initialized shutdownDatabase(); throw ex; } } } private void populateDatabase() { try { Connection connection = this.dataSource.getConnection(); try { this.databasePopulator.populate(connection); } finally { try { connection.close(); } catch (SQLException ex) { // ignore } } } catch (Exception ex) { throw new DataAccessResourceFailureException("Failed to populate database", ex); } } /** * Hook that gets the DataSource that provides the connectivity to the embedded database. *

Returns null if the DataSource has not been initialized or the database has been shut down. * Subclasses may call to access the datasource instance directly. */ protected DataSource getDataSource() { return this.dataSource; } /** * Hook to shutdown the embedded database. Subclasses may call to force shutdown. * After calling, {@link #getDataSource()} returns null. Does nothing if no embedded database has been initialized. */ protected void shutdownDatabase() { if (this.dataSource != null) { this.databaseConfigurer.shutdown(this.dataSource, this.databaseName); this.dataSource = null; } } private class EmbeddedDataSourceProxy implements EmbeddedDatabase { private final DataSource dataSource; public EmbeddedDataSourceProxy(DataSource dataSource) { this.dataSource = dataSource; } public Connection getConnection() throws SQLException { return this.dataSource.getConnection(); } public Connection getConnection(String username, String password) throws SQLException { return this.dataSource.getConnection(username, password); } public PrintWriter getLogWriter() throws SQLException { return this.dataSource.getLogWriter(); } public void setLogWriter(PrintWriter out) throws SQLException { this.dataSource.setLogWriter(out); } public int getLoginTimeout() throws SQLException { return this.dataSource.getLoginTimeout(); } public void setLoginTimeout(int seconds) throws SQLException { this.dataSource.setLoginTimeout(seconds); } public T unwrap(Class iface) throws SQLException { return this.dataSource.unwrap(iface); } public boolean isWrapperFor(Class iface) throws SQLException { return this.dataSource.isWrapperFor(iface); } public void shutdown() { shutdownDatabase(); } } } ././@LongLink0000000000000000000000000000023400000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/H2EmbeddedDatabaseConfigurer.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000405111623223530033265 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource.embedded; import java.sql.Driver; import org.springframework.util.ClassUtils; /** * Initializes an H2 embedded database instance. * Call {@link #getInstance()} to get the singleton instance of this class. * * @author Oliver Gierke * @author Juergen Hoeller * @since 3.0 */ final class H2EmbeddedDatabaseConfigurer extends AbstractEmbeddedDatabaseConfigurer { private static H2EmbeddedDatabaseConfigurer INSTANCE; private final Class driverClass; /** * Get the singleton {@link H2EmbeddedDatabaseConfigurer} instance. * @return the configurer * @throws ClassNotFoundException if H2 is not on the classpath */ @SuppressWarnings("unchecked") public static synchronized H2EmbeddedDatabaseConfigurer getInstance() throws ClassNotFoundException { if (INSTANCE == null) { INSTANCE = new H2EmbeddedDatabaseConfigurer( (Class) ClassUtils.forName("org.h2.Driver", H2EmbeddedDatabaseConfigurer.class.getClassLoader())); } return INSTANCE; } private H2EmbeddedDatabaseConfigurer(Class driverClass) { this.driverClass = driverClass; } public void configureConnectionProperties(ConnectionProperties properties, String databaseName) { properties.setDriverClass(this.driverClass); properties.setUrl(String.format("jdbc:h2:mem:%s;DB_CLOSE_DELAY=-1", databaseName)); properties.setUsername("sa"); properties.setPassword(""); } } ././@LongLink0000000000000000000000000000024200000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/AbstractEmbeddedDatabaseConfigurer.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000303411623223530033265 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource.embedded; import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; import javax.sql.DataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Base class for {@link EmbeddedDatabaseConfigurer} implementations providing common shutdown behavior. * * @author Oliver Gierke * @author Juergen Hoeller * @since 3.0 */ abstract class AbstractEmbeddedDatabaseConfigurer implements EmbeddedDatabaseConfigurer { protected final Log logger = LogFactory.getLog(getClass()); public void shutdown(DataSource dataSource, String databaseName) { try { Connection connection = dataSource.getConnection(); Statement stmt = connection.createStatement(); stmt.execute("SHUTDOWN"); } catch (SQLException ex) { if (logger.isWarnEnabled()) { logger.warn("Could not shutdown embedded database", ex); } } } } ././@LongLink0000000000000000000000000000022300000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/OutputStreamFactory.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000235111623223526033273 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource.embedded; import java.io.IOException; import java.io.OutputStream; /** * Internal helper for exposing dummy OutputStreams to embedded databases * such as Derby, preventing the creation of a log file. * * @author Juergen Hoeller * @since 3.0 */ public class OutputStreamFactory { /** * Returns an {@link java.io.OutputStream} that ignores all data given to it. */ public static OutputStream getNoopOutputStream() { return new OutputStream() { public void write(int b) throws IOException { // ignore the output } }; } } ././@LongLink0000000000000000000000000000023200000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseConfigurer.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000307611623223530033273 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource.embedded; import javax.sql.DataSource; /** * Encapsulates the configuration required to create, connect to, and shutdown a specific type of embedded database such as HSQL or H2. * Create a implementation for each database type you wish to support; for example HSQL, H2, or some other type. * * @author Keith Donald * @since 3.0 */ public interface EmbeddedDatabaseConfigurer { /** * Configure the properties required to create and connect to the embedded database instance. * @param dataSource the data source to configure * @param databaseName the name of the test database */ void configureConnectionProperties(ConnectionProperties properties, String databaseName); /** * Shutdown the embedded database instance that backs dataSource. * @param dataSource the data source * @param databaseName the name of the database being shutdown */ void shutdown(DataSource dataSource, String databaseName); } ././@LongLink0000000000000000000000000000023600000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/HsqlEmbeddedDatabaseConfigurer.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000404111623223526033271 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource.embedded; import java.sql.Driver; import org.springframework.util.ClassUtils; /** * Initializes an HSQL embedded database instance. * Call {@link #getInstance()} to get the singleton instance of this class. * * @author Keith Donald * @author Oliver Gierke * @since 3.0 */ final class HsqlEmbeddedDatabaseConfigurer extends AbstractEmbeddedDatabaseConfigurer { private static HsqlEmbeddedDatabaseConfigurer INSTANCE; private final Class driverClass; /** * Get the singleton {@link HsqlEmbeddedDatabaseConfigurer} instance. * @return the configurer * @throws ClassNotFoundException if HSQL is not on the classpath */ @SuppressWarnings("unchecked") public static synchronized HsqlEmbeddedDatabaseConfigurer getInstance() throws ClassNotFoundException { if (INSTANCE == null) { INSTANCE = new HsqlEmbeddedDatabaseConfigurer( (Class) ClassUtils.forName("org.hsqldb.jdbcDriver", HsqlEmbeddedDatabaseConfigurer.class.getClassLoader())); } return INSTANCE; } private HsqlEmbeddedDatabaseConfigurer(Class driverClass) { this.driverClass = driverClass; } public void configureConnectionProperties(ConnectionProperties properties, String databaseName) { properties.setDriverClass(this.driverClass); properties.setUrl("jdbc:hsqldb:mem:" + databaseName); properties.setUsername("sa"); properties.setPassword(""); } }././@LongLink0000000000000000000000000000024100000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseConfigurerFactory.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000330111623223530033262 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource.embedded; import org.springframework.util.Assert; /** * Maps well-known {@link EmbeddedDatabaseType embedded database types} to * {@link EmbeddedDatabaseConfigurer} strategies. * * @author Keith Donald * @author Oliver Gierke * @since 3.0 */ final class EmbeddedDatabaseConfigurerFactory { public static EmbeddedDatabaseConfigurer getConfigurer(EmbeddedDatabaseType type) throws IllegalStateException { Assert.notNull(type, "EmbeddedDatabaseType is required"); try { switch (type) { case HSQL: return HsqlEmbeddedDatabaseConfigurer.getInstance(); case H2: return H2EmbeddedDatabaseConfigurer.getInstance(); case DERBY: return DerbyEmbeddedDatabaseConfigurer.getInstance(); default: throw new UnsupportedOperationException("Other embedded database types not yet supported"); } } catch (ClassNotFoundException ex) { throw new IllegalStateException("Driver for test database type [" + type + "] is not available in the classpath", ex); } } private EmbeddedDatabaseConfigurerFactory() { } } ././@LongLink0000000000000000000000000000023500000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/SimpleDriverDataSourceFactory.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000313511623223530033267 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource.embedded; import java.sql.Driver; import javax.sql.DataSource; import org.springframework.jdbc.datasource.SimpleDriverDataSource; /** * Creates a {@link SimpleDriverDataSource}. * * @author Keith Donald * @author Juergen Hoeller * @since 3.0 */ final class SimpleDriverDataSourceFactory implements DataSourceFactory { private final SimpleDriverDataSource dataSource = new SimpleDriverDataSource(); public ConnectionProperties getConnectionProperties() { return new ConnectionProperties() { public void setDriverClass(Class driverClass) { dataSource.setDriverClass(driverClass); } public void setUrl(String url) { dataSource.setUrl(url); } public void setUsername(String username) { dataSource.setUsername(username); } public void setPassword(String password) { dataSource.setPassword(password); } }; } public DataSource getDataSource() { return this.dataSource; } } ././@LongLink0000000000000000000000000000022100000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/DataSourceFactory.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000264311623223530033272 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource.embedded; import javax.sql.DataSource; import org.springframework.jdbc.datasource.SimpleDriverDataSource; /** * Encapsulates the creation of a particular DataSource implementation, such as a * {@link SimpleDriverDataSource} or connection pool such as Apache DBCP or C3P0. * *

Call {@link #getConnectionProperties()} to configure normalized DataSource properties * before calling {@link #getDataSource()} to actually get the configured DataSource instance. * * @author Keith Donald * @since 3.0 */ public interface DataSourceFactory { /** * Allows properties of the DataSource to be configured. */ ConnectionProperties getConnectionProperties(); /** * Returns the DataSource with the connection properties applied. */ DataSource getDataSource(); } ././@LongLink0000000000000000000000000000022400000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/ConnectionProperties.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000302211623223530033262 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource.embedded; import java.sql.Driver; /** * DataSourceFactory helper that allows essential JDBC connection properties to be configured consistently, * independent of the actual DataSource implementation. * * @author Keith Donald * @since 3.0 * @see DataSourceFactory */ public interface ConnectionProperties { /** * Set the JDBC driver to use to connect to the database. * @param driverClass the jdbc driver class */ void setDriverClass(Class driverClass); /** * Sets the JDBC connection URL of the database. * @param url the connection url */ void setUrl(String url); /** * Sets the username to use to connect to the database. * @param username the username */ void setUsername(String username); /** * Sets the password to use to connect to the database. * @param password the password */ void setPassword(String password); } ././@LongLink0000000000000000000000000000022700000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseBuilder.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000672211623223530033274 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource.embedded; import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.ResourceLoader; import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; /** * A builder that provides a fluent API for constructing an embedded database. * *

Usage example: *

 * EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
 * EmbeddedDatabase db = builder.setType(H2).addScript("schema.sql").addScript("data.sql").build();
 * db.shutdown();
 * 
* * @author Keith Donald * @author Juergen Hoeller * @author Dave Syer * @since 3.0 */ public class EmbeddedDatabaseBuilder { private final EmbeddedDatabaseFactory databaseFactory; private final ResourceDatabasePopulator databasePopulator; private final ResourceLoader resourceLoader; /** * Create a new embedded database builder. */ public EmbeddedDatabaseBuilder() { this(new DefaultResourceLoader()); } /** * Create a new embedded database builder with the given ResourceLoader. * @param resourceLoader the ResourceLoader to delegate to */ public EmbeddedDatabaseBuilder(ResourceLoader resourceLoader) { this.databaseFactory = new EmbeddedDatabaseFactory(); this.databasePopulator = new ResourceDatabasePopulator(); this.databaseFactory.setDatabasePopulator(this.databasePopulator); this.resourceLoader = resourceLoader; } /** * Sets the name of the embedded database * Defaults to 'testdb' if not called. * @param databaseName the database name * @return this, for fluent call chaining */ public EmbeddedDatabaseBuilder setName(String databaseName) { this.databaseFactory.setDatabaseName(databaseName); return this; } /** * Sets the type of embedded database. * Defaults to HSQL if not called. * @param databaseType the database type * @return this, for fluent call chaining */ public EmbeddedDatabaseBuilder setType(EmbeddedDatabaseType databaseType) { this.databaseFactory.setDatabaseType(databaseType); return this; } /** * Adds a SQL script to execute to populate the database. * @param sqlResource the sql resource location * @return this, for fluent call chaining */ public EmbeddedDatabaseBuilder addScript(String sqlResource) { this.databasePopulator.addScript(this.resourceLoader.getResource(sqlResource)); return this; } /** * Add default scripts to execute to populate the database. * The default scripts are schema.sql to create the db schema and data.sql to populate the db with data. * @return this, for fluent call chaining */ public EmbeddedDatabaseBuilder addDefaultScripts() { addScript("schema.sql"); addScript("data.sql"); return this; } /** * Build the embedded database. * @return the embedded database */ public EmbeddedDatabase build() { return this.databaseFactory.getDatabase(); } } ././@LongLink0000000000000000000000000000022000000000000011557 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabase.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000201111623223530033257 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource.embedded; import javax.sql.DataSource; /** * A handle to an EmbeddedDatabase instance. * Is a {@link DataSource}. * Adds a shutdown operation so the embedded database instance can be shutdown. * * @author Keith Donald * @since 3.0 */ public interface EmbeddedDatabase extends DataSource { /** * Shutdown this embedded database. */ void shutdown(); } ././@LongLink0000000000000000000000000000023700000000000011567 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/DerbyEmbeddedDatabaseConfigurer.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000646711623223530033302 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource.embedded; import java.io.File; import java.io.IOException; import java.sql.SQLException; import java.util.Properties; import javax.sql.DataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.derby.impl.io.VFMemoryStorageFactory; import org.apache.derby.jdbc.EmbeddedDriver; /** * {@link EmbeddedDatabaseConfigurer} for the Apache Derby database. * * @author Oliver Gierke * @author Juergen Hoeller * @since 3.0 */ final class DerbyEmbeddedDatabaseConfigurer implements EmbeddedDatabaseConfigurer { private static final Log logger = LogFactory.getLog(DerbyEmbeddedDatabaseConfigurer.class); private static final String URL_TEMPLATE = "jdbc:derby:memory:%s;%s"; // Error code that indicates successful shutdown private static final String SHUTDOWN_CODE = "08006"; private static final boolean IS_AT_LEAST_DOT_SIX = new EmbeddedDriver().getMinorVersion() >= 6; private static final String SHUTDOWN_COMMAND = String.format("%s=true", IS_AT_LEAST_DOT_SIX ? "drop" : "shutdown"); private static DerbyEmbeddedDatabaseConfigurer INSTANCE; /** * Get the singleton {@link DerbyEmbeddedDatabaseConfigurer} instance. * @return the configurer * @throws ClassNotFoundException if Derby is not on the classpath */ public static synchronized DerbyEmbeddedDatabaseConfigurer getInstance() throws ClassNotFoundException { if (INSTANCE == null) { // disable log file System.setProperty("derby.stream.error.method", OutputStreamFactory.class.getName() + ".getNoopOutputStream"); INSTANCE = new DerbyEmbeddedDatabaseConfigurer(); } return INSTANCE; } private DerbyEmbeddedDatabaseConfigurer() { } public void configureConnectionProperties(ConnectionProperties properties, String databaseName) { properties.setDriverClass(EmbeddedDriver.class); properties.setUrl(String.format(URL_TEMPLATE, databaseName, "create=true")); properties.setUsername("sa"); properties.setPassword(""); } public void shutdown(DataSource dataSource, String databaseName) { try { new EmbeddedDriver().connect( String.format(URL_TEMPLATE, databaseName, SHUTDOWN_COMMAND), new Properties()); } catch (SQLException ex) { if (!SHUTDOWN_CODE.equals(ex.getSQLState())) { logger.warn("Could not shutdown in-memory Derby database", ex); return; } if (!IS_AT_LEAST_DOT_SIX) { // Explicitly purge the in-memory database, to prevent it // from hanging around after being shut down. try { VFMemoryStorageFactory.purgeDatabase(new File(databaseName).getCanonicalPath()); } catch (IOException ex2) { logger.warn("Could not purge in-memory Derby database", ex2); } } } } } ././@LongLink0000000000000000000000000000020600000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/SmartDataSource.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000357711623223530033301 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource; import java.sql.Connection; import javax.sql.DataSource; /** * Extension of the javax.sql.DataSource interface, to be * implemented by special DataSources that return JDBC Connections * in an unwrapped fashion. * *

Classes using this interface can query whether or not the Connection * should be closed after an operation. Spring's DataSourceUtils and * JdbcTemplate classes automatically perform such a check. * * @author Rod Johnson * @author Juergen Hoeller * @see SingleConnectionDataSource#shouldClose * @see DataSourceUtils#releaseConnection * @see org.springframework.jdbc.core.JdbcTemplate */ public interface SmartDataSource extends DataSource { /** * Should we close this Connection, obtained from this DataSource? *

Code that uses Connections from a SmartDataSource should always * perform a check via this method before invoking close(). *

Note that the JdbcTemplate class in the 'jdbc.core' package takes care of * releasing JDBC Connections, freeing application code of this responsibility. * @param con the Connection to check * @return whether the given Connection should be closed * @see java.sql.Connection#close() */ boolean shouldClose(Connection con); } ././@LongLink0000000000000000000000000000020300000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/package-info.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000034011623223530033262 0ustar drazzibdrazzib /** * * Provides a utility class for easy DataSource access, * a PlatformTransactionManager for a single DataSource, * and various simple DataSource implementations. * */ package org.springframework.jdbc.datasource; ././@LongLink0000000000000000000000000000022100000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/SingleConnectionDataSource.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000002763211623223530033277 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.sql.Connection; import java.sql.SQLException; import org.springframework.beans.factory.DisposableBean; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; /** * Implementation of {@link SmartDataSource} that wraps a single JDBC Connection * which is not closed after use. Obviously, this is not multi-threading capable. * *

Note that at shutdown, someone should close the underlying Connection * via the close() method. Client code will never call close * on the Connection handle if it is SmartDataSource-aware (e.g. uses * DataSourceUtils.releaseConnection). * *

If client code will call close() in the assumption of a pooled * Connection, like when using persistence tools, set "suppressClose" to "true". * This will return a close-suppressing proxy instead of the physical Connection. * Be aware that you will not be able to cast this to a native * OracleConnection or the like anymore; you need to use a * {@link org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor} then. * *

This is primarily intended for testing. For example, it enables easy testing * outside an application server, for code that expects to work on a DataSource. * In contrast to {@link DriverManagerDataSource}, it reuses the same Connection * all the time, avoiding excessive creation of physical Connections. * * @author Rod Johnson * @author Juergen Hoeller * @see #getConnection() * @see java.sql.Connection#close() * @see DataSourceUtils#releaseConnection * @see org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor */ public class SingleConnectionDataSource extends DriverManagerDataSource implements SmartDataSource, DisposableBean { /** Create a close-suppressing proxy? */ private boolean suppressClose; /** Override auto-commit state? */ private Boolean autoCommit; /** Wrapped Connection */ private Connection target; /** Proxy Connection */ private Connection connection; /** Synchronization monitor for the shared Connection */ private final Object connectionMonitor = new Object(); /** * Constructor for bean-style configuration. */ public SingleConnectionDataSource() { } /** * Create a new SingleConnectionDataSource with the given standard * DriverManager parameters. * @param driverClassName the JDBC driver class name * @param url the JDBC URL to use for accessing the DriverManager * @param username the JDBC username to use for accessing the DriverManager * @param password the JDBC password to use for accessing the DriverManager * @param suppressClose if the returned Connection should be a * close-suppressing proxy or the physical Connection * @deprecated since Spring 2.5. Driver parameter usage is generally not recommended * for a SingleConnectionDataSource. If you insist on using driver parameters * directly, set up the Driver class manually before invoking this DataSource. * @see java.sql.DriverManager#getConnection(String, String, String) */ @Deprecated public SingleConnectionDataSource( String driverClassName, String url, String username, String password, boolean suppressClose) { super(driverClassName, url, username, password); this.suppressClose = suppressClose; } /** * Create a new SingleConnectionDataSource with the given standard * DriverManager parameters. * @param url the JDBC URL to use for accessing the DriverManager * @param username the JDBC username to use for accessing the DriverManager * @param password the JDBC password to use for accessing the DriverManager * @param suppressClose if the returned Connection should be a * close-suppressing proxy or the physical Connection * @see java.sql.DriverManager#getConnection(String, String, String) */ public SingleConnectionDataSource(String url, String username, String password, boolean suppressClose) { super(url, username, password); this.suppressClose = suppressClose; } /** * Create a new SingleConnectionDataSource with the given standard * DriverManager parameters. * @param url the JDBC URL to use for accessing the DriverManager * @param suppressClose if the returned Connection should be a * close-suppressing proxy or the physical Connection * @see java.sql.DriverManager#getConnection(String, String, String) */ public SingleConnectionDataSource(String url, boolean suppressClose) { super(url); this.suppressClose = suppressClose; } /** * Create a new SingleConnectionDataSource with a given Connection. * @param target underlying target Connection * @param suppressClose if the Connection should be wrapped with a Connection that * suppresses close() calls (to allow for normal close() * usage in applications that expect a pooled Connection but do not know our * SmartDataSource interface) */ public SingleConnectionDataSource(Connection target, boolean suppressClose) { Assert.notNull(target, "Connection must not be null"); this.target = target; this.suppressClose = suppressClose; this.connection = (suppressClose ? getCloseSuppressingConnectionProxy(target) : target); } /** * Set whether the returned Connection should be a close-suppressing proxy * or the physical Connection. */ public void setSuppressClose(boolean suppressClose) { this.suppressClose = suppressClose; } /** * Return whether the returned Connection will be a close-suppressing proxy * or the physical Connection. */ protected boolean isSuppressClose() { return this.suppressClose; } /** * Set whether the returned Connection's "autoCommit" setting should be overridden. */ public void setAutoCommit(boolean autoCommit) { this.autoCommit = (autoCommit); } /** * Return whether the returned Connection's "autoCommit" setting should be overridden. * @return the "autoCommit" value, or null if none to be applied */ protected Boolean getAutoCommitValue() { return this.autoCommit; } @Override public Connection getConnection() throws SQLException { synchronized (this.connectionMonitor) { if (this.connection == null) { // No underlying Connection -> lazy init via DriverManager. initConnection(); } if (this.connection.isClosed()) { throw new SQLException( "Connection was closed in SingleConnectionDataSource. Check that user code checks " + "shouldClose() before closing Connections, or set 'suppressClose' to 'true'"); } return this.connection; } } /** * Specifying a custom username and password doesn't make sense * with a single Connection. Returns the single Connection if given * the same username and password; throws a SQLException else. */ @Override public Connection getConnection(String username, String password) throws SQLException { if (ObjectUtils.nullSafeEquals(username, getUsername()) && ObjectUtils.nullSafeEquals(password, getPassword())) { return getConnection(); } else { throw new SQLException("SingleConnectionDataSource does not support custom username and password"); } } /** * This is a single Connection: Do not close it when returning to the "pool". */ public boolean shouldClose(Connection con) { synchronized (this.connectionMonitor) { return (con != this.connection && con != this.target); } } /** * Close the underlying Connection. * The provider of this DataSource needs to care for proper shutdown. *

As this bean implements DisposableBean, a bean factory will * automatically invoke this on destruction of its cached singletons. */ public void destroy() { synchronized (this.connectionMonitor) { closeConnection(); } } /** * Initialize the underlying Connection via the DriverManager. */ public void initConnection() throws SQLException { if (getUrl() == null) { throw new IllegalStateException("'url' property is required for lazily initializing a Connection"); } synchronized (this.connectionMonitor) { closeConnection(); this.target = getConnectionFromDriver(getUsername(), getPassword()); prepareConnection(this.target); if (logger.isInfoEnabled()) { logger.info("Established shared JDBC Connection: " + this.target); } this.connection = (isSuppressClose() ? getCloseSuppressingConnectionProxy(this.target) : this.target); } } /** * Reset the underlying shared Connection, to be reinitialized on next access. */ public void resetConnection() { synchronized (this.connectionMonitor) { closeConnection(); this.target = null; this.connection = null; } } /** * Prepare the given Connection before it is exposed. *

The default implementation applies the auto-commit flag, if necessary. * Can be overridden in subclasses. * @param con the Connection to prepare * @see #setAutoCommit */ protected void prepareConnection(Connection con) throws SQLException { Boolean autoCommit = getAutoCommitValue(); if (autoCommit != null && con.getAutoCommit() != autoCommit) { con.setAutoCommit(autoCommit); } } /** * Close the underlying shared Connection. */ private void closeConnection() { if (this.target != null) { try { this.target.close(); } catch (Throwable ex) { logger.warn("Could not close shared JDBC Connection", ex); } } } /** * Wrap the given Connection with a proxy that delegates every method call to it * but suppresses close calls. * @param target the original Connection to wrap * @return the wrapped Connection */ protected Connection getCloseSuppressingConnectionProxy(Connection target) { return (Connection) Proxy.newProxyInstance( ConnectionProxy.class.getClassLoader(), new Class[] {ConnectionProxy.class}, new CloseSuppressingInvocationHandler(target)); } /** * Invocation handler that suppresses close calls on JDBC Connections. */ private static class CloseSuppressingInvocationHandler implements InvocationHandler { private final Connection target; public CloseSuppressingInvocationHandler(Connection target) { this.target = target; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // Invocation on ConnectionProxy interface coming in... if (method.getName().equals("equals")) { // Only consider equal when proxies are identical. return (proxy == args[0]); } else if (method.getName().equals("hashCode")) { // Use hashCode of Connection proxy. return System.identityHashCode(proxy); } else if (method.getName().equals("unwrap")) { if (((Class) args[0]).isInstance(proxy)) { return proxy; } } else if (method.getName().equals("isWrapperFor")) { if (((Class) args[0]).isInstance(proxy)) { return true; } } else if (method.getName().equals("close")) { // Handle close method: don't pass the call on. return null; } else if (method.getName().equals("isClosed")) { return false; } else if (method.getName().equals("getTargetConnection")) { // Handle getTargetConnection method: return underlying Connection. return this.target; } // Invoke method on target Connection. try { return method.invoke(this.target, args); } catch (InvocationTargetException ex) { throw ex.getTargetException(); } } } } ././@LongLink0000000000000000000000000000020600000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/DataSourceUtils.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000004450611623223530033276 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource; import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; import javax.sql.DataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.jdbc.CannotGetJdbcConnectionException; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.support.TransactionSynchronizationAdapter; import org.springframework.transaction.support.TransactionSynchronizationManager; import org.springframework.util.Assert; /** * Helper class that provides static methods for obtaining JDBC Connections from * a {@link javax.sql.DataSource}. Includes special support for Spring-managed * transactional Connections, e.g. managed by {@link DataSourceTransactionManager} * or {@link org.springframework.transaction.jta.JtaTransactionManager}. * *

Used internally by Spring's {@link org.springframework.jdbc.core.JdbcTemplate}, * Spring's JDBC operation objects and the JDBC {@link DataSourceTransactionManager}. * Can also be used directly in application code. * * @author Rod Johnson * @author Juergen Hoeller * @see #getConnection * @see #releaseConnection * @see DataSourceTransactionManager * @see org.springframework.transaction.jta.JtaTransactionManager * @see org.springframework.transaction.support.TransactionSynchronizationManager */ public abstract class DataSourceUtils { /** * Order value for TransactionSynchronization objects that clean up JDBC Connections. */ public static final int CONNECTION_SYNCHRONIZATION_ORDER = 1000; private static final Log logger = LogFactory.getLog(DataSourceUtils.class); /** * Obtain a Connection from the given DataSource. Translates SQLExceptions into * the Spring hierarchy of unchecked generic data access exceptions, simplifying * calling code and making any exception that is thrown more meaningful. *

Is aware of a corresponding Connection bound to the current thread, for example * when using {@link DataSourceTransactionManager}. Will bind a Connection to the * thread if transaction synchronization is active, e.g. when running within a * {@link org.springframework.transaction.jta.JtaTransactionManager JTA} transaction). * @param dataSource the DataSource to obtain Connections from * @return a JDBC Connection from the given DataSource * @throws org.springframework.jdbc.CannotGetJdbcConnectionException * if the attempt to get a Connection failed * @see #releaseConnection */ public static Connection getConnection(DataSource dataSource) throws CannotGetJdbcConnectionException { try { return doGetConnection(dataSource); } catch (SQLException ex) { throw new CannotGetJdbcConnectionException("Could not get JDBC Connection", ex); } } /** * Actually obtain a JDBC Connection from the given DataSource. * Same as {@link #getConnection}, but throwing the original SQLException. *

Is aware of a corresponding Connection bound to the current thread, for example * when using {@link DataSourceTransactionManager}. Will bind a Connection to the thread * if transaction synchronization is active (e.g. if in a JTA transaction). *

Directly accessed by {@link TransactionAwareDataSourceProxy}. * @param dataSource the DataSource to obtain Connections from * @return a JDBC Connection from the given DataSource * @throws SQLException if thrown by JDBC methods * @see #doReleaseConnection */ public static Connection doGetConnection(DataSource dataSource) throws SQLException { Assert.notNull(dataSource, "No DataSource specified"); ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource); if (conHolder != null && (conHolder.hasConnection() || conHolder.isSynchronizedWithTransaction())) { conHolder.requested(); if (!conHolder.hasConnection()) { logger.debug("Fetching resumed JDBC Connection from DataSource"); conHolder.setConnection(dataSource.getConnection()); } return conHolder.getConnection(); } // Else we either got no holder or an empty thread-bound holder here. logger.debug("Fetching JDBC Connection from DataSource"); Connection con = dataSource.getConnection(); if (TransactionSynchronizationManager.isSynchronizationActive()) { logger.debug("Registering transaction synchronization for JDBC Connection"); // Use same Connection for further JDBC actions within the transaction. // Thread-bound object will get removed by synchronization at transaction completion. ConnectionHolder holderToUse = conHolder; if (holderToUse == null) { holderToUse = new ConnectionHolder(con); } else { holderToUse.setConnection(con); } holderToUse.requested(); TransactionSynchronizationManager.registerSynchronization( new ConnectionSynchronization(holderToUse, dataSource)); holderToUse.setSynchronizedWithTransaction(true); if (holderToUse != conHolder) { TransactionSynchronizationManager.bindResource(dataSource, holderToUse); } } return con; } /** * Prepare the given Connection with the given transaction semantics. * @param con the Connection to prepare * @param definition the transaction definition to apply * @return the previous isolation level, if any * @throws SQLException if thrown by JDBC methods * @see #resetConnectionAfterTransaction */ public static Integer prepareConnectionForTransaction(Connection con, TransactionDefinition definition) throws SQLException { Assert.notNull(con, "No Connection specified"); // Set read-only flag. if (definition != null && definition.isReadOnly()) { try { if (logger.isDebugEnabled()) { logger.debug("Setting JDBC Connection [" + con + "] read-only"); } con.setReadOnly(true); } catch (SQLException ex) { Throwable exToCheck = ex; while (exToCheck != null) { if (exToCheck.getClass().getSimpleName().contains("Timeout")) { // Assume it's a connection timeout that would otherwise get lost: e.g. from JDBC 4.0 throw ex; } exToCheck = exToCheck.getCause(); } // "read-only not supported" SQLException -> ignore, it's just a hint anyway logger.debug("Could not set JDBC Connection read-only", ex); } catch (RuntimeException ex) { Throwable exToCheck = ex; while (exToCheck != null) { if (exToCheck.getClass().getSimpleName().contains("Timeout")) { // Assume it's a connection timeout that would otherwise get lost: e.g. from Hibernate throw ex; } exToCheck = exToCheck.getCause(); } // "read-only not supported" UnsupportedOperationException -> ignore, it's just a hint anyway logger.debug("Could not set JDBC Connection read-only", ex); } } // Apply specific isolation level, if any. Integer previousIsolationLevel = null; if (definition != null && definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) { if (logger.isDebugEnabled()) { logger.debug("Changing isolation level of JDBC Connection [" + con + "] to " + definition.getIsolationLevel()); } int currentIsolation = con.getTransactionIsolation(); if (currentIsolation != definition.getIsolationLevel()) { previousIsolationLevel = currentIsolation; con.setTransactionIsolation(definition.getIsolationLevel()); } } return previousIsolationLevel; } /** * Reset the given Connection after a transaction, * regarding read-only flag and isolation level. * @param con the Connection to reset * @param previousIsolationLevel the isolation level to restore, if any * @see #prepareConnectionForTransaction */ public static void resetConnectionAfterTransaction(Connection con, Integer previousIsolationLevel) { Assert.notNull(con, "No Connection specified"); try { // Reset transaction isolation to previous value, if changed for the transaction. if (previousIsolationLevel != null) { if (logger.isDebugEnabled()) { logger.debug("Resetting isolation level of JDBC Connection [" + con + "] to " + previousIsolationLevel); } con.setTransactionIsolation(previousIsolationLevel); } // Reset read-only flag. if (con.isReadOnly()) { if (logger.isDebugEnabled()) { logger.debug("Resetting read-only flag of JDBC Connection [" + con + "]"); } con.setReadOnly(false); } } catch (Throwable ex) { logger.debug("Could not reset JDBC Connection after transaction", ex); } } /** * Determine whether the given JDBC Connection is transactional, that is, * bound to the current thread by Spring's transaction facilities. * @param con the Connection to check * @param dataSource the DataSource that the Connection was obtained from * (may be null) * @return whether the Connection is transactional */ public static boolean isConnectionTransactional(Connection con, DataSource dataSource) { if (dataSource == null) { return false; } ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource); return (conHolder != null && connectionEquals(conHolder, con)); } /** * Apply the current transaction timeout, if any, * to the given JDBC Statement object. * @param stmt the JDBC Statement object * @param dataSource the DataSource that the Connection was obtained from * @throws SQLException if thrown by JDBC methods * @see java.sql.Statement#setQueryTimeout */ public static void applyTransactionTimeout(Statement stmt, DataSource dataSource) throws SQLException { applyTimeout(stmt, dataSource, 0); } /** * Apply the specified timeout - overridden by the current transaction timeout, * if any - to the given JDBC Statement object. * @param stmt the JDBC Statement object * @param dataSource the DataSource that the Connection was obtained from * @param timeout the timeout to apply (or 0 for no timeout outside of a transaction) * @throws SQLException if thrown by JDBC methods * @see java.sql.Statement#setQueryTimeout */ public static void applyTimeout(Statement stmt, DataSource dataSource, int timeout) throws SQLException { Assert.notNull(stmt, "No Statement specified"); Assert.notNull(dataSource, "No DataSource specified"); ConnectionHolder holder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource); if (holder != null && holder.hasTimeout()) { // Remaining transaction timeout overrides specified value. stmt.setQueryTimeout(holder.getTimeToLiveInSeconds()); } else if (timeout > 0) { // No current transaction timeout -> apply specified value. stmt.setQueryTimeout(timeout); } } /** * Close the given Connection, obtained from the given DataSource, * if it is not managed externally (that is, not bound to the thread). * @param con the Connection to close if necessary * (if this is null, the call will be ignored) * @param dataSource the DataSource that the Connection was obtained from * (may be null) * @see #getConnection */ public static void releaseConnection(Connection con, DataSource dataSource) { try { doReleaseConnection(con, dataSource); } catch (SQLException ex) { logger.debug("Could not close JDBC Connection", ex); } catch (Throwable ex) { logger.debug("Unexpected exception on closing JDBC Connection", ex); } } /** * Actually close the given Connection, obtained from the given DataSource. * Same as {@link #releaseConnection}, but throwing the original SQLException. *

Directly accessed by {@link TransactionAwareDataSourceProxy}. * @param con the Connection to close if necessary * (if this is null, the call will be ignored) * @param dataSource the DataSource that the Connection was obtained from * (may be null) * @throws SQLException if thrown by JDBC methods * @see #doGetConnection */ public static void doReleaseConnection(Connection con, DataSource dataSource) throws SQLException { if (con == null) { return; } if (dataSource != null) { ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource); if (conHolder != null && connectionEquals(conHolder, con)) { // It's the transactional Connection: Don't close it. conHolder.released(); return; } } // Leave the Connection open only if the DataSource is our // special SmartDataSoruce and it wants the Connection left open. if (!(dataSource instanceof SmartDataSource) || ((SmartDataSource) dataSource).shouldClose(con)) { logger.debug("Returning JDBC Connection to DataSource"); con.close(); } } /** * Determine whether the given two Connections are equal, asking the target * Connection in case of a proxy. Used to detect equality even if the * user passed in a raw target Connection while the held one is a proxy. * @param conHolder the ConnectionHolder for the held Connection (potentially a proxy) * @param passedInCon the Connection passed-in by the user * (potentially a target Connection without proxy) * @return whether the given Connections are equal * @see #getTargetConnection */ private static boolean connectionEquals(ConnectionHolder conHolder, Connection passedInCon) { if (!conHolder.hasConnection()) { return false; } Connection heldCon = conHolder.getConnection(); // Explicitly check for identity too: for Connection handles that do not implement // "equals" properly, such as the ones Commons DBCP exposes). return (heldCon == passedInCon || heldCon.equals(passedInCon) || getTargetConnection(heldCon).equals(passedInCon)); } /** * Return the innermost target Connection of the given Connection. If the given * Connection is a proxy, it will be unwrapped until a non-proxy Connection is * found. Otherwise, the passed-in Connection will be returned as-is. * @param con the Connection proxy to unwrap * @return the innermost target Connection, or the passed-in one if no proxy * @see ConnectionProxy#getTargetConnection() */ public static Connection getTargetConnection(Connection con) { Connection conToUse = con; while (conToUse instanceof ConnectionProxy) { conToUse = ((ConnectionProxy) conToUse).getTargetConnection(); } return conToUse; } /** * Determine the connection synchronization order to use for the given * DataSource. Decreased for every level of nesting that a DataSource * has, checked through the level of DelegatingDataSource nesting. * @param dataSource the DataSource to check * @return the connection synchronization order to use * @see #CONNECTION_SYNCHRONIZATION_ORDER */ private static int getConnectionSynchronizationOrder(DataSource dataSource) { int order = CONNECTION_SYNCHRONIZATION_ORDER; DataSource currDs = dataSource; while (currDs instanceof DelegatingDataSource) { order--; currDs = ((DelegatingDataSource) currDs).getTargetDataSource(); } return order; } /** * Callback for resource cleanup at the end of a non-native JDBC transaction * (e.g. when participating in a JtaTransactionManager transaction). * @see org.springframework.transaction.jta.JtaTransactionManager */ private static class ConnectionSynchronization extends TransactionSynchronizationAdapter { private final ConnectionHolder connectionHolder; private final DataSource dataSource; private int order; private boolean holderActive = true; public ConnectionSynchronization(ConnectionHolder connectionHolder, DataSource dataSource) { this.connectionHolder = connectionHolder; this.dataSource = dataSource; this.order = getConnectionSynchronizationOrder(dataSource); } @Override public int getOrder() { return this.order; } @Override public void suspend() { if (this.holderActive) { TransactionSynchronizationManager.unbindResource(this.dataSource); if (this.connectionHolder.hasConnection() && !this.connectionHolder.isOpen()) { // Release Connection on suspend if the application doesn't keep // a handle to it anymore. We will fetch a fresh Connection if the // application accesses the ConnectionHolder again after resume, // assuming that it will participate in the same transaction. releaseConnection(this.connectionHolder.getConnection(), this.dataSource); this.connectionHolder.setConnection(null); } } } @Override public void resume() { if (this.holderActive) { TransactionSynchronizationManager.bindResource(this.dataSource, this.connectionHolder); } } @Override public void beforeCompletion() { // Release Connection early if the holder is not open anymore // (that is, not used by another resource like a Hibernate Session // that has its own cleanup via transaction synchronization), // to avoid issues with strict JTA implementations that expect // the close call before transaction completion. if (!this.connectionHolder.isOpen()) { TransactionSynchronizationManager.unbindResource(this.dataSource); this.holderActive = false; if (this.connectionHolder.hasConnection()) { releaseConnection(this.connectionHolder.getConnection(), this.dataSource); } } } @Override public void afterCompletion(int status) { // If we haven't closed the Connection in beforeCompletion, // close it now. The holder might have been used for other // cleanup in the meantime, for example by a Hibernate Session. if (this.holderActive) { // The thread-bound ConnectionHolder might not be available anymore, // since afterCompletion might get called from a different thread. TransactionSynchronizationManager.unbindResourceIfPossible(this.dataSource); this.holderActive = false; if (this.connectionHolder.hasConnection()) { releaseConnection(this.connectionHolder.getConnection(), this.dataSource); // Reset the ConnectionHolder: It might remain bound to the thread. this.connectionHolder.setConnection(null); } } this.connectionHolder.reset(); } } } ././@LongLink0000000000000000000000000000021500000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/SimpleConnectionHandle.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000321411623223530033265 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource; import java.sql.Connection; import org.springframework.util.Assert; /** * Simple implementation of the {@link ConnectionHandle} interface, * containing a given JDBC Connection. * * @author Juergen Hoeller * @since 1.1 */ public class SimpleConnectionHandle implements ConnectionHandle { private final Connection connection; /** * Create a new SimpleConnectionHandle for the given Connection. * @param connection the JDBC Connection */ public SimpleConnectionHandle(Connection connection) { Assert.notNull(connection, "Connection must not be null"); this.connection = connection; } /** * Return the specified Connection as-is. */ public Connection getConnection() { return this.connection; } /** * This implementation is empty, as we're using a standard * Connection handle that does not have to be released. */ public void releaseConnection(Connection con) { } @Override public String toString() { return "SimpleConnectionHandle: " + this.connection; } } ././@LongLink0000000000000000000000000000022400000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/AbstractDriverBasedDataSource.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001124611623223530033271 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource; import java.sql.Connection; import java.sql.SQLException; import java.util.Properties; import org.springframework.util.Assert; /** * Abstract base class for JDBC {@link javax.sql.DataSource} implementations * that operate on a JDBC {@link java.sql.Driver}. * * @author Juergen Hoeller * @since 2.5.5 * @see SimpleDriverDataSource * @see DriverManagerDataSource */ public abstract class AbstractDriverBasedDataSource extends AbstractDataSource { private String url; private String username; private String password; private Properties connectionProperties; /** * Set the JDBC URL to use for connecting through the Driver. * @see java.sql.Driver#connect(String, java.util.Properties) */ public void setUrl(String url) { Assert.hasText(url, "Property 'url' must not be empty"); this.url = url.trim(); } /** * Return the JDBC URL to use for connecting through the Driver. */ public String getUrl() { return this.url; } /** * Set the JDBC username to use for connecting through the Driver. * @see java.sql.Driver#connect(String, java.util.Properties) */ public void setUsername(String username) { this.username = username; } /** * Return the JDBC username to use for connecting through the Driver. */ public String getUsername() { return this.username; } /** * Set the JDBC password to use for connecting through the Driver. * @see java.sql.Driver#connect(String, java.util.Properties) */ public void setPassword(String password) { this.password = password; } /** * Return the JDBC password to use for connecting through the Driver. */ public String getPassword() { return this.password; } /** * Specify arbitrary connection properties as key/value pairs, * to be passed to the Driver. *

Can also contain "user" and "password" properties. However, * any "username" and "password" bean properties specified on this * DataSource will override the corresponding connection properties. * @see java.sql.Driver#connect(String, java.util.Properties) */ public void setConnectionProperties(Properties connectionProperties) { this.connectionProperties = connectionProperties; } /** * Return the connection properties to be passed to the Driver, if any. */ public Properties getConnectionProperties() { return this.connectionProperties; } /** * This implementation delegates to getConnectionFromDriver, * using the default username and password of this DataSource. * @see #getConnectionFromDriver(String, String) * @see #setUsername * @see #setPassword */ public Connection getConnection() throws SQLException { return getConnectionFromDriver(getUsername(), getPassword()); } /** * This implementation delegates to getConnectionFromDriver, * using the given username and password. * @see #getConnectionFromDriver(String, String) */ public Connection getConnection(String username, String password) throws SQLException { return getConnectionFromDriver(username, password); } /** * Build properties for the Driver, including the given username and password (if any), * and obtain a corresponding Connection. * @param username the name of the user * @param password the password to use * @return the obtained Connection * @throws SQLException in case of failure * @see java.sql.Driver#connect(String, java.util.Properties) */ protected Connection getConnectionFromDriver(String username, String password) throws SQLException { Properties props = new Properties(getConnectionProperties()); if (username != null) { props.setProperty("user", username); } if (password != null) { props.setProperty("password", password); } return getConnectionFromDriver(props); } /** * Obtain a Connection using the given properties. *

Template method to be implemented by subclasses. * @param props the merged connection properties * @return the obtained Connection * @throws SQLException in case of failure */ protected abstract Connection getConnectionFromDriver(Properties props) throws SQLException; } ././@LongLink0000000000000000000000000000017100000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/lookup/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000755000175000017500000000000011623223530033263 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000021200000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/lookup/package-info.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000020411623223526033266 0ustar drazzibdrazzib /** * * Provides a strategy for looking up JDBC DataSources by name. * */ package org.springframework.jdbc.datasource.lookup; ././@LongLink0000000000000000000000000000023600000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/lookup/DataSourceLookupFailureException.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000270211623223530033266 0ustar drazzibdrazzib/* * Copyright 2002-2006 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource.lookup; import org.springframework.dao.NonTransientDataAccessException; /** * Exception to be thrown by a DataSourceLookup implementation, * indicating that the specified DataSource could not be obtained. * * @author Juergen Hoeller * @since 2.0 */ public class DataSourceLookupFailureException extends NonTransientDataAccessException { /** * Constructor for DataSourceLookupFailureException. * @param msg the detail message */ public DataSourceLookupFailureException(String msg) { super(msg); } /** * Constructor for DataSourceLookupFailureException. * @param msg the detail message * @param cause the root cause (usually from using a underlying * lookup API such as JNDI) */ public DataSourceLookupFailureException(String msg, Throwable cause) { super(msg, cause); } } ././@LongLink0000000000000000000000000000022100000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/lookup/MapDataSourceLookup.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000757711623223530033305 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource.lookup; import java.util.Collections; import java.util.HashMap; import java.util.Map; import javax.sql.DataSource; import org.springframework.util.Assert; /** * Simple {@link DataSourceLookup} implementation that relies on a map for doing lookups. * *

Useful for testing environments or applications that need to match arbitrary * {@link String} names to target {@link DataSource} objects. * * @author Costin Leau * @author Juergen Hoeller * @author Rick Evans * @since 2.0 */ public class MapDataSourceLookup implements DataSourceLookup { private final Map dataSources = new HashMap(4); /** * Create a new instance of the {@link MapDataSourceLookup} class. */ public MapDataSourceLookup() { } /** * Create a new instance of the {@link MapDataSourceLookup} class. * @param dataSources the {@link Map} of {@link DataSource DataSources}; the keys * are {@link String Strings}, the values are actual {@link DataSource} instances. */ public MapDataSourceLookup(Map dataSources) { setDataSources(dataSources); } /** * Create a new instance of the {@link MapDataSourceLookup} class. * @param dataSourceName the name under which the supplied {@link DataSource} is to be added * @param dataSource the {@link DataSource} to be added */ public MapDataSourceLookup(String dataSourceName, DataSource dataSource) { addDataSource(dataSourceName, dataSource); } /** * Set the {@link Map} of {@link DataSource DataSources}; the keys * are {@link String Strings}, the values are actual {@link DataSource} instances. *

If the supplied {@link Map} is null, then this method * call effectively has no effect. * @param dataSources said {@link Map} of {@link DataSource DataSources} */ public void setDataSources(Map dataSources) { if (dataSources != null) { this.dataSources.putAll(dataSources); } } /** * Get the {@link Map} of {@link DataSource DataSources} maintained by this object. *

The returned {@link Map} is {@link Collections#unmodifiableMap(java.util.Map) unmodifiable}. * @return said {@link Map} of {@link DataSource DataSources} (never null) */ public Map getDataSources() { return Collections.unmodifiableMap(this.dataSources); } /** * Add the supplied {@link DataSource} to the map of {@link DataSource DataSources} * maintained by this object. * @param dataSourceName the name under which the supplied {@link DataSource} is to be added * @param dataSource the {@link DataSource} to be so added */ public void addDataSource(String dataSourceName, DataSource dataSource) { Assert.notNull(dataSourceName, "DataSource name must not be null"); Assert.notNull(dataSource, "DataSource must not be null"); this.dataSources.put(dataSourceName, dataSource); } public DataSource getDataSource(String dataSourceName) throws DataSourceLookupFailureException { Assert.notNull(dataSourceName, "DataSource name must not be null"); DataSource dataSource = this.dataSources.get(dataSourceName); if (dataSource == null) { throw new DataSourceLookupFailureException( "No DataSource with name '" + dataSourceName + "' registered"); } return dataSource; } } ././@LongLink0000000000000000000000000000021600000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/lookup/DataSourceLookup.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000260511623223530033270 0ustar drazzibdrazzib/* * Copyright 2002-2006 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource.lookup; import javax.sql.DataSource; /** * Strategy interface for looking up DataSources by name. * *

Used, for example, to resolve data source names in JPA * persistence.xml files. * * @author Costin Leau * @author Juergen Hoeller * @since 2.0 * @see org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager#setDataSourceLookup */ public interface DataSourceLookup { /** * Retrieve the DataSource identified by the given name. * @param dataSourceName the name of the DataSource * @return the DataSource (never null) * @throws DataSourceLookupFailureException if the lookup failed */ DataSource getDataSource(String dataSourceName) throws DataSourceLookupFailureException; } ././@LongLink0000000000000000000000000000022400000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/lookup/SingleDataSourceLookup.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000261211623223526033273 0ustar drazzibdrazzib/* * Copyright 2002-2006 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource.lookup; import javax.sql.DataSource; import org.springframework.util.Assert; /** * An implementation of the DataSourceLookup that simply wraps a * single given DataSource, returned for any data source name. * * @author Juergen Hoeller * @since 2.0 */ public class SingleDataSourceLookup implements DataSourceLookup { private final DataSource dataSource; /** * Create a new instance of the {@link SingleDataSourceLookup} class. * @param dataSource the single {@link DataSource} to wrap */ public SingleDataSourceLookup(DataSource dataSource) { Assert.notNull(dataSource, "DataSource must not be null"); this.dataSource = dataSource; } public DataSource getDataSource(String dataSourceName) { return this.dataSource; } } ././@LongLink0000000000000000000000000000022700000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/lookup/AbstractRoutingDataSource.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001745311623223526033304 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource.lookup; import java.sql.Connection; import java.sql.SQLException; import java.util.HashMap; import java.util.Map; import javax.sql.DataSource; import org.springframework.beans.factory.InitializingBean; import org.springframework.jdbc.datasource.AbstractDataSource; import org.springframework.util.Assert; /** * Abstract {@link javax.sql.DataSource} implementation that routes {@link #getConnection()} * calls to one of various target DataSources based on a lookup key. The latter is usually * (but not necessarily) determined through some thread-bound transaction context. * * @author Juergen Hoeller * @since 2.0.1 * @see #setTargetDataSources * @see #setDefaultTargetDataSource * @see #determineCurrentLookupKey() */ public abstract class AbstractRoutingDataSource extends AbstractDataSource implements InitializingBean { private Map targetDataSources; private Object defaultTargetDataSource; private boolean lenientFallback = true; private DataSourceLookup dataSourceLookup = new JndiDataSourceLookup(); private Map resolvedDataSources; private DataSource resolvedDefaultDataSource; /** * Specify the map of target DataSources, with the lookup key as key. * The mapped value can either be a corresponding {@link javax.sql.DataSource} * instance or a data source name String (to be resolved via a * {@link #setDataSourceLookup DataSourceLookup}). *

The key can be of arbitrary type; this class implements the * generic lookup process only. The concrete key representation will * be handled by {@link #resolveSpecifiedLookupKey(Object)} and * {@link #determineCurrentLookupKey()}. */ public void setTargetDataSources(Map targetDataSources) { this.targetDataSources = targetDataSources; } /** * Specify the default target DataSource, if any. *

The mapped value can either be a corresponding {@link javax.sql.DataSource} * instance or a data source name String (to be resolved via a * {@link #setDataSourceLookup DataSourceLookup}). *

This DataSource will be used as target if none of the keyed * {@link #setTargetDataSources targetDataSources} match the * {@link #determineCurrentLookupKey()} current lookup key. */ public void setDefaultTargetDataSource(Object defaultTargetDataSource) { this.defaultTargetDataSource = defaultTargetDataSource; } /** * Specify whether to apply a lenient fallback to the default DataSource * if no specific DataSource could be found for the current lookup key. *

Default is "true", accepting lookup keys without a corresponding entry * in the target DataSource map - simply falling back to the default DataSource * in that case. *

Switch this flag to "false" if you would prefer the fallback to only apply * if the lookup key was null. Lookup keys without a DataSource * entry will then lead to an IllegalStateException. * @see #setTargetDataSources * @see #setDefaultTargetDataSource * @see #determineCurrentLookupKey() */ public void setLenientFallback(boolean lenientFallback) { this.lenientFallback = lenientFallback; } /** * Set the DataSourceLookup implementation to use for resolving data source * name Strings in the {@link #setTargetDataSources targetDataSources} map. *

Default is a {@link JndiDataSourceLookup}, allowing the JNDI names * of application server DataSources to be specified directly. */ public void setDataSourceLookup(DataSourceLookup dataSourceLookup) { this.dataSourceLookup = (dataSourceLookup != null ? dataSourceLookup : new JndiDataSourceLookup()); } public void afterPropertiesSet() { if (this.targetDataSources == null) { throw new IllegalArgumentException("Property 'targetDataSources' is required"); } this.resolvedDataSources = new HashMap(this.targetDataSources.size()); for (Map.Entry entry : this.targetDataSources.entrySet()) { Object lookupKey = resolveSpecifiedLookupKey(entry.getKey()); DataSource dataSource = resolveSpecifiedDataSource(entry.getValue()); this.resolvedDataSources.put(lookupKey, dataSource); } if (this.defaultTargetDataSource != null) { this.resolvedDefaultDataSource = resolveSpecifiedDataSource(this.defaultTargetDataSource); } } /** * Resolve the specified data source object into a DataSource instance. *

The default implementation handles DataSource instances and data source * names (to be resolved via a {@link #setDataSourceLookup DataSourceLookup}). * @param dataSource the data source value object as specified in the * {@link #setTargetDataSources targetDataSources} map * @return the resolved DataSource (never null) * @throws IllegalArgumentException in case of an unsupported value type */ protected DataSource resolveSpecifiedDataSource(Object dataSource) throws IllegalArgumentException { if (dataSource instanceof DataSource) { return (DataSource) dataSource; } else if (dataSource instanceof String) { return this.dataSourceLookup.getDataSource((String) dataSource); } else { throw new IllegalArgumentException( "Illegal data source value - only [javax.sql.DataSource] and String supported: " + dataSource); } } public Connection getConnection() throws SQLException { return determineTargetDataSource().getConnection(); } public Connection getConnection(String username, String password) throws SQLException { return determineTargetDataSource().getConnection(username, password); } /** * Retrieve the current target DataSource. Determines the * {@link #determineCurrentLookupKey() current lookup key}, performs * a lookup in the {@link #setTargetDataSources targetDataSources} map, * falls back to the specified * {@link #setDefaultTargetDataSource default target DataSource} if necessary. * @see #determineCurrentLookupKey() */ protected DataSource determineTargetDataSource() { Assert.notNull(this.resolvedDataSources, "DataSource router not initialized"); Object lookupKey = determineCurrentLookupKey(); DataSource dataSource = this.resolvedDataSources.get(lookupKey); if (dataSource == null && (this.lenientFallback || lookupKey == null)) { dataSource = this.resolvedDefaultDataSource; } if (dataSource == null) { throw new IllegalStateException("Cannot determine target DataSource for lookup key [" + lookupKey + "]"); } return dataSource; } /** * Resolve the given lookup key object, as specified in the * {@link #setTargetDataSources targetDataSources} map, into * the actual lookup key to be used for matching with the * {@link #determineCurrentLookupKey() current lookup key}. *

The default implementation simply returns the given key as-is. * @param lookupKey the lookup key object as specified by the user * @return the lookup key as needed for matching */ protected Object resolveSpecifiedLookupKey(Object lookupKey) { return lookupKey; } /** * Determine the current lookup key. This will typically be * implemented to check a thread-bound transaction context. *

Allows for arbitrary keys. The returned key needs * to match the stored lookup key type, as resolved by the * {@link #resolveSpecifiedLookupKey} method. */ protected abstract Object determineCurrentLookupKey(); } ././@LongLink0000000000000000000000000000023100000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/lookup/BeanFactoryDataSourceLookup.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000543211623223526033276 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource.lookup; import javax.sql.DataSource; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.util.Assert; /** * {@link DataSourceLookup} implementation based on a Spring {@link BeanFactory}. * *

Will lookup Spring managed beans identified by bean name, * expecting them to be of type javax.sql.DataSource. * * @author Costin Leau * @author Juergen Hoeller * @since 2.0 * @see org.springframework.beans.factory.BeanFactory */ public class BeanFactoryDataSourceLookup implements DataSourceLookup, BeanFactoryAware { private BeanFactory beanFactory; /** * Create a new instance of the {@link BeanFactoryDataSourceLookup} class. *

The BeanFactory to access must be set via setBeanFactory. * @see #setBeanFactory */ public BeanFactoryDataSourceLookup() { } /** * Create a new instance of the {@link BeanFactoryDataSourceLookup} class. *

Use of this constructor is redundant if this object is being created * by a Spring IoC container, as the supplied {@link BeanFactory} will be * replaced by the {@link BeanFactory} that creates it (c.f. the * {@link BeanFactoryAware} contract). So only use this constructor if you * are using this class outside the context of a Spring IoC container. * @param beanFactory the bean factory to be used to lookup {@link DataSource DataSources} */ public BeanFactoryDataSourceLookup(BeanFactory beanFactory) { Assert.notNull(beanFactory, "BeanFactory is required"); this.beanFactory = beanFactory; } public void setBeanFactory(BeanFactory beanFactory) { this.beanFactory = beanFactory; } public DataSource getDataSource(String dataSourceName) throws DataSourceLookupFailureException { Assert.state(this.beanFactory != null, "BeanFactory is required"); try { return (DataSource) this.beanFactory.getBean(dataSourceName, DataSource.class); } catch (BeansException ex) { throw new DataSourceLookupFailureException( "Failed to look up DataSource bean with name '" + dataSourceName + "'", ex); } } } ././@LongLink0000000000000000000000000000023400000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/lookup/IsolationLevelDataSourceRouter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001343611623223530033274 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource.lookup; import org.springframework.core.Constants; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.support.DefaultTransactionDefinition; import org.springframework.transaction.support.TransactionSynchronizationManager; /** * DataSource that routes to one of various target DataSources based on the * current transaction isolation level. The target DataSources need to be * configured with the isolation level name as key, as defined on the * {@link org.springframework.transaction.TransactionDefinition TransactionDefinition interface}. * *

This is particularly useful in combination with JTA transaction management * (typically through Spring's {@link org.springframework.transaction.jta.JtaTransactionManager}). * Standard JTA does not support transaction-specific isolation levels. Some JTA * providers support isolation levels as a vendor-specific extension (e.g. WebLogic), * which is the preferred way of addressing this. As alternative (e.g. on WebSphere), * the target database can be represented through multiple JNDI DataSources, each * configured with a different isolation level (for the entire DataSource). * The present DataSource router allows to transparently switch to the * appropriate DataSource based on the current transaction's isolation level. * *

The configuration can for example look like this, assuming that the target * DataSources are defined as individual Spring beans with names * "myRepeatableReadDataSource", "mySerializableDataSource" and "myDefaultDataSource": * *

 * <bean id="dataSourceRouter" class="org.springframework.jdbc.datasource.lookup.IsolationLevelDataSourceRouter">
 *   <property name="targetDataSources">
 *     <map>
 *       <entry key="ISOLATION_REPEATABLE_READ" value-ref="myRepeatableReadDataSource"/>
 *       <entry key="ISOLATION_SERIALIZABLE" value-ref="mySerializableDataSource"/>
 *     </map>
 *   </property>
 *   <property name="defaultTargetDataSource" ref="myDefaultDataSource"/>
 * </bean>
* * Alternatively, the keyed values can also be data source names, to be resolved * through a {@link #setDataSourceLookup DataSourceLookup}: by default, JNDI * names for a standard JNDI lookup. This allows for a single concise definition * without the need for separate DataSource bean definitions. * *
 * <bean id="dataSourceRouter" class="org.springframework.jdbc.datasource.lookup.IsolationLevelDataSourceRouter">
 *   <property name="targetDataSources">
 *     <map>
 *       <entry key="ISOLATION_REPEATABLE_READ" value="java:comp/env/jdbc/myrrds"/>
 *       <entry key="ISOLATION_SERIALIZABLE" value="java:comp/env/jdbc/myserds"/>
 *     </map>
 *   </property>
 *   <property name="defaultTargetDataSource" value="java:comp/env/jdbc/mydefds"/>
 * </bean>
* * Note: If you are using this router in combination with Spring's * {@link org.springframework.transaction.jta.JtaTransactionManager}, * don't forget to switch the "allowCustomIsolationLevels" flag to "true". * (By default, JtaTransactionManager will only accept a default isolation level * because of the lack of isolation level support in standard JTA itself.) * *
 * <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
 *   <property name="allowCustomIsolationLevels" value="true"/>
 * </bean>
* * @author Juergen Hoeller * @since 2.0.1 * @see #setTargetDataSources * @see #setDefaultTargetDataSource * @see org.springframework.transaction.TransactionDefinition#ISOLATION_READ_UNCOMMITTED * @see org.springframework.transaction.TransactionDefinition#ISOLATION_READ_COMMITTED * @see org.springframework.transaction.TransactionDefinition#ISOLATION_REPEATABLE_READ * @see org.springframework.transaction.TransactionDefinition#ISOLATION_SERIALIZABLE * @see org.springframework.transaction.jta.JtaTransactionManager */ public class IsolationLevelDataSourceRouter extends AbstractRoutingDataSource { /** Constants instance for TransactionDefinition */ private static final Constants constants = new Constants(TransactionDefinition.class); /** * Supports Integer values for the isolation level constants * as well as isolation level names as defined on the * {@link org.springframework.transaction.TransactionDefinition TransactionDefinition interface}. */ @Override protected Object resolveSpecifiedLookupKey(Object lookupKey) { if (lookupKey instanceof Integer) { return lookupKey; } else if (lookupKey instanceof String) { String constantName = (String) lookupKey; if (!constantName.startsWith(DefaultTransactionDefinition.PREFIX_ISOLATION)) { throw new IllegalArgumentException("Only isolation constants allowed"); } return constants.asNumber(constantName); } else { throw new IllegalArgumentException( "Invalid lookup key - needs to be isolation level Integer or isolation level name String: " + lookupKey); } } @Override protected Object determineCurrentLookupKey() { return TransactionSynchronizationManager.getCurrentTransactionIsolationLevel(); } } ././@LongLink0000000000000000000000000000022200000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/lookup/JndiDataSourceLookup.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000306511623223526033276 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource.lookup; import javax.naming.NamingException; import javax.sql.DataSource; import org.springframework.jndi.JndiLocatorSupport; /** * JNDI-based {@link DataSourceLookup} implementation. * *

For specific JNDI configuration, it is recommended to configure * the "jndiEnvironment"/"jndiTemplate" properties. * * @author Costin Leau * @author Juergen Hoeller * @since 2.0 * @see #setJndiEnvironment * @see #setJndiTemplate */ public class JndiDataSourceLookup extends JndiLocatorSupport implements DataSourceLookup { public JndiDataSourceLookup() { setResourceRef(true); } public DataSource getDataSource(String dataSourceName) throws DataSourceLookupFailureException { try { return lookup(dataSourceName, DataSource.class); } catch (NamingException ex) { throw new DataSourceLookupFailureException( "Failed to look up JNDI DataSource with name '" + dataSourceName + "'", ex); } } } ././@LongLink0000000000000000000000000000022600000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/IsolationLevelDataSourceAdapter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001617711623223530033301 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource; import java.sql.Connection; import java.sql.SQLException; import org.springframework.core.Constants; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.support.DefaultTransactionDefinition; import org.springframework.transaction.support.TransactionSynchronizationManager; /** * An adapter for a target {@link javax.sql.DataSource}, applying the current * Spring transaction's isolation level (and potentially specified user credentials) * to every getConnection call. Also applies the read-only flag, * if specified. * *

Can be used to proxy a target JNDI DataSource that does not have the * desired isolation level (and user credentials) configured. Client code * can work with this DataSource as usual, not worrying about such settings. * *

Inherits the capability to apply specific user credentials from its superclass * {@link UserCredentialsDataSourceAdapter}; see the latter's javadoc for details * on that functionality (e.g. {@link #setCredentialsForCurrentThread}). * *

WARNING: This adapter simply calls * {@link java.sql.Connection#setTransactionIsolation} and/or * {@link java.sql.Connection#setReadOnly} for every Connection obtained from it. * It does, however, not reset those settings; it rather expects the target * DataSource to perform such resetting as part of its connection pool handling. * Make sure that the target DataSource properly cleans up such transaction state. * * @author Juergen Hoeller * @since 2.0.3 * @see #setIsolationLevel * @see #setIsolationLevelName * @see #setUsername * @see #setPassword */ public class IsolationLevelDataSourceAdapter extends UserCredentialsDataSourceAdapter { /** Constants instance for TransactionDefinition */ private static final Constants constants = new Constants(TransactionDefinition.class); private Integer isolationLevel; /** * Set the default isolation level by the name of the corresponding constant * in {@link org.springframework.transaction.TransactionDefinition}, e.g. * "ISOLATION_SERIALIZABLE". *

If not specified, the target DataSource's default will be used. * Note that a transaction-specific isolation value will always override * any isolation setting specified at the DataSource level. * @param constantName name of the constant * @see org.springframework.transaction.TransactionDefinition#ISOLATION_READ_UNCOMMITTED * @see org.springframework.transaction.TransactionDefinition#ISOLATION_READ_COMMITTED * @see org.springframework.transaction.TransactionDefinition#ISOLATION_REPEATABLE_READ * @see org.springframework.transaction.TransactionDefinition#ISOLATION_SERIALIZABLE * @see #setIsolationLevel */ public final void setIsolationLevelName(String constantName) throws IllegalArgumentException { if (constantName == null || !constantName.startsWith(DefaultTransactionDefinition.PREFIX_ISOLATION)) { throw new IllegalArgumentException("Only isolation constants allowed"); } setIsolationLevel(constants.asNumber(constantName).intValue()); } /** * Specify the default isolation level to use for Connection retrieval, * according to the JDBC {@link java.sql.Connection} constants * (equivalent to the corresponding Spring * {@link org.springframework.transaction.TransactionDefinition} constants). *

If not specified, the target DataSource's default will be used. * Note that a transaction-specific isolation value will always override * any isolation setting specified at the DataSource level. * @see java.sql.Connection#TRANSACTION_READ_UNCOMMITTED * @see java.sql.Connection#TRANSACTION_READ_COMMITTED * @see java.sql.Connection#TRANSACTION_REPEATABLE_READ * @see java.sql.Connection#TRANSACTION_SERIALIZABLE * @see org.springframework.transaction.TransactionDefinition#ISOLATION_READ_UNCOMMITTED * @see org.springframework.transaction.TransactionDefinition#ISOLATION_READ_COMMITTED * @see org.springframework.transaction.TransactionDefinition#ISOLATION_REPEATABLE_READ * @see org.springframework.transaction.TransactionDefinition#ISOLATION_SERIALIZABLE * @see org.springframework.transaction.TransactionDefinition#getIsolationLevel() * @see org.springframework.transaction.support.TransactionSynchronizationManager#getCurrentTransactionIsolationLevel() */ public void setIsolationLevel(int isolationLevel) { if (!constants.getValues(DefaultTransactionDefinition.PREFIX_ISOLATION).contains(isolationLevel)) { throw new IllegalArgumentException("Only values of isolation constants allowed"); } this.isolationLevel = (isolationLevel != TransactionDefinition.ISOLATION_DEFAULT ? isolationLevel : null); } /** * Return the statically specified isolation level, * or null if none. */ protected Integer getIsolationLevel() { return this.isolationLevel; } /** * Applies the current isolation level value and read-only flag * to the returned Connection. * @see #getCurrentIsolationLevel() * @see #getCurrentReadOnlyFlag() */ @Override protected Connection doGetConnection(String username, String password) throws SQLException { Connection con = super.doGetConnection(username, password); Boolean readOnlyToUse = getCurrentReadOnlyFlag(); if (readOnlyToUse != null) { con.setReadOnly(readOnlyToUse); } Integer isolationLevelToUse = getCurrentIsolationLevel(); if (isolationLevelToUse != null) { con.setTransactionIsolation(isolationLevelToUse); } return con; } /** * Determine the current isolation level: either the transaction's * isolation level or a statically defined isolation level. * @return the current isolation level, or null if none * @see org.springframework.transaction.support.TransactionSynchronizationManager#getCurrentTransactionIsolationLevel() * @see #setIsolationLevel */ protected Integer getCurrentIsolationLevel() { Integer isolationLevelToUse = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel(); if (isolationLevelToUse == null) { isolationLevelToUse = getIsolationLevel(); } return isolationLevelToUse; } /** * Determine the current read-only flag: by default, * the transaction's read-only hint. * @return whether there is a read-only hint for the current scope * @see org.springframework.transaction.support.TransactionSynchronizationManager#isCurrentTransactionReadOnly() */ protected Boolean getCurrentReadOnlyFlag() { boolean txReadOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly(); return (txReadOnly ? Boolean.TRUE : null); } } ././@LongLink0000000000000000000000000000022700000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/UserCredentialsDataSourceAdapter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001551211623223526033276 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource; import java.sql.Connection; import java.sql.SQLException; import org.springframework.core.NamedThreadLocal; import org.springframework.util.Assert; import org.springframework.util.StringUtils; /** * An adapter for a target JDBC {@link javax.sql.DataSource}, applying the specified * user credentials to every standard getConnection() call, implicitly * invoking getConnection(username, password) on the target. * All other methods simply delegate to the corresponding methods of the * target DataSource. * *

Can be used to proxy a target JNDI DataSource that does not have user * credentials configured. Client code can work with this DataSource as usual, * using the standard getConnection() call. * *

In the following example, client code can simply transparently work with * the preconfigured "myDataSource", implicitly accessing "myTargetDataSource" * with the specified user credentials. * *

 * <bean id="myTargetDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
 *   <property name="jndiName" value="java:comp/env/jdbc/myds"/>
 * </bean>
 *
 * <bean id="myDataSource" class="org.springframework.jdbc.datasource.UserCredentialsDataSourceAdapter">
 *   <property name="targetDataSource" ref="myTargetDataSource"/>
 *   <property name="username" value="myusername"/>
 *   <property name="password" value="mypassword"/>
 * </bean>
* *

If the "username" is empty, this proxy will simply delegate to the * standard getConnection() method of the target DataSource. * This can be used to keep a UserCredentialsDataSourceAdapter bean definition * just for the option of implicitly passing in user credentials if * the particular target DataSource requires it. * * @author Juergen Hoeller * @since 1.0.2 * @see #getConnection */ public class UserCredentialsDataSourceAdapter extends DelegatingDataSource { private String username; private String password; private final ThreadLocal threadBoundCredentials = new NamedThreadLocal("Current JDBC user credentials"); /** * Set the default username that this adapter should use for retrieving Connections. *

Default is no specific user. Note that an explicitly specified username * will always override any username/password specified at the DataSource level. * @see #setPassword * @see #setCredentialsForCurrentThread(String, String) * @see #getConnection(String, String) */ public void setUsername(String username) { this.username = username; } /** * Set the default user's password that this adapter should use for retrieving Connections. *

Default is no specific password. Note that an explicitly specified username * will always override any username/password specified at the DataSource level. * @see #setUsername * @see #setCredentialsForCurrentThread(String, String) * @see #getConnection(String, String) */ public void setPassword(String password) { this.password = password; } /** * Set user credententials for this proxy and the current thread. * The given username and password will be applied to all subsequent * getConnection() calls on this DataSource proxy. *

This will override any statically specified user credentials, * that is, values of the "username" and "password" bean properties. * @param username the username to apply * @param password the password to apply * @see #removeCredentialsFromCurrentThread */ public void setCredentialsForCurrentThread(String username, String password) { this.threadBoundCredentials.set(new JdbcUserCredentials(username, password)); } /** * Remove any user credentials for this proxy from the current thread. * Statically specified user credentials apply again afterwards. * @see #setCredentialsForCurrentThread */ public void removeCredentialsFromCurrentThread() { this.threadBoundCredentials.remove(); } /** * Determine whether there are currently thread-bound credentials, * using them if available, falling back to the statically specified * username and password (i.e. values of the bean properties) else. *

Delegates to {@link #doGetConnection(String, String)} with the * determined credentials as parameters. */ @Override public Connection getConnection() throws SQLException { JdbcUserCredentials threadCredentials = this.threadBoundCredentials.get(); if (threadCredentials != null) { return doGetConnection(threadCredentials.username, threadCredentials.password); } else { return doGetConnection(this.username, this.password); } } /** * Simply delegates to {@link #doGetConnection(String, String)}, * keeping the given user credentials as-is. */ @Override public Connection getConnection(String username, String password) throws SQLException { return doGetConnection(username, password); } /** * This implementation delegates to the getConnection(username, password) * method of the target DataSource, passing in the specified user credentials. * If the specified username is empty, it will simply delegate to the standard * getConnection() method of the target DataSource. * @param username the username to use * @param password the password to use * @return the Connection * @see javax.sql.DataSource#getConnection(String, String) * @see javax.sql.DataSource#getConnection() */ protected Connection doGetConnection(String username, String password) throws SQLException { Assert.state(getTargetDataSource() != null, "'targetDataSource' is required"); if (StringUtils.hasLength(username)) { return getTargetDataSource().getConnection(username, password); } else { return getTargetDataSource().getConnection(); } } /** * Inner class used as ThreadLocal value. */ private static class JdbcUserCredentials { public final String username; public final String password; private JdbcUserCredentials(String username, String password) { this.username = username; this.password = password; } @Override public String toString() { return "JdbcUserCredentials[username='" + this.username + "',password='" + this.password + "']"; } } } ././@LongLink0000000000000000000000000000020700000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/ConnectionHandle.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000237111623223530033270 0ustar drazzibdrazzib/* * Copyright 2002-2005 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource; import java.sql.Connection; /** * Simple interface to be implemented by handles for a JDBC Connection. * Used by JdoDialect, for example. * * @author Juergen Hoeller * @since 1.1 * @see SimpleConnectionHandle * @see ConnectionHolder * @see org.springframework.orm.jdo.JdoDialect#getJdbcConnection */ public interface ConnectionHandle { /** * Fetch the JDBC Connection that this handle refers to. */ Connection getConnection(); /** * Release the JDBC Connection that this handle refers to. * @param con the JDBC Connection to release */ void releaseConnection(Connection con); } ././@LongLink0000000000000000000000000000016700000000000011571 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/init/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000755000175000017500000000000011623223530033263 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000022500000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/init/CannotReadScriptException.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000242011623223526033270 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource.init; import org.springframework.core.io.support.EncodedResource; /** * Thrown by {@link ResourceDatabasePopulator} if one of its SQL scripts could * not be read during population. * * @author Keith Donald * @since 3.0 */ public class CannotReadScriptException extends RuntimeException { /** * Constructor a new CannotReadScriptException. * @param resource the resource that could not be read from * @param cause the underlying cause of the resource access failure */ public CannotReadScriptException(EncodedResource resource, Throwable cause) { super("Cannot read SQL script from " + resource, cause); } } ././@LongLink0000000000000000000000000000021000000000000011556 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/init/package-info.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000022511623223526033271 0ustar drazzibdrazzib /** * * Provides extensible support for initializing databases through scripts. * */ package org.springframework.jdbc.datasource.init; ././@LongLink0000000000000000000000000000022100000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/init/DataSourceInitializer.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000517211623223530033272 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource.init; import java.sql.Connection; import java.sql.SQLException; import javax.sql.DataSource; import org.springframework.beans.factory.InitializingBean; import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.util.Assert; /** * Used to populate a database during initialization. * * @author Dave Syer * @since 3.0 * @see DatabasePopulator */ public class DataSourceInitializer implements InitializingBean { private DataSource dataSource; private DatabasePopulator databasePopulator; private boolean enabled = true; /** * The {@link DataSource} to populate when this component is initialized. * Mandatory with no default. * @param dataSource the DataSource */ public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } /** * The {@link DatabasePopulator} to use to populate the data source. * Mandatory with no default. * @param databasePopulator the database populator to use. */ public void setDatabasePopulator(DatabasePopulator databasePopulator) { this.databasePopulator = databasePopulator; } /** * Flag to explicitly enable or disable the database populator. * @param enabled true if the database populator will be called on startup */ public void setEnabled(boolean enabled) { this.enabled = enabled; } /** * Use the populator to set up data in the data source. */ public void afterPropertiesSet() throws Exception { if (this.enabled) { Assert.state(this.dataSource != null, "DataSource must be provided"); Assert.state(this.databasePopulator != null, "DatabasePopulator must be provided"); try { Connection connection = this.dataSource.getConnection(); try { this.databasePopulator.populate(connection); } finally { try { connection.close(); } catch (SQLException ex) { // ignore } } } catch (Exception ex) { throw new DataAccessResourceFailureException("Failed to populate database", ex); } } } } ././@LongLink0000000000000000000000000000022500000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/init/ResourceDatabasePopulator.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000002141211623223526033272 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource.init; import java.io.IOException; import java.io.LineNumberReader; import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedList; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.core.io.Resource; import org.springframework.core.io.support.EncodedResource; import org.springframework.util.StringUtils; /** * Populates a database from SQL scripts defined in external resources. * *

Call {@link #addScript(Resource)} to add a SQL script location. * Call {@link #setSqlScriptEncoding(String)} to set the encoding for all added scripts. * * @author Keith Donald * @author Dave Syer * @author Juergen Hoeller * @since 3.0 */ public class ResourceDatabasePopulator implements DatabasePopulator { private static String DEFAULT_COMMENT_PREFIX = "--"; private static final Log logger = LogFactory.getLog(ResourceDatabasePopulator.class); private List scripts = new ArrayList(); private String sqlScriptEncoding; private String commentPrefix = DEFAULT_COMMENT_PREFIX; private boolean continueOnError = false; private boolean ignoreFailedDrops = false; /** * Add a script to execute to populate the database. * @param script the path to a SQL script */ public void addScript(Resource script) { this.scripts.add(script); } /** * Set the scripts to execute to populate the database. * @param scripts the scripts to execute */ public void setScripts(Resource[] scripts) { this.scripts = Arrays.asList(scripts); } /** * Specify the encoding for SQL scripts, if different from the platform encoding. * Note setting this property has no effect on added scripts that are already * {@link EncodedResource encoded resources}. * @see #addScript(Resource) */ public void setSqlScriptEncoding(String sqlScriptEncoding) { this.sqlScriptEncoding = sqlScriptEncoding; } /** * Set the line prefix that identifies comments in the SQL script. * Default is "--". */ public void setCommentPrefix(String commentPrefix) { this.commentPrefix = commentPrefix; } /** * Flag to indicate that all failures in SQL should be logged but not cause a failure. * Defaults to false. */ public void setContinueOnError(boolean continueOnError) { this.continueOnError = continueOnError; } /** * Flag to indicate that a failed SQL DROP statement can be ignored. *

This is useful for non-embedded databases whose SQL dialect does not support an * IF EXISTS clause in a DROP. The default is false so that if the * populator runs accidentally, it will fail fast when the script starts with a DROP. */ public void setIgnoreFailedDrops(boolean ignoreFailedDrops) { this.ignoreFailedDrops = ignoreFailedDrops; } public void populate(Connection connection) throws SQLException { for (Resource script : this.scripts) { executeSqlScript(connection, applyEncodingIfNecessary(script), this.continueOnError, this.ignoreFailedDrops); } } private EncodedResource applyEncodingIfNecessary(Resource script) { if (script instanceof EncodedResource) { return (EncodedResource) script; } else { return new EncodedResource(script, this.sqlScriptEncoding); } } /** * Execute the given SQL script. *

The script will normally be loaded by classpath. There should be one statement per line. * Any semicolons will be removed. *

Do not use this method to execute DDL if you expect rollback. * @param connection the JDBC Connection with which to perform JDBC operations * @param resource the resource (potentially associated with a specific encoding) to load the SQL script from * @param continueOnError whether or not to continue without throwing an exception in the event of an error * @param ignoreFailedDrops whether of not to continue in the event of specifically an error on a DROP */ private void executeSqlScript(Connection connection, EncodedResource resource, boolean continueOnError, boolean ignoreFailedDrops) throws SQLException { if (logger.isInfoEnabled()) { logger.info("Executing SQL script from " + resource); } long startTime = System.currentTimeMillis(); List statements = new LinkedList(); String script; try { script = readScript(resource); } catch (IOException ex) { throw new CannotReadScriptException(resource, ex); } char delimiter = ';'; if (!containsSqlScriptDelimiters(script, delimiter)) { delimiter = '\n'; } splitSqlScript(script, delimiter, statements); int lineNumber = 0; Statement stmt = connection.createStatement(); try { for (String statement : statements) { lineNumber++; try { int rowsAffected = stmt.executeUpdate(statement); if (logger.isDebugEnabled()) { logger.debug(rowsAffected + " rows affected by SQL: " + statement); } } catch (SQLException ex) { boolean dropStatement = StringUtils.startsWithIgnoreCase(statement.trim(), "drop"); if (continueOnError || (dropStatement && ignoreFailedDrops)) { if (logger.isDebugEnabled()) { logger.debug("Failed to execute SQL script statement at line " + lineNumber + " of resource " + resource + ": " + statement, ex); } } else { throw new ScriptStatementFailedException(statement, lineNumber, resource, ex); } } } } finally { try { stmt.close(); } catch (Throwable ex) { logger.debug("Could not close JDBC Statement", ex); } } long elapsedTime = System.currentTimeMillis() - startTime; if (logger.isInfoEnabled()) { logger.info("Done executing SQL script from " + resource + " in " + elapsedTime + " ms."); } } /** * Read a script from the given resource and build a String containing the lines. * @param resource the resource to be read * @return String containing the script lines * @throws IOException in case of I/O errors */ private String readScript(EncodedResource resource) throws IOException { LineNumberReader lnr = new LineNumberReader(resource.getReader()); String currentStatement = lnr.readLine(); StringBuilder scriptBuilder = new StringBuilder(); while (currentStatement != null) { if (StringUtils.hasText(currentStatement) && (this.commentPrefix != null && !currentStatement.startsWith(this.commentPrefix))) { if (scriptBuilder.length() > 0) { scriptBuilder.append('\n'); } scriptBuilder.append(currentStatement); } currentStatement = lnr.readLine(); } return scriptBuilder.toString(); } /** * Does the provided SQL script contain the specified delimiter? * @param script the SQL script * @param delim character delimiting each statement - typically a ';' character */ private boolean containsSqlScriptDelimiters(String script, char delim) { boolean inLiteral = false; char[] content = script.toCharArray(); for (int i = 0; i < script.length(); i++) { if (content[i] == '\'') { inLiteral = !inLiteral; } if (content[i] == delim && !inLiteral) { return true; } } return false; } /** * Split an SQL script into separate statements delimited with the provided delimiter character. * Each individual statement will be added to the provided List. * @param script the SQL script * @param delim character delimiting each statement (typically a ';' character) * @param statements the List that will contain the individual statements */ private void splitSqlScript(String script, char delim, List statements) { StringBuilder sb = new StringBuilder(); boolean inLiteral = false; char[] content = script.toCharArray(); for (int i = 0; i < script.length(); i++) { char c = content[i]; if (c == '\'') { inLiteral = !inLiteral; } if (!inLiteral) { if (c == delim) { if (sb.length() > 0) { statements.add(sb.toString()); sb = new StringBuilder(); } continue; } else if (c == '\n' || c == '\t') { c = ' '; } } sb.append(c); } if (StringUtils.hasText(sb)) { statements.add(sb.toString()); } } } ././@LongLink0000000000000000000000000000021500000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/init/DatabasePopulator.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000235111623223526033273 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource.init; import java.sql.Connection; import java.sql.SQLException; /** * Strategy used to populate a database during initialization. * * @author Keith Donald * @since 3.0 * @see ResourceDatabasePopulator */ public interface DatabasePopulator { /** * Populate the database using the JDBC connection provided. * @param connection the JDBC connection to use to populate the db; already configured and ready to use * @throws SQLException if an unrecoverable data access exception occurs during database population */ void populate(Connection connection) throws SQLException; } ././@LongLink0000000000000000000000000000023200000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/init/ScriptStatementFailedException.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000304111623223530033263 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource.init; import org.springframework.core.io.support.EncodedResource; /** * Thrown by {@link ResourceDatabasePopulator} if a statement in one of its SQL scripts * failed when executing it against the target database. * * @author Juergen Hoeller * @since 3.0.5 */ public class ScriptStatementFailedException extends RuntimeException { /** * Constructor a new ScriptStatementFailedException. * @param statement the actual SQL statement that failed * @param lineNumber the line number in the SQL script * @param resource the resource that could not be read from * @param cause the underlying cause of the resource access failure */ public ScriptStatementFailedException(String statement, int lineNumber, EncodedResource resource, Throwable cause) { super("Failed to execute SQL script statement at line " + lineNumber + " of resource " + resource + ": " + statement, cause); } } ././@LongLink0000000000000000000000000000021600000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/DriverManagerDataSource.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001642711623223526033304 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.util.Properties; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; /** * Simple implementation of the standard JDBC {@link javax.sql.DataSource} interface, * configuring the plain old JDBC {@link java.sql.DriverManager} via bean properties, and * returning a new {@link java.sql.Connection} from every getConnection call. * *

NOTE: This class is not an actual connection pool; it does not actually * pool Connections. It just serves as simple replacement for a full-blown * connection pool, implementing the same standard interface, but creating new * Connections on every call. * *

Useful for test or standalone environments outside of a J2EE container, either * as a DataSource bean in a corresponding ApplicationContext or in conjunction with * a simple JNDI environment. Pool-assuming Connection.close() calls will * simply close the Connection, so any DataSource-aware persistence code should work. * *

NOTE: Within special class loading environments such as OSGi, this class * is effectively superseded by {@link SimpleDriverDataSource} due to general class * loading issues with the JDBC DriverManager that be resolved through direct Driver * usage (which is exactly what SimpleDriverDataSource does). * *

In a J2EE container, it is recommended to use a JNDI DataSource provided by * the container. Such a DataSource can be exposed as a DataSource bean in a Spring * ApplicationContext via {@link org.springframework.jndi.JndiObjectFactoryBean}, * for seamless switching to and from a local DataSource bean like this class. * For tests, you can then either set up a mock JNDI environment through Spring's * {@link org.springframework.mock.jndi.SimpleNamingContextBuilder}, or switch the * bean definition to a local DataSource (which is simpler and thus recommended). * *

If you need a "real" connection pool outside of a J2EE container, consider * Apache's Jakarta Commons DBCP * or C3P0. * Commons DBCP's BasicDataSource and C3P0's ComboPooledDataSource are full * connection pool beans, supporting the same basic properties as this class * plus specific settings (such as minimal/maximal pool size etc). * * @author Juergen Hoeller * @since 14.03.2003 * @see SimpleDriverDataSource */ public class DriverManagerDataSource extends AbstractDriverBasedDataSource { /** * Constructor for bean-style configuration. */ public DriverManagerDataSource() { } /** * Create a new DriverManagerDataSource with the given JDBC URL, * not specifying a username or password for JDBC access. * @param url the JDBC URL to use for accessing the DriverManager * @see java.sql.DriverManager#getConnection(String) */ public DriverManagerDataSource(String url) { setUrl(url); } /** * Create a new DriverManagerDataSource with the given standard * DriverManager parameters. * @param url the JDBC URL to use for accessing the DriverManager * @param username the JDBC username to use for accessing the DriverManager * @param password the JDBC password to use for accessing the DriverManager * @see java.sql.DriverManager#getConnection(String, String, String) */ public DriverManagerDataSource(String url, String username, String password) { setUrl(url); setUsername(username); setPassword(password); } /** * Create a new DriverManagerDataSource with the given JDBC URL, * not specifying a username or password for JDBC access. * @param url the JDBC URL to use for accessing the DriverManager * @param conProps JDBC connection properties * @see java.sql.DriverManager#getConnection(String) */ public DriverManagerDataSource(String url, Properties conProps) { setUrl(url); setConnectionProperties(conProps); } /** * Create a new DriverManagerDataSource with the given standard * DriverManager parameters. * @param driverClassName the JDBC driver class name * @param url the JDBC URL to use for accessing the DriverManager * @param username the JDBC username to use for accessing the DriverManager * @param password the JDBC password to use for accessing the DriverManager * @deprecated since Spring 2.5. DriverManagerDataSource is primarily * intended for accessing pre-registered JDBC drivers. * If you need to register a new driver, consider using * {@link SimpleDriverDataSource} instead. */ @Deprecated public DriverManagerDataSource(String driverClassName, String url, String username, String password) { setDriverClassName(driverClassName); setUrl(url); setUsername(username); setPassword(password); } /** * Set the JDBC driver class name. This driver will get initialized * on startup, registering itself with the JDK's DriverManager. *

NOTE: DriverManagerDataSource is primarily intended for accessing * pre-registered JDBC drivers. If you need to register a new driver, * consider using {@link SimpleDriverDataSource} instead. Alternatively, consider * initializing the JDBC driver yourself before instantiating this DataSource. * The "driverClassName" property is mainly preserved for backwards compatibility, * as well as for migrating between Commons DBCP and this DataSource. * @see java.sql.DriverManager#registerDriver(java.sql.Driver) * @see SimpleDriverDataSource */ public void setDriverClassName(String driverClassName) { Assert.hasText(driverClassName, "Property 'driverClassName' must not be empty"); String driverClassNameToUse = driverClassName.trim(); try { Class.forName(driverClassNameToUse, true, ClassUtils.getDefaultClassLoader()); } catch (ClassNotFoundException ex) { throw new IllegalStateException("Could not load JDBC driver class [" + driverClassNameToUse + "]", ex); } if (logger.isInfoEnabled()) { logger.info("Loaded JDBC driver: " + driverClassNameToUse); } } @Override protected Connection getConnectionFromDriver(Properties props) throws SQLException { String url = getUrl(); if (logger.isDebugEnabled()) { logger.debug("Creating new JDBC DriverManager Connection to [" + url + "]"); } return getConnectionFromDriverManager(url, props); } /** * Getting a Connection using the nasty static from DriverManager is extracted * into a protected method to allow for easy unit testing. * @see java.sql.DriverManager#getConnection(String, java.util.Properties) */ protected Connection getConnectionFromDriverManager(String url, Properties props) throws SQLException { return DriverManager.getConnection(url, props); } } ././@LongLink0000000000000000000000000000022100000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/WebSphereDataSourceAdapter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000002014611623223526033275 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource; import java.lang.reflect.Method; import java.sql.Connection; import java.sql.SQLException; import javax.sql.DataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.util.ReflectionUtils; import org.springframework.util.StringUtils; /** * {@link DataSource} implementation that delegates all calls to a WebSphere * target {@link DataSource}, typically obtained from JNDI, applying a current * isolation level and/or current user credentials to every Connection obtained * from it. * *

Uses IBM-specific API to get a JDBC Connection with a specific isolation * level (and read-only flag) from a WebSphere DataSource * (IBM code example). * Supports the transaction-specific isolation level exposed by * {@link org.springframework.transaction.support.TransactionSynchronizationManager#getCurrentTransactionIsolationLevel()}. * It's also possible to specify a default isolation level, to be applied when the * current Spring-managed transaction does not define a specific isolation level. * *

Usage example, defining the target DataSource as an inner-bean JNDI lookup * (of course, you can link to any WebSphere DataSource through a bean reference): * *

 * <bean id="myDataSource" class="org.springframework.jdbc.datasource.WebSphereDataSourceAdapter">
 *   <property name="targetDataSource">
 *     <bean class="org.springframework.jndi.JndiObjectFactoryBean">
 *       <property name="jndiName" value="jdbc/myds"/>
 *     </bean>
 *   </property>
 * </bean>
* * Thanks to Ricardo Olivieri for submitting the original implementation * of this approach! * * @author Juergen Hoeller * @author Lari Hotari * @author Ricardo N. Olivieri * @since 2.0.3 * @see com.ibm.websphere.rsadapter.JDBCConnectionSpec * @see com.ibm.websphere.rsadapter.WSDataSource#getConnection(com.ibm.websphere.rsadapter.JDBCConnectionSpec) * @see org.springframework.transaction.support.TransactionSynchronizationManager#getCurrentTransactionIsolationLevel() * @see org.springframework.transaction.support.TransactionSynchronizationManager#isCurrentTransactionReadOnly() */ public class WebSphereDataSourceAdapter extends IsolationLevelDataSourceAdapter { protected final Log logger = LogFactory.getLog(getClass()); private Class wsDataSourceClass; private Method newJdbcConnSpecMethod; private Method wsDataSourceGetConnectionMethod; private Method setTransactionIsolationMethod; private Method setReadOnlyMethod; private Method setUserNameMethod; private Method setPasswordMethod; /** * This constructor retrieves the WebSphere JDBC connection spec API, * so we can get obtain specific WebSphere Connections using reflection. */ public WebSphereDataSourceAdapter() { try { this.wsDataSourceClass = getClass().getClassLoader().loadClass("com.ibm.websphere.rsadapter.WSDataSource"); Class jdbcConnSpecClass = getClass().getClassLoader().loadClass("com.ibm.websphere.rsadapter.JDBCConnectionSpec"); Class wsrraFactoryClass = getClass().getClassLoader().loadClass("com.ibm.websphere.rsadapter.WSRRAFactory"); this.newJdbcConnSpecMethod = wsrraFactoryClass.getMethod("createJDBCConnectionSpec", (Class[]) null); this.wsDataSourceGetConnectionMethod = this.wsDataSourceClass.getMethod("getConnection", new Class[] {jdbcConnSpecClass}); this.setTransactionIsolationMethod = jdbcConnSpecClass.getMethod("setTransactionIsolation", new Class[] {int.class}); this.setReadOnlyMethod = jdbcConnSpecClass.getMethod("setReadOnly", new Class[] {Boolean.class}); this.setUserNameMethod = jdbcConnSpecClass.getMethod("setUserName", new Class[] {String.class}); this.setPasswordMethod = jdbcConnSpecClass.getMethod("setPassword", new Class[] {String.class}); } catch (Exception ex) { throw new IllegalStateException( "Could not initialize WebSphereDataSourceAdapter because WebSphere API classes are not available: " + ex); } } /** * Checks that the specified 'targetDataSource' actually is * a WebSphere WSDataSource. */ @Override public void afterPropertiesSet() { super.afterPropertiesSet(); if (!this.wsDataSourceClass.isInstance(getTargetDataSource())) { throw new IllegalStateException( "Specified 'targetDataSource' is not a WebSphere WSDataSource: " + getTargetDataSource()); } } /** * Builds a WebSphere JDBCConnectionSpec object for the current settings * and calls WSDataSource.getConnection(JDBCConnectionSpec). * @see #createConnectionSpec * @see com.ibm.websphere.rsadapter.WSDataSource#getConnection(com.ibm.websphere.rsadapter.JDBCConnectionSpec) */ @Override protected Connection doGetConnection(String username, String password) throws SQLException { // Create JDBCConnectionSpec using current isolation level value and read-only flag. Object connSpec = createConnectionSpec( getCurrentIsolationLevel(), getCurrentReadOnlyFlag(), username, password); if (logger.isDebugEnabled()) { logger.debug("Obtaining JDBC Connection from WebSphere DataSource [" + getTargetDataSource() + "], using ConnectionSpec [" + connSpec + "]"); } // Create Connection through invoking WSDataSource.getConnection(JDBCConnectionSpec) return (Connection) ReflectionUtils.invokeJdbcMethod( this.wsDataSourceGetConnectionMethod, getTargetDataSource(), new Object[] {connSpec}); } /** * Create a WebSphere JDBCConnectionSpec object for the given charateristics. *

The default implementation uses reflection to apply the given settings. * Can be overridden in subclasses to customize the JDBCConnectionSpec object * (JDBCConnectionSpec javadoc; * IBM developerWorks article). * @param isolationLevel the isolation level to apply (or null if none) * @param readOnlyFlag the read-only flag to apply (or null if none) * @param username the username to apply (null or empty indicates the default) * @param password the password to apply (may be null or empty) * @throws SQLException if thrown by JDBCConnectionSpec API methods * @see com.ibm.websphere.rsadapter.JDBCConnectionSpec */ protected Object createConnectionSpec( Integer isolationLevel, Boolean readOnlyFlag, String username, String password) throws SQLException { Object connSpec = ReflectionUtils.invokeJdbcMethod(this.newJdbcConnSpecMethod, null); if (isolationLevel != null) { ReflectionUtils.invokeJdbcMethod(this.setTransactionIsolationMethod, connSpec, new Object[] {isolationLevel}); } if (readOnlyFlag != null) { ReflectionUtils.invokeJdbcMethod(this.setReadOnlyMethod, connSpec, new Object[] {readOnlyFlag}); } // If the username is empty, we'll simply let the target DataSource // use its default credentials. if (StringUtils.hasLength(username)) { ReflectionUtils.invokeJdbcMethod(this.setUserNameMethod, connSpec, new Object[] {username}); ReflectionUtils.invokeJdbcMethod(this.setPasswordMethod, connSpec, new Object[] {password}); } return connSpec; } } ././@LongLink0000000000000000000000000000021500000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/SimpleDriverDataSource.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001147611623223530033276 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource; import java.sql.Connection; import java.sql.Driver; import java.sql.SQLException; import java.util.Properties; import org.springframework.beans.BeanUtils; import org.springframework.util.Assert; /** * Simple implementation of the standard JDBC {@link javax.sql.DataSource} interface, * configuring a plain old JDBC {@link java.sql.Driver} via bean properties, and returning * a new {@link java.sql.Connection} from every getConnection call. * *

NOTE: This class is not an actual connection pool; it does not actually * pool Connections. It just serves as simple replacement for a full-blown * connection pool, implementing the same standard interface, but creating new * Connections on every call. * *

In a J2EE container, it is recommended to use a JNDI DataSource provided by * the container. Such a DataSource can be exposed as a DataSource bean in a Spring * ApplicationContext via {@link org.springframework.jndi.JndiObjectFactoryBean}, * for seamless switching to and from a local DataSource bean like this class. * *

If you need a "real" connection pool outside of a J2EE container, consider * Apache's Jakarta Commons DBCP * or C3P0. * Commons DBCP's BasicDataSource and C3P0's ComboPooledDataSource are full * connection pool beans, supporting the same basic properties as this class * plus specific settings (such as minimal/maximal pool size etc). * * @author Juergen Hoeller * @since 2.5.5 * @see DriverManagerDataSource */ public class SimpleDriverDataSource extends AbstractDriverBasedDataSource { private Driver driver; /** * Constructor for bean-style configuration. */ public SimpleDriverDataSource() { } /** * Create a new DriverManagerDataSource with the given standard Driver parameters. * @param driver the JDBC Driver object * @param url the JDBC URL to use for accessing the DriverManager * @see java.sql.Driver#connect(String, java.util.Properties) */ public SimpleDriverDataSource(Driver driver, String url) { setDriver(driver); setUrl(url); } /** * Create a new DriverManagerDataSource with the given standard Driver parameters. * @param driver the JDBC Driver object * @param url the JDBC URL to use for accessing the DriverManager * @param username the JDBC username to use for accessing the DriverManager * @param password the JDBC password to use for accessing the DriverManager * @see java.sql.Driver#connect(String, java.util.Properties) */ public SimpleDriverDataSource(Driver driver, String url, String username, String password) { setDriver(driver); setUrl(url); setUsername(username); setPassword(password); } /** * Create a new DriverManagerDataSource with the given standard Driver parameters. * @param driver the JDBC Driver object * @param url the JDBC URL to use for accessing the DriverManager * @param conProps JDBC connection properties * @see java.sql.Driver#connect(String, java.util.Properties) */ public SimpleDriverDataSource(Driver driver, String url, Properties conProps) { setDriver(driver); setUrl(url); setConnectionProperties(conProps); } /** * Specify the JDBC Driver implementation class to use. *

An instance of this Driver class will be created and held * within the SimpleDriverDataSource. * @see #setDriver */ public void setDriverClass(Class driverClass) { this.driver = BeanUtils.instantiateClass(driverClass); } /** * Specify the JDBC Driver instance to use. *

This allows for passing in a shared, possibly pre-configured * Driver instance. * @see #setDriverClass */ public void setDriver(Driver driver) { this.driver = driver; } /** * Return the JDBC Driver instance to use. */ public Driver getDriver() { return this.driver; } @Override protected Connection getConnectionFromDriver(Properties props) throws SQLException { Driver driver = getDriver(); String url = getUrl(); Assert.notNull(driver, "Driver must not be null"); if (logger.isDebugEnabled()) { logger.debug("Creating new JDBC Driver Connection to [" + url + "]"); } return driver.connect(url, props); } } ././@LongLink0000000000000000000000000000021100000000000011557 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/AbstractDataSource.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000543311623223526033277 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource; import java.io.PrintWriter; import java.sql.SQLException; import javax.sql.DataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.util.Assert; /** * Abstract base class for Spring's {@link javax.sql.DataSource} * implementations, taking care of the padding. * *

'Padding' in the context of this class means default implementations * for certain methods from the DataSource interface, such as * {@link #getLoginTimeout()}, {@link #setLoginTimeout(int)}, and so forth. * * @author Juergen Hoeller * @since 07.05.2003 * @see DriverManagerDataSource */ public abstract class AbstractDataSource implements DataSource { /** Logger available to subclasses */ protected final Log logger = LogFactory.getLog(getClass()); /** * Returns 0, indicating the default system timeout is to be used. */ public int getLoginTimeout() throws SQLException { return 0; } /** * Setting a login timeout is not supported. */ public void setLoginTimeout(int timeout) throws SQLException { throw new UnsupportedOperationException("setLoginTimeout"); } /** * LogWriter methods are not supported. */ public PrintWriter getLogWriter() { throw new UnsupportedOperationException("getLogWriter"); } /** * LogWriter methods are not supported. */ public void setLogWriter(PrintWriter pw) throws SQLException { throw new UnsupportedOperationException("setLogWriter"); } //--------------------------------------------------------------------- // Implementation of JDBC 4.0's Wrapper interface //--------------------------------------------------------------------- @SuppressWarnings("unchecked") public T unwrap(Class iface) throws SQLException { Assert.notNull(iface, "Interface argument must not be null"); if (!DataSource.class.equals(iface)) { throw new SQLException("DataSource of type [" + getClass().getName() + "] can only be unwrapped as [javax.sql.DataSource], not as [" + iface.getName()); } return (T) this; } public boolean isWrapperFor(Class iface) throws SQLException { return DataSource.class.equals(iface); } } ././@LongLink0000000000000000000000000000020700000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/ConnectionHolder.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001463411623223530033275 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource; import java.sql.Connection; import java.sql.SQLException; import java.sql.Savepoint; import org.springframework.transaction.support.ResourceHolderSupport; import org.springframework.util.Assert; /** * Connection holder, wrapping a JDBC Connection. * {@link DataSourceTransactionManager} binds instances of this class * to the thread, for a specific DataSource. * *

Inherits rollback-only support for nested JDBC transactions * and reference count functionality from the base class. * *

Note: This is an SPI class, not intended to be used by applications. * * @author Juergen Hoeller * @since 06.05.2003 * @see DataSourceTransactionManager * @see DataSourceUtils */ public class ConnectionHolder extends ResourceHolderSupport { public static final String SAVEPOINT_NAME_PREFIX = "SAVEPOINT_"; private ConnectionHandle connectionHandle; private Connection currentConnection; private boolean transactionActive = false; private Boolean savepointsSupported; private int savepointCounter = 0; /** * Create a new ConnectionHolder for the given ConnectionHandle. * @param connectionHandle the ConnectionHandle to hold */ public ConnectionHolder(ConnectionHandle connectionHandle) { Assert.notNull(connectionHandle, "ConnectionHandle must not be null"); this.connectionHandle = connectionHandle; } /** * Create a new ConnectionHolder for the given JDBC Connection, * wrapping it with a {@link SimpleConnectionHandle}, * assuming that there is no ongoing transaction. * @param connection the JDBC Connection to hold * @see SimpleConnectionHandle * @see #ConnectionHolder(java.sql.Connection, boolean) */ public ConnectionHolder(Connection connection) { this.connectionHandle = new SimpleConnectionHandle(connection); } /** * Create a new ConnectionHolder for the given JDBC Connection, * wrapping it with a {@link SimpleConnectionHandle}. * @param connection the JDBC Connection to hold * @param transactionActive whether the given Connection is involved * in an ongoing transaction * @see SimpleConnectionHandle */ public ConnectionHolder(Connection connection, boolean transactionActive) { this(connection); this.transactionActive = transactionActive; } /** * Return the ConnectionHandle held by this ConnectionHolder. */ public ConnectionHandle getConnectionHandle() { return this.connectionHandle; } /** * Return whether this holder currently has a Connection. */ protected boolean hasConnection() { return (this.connectionHandle != null); } /** * Set whether this holder represents an active, JDBC-managed transaction. * @see DataSourceTransactionManager */ protected void setTransactionActive(boolean transactionActive) { this.transactionActive = transactionActive; } /** * Return whether this holder represents an active, JDBC-managed transaction. */ protected boolean isTransactionActive() { return this.transactionActive; } /** * Override the existing Connection handle with the given Connection. * Reset the handle if given null. *

Used for releasing the Connection on suspend (with a null * argument) and setting a fresh Connection on resume. */ protected void setConnection(Connection connection) { if (this.currentConnection != null) { this.connectionHandle.releaseConnection(this.currentConnection); this.currentConnection = null; } if (connection != null) { this.connectionHandle = new SimpleConnectionHandle(connection); } else { this.connectionHandle = null; } } /** * Return the current Connection held by this ConnectionHolder. *

This will be the same Connection until released * gets called on the ConnectionHolder, which will reset the * held Connection, fetching a new Connection on demand. * @see ConnectionHandle#getConnection() * @see #released() */ public Connection getConnection() { Assert.notNull(this.connectionHandle, "Active Connection is required"); if (this.currentConnection == null) { this.currentConnection = this.connectionHandle.getConnection(); } return this.currentConnection; } /** * Return whether JDBC 3.0 Savepoints are supported. * Caches the flag for the lifetime of this ConnectionHolder. * @throws SQLException if thrown by the JDBC driver */ public boolean supportsSavepoints() throws SQLException { if (this.savepointsSupported == null) { this.savepointsSupported = new Boolean(getConnection().getMetaData().supportsSavepoints()); } return this.savepointsSupported.booleanValue(); } /** * Create a new JDBC 3.0 Savepoint for the current Connection, * using generated savepoint names that are unique for the Connection. * @return the new Savepoint * @throws SQLException if thrown by the JDBC driver */ public Savepoint createSavepoint() throws SQLException { this.savepointCounter++; return getConnection().setSavepoint(SAVEPOINT_NAME_PREFIX + this.savepointCounter); } /** * Releases the current Connection held by this ConnectionHolder. *

This is necessary for ConnectionHandles that expect "Connection borrowing", * where each returned Connection is only temporarily leased and needs to be * returned once the data operation is done, to make the Connection available * for other operations within the same transaction. This is the case with * JDO 2.0 DataStoreConnections, for example. * @see org.springframework.orm.jdo.DefaultJdoDialect#getJdbcConnection */ @Override public void released() { super.released(); if (!isOpen() && this.currentConnection != null) { this.connectionHandle.releaseConnection(this.currentConnection); this.currentConnection = null; } } @Override public void clear() { super.clear(); this.transactionActive = false; this.savepointsSupported = null; this.savepointCounter = 0; } } ././@LongLink0000000000000000000000000000022300000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/JdbcTransactionObjectSupport.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001224311623223530033267 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource; import java.sql.Savepoint; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.transaction.CannotCreateTransactionException; import org.springframework.transaction.NestedTransactionNotSupportedException; import org.springframework.transaction.SavepointManager; import org.springframework.transaction.TransactionException; import org.springframework.transaction.TransactionSystemException; import org.springframework.transaction.TransactionUsageException; import org.springframework.transaction.support.SmartTransactionObject; /** * Convenient base class for JDBC-aware transaction objects. * Can contain a {@link ConnectionHolder}, and implements the * {@link org.springframework.transaction.SavepointManager} * interface based on that ConnectionHolder. * *

Allows for programmatic management of JDBC 3.0 * {@link java.sql.Savepoint Savepoints}. Spring's * {@link org.springframework.transaction.support.DefaultTransactionStatus} * will automatically delegate to this, as it autodetects transaction * objects that implement the SavepointManager interface. * *

Note that savepoints are only supported for drivers which * support JDBC 3.0 or higher. * * @author Juergen Hoeller * @since 1.1 */ public abstract class JdbcTransactionObjectSupport implements SavepointManager, SmartTransactionObject { private static final Log logger = LogFactory.getLog(JdbcTransactionObjectSupport.class); private ConnectionHolder connectionHolder; private Integer previousIsolationLevel; private boolean savepointAllowed = false; public void setConnectionHolder(ConnectionHolder connectionHolder) { this.connectionHolder = connectionHolder; } public ConnectionHolder getConnectionHolder() { return this.connectionHolder; } public boolean hasConnectionHolder() { return (this.connectionHolder != null); } public void setPreviousIsolationLevel(Integer previousIsolationLevel) { this.previousIsolationLevel = previousIsolationLevel; } public Integer getPreviousIsolationLevel() { return this.previousIsolationLevel; } public void setSavepointAllowed(boolean savepointAllowed) { this.savepointAllowed = savepointAllowed; } public boolean isSavepointAllowed() { return this.savepointAllowed; } public void flush() { // no-op } //--------------------------------------------------------------------- // Implementation of SavepointManager //--------------------------------------------------------------------- /** * This implementation creates a JDBC 3.0 Savepoint and returns it. * @see java.sql.Connection#setSavepoint */ public Object createSavepoint() throws TransactionException { ConnectionHolder conHolder = getConnectionHolderForSavepoint(); try { if (!conHolder.supportsSavepoints()) { throw new NestedTransactionNotSupportedException( "Cannot create a nested transaction because savepoints are not supported by your JDBC driver"); } } catch (Throwable ex) { throw new NestedTransactionNotSupportedException( "Cannot create a nested transaction because your JDBC driver is not a JDBC 3.0 driver", ex); } try { return conHolder.createSavepoint(); } catch (Throwable ex) { throw new CannotCreateTransactionException("Could not create JDBC savepoint", ex); } } /** * This implementation rolls back to the given JDBC 3.0 Savepoint. * @see java.sql.Connection#rollback(java.sql.Savepoint) */ public void rollbackToSavepoint(Object savepoint) throws TransactionException { try { getConnectionHolderForSavepoint().getConnection().rollback((Savepoint) savepoint); } catch (Throwable ex) { throw new TransactionSystemException("Could not roll back to JDBC savepoint", ex); } } /** * This implementation releases the given JDBC 3.0 Savepoint. * @see java.sql.Connection#releaseSavepoint */ public void releaseSavepoint(Object savepoint) throws TransactionException { try { getConnectionHolderForSavepoint().getConnection().releaseSavepoint((Savepoint) savepoint); } catch (Throwable ex) { logger.debug("Could not explicitly release JDBC savepoint", ex); } } protected ConnectionHolder getConnectionHolderForSavepoint() throws TransactionException { if (!isSavepointAllowed()) { throw new NestedTransactionNotSupportedException( "Transaction manager does not allow nested transactions"); } if (!hasConnectionHolder()) { throw new TransactionUsageException( "Cannot create nested transaction if not exposing a JDBC transaction"); } return getConnectionHolder(); } } ././@LongLink0000000000000000000000000000022400000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/LazyConnectionDataSourceProxy.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000003657411623223530033304 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.sql.Connection; import java.sql.SQLException; import javax.sql.DataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.core.Constants; /** * Proxy for a target DataSource, fetching actual JDBC Connections lazily, * i.e. not until first creation of a Statement. Connection initialization * properties like auto-commit mode, transaction isolation and read-only mode * will be kept and applied to the actual JDBC Connection as soon as an * actual Connection is fetched (if ever). Consequently, commit and rollback * calls will be ignored if no Statements have been created. * *

This DataSource proxy allows to avoid fetching JDBC Connections from * a pool unless actually necessary. JDBC transaction control can happen * without fetching a Connection from the pool or communicating with the * database; this will be done lazily on first creation of a JDBC Statement. * *

If you configure both a LazyConnectionDataSourceProxy and a * TransactionAwareDataSourceProxy, make sure that the latter is the outermost * DataSource. In such a scenario, data access code will talk to the * transaction-aware DataSource, which will in turn work with the * LazyConnectionDataSourceProxy. * *

Lazy fetching of physical JDBC Connections is particularly beneficial * in a generic transaction demarcation environment. It allows you to demarcate * transactions on all methods that could potentially perform data access, * without paying a performance penalty if no actual data access happens. * *

This DataSource proxy gives you behavior analogous to JTA and a * transactional JNDI DataSource (as provided by the J2EE server), even * with a local transaction strategy like DataSourceTransactionManager or * HibernateTransactionManager. It does not add value with Spring's * JtaTransactionManager as transaction strategy. * *

Lazy fetching of JDBC Connections is also recommended for read-only * operations with Hibernate, in particular if the chances of resolving the * result in the second-level cache are high. This avoids the need to * communicate with the database at all for such read-only operations. * You will get the same effect with non-transactional reads, but lazy fetching * of JDBC Connections allows you to still perform reads in transactions. * *

NOTE: This DataSource proxy needs to return wrapped Connections to * handle lazy fetching of an actual JDBC Connection. Therefore, the returned * Connections cannot be cast to a native JDBC Connection type like OracleConnection, * or to a connection pool implementation type. Use a corresponding * NativeJdbcExtractor to retrieve the native JDBC Connection. * * @author Juergen Hoeller * @since 1.1.4 * @see ConnectionProxy * @see DataSourceTransactionManager * @see org.springframework.orm.hibernate3.HibernateTransactionManager * @see org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor */ public class LazyConnectionDataSourceProxy extends DelegatingDataSource { /** Constants instance for TransactionDefinition */ private static final Constants constants = new Constants(Connection.class); private static final Log logger = LogFactory.getLog(LazyConnectionDataSourceProxy.class); private Boolean defaultAutoCommit; private Integer defaultTransactionIsolation; /** * Create a new LazyConnectionDataSourceProxy. * @see #setTargetDataSource */ public LazyConnectionDataSourceProxy() { } /** * Create a new LazyConnectionDataSourceProxy. * @param targetDataSource the target DataSource */ public LazyConnectionDataSourceProxy(DataSource targetDataSource) { setTargetDataSource(targetDataSource); afterPropertiesSet(); } /** * Set the default auto-commit mode to expose when no target Connection * has been fetched yet (-> actual JDBC Connection default not known yet). *

If not specified, the default gets determined by checking a target * Connection on startup. If that check fails, the default will be determined * lazily on first access of a Connection. * @see java.sql.Connection#setAutoCommit */ public void setDefaultAutoCommit(boolean defaultAutoCommit) { this.defaultAutoCommit = defaultAutoCommit; } /** * Set the default transaction isolation level to expose when no target Connection * has been fetched yet (-> actual JDBC Connection default not known yet). *

This property accepts the int constant value (e.g. 8) as defined in the * {@link java.sql.Connection} interface; it is mainly intended for programmatic * use. Consider using the "defaultTransactionIsolationName" property for setting * the value by name (e.g. "TRANSACTION_SERIALIZABLE"). *

If not specified, the default gets determined by checking a target * Connection on startup. If that check fails, the default will be determined * lazily on first access of a Connection. * @see #setDefaultTransactionIsolationName * @see java.sql.Connection#setTransactionIsolation */ public void setDefaultTransactionIsolation(int defaultTransactionIsolation) { this.defaultTransactionIsolation = defaultTransactionIsolation; } /** * Set the default transaction isolation level by the name of the corresponding * constant in {@link java.sql.Connection}, e.g. "TRANSACTION_SERIALIZABLE". * @param constantName name of the constant * @see #setDefaultTransactionIsolation * @see java.sql.Connection#TRANSACTION_READ_UNCOMMITTED * @see java.sql.Connection#TRANSACTION_READ_COMMITTED * @see java.sql.Connection#TRANSACTION_REPEATABLE_READ * @see java.sql.Connection#TRANSACTION_SERIALIZABLE */ public void setDefaultTransactionIsolationName(String constantName) { setDefaultTransactionIsolation(constants.asNumber(constantName).intValue()); } @Override public void afterPropertiesSet() { super.afterPropertiesSet(); // Determine default auto-commit and transaction isolation // via a Connection from the target DataSource, if possible. if (this.defaultAutoCommit == null || this.defaultTransactionIsolation == null) { try { Connection con = getTargetDataSource().getConnection(); try { checkDefaultConnectionProperties(con); } finally { con.close(); } } catch (SQLException ex) { logger.warn("Could not retrieve default auto-commit and transaction isolation settings", ex); } } } /** * Check the default connection properties (auto-commit, transaction isolation), * keeping them to be able to expose them correctly without fetching an actual * JDBC Connection from the target DataSource. *

This will be invoked once on startup, but also for each retrieval of a * target Connection. If the check failed on startup (because the database was * down), we'll lazily retrieve those settings. * @param con the Connection to use for checking * @throws SQLException if thrown by Connection methods */ protected synchronized void checkDefaultConnectionProperties(Connection con) throws SQLException { if (this.defaultAutoCommit == null) { this.defaultAutoCommit = con.getAutoCommit(); } if (this.defaultTransactionIsolation == null) { this.defaultTransactionIsolation = con.getTransactionIsolation(); } } /** * Expose the default auto-commit value. */ protected Boolean defaultAutoCommit() { return this.defaultAutoCommit; } /** * Expose the default transaction isolation value. */ protected Integer defaultTransactionIsolation() { return this.defaultTransactionIsolation; } /** * Return a Connection handle that lazily fetches an actual JDBC Connection * when asked for a Statement (or PreparedStatement or CallableStatement). *

The returned Connection handle implements the ConnectionProxy interface, * allowing to retrieve the underlying target Connection. * @return a lazy Connection handle * @see ConnectionProxy#getTargetConnection() */ @Override public Connection getConnection() throws SQLException { return (Connection) Proxy.newProxyInstance( ConnectionProxy.class.getClassLoader(), new Class[] {ConnectionProxy.class}, new LazyConnectionInvocationHandler()); } /** * Return a Connection handle that lazily fetches an actual JDBC Connection * when asked for a Statement (or PreparedStatement or CallableStatement). *

The returned Connection handle implements the ConnectionProxy interface, * allowing to retrieve the underlying target Connection. * @param username the per-Connection username * @param password the per-Connection password * @return a lazy Connection handle * @see ConnectionProxy#getTargetConnection() */ @Override public Connection getConnection(String username, String password) throws SQLException { return (Connection) Proxy.newProxyInstance( ConnectionProxy.class.getClassLoader(), new Class[] {ConnectionProxy.class}, new LazyConnectionInvocationHandler(username, password)); } /** * Invocation handler that defers fetching an actual JDBC Connection * until first creation of a Statement. */ private class LazyConnectionInvocationHandler implements InvocationHandler { private String username; private String password; private Boolean readOnly = Boolean.FALSE; private Integer transactionIsolation; private Boolean autoCommit; private boolean closed = false; private Connection target; public LazyConnectionInvocationHandler() { this.autoCommit = defaultAutoCommit(); this.transactionIsolation = defaultTransactionIsolation(); } public LazyConnectionInvocationHandler(String username, String password) { this(); this.username = username; this.password = password; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // Invocation on ConnectionProxy interface coming in... if (method.getName().equals("equals")) { // We must avoid fetching a target Connection for "equals". // Only consider equal when proxies are identical. return (proxy == args[0]); } else if (method.getName().equals("hashCode")) { // We must avoid fetching a target Connection for "hashCode", // and we must return the same hash code even when the target // Connection has been fetched: use hashCode of Connection proxy. return System.identityHashCode(proxy); } else if (method.getName().equals("unwrap")) { if (((Class) args[0]).isInstance(proxy)) { return proxy; } } else if (method.getName().equals("isWrapperFor")) { if (((Class) args[0]).isInstance(proxy)) { return true; } } else if (method.getName().equals("getTargetConnection")) { // Handle getTargetConnection method: return underlying connection. return getTargetConnection(method); } if (!hasTargetConnection()) { // No physical target Connection kept yet -> // resolve transaction demarcation methods without fetching // a physical JDBC Connection until absolutely necessary. if (method.getName().equals("toString")) { return "Lazy Connection proxy for target DataSource [" + getTargetDataSource() + "]"; } else if (method.getName().equals("isReadOnly")) { return this.readOnly; } else if (method.getName().equals("setReadOnly")) { this.readOnly = (Boolean) args[0]; return null; } else if (method.getName().equals("getTransactionIsolation")) { if (this.transactionIsolation != null) { return this.transactionIsolation; } // Else fetch actual Connection and check there, // because we didn't have a default specified. } else if (method.getName().equals("setTransactionIsolation")) { this.transactionIsolation = (Integer) args[0]; return null; } else if (method.getName().equals("getAutoCommit")) { if (this.autoCommit != null) { return this.autoCommit; } // Else fetch actual Connection and check there, // because we didn't have a default specified. } else if (method.getName().equals("setAutoCommit")) { this.autoCommit = (Boolean) args[0]; return null; } else if (method.getName().equals("commit")) { // Ignore: no statements created yet. return null; } else if (method.getName().equals("rollback")) { // Ignore: no statements created yet. return null; } else if (method.getName().equals("getWarnings")) { return null; } else if (method.getName().equals("clearWarnings")) { return null; } else if (method.getName().equals("close")) { // Ignore: no target connection yet. this.closed = true; return null; } else if (method.getName().equals("isClosed")) { return this.closed; } else if (this.closed) { // Connection proxy closed, without ever having fetched a // physical JDBC Connection: throw corresponding SQLException. throw new SQLException("Illegal operation: connection is closed"); } } // Target Connection already fetched, // or target Connection necessary for current operation -> // invoke method on target connection. try { return method.invoke(getTargetConnection(method), args); } catch (InvocationTargetException ex) { throw ex.getTargetException(); } } /** * Return whether the proxy currently holds a target Connection. */ private boolean hasTargetConnection() { return (this.target != null); } /** * Return the target Connection, fetching it and initializing it if necessary. */ private Connection getTargetConnection(Method operation) throws SQLException { if (this.target == null) { // No target Connection held -> fetch one. if (logger.isDebugEnabled()) { logger.debug("Connecting to database for operation '" + operation.getName() + "'"); } // Fetch physical Connection from DataSource. this.target = (this.username != null) ? getTargetDataSource().getConnection(this.username, this.password) : getTargetDataSource().getConnection(); // If we still lack default connection properties, check them now. checkDefaultConnectionProperties(this.target); // Apply kept transaction settings, if any. if (this.readOnly) { this.target.setReadOnly(this.readOnly); } if (this.transactionIsolation != null && !this.transactionIsolation.equals(defaultTransactionIsolation())) { this.target.setTransactionIsolation(this.transactionIsolation); } if (this.autoCommit != null && this.autoCommit != this.target.getAutoCommit()) { this.target.setAutoCommit(this.autoCommit); } } else { // Target Connection already held -> return it. if (logger.isDebugEnabled()) { logger.debug("Using existing database connection for operation '" + operation.getName() + "'"); } } return this.target; } } } ././@LongLink0000000000000000000000000000022600000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/TransactionAwareDataSourceProxy.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000002366711623223530033303 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; import javax.sql.DataSource; import org.springframework.transaction.support.TransactionSynchronizationManager; import org.springframework.util.Assert; /** * Proxy for a target JDBC {@link javax.sql.DataSource}, adding awareness of * Spring-managed transactions. Similar to a transactional JNDI DataSource * as provided by a J2EE server. * *

Data access code that should remain unaware of Spring's data access support * can work with this proxy to seamlessly participate in Spring-managed transactions. * Note that the transaction manager, for example {@link DataSourceTransactionManager}, * still needs to work with the underlying DataSource, not with this proxy. * *

Make sure that TransactionAwareDataSourceProxy is the outermost DataSource * of a chain of DataSource proxies/adapters. TransactionAwareDataSourceProxy * can delegate either directly to the target connection pool or to some * intermediary proxy/adapter like {@link LazyConnectionDataSourceProxy} or * {@link UserCredentialsDataSourceAdapter}. * *

Delegates to {@link DataSourceUtils} for automatically participating in * thread-bound transactions, for example managed by {@link DataSourceTransactionManager}. * getConnection calls and close calls on returned Connections * will behave properly within a transaction, i.e. always operate on the transactional * Connection. If not within a transaction, normal DataSource behavior applies. * *

This proxy allows data access code to work with the plain JDBC API and still * participate in Spring-managed transactions, similar to JDBC code in a J2EE/JTA * environment. However, if possible, use Spring's DataSourceUtils, JdbcTemplate or * JDBC operation objects to get transaction participation even without a proxy for * the target DataSource, avoiding the need to define such a proxy in the first place. * *

As a further effect, using a transaction-aware DataSource will apply remaining * transaction timeouts to all created JDBC (Prepared/Callable)Statement. This means * that all operations performed through standard JDBC will automatically participate * in Spring-managed transaction timeouts. * *

NOTE: This DataSource proxy needs to return wrapped Connections * (which implement the {@link ConnectionProxy} interface) in order to handle * close calls properly. Therefore, the returned Connections cannot be cast * to a native JDBC Connection type like OracleConnection or to a connection * pool implementation type. Use a corresponding * {@link org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor} * to retrieve the native JDBC Connection. * * @author Juergen Hoeller * @since 1.1 * @see javax.sql.DataSource#getConnection() * @see java.sql.Connection#close() * @see DataSourceUtils#doGetConnection * @see DataSourceUtils#applyTransactionTimeout * @see DataSourceUtils#doReleaseConnection */ public class TransactionAwareDataSourceProxy extends DelegatingDataSource { private boolean reobtainTransactionalConnections = false; /** * Create a new TransactionAwareDataSourceProxy. * @see #setTargetDataSource */ public TransactionAwareDataSourceProxy() { } /** * Create a new TransactionAwareDataSourceProxy. * @param targetDataSource the target DataSource */ public TransactionAwareDataSourceProxy(DataSource targetDataSource) { super(targetDataSource); } /** * Specify whether to reobtain the target Connection for each operation * performed within a transaction. *

The default is "false". Specify "true" to reobtain transactional * Connections for every call on the Connection proxy; this is advisable * on JBoss if you hold on to a Connection handle across transaction boundaries. *

The effect of this setting is similar to the * "hibernate.connection.release_mode" value "after_statement". */ public void setReobtainTransactionalConnections(boolean reobtainTransactionalConnections) { this.reobtainTransactionalConnections = reobtainTransactionalConnections; } /** * Delegates to DataSourceUtils for automatically participating in Spring-managed * transactions. Throws the original SQLException, if any. *

The returned Connection handle implements the ConnectionProxy interface, * allowing to retrieve the underlying target Connection. * @return a transactional Connection if any, a new one else * @see DataSourceUtils#doGetConnection * @see ConnectionProxy#getTargetConnection */ @Override public Connection getConnection() throws SQLException { DataSource ds = getTargetDataSource(); Assert.state(ds != null, "'targetDataSource' is required"); return getTransactionAwareConnectionProxy(ds); } /** * Wraps the given Connection with a proxy that delegates every method call to it * but delegates close() calls to DataSourceUtils. * @param targetDataSource DataSource that the Connection came from * @return the wrapped Connection * @see java.sql.Connection#close() * @see DataSourceUtils#doReleaseConnection */ protected Connection getTransactionAwareConnectionProxy(DataSource targetDataSource) { return (Connection) Proxy.newProxyInstance( ConnectionProxy.class.getClassLoader(), new Class[] {ConnectionProxy.class}, new TransactionAwareInvocationHandler(targetDataSource)); } /** * Determine whether to obtain a fixed target Connection for the proxy * or to reobtain the target Connection for each operation. *

The default implementation returns true for all * standard cases. This can be overridden through the * {@link #setReobtainTransactionalConnections "reobtainTransactionalConnections"} * flag, which enforces a non-fixed target Connection within an active transaction. * Note that non-transactional access will always use a fixed Connection. * @param targetDataSource the target DataSource */ protected boolean shouldObtainFixedConnection(DataSource targetDataSource) { return (!TransactionSynchronizationManager.isSynchronizationActive() || !this.reobtainTransactionalConnections); } /** * Invocation handler that delegates close calls on JDBC Connections * to DataSourceUtils for being aware of thread-bound transactions. */ private class TransactionAwareInvocationHandler implements InvocationHandler { private final DataSource targetDataSource; private Connection target; private boolean closed = false; public TransactionAwareInvocationHandler(DataSource targetDataSource) { this.targetDataSource = targetDataSource; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // Invocation on ConnectionProxy interface coming in... if (method.getName().equals("equals")) { // Only considered as equal when proxies are identical. return (proxy == args[0]); } else if (method.getName().equals("hashCode")) { // Use hashCode of Connection proxy. return System.identityHashCode(proxy); } else if (method.getName().equals("toString")) { // Allow for differentiating between the proxy and the raw Connection. StringBuilder sb = new StringBuilder("Transaction-aware proxy for target Connection "); if (this.target != null) { sb.append("[").append(this.target.toString()).append("]"); } else { sb.append(" from DataSource [").append(this.targetDataSource).append("]"); } return sb.toString(); } else if (method.getName().equals("unwrap")) { if (((Class) args[0]).isInstance(proxy)) { return proxy; } } else if (method.getName().equals("isWrapperFor")) { if (((Class) args[0]).isInstance(proxy)) { return true; } } else if (method.getName().equals("close")) { // Handle close method: only close if not within a transaction. DataSourceUtils.doReleaseConnection(this.target, this.targetDataSource); this.closed = true; return null; } else if (method.getName().equals("isClosed")) { return this.closed; } if (this.target == null) { if (this.closed) { throw new SQLException("Connection handle already closed"); } if (shouldObtainFixedConnection(this.targetDataSource)) { this.target = DataSourceUtils.doGetConnection(this.targetDataSource); } } Connection actualTarget = this.target; if (actualTarget == null) { actualTarget = DataSourceUtils.doGetConnection(this.targetDataSource); } if (method.getName().equals("getTargetConnection")) { // Handle getTargetConnection method: return underlying Connection. return actualTarget; } // Invoke method on target Connection. try { Object retVal = method.invoke(actualTarget, args); // If return value is a Statement, apply transaction timeout. // Applies to createStatement, prepareStatement, prepareCall. if (retVal instanceof Statement) { DataSourceUtils.applyTransactionTimeout((Statement) retVal, this.targetDataSource); } return retVal; } catch (InvocationTargetException ex) { throw ex.getTargetException(); } finally { if (actualTarget != this.target) { DataSourceUtils.doReleaseConnection(actualTarget, this.targetDataSource); } } } } } ././@LongLink0000000000000000000000000000020600000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/ConnectionProxy.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000323211623223530033265 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource; import java.sql.Connection; /** * Subinterface of {@link java.sql.Connection} to be implemented by * Connection proxies. Allows access to the underlying target Connection. * *

This interface can be checked when there is a need to cast to a * native JDBC Connection such as Oracle's OracleConnection. Spring's * {@link org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractorAdapter} * automatically detects such proxies before delegating to the actual * unwrapping for a specific connection pool. * * @author Juergen Hoeller * @since 1.1 * @see TransactionAwareDataSourceProxy * @see LazyConnectionDataSourceProxy * @see DataSourceUtils#getTargetConnection(java.sql.Connection) */ public interface ConnectionProxy extends Connection { /** * Return the target Connection of this proxy. *

This will typically be the native driver Connection * or a wrapper from a connection pool. * @return the underlying Connection (never null) */ Connection getTargetConnection(); } ././@LongLink0000000000000000000000000000021300000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/DelegatingDataSource.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000664411623223526033304 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource; import java.io.PrintWriter; import java.sql.Connection; import java.sql.SQLException; import javax.sql.DataSource; import org.springframework.beans.factory.InitializingBean; import org.springframework.util.Assert; /** * JDBC {@link javax.sql.DataSource} implementation that delegates all calls * to a given target {@link javax.sql.DataSource}. * *

This class is meant to be subclassed, with subclasses overriding only * those methods (such as {@link #getConnection()}) that should not simply * delegate to the target DataSource. * * @author Juergen Hoeller * @since 1.1 * @see #getConnection */ public class DelegatingDataSource implements DataSource, InitializingBean { private DataSource targetDataSource; /** * Create a new DelegatingDataSource. * @see #setTargetDataSource */ public DelegatingDataSource() { } /** * Create a new DelegatingDataSource. * @param targetDataSource the target DataSource */ public DelegatingDataSource(DataSource targetDataSource) { setTargetDataSource(targetDataSource); } /** * Set the target DataSource that this DataSource should delegate to. */ public void setTargetDataSource(DataSource targetDataSource) { Assert.notNull(targetDataSource, "'targetDataSource' must not be null"); this.targetDataSource = targetDataSource; } /** * Return the target DataSource that this DataSource should delegate to. */ public DataSource getTargetDataSource() { return this.targetDataSource; } public void afterPropertiesSet() { if (getTargetDataSource() == null) { throw new IllegalArgumentException("Property 'targetDataSource' is required"); } } public Connection getConnection() throws SQLException { return getTargetDataSource().getConnection(); } public Connection getConnection(String username, String password) throws SQLException { return getTargetDataSource().getConnection(username, password); } public PrintWriter getLogWriter() throws SQLException { return getTargetDataSource().getLogWriter(); } public void setLogWriter(PrintWriter out) throws SQLException { getTargetDataSource().setLogWriter(out); } public int getLoginTimeout() throws SQLException { return getTargetDataSource().getLoginTimeout(); } public void setLoginTimeout(int seconds) throws SQLException { getTargetDataSource().setLoginTimeout(seconds); } //--------------------------------------------------------------------- // Implementation of JDBC 4.0's Wrapper interface //--------------------------------------------------------------------- @SuppressWarnings("unchecked") public T unwrap(Class iface) throws SQLException { return getTargetDataSource().unwrap(iface); } public boolean isWrapperFor(Class iface) throws SQLException { return getTargetDataSource().isWrapperFor(iface); } } ././@LongLink0000000000000000000000000000022300000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/DataSourceTransactionManager.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000003507711623223526033306 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource; import java.sql.Connection; import java.sql.SQLException; import javax.sql.DataSource; import org.springframework.beans.factory.InitializingBean; import org.springframework.transaction.CannotCreateTransactionException; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionSystemException; import org.springframework.transaction.support.AbstractPlatformTransactionManager; import org.springframework.transaction.support.DefaultTransactionStatus; import org.springframework.transaction.support.ResourceTransactionManager; import org.springframework.transaction.support.TransactionSynchronizationManager; /** * {@link org.springframework.transaction.PlatformTransactionManager} * implementation for a single JDBC {@link javax.sql.DataSource}. This class is * capable of working in any environment with any JDBC driver, as long as the setup * uses a JDBC 2.0 Standard Extensions / JDBC 3.0 javax.sql.DataSource * as its Connection factory mechanism. Binds a JDBC Connection from the specified * DataSource to the current thread, potentially allowing for one thread-bound * Connection per DataSource. * *

Note: The DataSource that this transaction manager operates on needs * to return independent Connections. The Connections may come from a pool * (the typical case), but the DataSource must not return thread-scoped / * request-scoped Connections or the like. This transaction manager will * associate Connections with thread-bound transactions itself, according * to the specified propagation behavior. It assumes that a separate, * independent Connection can be obtained even during an ongoing transaction. * *

Application code is required to retrieve the JDBC Connection via * {@link DataSourceUtils#getConnection(DataSource)} instead of a standard * J2EE-style {@link DataSource#getConnection()} call. Spring classes such as * {@link org.springframework.jdbc.core.JdbcTemplate} use this strategy implicitly. * If not used in combination with this transaction manager, the * {@link DataSourceUtils} lookup strategy behaves exactly like the native * DataSource lookup; it can thus be used in a portable fashion. * *

Alternatively, you can allow application code to work with the standard * J2EE-style lookup pattern {@link DataSource#getConnection()}, for example for * legacy code that is not aware of Spring at all. In that case, define a * {@link TransactionAwareDataSourceProxy} for your target DataSource, and pass * that proxy DataSource to your DAOs, which will automatically participate in * Spring-managed transactions when accessing it. * *

Supports custom isolation levels, and timeouts which get applied as * appropriate JDBC statement timeouts. To support the latter, application code * must either use {@link org.springframework.jdbc.core.JdbcTemplate}, call * {@link DataSourceUtils#applyTransactionTimeout} for each created JDBC Statement, * or go through a {@link TransactionAwareDataSourceProxy} which will create * timeout-aware JDBC Connections and Statements automatically. * *

Consider defining a {@link LazyConnectionDataSourceProxy} for your target * DataSource, pointing both this transaction manager and your DAOs to it. * This will lead to optimized handling of "empty" transactions, i.e. of transactions * without any JDBC statements executed. A LazyConnectionDataSourceProxy will not fetch * an actual JDBC Connection from the target DataSource until a Statement gets executed, * lazily applying the specified transaction settings to the target Connection. * *

On JDBC 3.0, this transaction manager supports nested transactions via the * JDBC 3.0 {@link java.sql.Savepoint} mechanism. The * {@link #setNestedTransactionAllowed "nestedTransactionAllowed"} flag defaults * to "true", since nested transactions will work without restrictions on JDBC * drivers that support savepoints (such as the Oracle JDBC driver). * *

This transaction manager can be used as a replacement for the * {@link org.springframework.transaction.jta.JtaTransactionManager} in the single * resource case, as it does not require a container that supports JTA, typically * in combination with a locally defined JDBC DataSource (e.g. a Jakarta Commons * DBCP connection pool). Switching between this local strategy and a JTA * environment is just a matter of configuration! * * @author Juergen Hoeller * @since 02.05.2003 * @see #setNestedTransactionAllowed * @see java.sql.Savepoint * @see DataSourceUtils#getConnection(javax.sql.DataSource) * @see DataSourceUtils#applyTransactionTimeout * @see DataSourceUtils#releaseConnection * @see TransactionAwareDataSourceProxy * @see LazyConnectionDataSourceProxy * @see org.springframework.jdbc.core.JdbcTemplate */ public class DataSourceTransactionManager extends AbstractPlatformTransactionManager implements ResourceTransactionManager, InitializingBean { private DataSource dataSource; /** * Create a new DataSourceTransactionManager instance. * A DataSource has to be set to be able to use it. * @see #setDataSource */ public DataSourceTransactionManager() { setNestedTransactionAllowed(true); } /** * Create a new DataSourceTransactionManager instance. * @param dataSource JDBC DataSource to manage transactions for */ public DataSourceTransactionManager(DataSource dataSource) { this(); setDataSource(dataSource); afterPropertiesSet(); } /** * Set the JDBC DataSource that this instance should manage transactions for. *

This will typically be a locally defined DataSource, for example a * Jakarta Commons DBCP connection pool. Alternatively, you can also drive * transactions for a non-XA J2EE DataSource fetched from JNDI. For an XA * DataSource, use JtaTransactionManager. *

The DataSource specified here should be the target DataSource to manage * transactions for, not a TransactionAwareDataSourceProxy. Only data access * code may work with TransactionAwareDataSourceProxy, while the transaction * manager needs to work on the underlying target DataSource. If there's * nevertheless a TransactionAwareDataSourceProxy passed in, it will be * unwrapped to extract its target DataSource. *

The DataSource passed in here needs to return independent Connections. * The Connections may come from a pool (the typical case), but the DataSource * must not return thread-scoped / request-scoped Connections or the like. * @see TransactionAwareDataSourceProxy * @see org.springframework.transaction.jta.JtaTransactionManager */ public void setDataSource(DataSource dataSource) { if (dataSource instanceof TransactionAwareDataSourceProxy) { // If we got a TransactionAwareDataSourceProxy, we need to perform transactions // for its underlying target DataSource, else data access code won't see // properly exposed transactions (i.e. transactions for the target DataSource). this.dataSource = ((TransactionAwareDataSourceProxy) dataSource).getTargetDataSource(); } else { this.dataSource = dataSource; } } /** * Return the JDBC DataSource that this instance manages transactions for. */ public DataSource getDataSource() { return this.dataSource; } public void afterPropertiesSet() { if (getDataSource() == null) { throw new IllegalArgumentException("Property 'dataSource' is required"); } } public Object getResourceFactory() { return getDataSource(); } @Override protected Object doGetTransaction() { DataSourceTransactionObject txObject = new DataSourceTransactionObject(); txObject.setSavepointAllowed(isNestedTransactionAllowed()); ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(this.dataSource); txObject.setConnectionHolder(conHolder, false); return txObject; } @Override protected boolean isExistingTransaction(Object transaction) { DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction; return (txObject.getConnectionHolder() != null && txObject.getConnectionHolder().isTransactionActive()); } /** * This implementation sets the isolation level but ignores the timeout. */ @Override protected void doBegin(Object transaction, TransactionDefinition definition) { DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction; Connection con = null; try { if (txObject.getConnectionHolder() == null || txObject.getConnectionHolder().isSynchronizedWithTransaction()) { Connection newCon = this.dataSource.getConnection(); if (logger.isDebugEnabled()) { logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction"); } txObject.setConnectionHolder(new ConnectionHolder(newCon), true); } txObject.getConnectionHolder().setSynchronizedWithTransaction(true); con = txObject.getConnectionHolder().getConnection(); Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition); txObject.setPreviousIsolationLevel(previousIsolationLevel); // Switch to manual commit if necessary. This is very expensive in some JDBC drivers, // so we don't want to do it unnecessarily (for example if we've explicitly // configured the connection pool to set it already). if (con.getAutoCommit()) { txObject.setMustRestoreAutoCommit(true); if (logger.isDebugEnabled()) { logger.debug("Switching JDBC Connection [" + con + "] to manual commit"); } con.setAutoCommit(false); } txObject.getConnectionHolder().setTransactionActive(true); int timeout = determineTimeout(definition); if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) { txObject.getConnectionHolder().setTimeoutInSeconds(timeout); } // Bind the session holder to the thread. if (txObject.isNewConnectionHolder()) { TransactionSynchronizationManager.bindResource(getDataSource(), txObject.getConnectionHolder()); } } catch (Exception ex) { DataSourceUtils.releaseConnection(con, this.dataSource); throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex); } } @Override protected Object doSuspend(Object transaction) { DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction; txObject.setConnectionHolder(null); ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.unbindResource(this.dataSource); return conHolder; } @Override protected void doResume(Object transaction, Object suspendedResources) { ConnectionHolder conHolder = (ConnectionHolder) suspendedResources; TransactionSynchronizationManager.bindResource(this.dataSource, conHolder); } @Override protected void doCommit(DefaultTransactionStatus status) { DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction(); Connection con = txObject.getConnectionHolder().getConnection(); if (status.isDebug()) { logger.debug("Committing JDBC transaction on Connection [" + con + "]"); } try { con.commit(); } catch (SQLException ex) { throw new TransactionSystemException("Could not commit JDBC transaction", ex); } } @Override protected void doRollback(DefaultTransactionStatus status) { DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction(); Connection con = txObject.getConnectionHolder().getConnection(); if (status.isDebug()) { logger.debug("Rolling back JDBC transaction on Connection [" + con + "]"); } try { con.rollback(); } catch (SQLException ex) { throw new TransactionSystemException("Could not roll back JDBC transaction", ex); } } @Override protected void doSetRollbackOnly(DefaultTransactionStatus status) { DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction(); if (status.isDebug()) { logger.debug("Setting JDBC transaction [" + txObject.getConnectionHolder().getConnection() + "] rollback-only"); } txObject.setRollbackOnly(); } @Override protected void doCleanupAfterCompletion(Object transaction) { DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction; // Remove the connection holder from the thread, if exposed. if (txObject.isNewConnectionHolder()) { TransactionSynchronizationManager.unbindResource(this.dataSource); } // Reset connection. Connection con = txObject.getConnectionHolder().getConnection(); try { if (txObject.isMustRestoreAutoCommit()) { con.setAutoCommit(true); } DataSourceUtils.resetConnectionAfterTransaction(con, txObject.getPreviousIsolationLevel()); } catch (Throwable ex) { logger.debug("Could not reset JDBC Connection after transaction", ex); } if (txObject.isNewConnectionHolder()) { if (logger.isDebugEnabled()) { logger.debug("Releasing JDBC Connection [" + con + "] after transaction"); } DataSourceUtils.releaseConnection(con, this.dataSource); } txObject.getConnectionHolder().clear(); } /** * DataSource transaction object, representing a ConnectionHolder. * Used as transaction object by DataSourceTransactionManager. */ private static class DataSourceTransactionObject extends JdbcTransactionObjectSupport { private boolean newConnectionHolder; private boolean mustRestoreAutoCommit; public void setConnectionHolder(ConnectionHolder connectionHolder, boolean newConnectionHolder) { super.setConnectionHolder(connectionHolder); this.newConnectionHolder = newConnectionHolder; } public boolean isNewConnectionHolder() { return this.newConnectionHolder; } public boolean hasTransaction() { return (getConnectionHolder() != null && getConnectionHolder().isTransactionActive()); } public void setMustRestoreAutoCommit(boolean mustRestoreAutoCommit) { this.mustRestoreAutoCommit = mustRestoreAutoCommit; } public boolean isMustRestoreAutoCommit() { return this.mustRestoreAutoCommit; } public void setRollbackOnly() { getConnectionHolder().setRollbackOnly(); } public boolean isRollbackOnly() { return getConnectionHolder().isRollbackOnly(); } } } ././@LongLink0000000000000000000000000000015600000000000011567 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/object/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000755000175000017500000000000011623223530033263 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000017700000000000011572 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/object/package-info.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000154711623223526033301 0ustar drazzibdrazzib /** * * The classes in this package represent RDBMS queries, updates, * and stored procedures as threadsafe, reusable objects. This approach * is modelled by JDO, although of course objects returned by queries * are "disconnected" from the database. * *

This higher level of JDBC abstraction depends on the lower-level * abstraction in the org.springframework.jdbc.core package. * Exceptions thrown are as in the org.springframework.dao package, * meaning that code using this package does not need to implement JDBC or * RDBMS-specific error handling. * *

This package and related packages are discussed in Chapter 9 of * Expert One-On-One J2EE Design and Development * by Rod Johnson (Wrox, 2002). * */ package org.springframework.jdbc.object; ././@LongLink0000000000000000000000000000017200000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/object/SqlCall.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001272411623223530033273 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.object; import java.util.List; import java.util.Map; import javax.sql.DataSource; import org.springframework.jdbc.core.CallableStatementCreator; import org.springframework.jdbc.core.CallableStatementCreatorFactory; import org.springframework.jdbc.core.ParameterMapper; import org.springframework.jdbc.core.SqlParameter; /** * RdbmsOperation using a JdbcTemplate and representing a SQL-based * call such as a stored procedure or a stored function. * *

Configures a CallableStatementCreatorFactory based on the declared * parameters. * * @author Rod Johnson * @author Thomas Risberg * @see CallableStatementCreatorFactory */ public abstract class SqlCall extends RdbmsOperation { /** * Object enabling us to create CallableStatementCreators * efficiently, based on this class's declared parameters. */ private CallableStatementCreatorFactory callableStatementFactory; /** * Flag used to indicate that this call is for a function and to * use the {? = call get_invoice_count(?)} syntax. */ private boolean function = false; /** * Flag used to indicate that the sql for this call should be used exactly as it is * defined. No need to add the escape syntax and parameter place holders. */ private boolean sqlReadyForUse = false; /** * Call string as defined in java.sql.CallableStatement. * String of form {call add_invoice(?, ?, ?)} * or {? = call get_invoice_count(?)} if isFunction is set to true * Updated after each parameter is added. */ private String callString; /** * Constructor to allow use as a JavaBean. * A DataSource, SQL and any parameters must be supplied before * invoking the compile method and using this object. * @see #setDataSource * @see #setSql * @see #compile */ public SqlCall() { } /** * Create a new SqlCall object with SQL, but without parameters. * Must add parameters or settle with none. * @param ds DataSource to obtain connections from * @param sql SQL to execute */ public SqlCall(DataSource ds, String sql) { setDataSource(ds); setSql(sql); } /** * Set whether this call is for a function. */ public void setFunction(boolean function) { this.function = function; } /** * Return whether this call is for a function. */ public boolean isFunction() { return function; } /** * Set whether the SQL can be used as is. */ public void setSqlReadyForUse(boolean sqlReadyForUse) { this.sqlReadyForUse = sqlReadyForUse; } /** * Return whether the SQL can be used as is. */ public boolean isSqlReadyForUse() { return sqlReadyForUse; } /** * Overridden method to configure the CallableStatementCreatorFactory * based on our declared parameters. * @see RdbmsOperation#compileInternal() */ @Override protected final void compileInternal() { if (isSqlReadyForUse()) { this.callString = getSql(); } else { List parameters = getDeclaredParameters(); int parameterCount = 0; if (isFunction()) { this.callString = "{? = call " + getSql() + "("; parameterCount = -1; } else { this.callString = "{call " + getSql() + "("; } for (SqlParameter parameter : parameters) { if (!(parameter.isResultsParameter())) { if (parameterCount > 0) { this.callString += ", "; } if (parameterCount >= 0) { this.callString += "?"; } parameterCount++; } } this.callString += ")}"; } if (logger.isDebugEnabled()) { logger.debug("Compiled stored procedure. Call string is [" + getCallString() + "]"); } this.callableStatementFactory = new CallableStatementCreatorFactory(getCallString(), getDeclaredParameters()); this.callableStatementFactory.setResultSetType(getResultSetType()); this.callableStatementFactory.setUpdatableResults(isUpdatableResults()); this.callableStatementFactory.setNativeJdbcExtractor(getJdbcTemplate().getNativeJdbcExtractor()); onCompileInternal(); } /** * Hook method that subclasses may override to react to compilation. * This implementation does nothing. */ protected void onCompileInternal() { } /** * Get the call string. */ public String getCallString() { return this.callString; } /** * Return a CallableStatementCreator to perform an operation * with this parameters. * @param inParams parameters. May be null. */ protected CallableStatementCreator newCallableStatementCreator(Map inParams) { return this.callableStatementFactory.newCallableStatementCreator(inParams); } /** * Return a CallableStatementCreator to perform an operation * with the parameters returned from this ParameterMapper. * @param inParamMapper parametermapper. May not be null. */ protected CallableStatementCreator newCallableStatementCreator(ParameterMapper inParamMapper) { return this.callableStatementFactory.newCallableStatementCreator(inParamMapper); } } ././@LongLink0000000000000000000000000000021100000000000011557 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/object/GenericStoredProcedure.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000234511623223530033271 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.object; /** * Concrete implementation making it possible to define the RDBMS stored procedures * in an application context without writing a custom Java implementation class. *

* This implementation does not provide a typed method for invocation so executions * must use one of the generic {@link StoredProcedure#execute(java.util.Map)} or * {@link StoredProcedure#execute(org.springframework.jdbc.core.ParameterMapper)} methods. * * @author Thomas Risberg * @see org.springframework.jdbc.object.StoredProcedure */ public class GenericStoredProcedure extends StoredProcedure { } ././@LongLink0000000000000000000000000000020100000000000011556 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/object/RdbmsOperation.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000004005311623223530033267 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.object; import java.sql.ResultSet; import java.sql.Types; import java.util.Arrays; import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Map; import javax.sql.DataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.InitializingBean; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.SqlParameter; /** * An "RDBMS operation" is a multi-threaded, reusable object representing a query, * update, or stored procedure call. An RDBMS operation is not a command, * as a command is not reusable. However, execute methods may take commands as * arguments. Subclasses should be JavaBeans, allowing easy configuration. * *

This class and subclasses throw runtime exceptions, defined in the * (and as thrown by the * org.springframework.jdbc.core package, which the classes * in this package use under the hood to perform raw JDBC operations). * *

Subclasses should set SQL and add parameters before invoking the * {@link #compile()} method. The order in which parameters are added is * significant. The appropriate execute or update * method can then be invoked. * * @author Rod Johnson * @author Juergen Hoeller * @see SqlQuery * @see SqlUpdate * @see StoredProcedure * @see org.springframework.jdbc.core.JdbcTemplate */ public abstract class RdbmsOperation implements InitializingBean { /** Logger available to subclasses */ protected final Log logger = LogFactory.getLog(getClass()); /** Lower-level class used to execute SQL */ private JdbcTemplate jdbcTemplate = new JdbcTemplate(); private int resultSetType = ResultSet.TYPE_FORWARD_ONLY; private boolean updatableResults = false; private boolean returnGeneratedKeys = false; private String[] generatedKeysColumnNames = null; private String sql; private final List declaredParameters = new LinkedList(); /** * Has this operation been compiled? Compilation means at * least checking that a DataSource and sql have been provided, * but subclasses may also implement their own custom validation. */ private boolean compiled; /** * An alternative to the more commonly used setDataSource() when you want to * use the same JdbcTemplate in multiple RdbmsOperations. This is appropriate if the * JdbcTemplate has special configuration such as a SQLExceptionTranslator that should * apply to multiple RdbmsOperation objects. */ public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { if (jdbcTemplate == null) { throw new IllegalArgumentException("jdbcTemplate must not be null"); } this.jdbcTemplate = jdbcTemplate; } /** * Return the JdbcTemplate object used by this object. */ public JdbcTemplate getJdbcTemplate() { return this.jdbcTemplate; } /** * Set the JDBC DataSource to obtain connections from. * @see org.springframework.jdbc.core.JdbcTemplate#setDataSource */ public void setDataSource(DataSource dataSource) { this.jdbcTemplate.setDataSource(dataSource); } /** * Set the fetch size for this RDBMS operation. This is important for processing * large result sets: Setting this higher than the default value will increase * processing speed at the cost of memory consumption; setting this lower can * avoid transferring row data that will never be read by the application. *

Default is 0, indicating to use the driver's default. * @see org.springframework.jdbc.core.JdbcTemplate#setFetchSize */ public void setFetchSize(int fetchSize) { this.jdbcTemplate.setFetchSize(fetchSize); } /** * Set the maximum number of rows for this RDBMS operation. This is important * for processing subsets of large result sets, avoiding to read and hold * the entire result set in the database or in the JDBC driver. *

Default is 0, indicating to use the driver's default. * @see org.springframework.jdbc.core.JdbcTemplate#setMaxRows */ public void setMaxRows(int maxRows) { this.jdbcTemplate.setMaxRows(maxRows); } /** * Set the query timeout for statements that this RDBMS operation executes. *

Default is 0, indicating to use the JDBC driver's default. *

Note: Any timeout specified here will be overridden by the remaining * transaction timeout when executing within a transaction that has a * timeout specified at the transaction level. */ public void setQueryTimeout(int queryTimeout) { this.jdbcTemplate.setQueryTimeout(queryTimeout); } /** * Set whether to use statements that return a specific type of ResultSet. * @param resultSetType the ResultSet type * @see java.sql.ResultSet#TYPE_FORWARD_ONLY * @see java.sql.ResultSet#TYPE_SCROLL_INSENSITIVE * @see java.sql.ResultSet#TYPE_SCROLL_SENSITIVE * @see java.sql.Connection#prepareStatement(String, int, int) */ public void setResultSetType(int resultSetType) { this.resultSetType = resultSetType; } /** * Return whether statements will return a specific type of ResultSet. */ public int getResultSetType() { return this.resultSetType; } /** * Set whether to use statements that are capable of returning * updatable ResultSets. * @see java.sql.Connection#prepareStatement(String, int, int) */ public void setUpdatableResults(boolean updatableResults) { if (isCompiled()) { throw new InvalidDataAccessApiUsageException( "The updateableResults flag must be set before the operation is compiled"); } this.updatableResults = updatableResults; } /** * Return whether statements will return updatable ResultSets. */ public boolean isUpdatableResults() { return this.updatableResults; } /** * Set whether prepared statements should be capable of returning * auto-generated keys. * @see java.sql.Connection#prepareStatement(String, int) */ public void setReturnGeneratedKeys(boolean returnGeneratedKeys) { if (isCompiled()) { throw new InvalidDataAccessApiUsageException( "The returnGeneratedKeys flag must be set before the operation is compiled"); } this.returnGeneratedKeys = returnGeneratedKeys; } /** * Return whether statements should be capable of returning * auto-generated keys. */ public boolean isReturnGeneratedKeys() { return this.returnGeneratedKeys; } /** * Set the column names of the auto-generated keys. * @see java.sql.Connection#prepareStatement(String, String[]) */ public void setGeneratedKeysColumnNames(String[] names) { if (isCompiled()) { throw new InvalidDataAccessApiUsageException( "The column names for the generated keys must be set before the operation is compiled"); } this.generatedKeysColumnNames = names; } /** * Return the column names of the auto generated keys. */ public String[] getGeneratedKeysColumnNames() { return this.generatedKeysColumnNames; } /** * Set the SQL executed by this operation. */ public void setSql(String sql) { this.sql = sql; } /** * Subclasses can override this to supply dynamic SQL if they wish, * but SQL is normally set by calling the setSql() method * or in a subclass constructor. */ public String getSql() { return this.sql; } /** * Add anonymous parameters, specifying only their SQL types * as defined in the java.sql.Types class. *

Parameter ordering is significant. This method is an alternative * to the {@link #declareParameter} method, which should normally be preferred. * @param types array of SQL types as defined in the * java.sql.Types class * @throws InvalidDataAccessApiUsageException if the operation is already compiled */ public void setTypes(int[] types) throws InvalidDataAccessApiUsageException { if (isCompiled()) { throw new InvalidDataAccessApiUsageException("Cannot add parameters once query is compiled"); } if (types != null) { for (int type : types) { declareParameter(new SqlParameter(type)); } } } /** * Declare a parameter for this operation. *

The order in which this method is called is significant when using * positional parameters. It is not significant when using named parameters * with named SqlParameter objects here; it remains significant when using * named parameters in combination with unnamed SqlParameter objects here. * @param param the SqlParameter to add. This will specify SQL type and (optionally) * the parameter's name. Note that you typically use the {@link SqlParameter} class * itself here, not any of its subclasses. * @throws InvalidDataAccessApiUsageException if the operation is already compiled, * and hence cannot be configured further */ public void declareParameter(SqlParameter param) throws InvalidDataAccessApiUsageException { if (isCompiled()) { throw new InvalidDataAccessApiUsageException("Cannot add parameters once the query is compiled"); } this.declaredParameters.add(param); } /** * Add one or more declared parameters. Used for configuring this operation * when used in a bean factory. Each parameter will specify SQL type and (optionally) * the parameter's name. * @param parameters Array containing the declared {@link SqlParameter} objects * @see #declaredParameters */ public void setParameters(SqlParameter[] parameters) { if (isCompiled()) { throw new InvalidDataAccessApiUsageException("Cannot add parameters once the query is compiled"); } for (int i = 0; i < parameters.length; i++) { if (parameters[i] != null) { this.declaredParameters.add(parameters[i]); } else { throw new InvalidDataAccessApiUsageException("Cannot add parameter at index " + i + " from " + Arrays.asList(parameters) + " since it is 'null'"); } } } /** * Return a list of the declared {@link SqlParameter} objects. */ protected List getDeclaredParameters() { return this.declaredParameters; } /** * Ensures compilation if used in a bean factory. */ public void afterPropertiesSet() { compile(); } /** * Compile this query. * Ignores subsequent attempts to compile. * @throws InvalidDataAccessApiUsageException if the object hasn't * been correctly initialized, for example if no DataSource has been provided */ public final void compile() throws InvalidDataAccessApiUsageException { if (!isCompiled()) { if (getSql() == null) { throw new InvalidDataAccessApiUsageException("Property 'sql' is required"); } try { this.jdbcTemplate.afterPropertiesSet(); } catch (IllegalArgumentException ex) { throw new InvalidDataAccessApiUsageException(ex.getMessage()); } compileInternal(); this.compiled = true; if (logger.isDebugEnabled()) { logger.debug("RdbmsOperation with SQL [" + getSql() + "] compiled"); } } } /** * Is this operation "compiled"? Compilation, as in JDO, * means that the operation is fully configured, and ready to use. * The exact meaning of compilation will vary between subclasses. * @return whether this operation is compiled, and ready to use. */ public boolean isCompiled() { return this.compiled; } /** * Check whether this operation has been compiled already; * lazily compile it if not already compiled. *

Automatically called by validateParameters. * @see #validateParameters */ protected void checkCompiled() { if (!isCompiled()) { logger.debug("SQL operation not compiled before execution - invoking compile"); compile(); } } /** * Validate the parameters passed to an execute method based on declared parameters. * Subclasses should invoke this method before every executeQuery() * or update() method. * @param parameters parameters supplied (may be null) * @throws InvalidDataAccessApiUsageException if the parameters are invalid */ protected void validateParameters(Object[] parameters) throws InvalidDataAccessApiUsageException { checkCompiled(); int declaredInParameters = 0; for (SqlParameter param : this.declaredParameters) { if (param.isInputValueProvided()) { if (!supportsLobParameters() && (param.getSqlType() == Types.BLOB || param.getSqlType() == Types.CLOB)) { throw new InvalidDataAccessApiUsageException( "BLOB or CLOB parameters are not allowed for this kind of operation"); } declaredInParameters++; } } validateParameterCount((parameters != null ? parameters.length : 0), declaredInParameters); } /** * Validate the named parameters passed to an execute method based on declared parameters. * Subclasses should invoke this method before every executeQuery() or * update() method. * @param parameters parameter Map supplied. May be null. * @throws InvalidDataAccessApiUsageException if the parameters are invalid */ protected void validateNamedParameters(Map parameters) throws InvalidDataAccessApiUsageException { checkCompiled(); Map paramsToUse = (parameters != null ? parameters : Collections.emptyMap()); int declaredInParameters = 0; for (SqlParameter param : this.declaredParameters) { if (param.isInputValueProvided()) { if (!supportsLobParameters() && (param.getSqlType() == Types.BLOB || param.getSqlType() == Types.CLOB)) { throw new InvalidDataAccessApiUsageException( "BLOB or CLOB parameters are not allowed for this kind of operation"); } if (param.getName() != null && !paramsToUse.containsKey(param.getName())) { throw new InvalidDataAccessApiUsageException("The parameter named '" + param.getName() + "' was not among the parameters supplied: " + paramsToUse.keySet()); } declaredInParameters++; } } validateParameterCount(paramsToUse.size(), declaredInParameters); } /** * Validate the given parameter count against the given declared parameters. * @param suppliedParamCount the number of actual parameters given * @param declaredInParamCount the number of input parameters declared */ private void validateParameterCount(int suppliedParamCount, int declaredInParamCount) { if (suppliedParamCount < declaredInParamCount) { throw new InvalidDataAccessApiUsageException(suppliedParamCount + " parameters were supplied, but " + declaredInParamCount + " in parameters were declared in class [" + getClass().getName() + "]"); } if (suppliedParamCount > this.declaredParameters.size() && !allowsUnusedParameters()) { throw new InvalidDataAccessApiUsageException(suppliedParamCount + " parameters were supplied, but " + declaredInParamCount + " parameters were declared in class [" + getClass().getName() + "]"); } } /** * Subclasses must implement this template method to perform their own compilation. * Invoked after this base class's compilation is complete. *

Subclasses can assume that SQL and a DataSource have been supplied. * @throws InvalidDataAccessApiUsageException if the subclass hasn't been * properly configured */ protected abstract void compileInternal() throws InvalidDataAccessApiUsageException; /** * Return whether BLOB/CLOB parameters are supported for this kind of operation. *

The default is true. */ protected boolean supportsLobParameters() { return true; } /** * Return whether this operation accepts additional parameters that are * given but not actually used. Applies in particular to parameter Maps. *

The default is false. * @see StoredProcedure */ protected boolean allowsUnusedParameters() { return false; } } ././@LongLink0000000000000000000000000000017600000000000011571 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/object/SqlFunction.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001422411623223526033275 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.object; import java.sql.ResultSet; import java.sql.SQLException; import javax.sql.DataSource; import org.springframework.dao.TypeMismatchDataAccessException; import org.springframework.jdbc.core.SingleColumnRowMapper; /** * SQL "function" wrapper for a query that returns a single row of results. * The default behavior is to return an int, but that can be overridden by * using the constructor with an extra return type parameter. * *

Intended to use to call SQL functions that return a single result using a * query like "select user()" or "select sysdate from dual". It is not intended * for calling more complex stored functions or for using a CallableStatement to * invoke a stored procedure or stored function. Use StoredProcedure or SqlCall * for this type of processing. * *

This is a concrete class, which there is often no need to subclass. * Code using this package can create an object of this type, declaring SQL * and parameters, and then invoke the appropriate run method * repeatedly to execute the function. Subclasses are only supposed to add * specialized run methods for specific parameter and return types. * *

Like all RdbmsOperation objects, SqlFunction objects are thread-safe. * * @author Rod Johnson * @author Juergen Hoeller * @author Jean-Pierre Pawlak * @see org.springframework.jdbc.object.StoredProcedure */ public class SqlFunction extends MappingSqlQuery { private final SingleColumnRowMapper rowMapper = new SingleColumnRowMapper(); /** * Constructor to allow use as a JavaBean. * A DataSource, SQL and any parameters must be supplied before * invoking the compile method and using this object. * @see #setDataSource * @see #setSql * @see #compile */ public SqlFunction() { setRowsExpected(1); } /** * Create a new SqlFunction object with SQL, but without parameters. * Must add parameters or settle with none. * @param ds DataSource to obtain connections from * @param sql SQL to execute */ public SqlFunction(DataSource ds, String sql) { setRowsExpected(1); setDataSource(ds); setSql(sql); } /** * Create a new SqlFunction object with SQL and parameters. * @param ds DataSource to obtain connections from * @param sql SQL to execute * @param types SQL types of the parameters, as defined in the * java.sql.Types class * @see java.sql.Types */ public SqlFunction(DataSource ds, String sql, int[] types) { setRowsExpected(1); setDataSource(ds); setSql(sql); setTypes(types); } /** * Create a new SqlFunction object with SQL, parameters and a result type. * @param ds DataSource to obtain connections from * @param sql SQL to execute * @param types SQL types of the parameters, as defined in the * java.sql.Types class * @param resultType the type that the result object is required to match * @see #setResultType(Class) * @see java.sql.Types */ public SqlFunction(DataSource ds, String sql, int[] types, Class resultType) { setRowsExpected(1); setDataSource(ds); setSql(sql); setTypes(types); setResultType(resultType); } /** * Specify the type that the result object is required to match. *

If not specified, the result value will be exposed as * returned by the JDBC driver. */ public void setResultType(Class resultType) { this.rowMapper.setRequiredType(resultType); } /** * This implementation of this method extracts a single value from the * single row returned by the function. If there are a different number * of rows returned, this is treated as an error. */ @Override protected T mapRow(ResultSet rs, int rowNum) throws SQLException { return this.rowMapper.mapRow(rs, rowNum); } /** * Convenient method to run the function without arguments. * @return the value of the function */ public int run() { return run(new Object[0]); } /** * Convenient method to run the function with a single int argument. * @param parameter single int parameter * @return the value of the function */ public int run(int parameter) { return run(new Object[] {parameter}); } /** * Analogous to the SqlQuery.execute([]) method. This is a * generic method to execute a query, taken a number of arguments. * @param parameters array of parameters. These will be objects or * object wrapper types for primitives. * @return the value of the function */ public int run(Object... parameters) { Object obj = super.findObject(parameters); if (!(obj instanceof Number)) { throw new TypeMismatchDataAccessException("Couldn't convert result object [" + obj + "] to int"); } return ((Number) obj).intValue(); } /** * Convenient method to run the function without arguments, * returning the value as an object. * @return the value of the function */ public Object runGeneric() { return findObject((Object[]) null); } /** * Convenient method to run the function with a single int argument. * @param parameter single int parameter * @return the value of the function as an Object */ public Object runGeneric(int parameter) { return findObject(parameter); } /** * Analogous to the SqlQuery.findObject(Object[]) method. * This is a generic method to execute a query, taken a number of arguments. * @param parameters array of parameters. These will be objects or * object wrapper types for primitives. * @return the value of the function, as an Object * @see #execute(Object[]) */ public Object runGeneric(Object[] parameters) { return findObject(parameters); } } ././@LongLink0000000000000000000000000000017300000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/object/SqlQuery.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000003164111623223530033272 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.object; import java.util.List; import java.util.Map; import javax.sql.DataSource; import org.springframework.dao.DataAccessException; import org.springframework.dao.support.DataAccessUtils; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.namedparam.NamedParameterUtils; import org.springframework.jdbc.core.namedparam.ParsedSql; /** * Reusable operation object representing a SQL query. * *

Subclasses must implement the {@link #newRowMapper} method to provide * an object that can extract the results of iterating over the * ResultSet created during the execution of the query. * *

This class provides a number of public execute methods that are * analogous to the different convenient JDO query execute methods. Subclasses * can either rely on one of these inherited methods, or can add their own * custom execution methods, with meaningful names and typed parameters * (definitely a best practice). Each custom query method will invoke one of * this class's untyped query methods. * *

Like all RdbmsOperation classes that ship with the Spring * Framework, SqlQuery instances are thread-safe after their * initialization is complete. That is, after they are constructed and configured * via their setter methods, they can be used safely from multiple threads. * * @author Rod Johnson * @author Juergen Hoeller * @author Thomas Risberg * @see SqlUpdate */ public abstract class SqlQuery extends SqlOperation { /** The number of rows to expect; if 0, unknown. */ private int rowsExpected = 0; /** * Constructor to allow use as a JavaBean. *

The DataSource and SQL must be supplied before * compilation and use. */ public SqlQuery() { } /** * Convenient constructor with a DataSource and SQL string. * @param ds the DataSource to use to get connections * @param sql the SQL to execute; SQL can also be supplied at runtime * by overriding the {@link #getSql()} method. */ public SqlQuery(DataSource ds, String sql) { setDataSource(ds); setSql(sql); } /** * Set the number of rows expected. *

This can be used to ensure efficient storage of results. The * default behavior is not to expect any specific number of rows. */ public void setRowsExpected(int rowsExpected) { this.rowsExpected = rowsExpected; } /** * Get the number of rows expected. */ public int getRowsExpected() { return this.rowsExpected; } /** * Central execution method. All un-named parameter execution goes through this method. * @param params parameters, similar to JDO query parameters. * Primitive parameters must be represented by their Object wrapper type. * The ordering of parameters is significant. * @param context contextual information passed to the mapRow * callback method. The JDBC operation itself doesn't rely on this parameter, * but it can be useful for creating the objects of the result list. * @return a List of objects, one per row of the ResultSet. Normally all these * will be of the same class, although it is possible to use different types. */ public List execute(Object[] params, Map context) throws DataAccessException { validateParameters(params); RowMapper rowMapper = newRowMapper(params, context); return getJdbcTemplate().query(newPreparedStatementCreator(params), rowMapper); } /** * Convenient method to execute without context. * @param params parameters for the query. Primitive parameters must * be represented by their Object wrapper type. The ordering of parameters is * significant. */ public List execute(Object... params) throws DataAccessException { return execute(params, null); } /** * Convenient method to execute without parameters. * @param context the contextual information for object creation */ public List execute(Map context) throws DataAccessException { return execute((Object[]) null, context); } /** * Convenient method to execute without parameters nor context. */ public List execute() throws DataAccessException { return execute((Object[]) null); } /** * Convenient method to execute with a single int parameter and context. * @param p1 single int parameter * @param context the contextual information for object creation */ public List execute(int p1, Map context) throws DataAccessException { return execute(new Object[] {p1}, context); } /** * Convenient method to execute with a single int parameter. * @param p1 single int parameter */ public List execute(int p1) throws DataAccessException { return execute(p1, null); } /** * Convenient method to execute with two int parameters and context. * @param p1 first int parameter * @param p2 second int parameter * @param context the contextual information for object creation */ public List execute(int p1, int p2, Map context) throws DataAccessException { return execute(new Object[] {p1, p2}, context); } /** * Convenient method to execute with two int parameters. * @param p1 first int parameter * @param p2 second int parameter */ public List execute(int p1, int p2) throws DataAccessException { return execute(p1, p2, null); } /** * Convenient method to execute with a single long parameter and context. * @param p1 single long parameter * @param context the contextual information for object creation */ public List execute(long p1, Map context) throws DataAccessException { return execute(new Object[] {p1}, context); } /** * Convenient method to execute with a single long parameter. * @param p1 single long parameter */ public List execute(long p1) throws DataAccessException { return execute(p1, null); } /** * Convenient method to execute with a single String parameter and context. * @param p1 single String parameter * @param context the contextual information for object creation */ public List execute(String p1, Map context) throws DataAccessException { return execute(new Object[] {p1}, context); } /** * Convenient method to execute with a single String parameter. * @param p1 single String parameter */ public List execute(String p1) throws DataAccessException { return execute(p1, null); } /** * Central execution method. All named parameter execution goes through this method. * @param paramMap parameters associated with the name specified while declaring * the SqlParameters. Primitive parameters must be represented by their Object wrapper * type. The ordering of parameters is not significant since they are supplied in a * SqlParameterMap which is an implementation of the Map interface. * @param context contextual information passed to the mapRow * callback method. The JDBC operation itself doesn't rely on this parameter, * but it can be useful for creating the objects of the result list. * @return a List of objects, one per row of the ResultSet. Normally all these * will be of the same class, although it is possible to use different types. */ public List executeByNamedParam(Map paramMap, Map context) throws DataAccessException { validateNamedParameters(paramMap); ParsedSql parsedSql = getParsedSql(); MapSqlParameterSource paramSource = new MapSqlParameterSource(paramMap); String sqlToUse = NamedParameterUtils.substituteNamedParameters(parsedSql, paramSource); Object[] params = NamedParameterUtils.buildValueArray(parsedSql, paramSource, getDeclaredParameters()); RowMapper rowMapper = newRowMapper(params, context); return getJdbcTemplate().query(newPreparedStatementCreator(sqlToUse, params), rowMapper); } /** * Convenient method to execute without context. * @param paramMap parameters associated with the name specified while declaring * the SqlParameters. Primitive parameters must be represented by their Object wrapper * type. The ordering of parameters is not significant. */ public List executeByNamedParam(Map paramMap) throws DataAccessException { return executeByNamedParam(paramMap, null); } /** * Generic object finder method, used by all other findObject methods. * Object finder methods are like EJB entity bean finders, in that it is * considered an error if they return more than one result. * @return the result object, or null if not found. Subclasses may * choose to treat this as an error and throw an exception. * @see org.springframework.dao.support.DataAccessUtils#singleResult */ public T findObject(Object[] params, Map context) throws DataAccessException { List results = execute(params, context); return DataAccessUtils.singleResult(results); } /** * Convenient method to find a single object without context. */ public T findObject(Object... params) throws DataAccessException { return findObject(params, null); } /** * Convenient method to find a single object given a single int parameter * and a context. */ public T findObject(int p1, Map context) throws DataAccessException { return findObject(new Object[] {p1}, context); } /** * Convenient method to find a single object given a single int parameter. */ public T findObject(int p1) throws DataAccessException { return findObject(p1, null); } /** * Convenient method to find a single object given two int parameters * and a context. */ public T findObject(int p1, int p2, Map context) throws DataAccessException { return findObject(new Object[] {p1, p2}, context); } /** * Convenient method to find a single object given two int parameters. */ public T findObject(int p1, int p2) throws DataAccessException { return findObject(p1, p2, null); } /** * Convenient method to find a single object given a single long parameter * and a context. */ public T findObject(long p1, Map context) throws DataAccessException { return findObject(new Object[] {p1}, context); } /** * Convenient method to find a single object given a single long parameter. */ public T findObject(long p1) throws DataAccessException { return findObject(p1, null); } /** * Convenient method to find a single object given a single String parameter * and a context. */ public T findObject(String p1, Map context) throws DataAccessException { return findObject(new Object[] {p1}, context); } /** * Convenient method to find a single object given a single String parameter. */ public T findObject(String p1) throws DataAccessException { return findObject(p1, null); } /** * Generic object finder method for named parameters. * @param paramMap Map of parameter name to parameter object, * matching named parameters specified in the SQL statement. * Ordering is not significant. * @param context contextual information passed to the mapRow * callback method. The JDBC operation itself doesn't rely on this parameter, * but it can be useful for creating the objects of the result list. * @return a List of objects, one per row of the ResultSet. Normally all these * will be of the same class, although it is possible to use different types. */ public T findObjectByNamedParam(Map paramMap, Map context) throws DataAccessException { List results = executeByNamedParam(paramMap, context); return DataAccessUtils.singleResult(results); } /** * Convenient method to execute without context. * @param paramMap Map of parameter name to parameter object, * matching named parameters specified in the SQL statement. * Ordering is not significant. */ public T findObjectByNamedParam(Map paramMap) throws DataAccessException { return findObjectByNamedParam(paramMap, null); } /** * Subclasses must implement this method to extract an object per row, to be * returned by the execute method as an aggregated {@link List}. * @param parameters the parameters to the execute() method, * in case subclass is interested; may be null if there * were no parameters. * @param context contextual information passed to the mapRow * callback method. The JDBC operation itself doesn't rely on this parameter, * but it can be useful for creating the objects of the result list. * @see #execute */ protected abstract RowMapper newRowMapper(Object[] parameters, Map context); } ././@LongLink0000000000000000000000000000020100000000000011556 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/object/BatchSqlUpdate.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001643611623223526033304 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package org.springframework.jdbc.object; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import javax.sql.DataSource; import org.springframework.dao.DataAccessException; import org.springframework.jdbc.core.BatchPreparedStatementSetter; /** * SqlUpdate subclass that performs batch update operations. Encapsulates * queuing up records to be updated, and adds them as a single batch once * flush is called or the given batch size has been met. * *

Note that this class is a non-thread-safe object, in contrast * to all other JDBC operations objects in this package. You need to create * a new instance of it for each use, or call reset before * reuse within the same thread. * * @author Keith Donald * @author Juergen Hoeller * @since 1.1 * @see #flush * @see #reset */ public class BatchSqlUpdate extends SqlUpdate { /** * Default number of inserts to accumulate before commiting a batch (5000). */ public static int DEFAULT_BATCH_SIZE = 5000; private int batchSize = DEFAULT_BATCH_SIZE; private boolean trackRowsAffected = true; private final LinkedList parameterQueue = new LinkedList(); private final List rowsAffected = new ArrayList(); /** * Constructor to allow use as a JavaBean. DataSource and SQL * must be supplied before compilation and use. * @see #setDataSource * @see #setSql */ public BatchSqlUpdate() { super(); } /** * Construct an update object with a given DataSource and SQL. * @param ds DataSource to use to obtain connections * @param sql SQL statement to execute */ public BatchSqlUpdate(DataSource ds, String sql) { super(ds, sql); } /** * Construct an update object with a given DataSource, SQL * and anonymous parameters. * @param ds DataSource to use to obtain connections * @param sql SQL statement to execute * @param types SQL types of the parameters, as defined in the * java.sql.Types class * @see java.sql.Types */ public BatchSqlUpdate(DataSource ds, String sql, int[] types) { super(ds, sql, types); } /** * Construct an update object with a given DataSource, SQL, * anonymous parameters and specifying the maximum number of rows * that may be affected. * @param ds DataSource to use to obtain connections * @param sql SQL statement to execute * @param types SQL types of the parameters, as defined in the * java.sql.Types class * @param batchSize the number of statements that will trigger * an automatic intermediate flush * @see java.sql.Types */ public BatchSqlUpdate(DataSource ds, String sql, int[] types, int batchSize) { super(ds, sql, types); setBatchSize(batchSize); } /** * Set the number of statements that will trigger an automatic intermediate * flush. update calls or the given statement parameters will * be queued until the batch size is met, at which point it will empty the * queue and execute the batch. *

You can also flush already queued statements with an explicit * flush call. Note that you need to this after queueing * all parameters to guarantee that all statements have been flushed. */ public void setBatchSize(int batchSize) { this.batchSize = batchSize; } /** * Set whether to track the rows affected by batch updates performed * by this operation object. *

Default is "true". Turn this off to save the memory needed for * the list of row counts. * @see #getRowsAffected() */ public void setTrackRowsAffected(boolean trackRowsAffected) { this.trackRowsAffected = trackRowsAffected; } /** * BatchSqlUpdate does not support BLOB or CLOB parameters. */ @Override protected boolean supportsLobParameters() { return false; } /** * Overridden version of update that adds the given statement * parameters to the queue rather than executing them immediately. * All other update methods of the SqlUpdate base class go * through this method and will thus behave similarly. *

You need to call flush to actually execute the batch. * If the specified batch size is reached, an implicit flush will happen; * you still need to finally call flush to flush all statements. * @param params array of parameter objects * @return the number of rows affected by the update (always -1, * meaning "not applicable", as the statement is not actually * executed by this method) * @see #flush */ @Override public int update(Object... params) throws DataAccessException { validateParameters(params); this.parameterQueue.add(params.clone()); if (this.parameterQueue.size() == this.batchSize) { if (logger.isDebugEnabled()) { logger.debug("Triggering auto-flush because queue reached batch size of " + this.batchSize); } flush(); } return -1; } /** * Trigger any queued update operations to be added as a final batch. * @return an array of the number of rows affected by each statement */ public int[] flush() { if (this.parameterQueue.isEmpty()) { return new int[0]; } int[] rowsAffected = getJdbcTemplate().batchUpdate( getSql(), new BatchPreparedStatementSetter() { public int getBatchSize() { return parameterQueue.size(); } public void setValues(PreparedStatement ps, int index) throws SQLException { Object[] params = parameterQueue.removeFirst(); newPreparedStatementSetter(params).setValues(ps); } }); for (int rowCount : rowsAffected) { checkRowsAffected(rowCount); if (this.trackRowsAffected) { this.rowsAffected.add(rowCount); } } return rowsAffected; } /** * Return the current number of statements or statement parameters * in the queue. */ public int getQueueCount() { return this.parameterQueue.size(); } /** * Return the number of already executed statements. */ public int getExecutionCount() { return this.rowsAffected.size(); } /** * Return the number of affected rows for all already executed statements. * Accumulates all of flush's return values until * reset is invoked. * @return an array of the number of rows affected by each statement * @see #reset */ public int[] getRowsAffected() { int[] result = new int[this.rowsAffected.size()]; int i = 0; for (Iterator it = this.rowsAffected.iterator(); it.hasNext(); i++) { result[i] = it.next(); } return result; } /** * Reset the statement parameter queue, the rows affected cache, * and the execution count. */ public void reset() { this.parameterQueue.clear(); this.rowsAffected.clear(); } } ././@LongLink0000000000000000000000000000017700000000000011572 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/object/SqlOperation.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001026011623223526033271 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.object; import org.springframework.jdbc.core.PreparedStatementCreator; import org.springframework.jdbc.core.PreparedStatementCreatorFactory; import org.springframework.jdbc.core.PreparedStatementSetter; import org.springframework.jdbc.core.namedparam.NamedParameterUtils; import org.springframework.jdbc.core.namedparam.ParsedSql; /** * Operation object representing a SQL-based operation such as a query or update, * as opposed to a stored procedure. * *

Configures a {@link org.springframework.jdbc.core.PreparedStatementCreatorFactory} * based on the declared parameters. * * @author Rod Johnson * @author Juergen Hoeller */ public abstract class SqlOperation extends RdbmsOperation { /** * Object enabling us to create PreparedStatementCreators efficiently, * based on this class's declared parameters. */ private PreparedStatementCreatorFactory preparedStatementFactory; /** Parsed representation of the SQL statement */ private ParsedSql cachedSql; /** Monitor for locking the cached representation of the parsed SQL statement */ private final Object parsedSqlMonitor = new Object(); /** * Overridden method to configure the PreparedStatementCreatorFactory * based on our declared parameters. */ @Override protected final void compileInternal() { this.preparedStatementFactory = new PreparedStatementCreatorFactory(getSql(), getDeclaredParameters()); this.preparedStatementFactory.setResultSetType(getResultSetType()); this.preparedStatementFactory.setUpdatableResults(isUpdatableResults()); this.preparedStatementFactory.setReturnGeneratedKeys(isReturnGeneratedKeys()); if (getGeneratedKeysColumnNames() != null) { this.preparedStatementFactory.setGeneratedKeysColumnNames(getGeneratedKeysColumnNames()); } this.preparedStatementFactory.setNativeJdbcExtractor(getJdbcTemplate().getNativeJdbcExtractor()); onCompileInternal(); } /** * Hook method that subclasses may override to post-process compilation. * This implementation does nothing. * @see #compileInternal */ protected void onCompileInternal() { } /** * Obtain a parsed representation of this operation's SQL statement. *

Typically used for named parameter parsing. */ protected ParsedSql getParsedSql() { synchronized (this.parsedSqlMonitor) { if (this.cachedSql == null) { this.cachedSql = NamedParameterUtils.parseSqlStatement(getSql()); } return this.cachedSql; } } /** * Return a PreparedStatementSetter to perform an operation * with the given parameters. * @param params the parameter array (may be null) */ protected final PreparedStatementSetter newPreparedStatementSetter(Object[] params) { return this.preparedStatementFactory.newPreparedStatementSetter(params); } /** * Return a PreparedStatementCreator to perform an operation * with the given parameters. * @param params the parameter array (may be null) */ protected final PreparedStatementCreator newPreparedStatementCreator(Object[] params) { return this.preparedStatementFactory.newPreparedStatementCreator(params); } /** * Return a PreparedStatementCreator to perform an operation * with the given parameters. * @param sqlToUse the actual SQL statement to use (if different from * the factory's, for example because of named parameter expanding) * @param params the parameter array (may be null) */ protected final PreparedStatementCreator newPreparedStatementCreator(String sqlToUse, Object[] params) { return this.preparedStatementFactory.newPreparedStatementCreator(sqlToUse, params); } } ././@LongLink0000000000000000000000000000022000000000000011557 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/object/MappingSqlQueryWithParameters.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000767411623223526033310 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.object; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Map; import javax.sql.DataSource; import org.springframework.jdbc.core.RowMapper; /** * Reusable RDBMS query in which concrete subclasses must implement * the abstract mapRow(ResultSet, int) method to map each row of * the JDBC ResultSet into an object. * *

Such manual mapping is usually preferable to "automatic" * mapping using reflection, which can become complex in non-trivial * cases. For example, the present class allows different objects * to be used for different rows (for example, if a subclass is indicated). * It allows computed fields to be set. And there's no need for * ResultSet columns to have the same names as bean properties. * The Pareto Principle in action: going the extra mile to automate * the extraction process makes the framework much more complex * and delivers little real benefit. * *

Subclasses can be constructed providing SQL, parameter types * and a DataSource. SQL will often vary between subclasses. * * @author Rod Johnson * @author Thomas Risberg * @author Jean-Pierre Pawlak * @see org.springframework.jdbc.object.MappingSqlQuery * @see org.springframework.jdbc.object.SqlQuery */ public abstract class MappingSqlQueryWithParameters extends SqlQuery { /** * Constructor to allow use as a JavaBean */ public MappingSqlQueryWithParameters() { } /** * Convenient constructor with DataSource and SQL string. * @param ds DataSource to use to get connections * @param sql SQL to run */ public MappingSqlQueryWithParameters(DataSource ds, String sql) { super(ds, sql); } /** * Implementation of protected abstract method. This invokes the subclass's * implementation of the mapRow() method. */ @Override protected RowMapper newRowMapper(Object[] parameters, Map context) { return new RowMapperImpl(parameters, context); } /** * Subclasses must implement this method to convert each row * of the ResultSet into an object of the result type. * @param rs ResultSet we're working through * @param rowNum row number (from 0) we're up to * @param parameters to the query (passed to the execute() method). * Subclasses are rarely interested in these. * It can be null if there are no parameters. * @param context passed to the execute() method. * It can be null if no contextual information is need. * @return an object of the result type * @throws SQLException if there's an error extracting data. * Subclasses can simply not catch SQLExceptions, relying on the * framework to clean up. */ protected abstract T mapRow(ResultSet rs, int rowNum, Object[] parameters, Map context) throws SQLException; /** * Implementation of RowMapper that calls the enclosing * class's mapRow method for each row. */ protected class RowMapperImpl implements RowMapper { private final Object[] params; private final Map context; /** * Use an array results. More efficient if we know how many results to expect. */ public RowMapperImpl(Object[] parameters, Map context) { this.params = parameters; this.context = context; } public T mapRow(ResultSet rs, int rowNum) throws SQLException { return MappingSqlQueryWithParameters.this.mapRow(rs, rowNum, this.params, this.context); } } } ././@LongLink0000000000000000000000000000020200000000000011557 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/object/StoredProcedure.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001546311623223530033276 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.object; import java.util.Map; import java.util.HashMap; import javax.sql.DataSource; import org.springframework.dao.DataAccessException; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.ParameterMapper; import org.springframework.jdbc.core.SqlParameter; /** * Superclass for object abstractions of RDBMS stored procedures. * This class is abstract and it is intended that subclasses will provide * a typed method for invocation that delegates to the supplied * {@link #execute} method. * *

The inherited sql property is the name of the stored * procedure in the RDBMS. Note that JDBC 3.0 introduces named parameters, * although the other features provided by this class are still necessary * in JDBC 3.0. * * @author Rod Johnson * @author Thomas Risberg * @see #setSql */ public abstract class StoredProcedure extends SqlCall { /** * Allow use as a bean. */ protected StoredProcedure() { } /** * Create a new object wrapper for a stored procedure. * @param ds DataSource to use throughout the lifetime * of this object to obtain connections * @param name name of the stored procedure in the database */ protected StoredProcedure(DataSource ds, String name) { setDataSource(ds); setSql(name); } /** * Create a new object wrapper for a stored procedure. * @param jdbcTemplate JdbcTemplate which wraps DataSource * @param name name of the stored procedure in the database */ protected StoredProcedure(JdbcTemplate jdbcTemplate, String name) { setJdbcTemplate(jdbcTemplate); setSql(name); } /** * StoredProcedure parameter Maps are by default allowed to contain * additional entries that are not actually used as parameters. */ @Override protected boolean allowsUnusedParameters() { return true; } /** * Declare a parameter. Overridden method. * Parameters declared as SqlParameter and SqlInOutParameter * will always be used to provide input values. In addition to this any parameter declared * as SqlOutParameter where an non-null input value is provided will also be used * as an input paraneter. * Note: Calls to declareParameter must be made in the same order as * they appear in the database's stored procedure parameter list. * Names are purely used to help mapping. * @param param parameter object */ @Override public void declareParameter(SqlParameter param) throws InvalidDataAccessApiUsageException { if (param.getName() == null) { throw new InvalidDataAccessApiUsageException("Parameters to stored procedures must have names as well as types"); } super.declareParameter(param); } /** * Execute the stored procedure with the provided parameter values. This is * a convenience method where the order of the passed in parameter values * must match the order that the parameters where declared in. * @param inParams variable number of input parameters. Output parameters should * not be included in this map. * It is legal for values to be null, and this will produce the * correct behavior using a NULL argument to the stored procedure. * @return map of output params, keyed by name as in parameter declarations. * Output parameters will appear here, with their values after the * stored procedure has been called. */ public Map execute(Object... inParams) { Map paramsToUse = new HashMap(); validateParameters(inParams); int i = 0; for (SqlParameter sqlParameter : getDeclaredParameters()) { if (sqlParameter.isInputValueProvided()) { if (i < inParams.length) { paramsToUse.put(sqlParameter.getName(), inParams[i++]); } } } return getJdbcTemplate().call(newCallableStatementCreator(paramsToUse), getDeclaredParameters()); } /** * Execute the stored procedure. Subclasses should define a strongly typed * execute method (with a meaningful name) that invokes this method, populating * the input map and extracting typed values from the output map. Subclass * execute methods will often take domain objects as arguments and return values. * Alternatively, they can return void. * @param inParams map of input parameters, keyed by name as in parameter * declarations. Output parameters need not (but can) be included in this map. * It is legal for map entries to be null, and this will produce the * correct behavior using a NULL argument to the stored procedure. * @return map of output params, keyed by name as in parameter declarations. * Output parameters will appear here, with their values after the * stored procedure has been called. */ public Map execute(Map inParams) throws DataAccessException { validateParameters(inParams.values().toArray()); return getJdbcTemplate().call(newCallableStatementCreator(inParams), getDeclaredParameters()); } /** * Execute the stored procedure. Subclasses should define a strongly typed * execute method (with a meaningful name) that invokes this method, passing in * a ParameterMapper that will populate the input map. This allows mapping database * specific features since the ParameterMapper has access to the Connection object. * The execute method is also responsible for extracting typed values from the output map. * Subclass execute methods will often take domain objects as arguments and return values. * Alternatively, they can return void. * @param inParamMapper map of input parameters, keyed by name as in parameter * declarations. Output parameters need not (but can) be included in this map. * It is legal for map entries to be null, and this will produce the correct * behavior using a NULL argument to the stored procedure. * @return map of output params, keyed by name as in parameter declarations. * Output parameters will appear here, with their values after the * stored procedure has been called. */ public Map execute(ParameterMapper inParamMapper) throws DataAccessException { checkCompiled(); return getJdbcTemplate().call(newCallableStatementCreator(inParamMapper), getDeclaredParameters()); } } ././@LongLink0000000000000000000000000000017400000000000011567 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/object/SqlUpdate.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000002301311623223526033271 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.object; import java.util.Map; import javax.sql.DataSource; import org.springframework.dao.DataAccessException; import org.springframework.jdbc.JdbcUpdateAffectedIncorrectNumberOfRowsException; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.namedparam.NamedParameterUtils; import org.springframework.jdbc.core.namedparam.ParsedSql; import org.springframework.jdbc.support.KeyHolder; /** * Reusable operation object representing a SQL update. * *

This class provides a number of update methods, * analogous to the execute methods of query objects. * *

This class is concrete. Although it can be subclassed (for example * to add a custom update method) it can easily be parameterized by setting * SQL and declaring parameters. * *

Like all RdbmsOperation classes that ship with the Spring * Framework, SqlQuery instances are thread-safe after their * initialization is complete. That is, after they are constructed and configured * via their setter methods, they can be used safely from multiple threads. * * @author Rod Johnson * @author Thomas Risberg * @author Juergen Hoeller * @see SqlQuery */ public class SqlUpdate extends SqlOperation { /** * Maximum number of rows the update may affect. If more are * affected, an exception will be thrown. Ignored if 0. */ private int maxRowsAffected = 0; /** * An exact number of rows that must be affected. * Ignored if 0. */ private int requiredRowsAffected = 0; /** * Constructor to allow use as a JavaBean. DataSource and SQL * must be supplied before compilation and use. * @see #setDataSource * @see #setSql */ public SqlUpdate() { } /** * Constructs an update object with a given DataSource and SQL. * @param ds DataSource to use to obtain connections * @param sql SQL statement to execute */ public SqlUpdate(DataSource ds, String sql) { setDataSource(ds); setSql(sql); } /** * Construct an update object with a given DataSource, SQL * and anonymous parameters. * @param ds DataSource to use to obtain connections * @param sql SQL statement to execute * @param types SQL types of the parameters, as defined in the * java.sql.Types class * @see java.sql.Types */ public SqlUpdate(DataSource ds, String sql, int[] types) { setDataSource(ds); setSql(sql); setTypes(types); } /** * Construct an update object with a given DataSource, SQL, * anonymous parameters and specifying the maximum number of rows * that may be affected. * @param ds DataSource to use to obtain connections * @param sql SQL statement to execute * @param types SQL types of the parameters, as defined in the * java.sql.Types class * @param maxRowsAffected the maximum number of rows that may * be affected by the update * @see java.sql.Types */ public SqlUpdate(DataSource ds, String sql, int[] types, int maxRowsAffected) { setDataSource(ds); setSql(sql); setTypes(types); this.maxRowsAffected = maxRowsAffected; } /** * Set the maximum number of rows that may be affected by this update. * The default value is 0, which does not limit the number of rows affected. * @param maxRowsAffected the maximum number of rows that can be affected by * this update without this class's update method considering it an error */ public void setMaxRowsAffected(int maxRowsAffected) { this.maxRowsAffected = maxRowsAffected; } /** * Set the exact number of rows that must be affected by this update. * The default value is 0, which allows any number of rows to be affected. *

This is an alternative to setting the maximum number of rows * that may be affected. * @param requiredRowsAffected the exact number of rows that must be affected * by this update without this class's update method considering it an error */ public void setRequiredRowsAffected(int requiredRowsAffected) { this.requiredRowsAffected = requiredRowsAffected; } /** * Check the given number of affected rows against the * specified maximum number or required number. * @param rowsAffected the number of affected rows * @throws JdbcUpdateAffectedIncorrectNumberOfRowsException * if the actually affected rows are out of bounds * @see #setMaxRowsAffected * @see #setRequiredRowsAffected */ protected void checkRowsAffected(int rowsAffected) throws JdbcUpdateAffectedIncorrectNumberOfRowsException { if (this.maxRowsAffected > 0 && rowsAffected > this.maxRowsAffected) { throw new JdbcUpdateAffectedIncorrectNumberOfRowsException(getSql(), this.maxRowsAffected, rowsAffected); } if (this.requiredRowsAffected > 0 && rowsAffected != this.requiredRowsAffected) { throw new JdbcUpdateAffectedIncorrectNumberOfRowsException(getSql(), this.requiredRowsAffected, rowsAffected); } } /** * Generic method to execute the update given parameters. * All other update methods invoke this method. * @param params array of parameters objects * @return the number of rows affected by the update */ public int update(Object... params) throws DataAccessException { validateParameters(params); int rowsAffected = getJdbcTemplate().update(newPreparedStatementCreator(params)); checkRowsAffected(rowsAffected); return rowsAffected; } /** * Method to execute the update given arguments and * retrieve the generated keys using a KeyHolder. * @param params array of parameter objects * @param generatedKeyHolder KeyHolder that will hold the generated keys * @return the number of rows affected by the update */ public int update(Object[] params, KeyHolder generatedKeyHolder) throws DataAccessException { validateParameters(params); int rowsAffected = getJdbcTemplate().update(newPreparedStatementCreator(params), generatedKeyHolder); checkRowsAffected(rowsAffected); return rowsAffected; } /** * Convenience method to execute an update with no parameters. */ public int update() throws DataAccessException { return update((Object[]) null); } /** * Convenient method to execute an update given one int arg. */ public int update(int p1) throws DataAccessException { return update(new Object[] {p1}); } /** * Convenient method to execute an update given two int args. */ public int update(int p1, int p2) throws DataAccessException { return update(new Object[] {p1, p2}); } /** * Convenient method to execute an update given one long arg. */ public int update(long p1) throws DataAccessException { return update(new Object[] {p1}); } /** * Convenient method to execute an update given two long args. */ public int update(long p1, long p2) throws DataAccessException { return update(new Object[] {p1, p2}); } /** * Convenient method to execute an update given one String arg. */ public int update(String p) throws DataAccessException { return update(new Object[] {p}); } /** * Convenient method to execute an update given two String args. */ public int update(String p1, String p2) throws DataAccessException { return update(new Object[] {p1, p2}); } /** * Generic method to execute the update given named parameters. * All other update methods invoke this method. * @param paramMap Map of parameter name to parameter object, * matching named parameters specified in the SQL statement * @return the number of rows affected by the update */ public int updateByNamedParam(Map paramMap) throws DataAccessException { validateNamedParameters(paramMap); ParsedSql parsedSql = getParsedSql(); MapSqlParameterSource paramSource = new MapSqlParameterSource(paramMap); String sqlToUse = NamedParameterUtils.substituteNamedParameters(parsedSql, paramSource); Object[] params = NamedParameterUtils.buildValueArray(parsedSql, paramSource, getDeclaredParameters()); int rowsAffected = getJdbcTemplate().update(newPreparedStatementCreator(sqlToUse, params)); checkRowsAffected(rowsAffected); return rowsAffected; } /** * Method to execute the update given arguments and * retrieve the generated keys using a KeyHolder. * @param paramMap Map of parameter name to parameter object, * matching named parameters specified in the SQL statement * @param generatedKeyHolder KeyHolder that will hold the generated keys * @return the number of rows affected by the update */ public int updateByNamedParam(Map paramMap, KeyHolder generatedKeyHolder) throws DataAccessException { validateNamedParameters(paramMap); ParsedSql parsedSql = getParsedSql(); MapSqlParameterSource paramSource = new MapSqlParameterSource(paramMap); String sqlToUse = NamedParameterUtils.substituteNamedParameters(parsedSql, paramSource); Object[] params = NamedParameterUtils.buildValueArray(parsedSql, paramSource, getDeclaredParameters()); int rowsAffected = getJdbcTemplate().update(newPreparedStatementCreator(sqlToUse, params), generatedKeyHolder); checkRowsAffected(rowsAffected); return rowsAffected; } } ././@LongLink0000000000000000000000000000020200000000000011557 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/object/GenericSqlQuery.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000353711623223530033275 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.object; import java.util.Map; import org.springframework.jdbc.core.RowMapper; import org.springframework.util.Assert; import org.springframework.dao.InvalidDataAccessResourceUsageException; public class GenericSqlQuery extends SqlQuery { Class rowMapperClass; RowMapper rowMapper; public void setRowMapperClass(Class rowMapperClass) throws IllegalAccessException, InstantiationException { this.rowMapperClass = rowMapperClass; if (!RowMapper.class.isAssignableFrom(rowMapperClass)) throw new IllegalStateException("The specified class '" + rowMapperClass.getName() + " is not a sub class of " + "'org.springframework.jdbc.core.RowMapper'"); } public void afterPropertiesSet() { super.afterPropertiesSet(); Assert.notNull(rowMapperClass, "The 'rowMapperClass' property is required"); } protected RowMapper newRowMapper(Object[] parameters, Map context) { try { return (RowMapper) rowMapperClass.newInstance(); } catch (InstantiationException e) { throw new InvalidDataAccessResourceUsageException("Unable to instantiate RowMapper", e); } catch (IllegalAccessException e) { throw new InvalidDataAccessResourceUsageException("Unable to instantiate RowMapper", e); } } } ././@LongLink0000000000000000000000000000020400000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/object/UpdatableSqlQuery.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000627711623223530033301 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.object; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Map; import javax.sql.DataSource; import org.springframework.jdbc.core.RowMapper; /** * Reusable RDBMS query in which concrete subclasses must implement * the abstract updateRow(ResultSet, int, context) method to update each * row of the JDBC ResultSet and optionally map contents into an object. * *

Subclasses can be constructed providing SQL, parameter types * and a DataSource. SQL will often vary between subclasses. * * @author Thomas Risberg * @see org.springframework.jdbc.object.SqlQuery */ public abstract class UpdatableSqlQuery extends SqlQuery { /** * Constructor to allow use as a JavaBean */ public UpdatableSqlQuery() { setUpdatableResults(true); } /** * Convenient constructor with DataSource and SQL string. * @param ds DataSource to use to get connections * @param sql SQL to run */ public UpdatableSqlQuery(DataSource ds, String sql) { super(ds, sql); setUpdatableResults(true); } /** * Implementation of the superclass template method. This invokes the subclass's * implementation of the updateRow() method. */ @Override protected RowMapper newRowMapper(Object[] parameters, Map context) { return new RowMapperImpl(context); } /** * Subclasses must implement this method to update each row of the * ResultSet and optionally create object of the result type. * @param rs ResultSet we're working through * @param rowNum row number (from 0) we're up to * @param context passed to the execute() method. * It can be null if no contextual information is need. If you * need to pass in data for each row, you can pass in a HashMap with * the primary key of the row being the key for the HashMap. That way * it is easy to locate the updates for each row * @return an object of the result type * @throws SQLException if there's an error updateing data. * Subclasses can simply not catch SQLExceptions, relying on the * framework to clean up. */ protected abstract T updateRow(ResultSet rs, int rowNum, Map context) throws SQLException; /** * Implementation of RowMapper that calls the enclosing * class's updateRow() method for each row. */ protected class RowMapperImpl implements RowMapper { private final Map context; public RowMapperImpl(Map context) { this.context = context; } public T mapRow(ResultSet rs, int rowNum) throws SQLException { T result = updateRow(rs, rowNum, this.context); rs.updateRow(); return result; } } } ././@LongLink0000000000000000000000000000020200000000000011557 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/object/MappingSqlQuery.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000522611623223526033277 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.object; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Map; import javax.sql.DataSource; /** * Reusable query in which concrete subclasses must implement the abstract * mapRow(ResultSet, int) method to convert each row of the JDBC ResultSet * into an object. * *

Simplifies MappingSqlQueryWithParameters API by dropping parameters and * context. Most subclasses won't care about parameters. If you don't use * contextual information, subclass this instead of MappingSqlQueryWithParameters. * * @author Rod Johnson * @author Thomas Risberg * @author Jean-Pierre Pawlak * @see MappingSqlQueryWithParameters */ public abstract class MappingSqlQuery extends MappingSqlQueryWithParameters { /** * Constructor that allows use as a JavaBean. */ public MappingSqlQuery() { } /** * Convenient constructor with DataSource and SQL string. * @param ds DataSource to use to obtain connections * @param sql SQL to run */ public MappingSqlQuery(DataSource ds, String sql) { super(ds, sql); } /** * This method is implemented to invoke the simpler mapRow * template method, ignoring parameters. * @see #mapRow(ResultSet, int) */ @Override protected final T mapRow(ResultSet rs, int rowNum, Object[] parameters, Map context) throws SQLException { return mapRow(rs, rowNum); } /** * Subclasses must implement this method to convert each row of the * ResultSet into an object of the result type. *

Subclasses of this class, as opposed to direct subclasses of * MappingSqlQueryWithParameters, don't need to concern themselves * with the parameters to the execute method of the query object. * @param rs ResultSet we're working through * @param rowNum row number (from 0) we're up to * @return an object of the result type * @throws SQLException if there's an error extracting data. * Subclasses can simply not catch SQLExceptions, relying on the * framework to clean up. */ protected abstract T mapRow(ResultSet rs, int rowNum) throws SQLException; } ././@LongLink0000000000000000000000000000015600000000000011567 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/config/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000755000175000017500000000000011623223530033263 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000017700000000000011572 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/config/package-info.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000014711623223530033267 0ustar drazzibdrazzib /** * Defines the Spring JDBC configuration namespace. */ package org.springframework.jdbc.config; ././@LongLink0000000000000000000000000000023100000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/config/InitializeDatabaseBeanDefinitionParser.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000716311623223526033301 0ustar drazzibdrazzib/* * Copyright 2002-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.config; import java.util.ArrayList; import java.util.List; import org.w3c.dom.Element; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser; import org.springframework.beans.factory.xml.ParserContext; import org.springframework.jdbc.datasource.init.DataSourceInitializer; import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; import org.springframework.util.xml.DomUtils; /** * {@link org.springframework.beans.factory.xml.BeanDefinitionParser} that parses an {@code initialize-database} * element and creates a {@link BeanDefinition} of type {@link DataSourceInitializer}. Picks up nested * {@code script} elements and configures a {@link ResourceDatabasePopulator} for them. * * @author Dave Syer * @since 3.0 */ public class InitializeDatabaseBeanDefinitionParser extends AbstractBeanDefinitionParser { @Override protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) { BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(DataSourceInitializer.class); builder.addPropertyReference("dataSource", element.getAttribute("data-source")); builder.addPropertyValue("enabled", element.getAttribute("enabled")); setDatabasePopulator(element, builder); builder.getRawBeanDefinition().setSource(parserContext.extractSource(element)); return builder.getBeanDefinition(); } @Override protected boolean shouldGenerateId() { return true; } private void setDatabasePopulator(Element element, BeanDefinitionBuilder builder) { List scripts = DomUtils.getChildElementsByTagName(element, "script"); if (scripts.size() > 0) { builder.addPropertyValue("databasePopulator", createDatabasePopulator(element, scripts)); } } private BeanDefinition createDatabasePopulator(Element element, List scripts) { BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(ResourceDatabasePopulator.class); builder.addPropertyValue("ignoreFailedDrops", element.getAttribute("ignore-failures").equals("DROPS")); builder.addPropertyValue("continueOnError", element.getAttribute("ignore-failures").equals("ALL")); List locations = new ArrayList(); for (Element scriptElement : scripts) { String location = scriptElement.getAttribute("location"); locations.add(location); } // Use a factory bean for the resources so they can be given an order if a pattern is used BeanDefinitionBuilder resourcesFactory = BeanDefinitionBuilder.genericBeanDefinition(SortedResourcesFactoryBean.class); resourcesFactory.addConstructorArgValue(locations); builder.addPropertyValue("scripts", resourcesFactory.getBeanDefinition()); return builder.getBeanDefinition(); } } ././@LongLink0000000000000000000000000000022700000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/config/EmbeddedDatabaseBeanDefinitionParser.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000717711623223530033301 0ustar drazzibdrazzib/* * Copyright 2002-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.config; import java.util.ArrayList; import java.util.List; import org.w3c.dom.Element; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser; import org.springframework.beans.factory.xml.ParserContext; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseFactoryBean; import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; import org.springframework.util.StringUtils; import org.springframework.util.xml.DomUtils; /** * {@link org.springframework.beans.factory.xml.BeanDefinitionParser} that parses an {@code embedded-database} * element and creates a {@link BeanDefinition} for {@link EmbeddedDatabaseFactoryBean}. Picks up nested * {@code script} elements and configures a {@link ResourceDatabasePopulator} for them. * * @author Oliver Gierke * @since 3.0 */ class EmbeddedDatabaseBeanDefinitionParser extends AbstractBeanDefinitionParser { @Override protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) { BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(EmbeddedDatabaseFactoryBean.class); setDatabaseType(element, builder); setDatabasePopulator(element, builder); useIdAsDatabaseNameIfGiven(element, builder); builder.getRawBeanDefinition().setSource(parserContext.extractSource(element)); return builder.getBeanDefinition(); } private void useIdAsDatabaseNameIfGiven(Element element, BeanDefinitionBuilder builder) { String id = element.getAttribute(ID_ATTRIBUTE); if (StringUtils.hasText(id)) { builder.addPropertyValue("databaseName", id); } } private void setDatabaseType(Element element, BeanDefinitionBuilder builder) { String type = element.getAttribute("type"); if (StringUtils.hasText(type)) { builder.addPropertyValue("databaseType", type); } } private void setDatabasePopulator(Element element, BeanDefinitionBuilder builder) { List scripts = DomUtils.getChildElementsByTagName(element, "script"); if (scripts.size() > 0) { builder.addPropertyValue("databasePopulator", createDatabasePopulator(scripts)); } } private BeanDefinition createDatabasePopulator(List scripts) { BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(ResourceDatabasePopulator.class); List locations = new ArrayList(); for (Element scriptElement : scripts) { locations.add(scriptElement.getAttribute("location")); } // Use a factory bean for the resources so they can be given an order if a pattern is used BeanDefinitionBuilder resourcesFactory = BeanDefinitionBuilder.genericBeanDefinition(SortedResourcesFactoryBean.class); resourcesFactory.addConstructorArgValue(locations); builder.addPropertyValue("scripts", resourcesFactory.getBeanDefinition()); return builder.getBeanDefinition(); } } ././@LongLink0000000000000000000000000000020700000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/config/JdbcNamespaceHandler.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000227011623223530033266 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.config; import org.springframework.beans.factory.xml.NamespaceHandler; import org.springframework.beans.factory.xml.NamespaceHandlerSupport; /** * {@link NamespaceHandler} for JDBC configuration namespace. * @author Oliver Gierke * @author Dave Syer */ public class JdbcNamespaceHandler extends NamespaceHandlerSupport { public void init() { registerBeanDefinitionParser("embedded-database", new EmbeddedDatabaseBeanDefinitionParser()); registerBeanDefinitionParser("initialize-database", new InitializeDatabaseBeanDefinitionParser()); } } ././@LongLink0000000000000000000000000000021500000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/config/SortedResourcesFactoryBean.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000607111623223530033271 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.config; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.config.AbstractFactoryBean; import org.springframework.context.ResourceLoaderAware; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.core.io.support.ResourcePatternResolver; import org.springframework.core.io.support.ResourcePatternUtils; /** * {@link FactoryBean} implementation that takes a list of location Strings * and creates a sorted array of {@link Resource} instances. * * @author Dave Syer * @author Juergen Hoeller * @author Christian Dupuis * @since 3.0 */ public class SortedResourcesFactoryBean extends AbstractFactoryBean implements ResourceLoaderAware { private final List locations; private ResourcePatternResolver resourcePatternResolver; public SortedResourcesFactoryBean(List locations) { this.locations = locations; this.resourcePatternResolver = new PathMatchingResourcePatternResolver(); } public SortedResourcesFactoryBean(ResourceLoader resourceLoader, List locations) { this.locations = locations; this.resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader); } public void setResourceLoader(ResourceLoader resourceLoader) { this.resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader); } @Override public Class getObjectType() { return Resource[].class; } @Override protected Resource[] createInstance() throws Exception { List scripts = new ArrayList(); for (String location : this.locations) { List resources = new ArrayList( Arrays.asList(this.resourcePatternResolver.getResources(location))); Collections.sort(resources, new Comparator() { public int compare(Resource r1, Resource r2) { try { return r1.getURL().toString().compareTo(r2.getURL().toString()); } catch (IOException ex) { return 0; } } }); for (Resource resource : resources) { scripts.add(resource); } } return scripts.toArray(new Resource[scripts.size()]); } } ././@LongLink0000000000000000000000000000015400000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000755000175000017500000000000011623223530033263 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000021500000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/BatchPreparedStatementSetter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000401411623223530033264 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; import java.sql.PreparedStatement; import java.sql.SQLException; /** * Batch update callback interface used by the {@link JdbcTemplate} class. * *

This interface sets values on a {@link java.sql.PreparedStatement} provided * by the JdbcTemplate class, for each of a number of updates in a batch using the * same SQL. Implementations are responsible for setting any necessary parameters. * SQL with placeholders will already have been supplied. * *

Implementations do not need to concern themselves with SQLExceptions * that may be thrown from operations they attempt. The JdbcTemplate class will * catch and handle SQLExceptions appropriately. * * @author Rod Johnson * @since March 2, 2003 * @see JdbcTemplate#batchUpdate(String, BatchPreparedStatementSetter) * @see InterruptibleBatchPreparedStatementSetter */ public interface BatchPreparedStatementSetter { /** * Set parameter values on the given PreparedStatement. * @param ps the PreparedStatement to invoke setter methods on * @param i index of the statement we're issuing in the batch, starting from 0 * @throws SQLException if a SQLException is encountered * (i.e. there is no need to catch SQLException) */ void setValues(PreparedStatement ps, int i) throws SQLException; /** * Return the size of the batch. * @return the number of statements in the batch */ int getBatchSize(); } ././@LongLink0000000000000000000000000000017500000000000011570 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/package-info.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000026011623223526033270 0ustar drazzibdrazzib /** * * Provides the core JDBC framework, based on JdbcTemplate * and its associated callback interfaces and helper objects. * */ package org.springframework.jdbc.core; ././@LongLink0000000000000000000000000000020700000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/DisposableSqlTypeValue.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000236711623223530033275 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; /** * Subinterface of {@link SqlTypeValue} that adds a cleanup callback, * to be invoked after the value has been set and the corresponding * statement has been executed. * * @author Juergen Hoeller * @since 1.1 * @see org.springframework.jdbc.core.support.SqlLobValue */ public interface DisposableSqlTypeValue extends SqlTypeValue { /** * Clean up resources held by this type value, * for example the LobCreator in case of a SqlLobValue. * @see org.springframework.jdbc.core.support.SqlLobValue#cleanup() * @see org.springframework.jdbc.support.SqlValue#cleanup() */ void cleanup(); } ././@LongLink0000000000000000000000000000017600000000000011571 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/SqlReturnType.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000466611623223526033306 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; import java.sql.CallableStatement; import java.sql.SQLException; /** * Interface to be implemented for retrieving values for more complex database-specific * types not supported by the standard CallableStatement.getObject method. * *

Implementations perform the actual work of getting the actual values. They must * implement the callback method getTypeValue which can throw SQLExceptions * that will be caught and translated by the calling code. This callback method has * access to the underlying Connection via the given CallableStatement object, if that * should be needed to create any database-specific objects. * * @author Thomas Risberg * @since 1.1 * @see java.sql.Types * @see java.sql.CallableStatement#getObject * @see org.springframework.jdbc.object.StoredProcedure#execute(java.util.Map) */ public interface SqlReturnType { /** * Constant that indicates an unknown (or unspecified) SQL type. * Passed into setTypeValue if the original operation method does * not specify a SQL type. * @see java.sql.Types * @see JdbcOperations#update(String, Object[]) */ int TYPE_UNKNOWN = Integer.MIN_VALUE; /** * Get the type value from the specific object. * @param cs the CallableStatement to operate on * @param paramIndex the index of the parameter for which we need to set the value * @param sqlType SQL type of the parameter we are setting * @param typeName the type name of the parameter * @return the target value * @throws SQLException if a SQLException is encountered setting parameter values * (that is, there's no need to catch SQLException) * @see java.sql.Types * @see java.sql.CallableStatement#getObject */ Object getTypeValue(CallableStatement cs, int paramIndex, int sqlType, String typeName) throws SQLException; } ././@LongLink0000000000000000000000000000020500000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/SqlReturnUpdateCount.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000215511623223526033275 0ustar drazzibdrazzibpackage org.springframework.jdbc.core; import java.sql.Types; /** * Represents a returned update count from a stored procedure call. * *

Returned update counts - like all stored procedure * parameters - must have names. * * @author Thomas Risberg */ public class SqlReturnUpdateCount extends SqlParameter { /** * Create a new instance of the {@link SqlReturnUpdateCount} class. * @param name name of the parameter, as used in input and output maps */ public SqlReturnUpdateCount(String name) { super(name, Types.INTEGER); } /** * Return whether this parameter holds input values that should be set * before execution even if they are null. *

This implementation always returns false. */ @Override public boolean isInputValueProvided() { return false; } /** * Return whether this parameter is an implicit return parameter used during the * results preocessing of the CallableStatement.getMoreResults/getUpdateCount. *

This implementation always returns true. */ @Override public boolean isResultsParameter() { return true; } } ././@LongLink0000000000000000000000000000016300000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/simple/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000755000175000017500000000000011623223530033263 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000021000000000000011556 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/simple/AbstractJdbcCall.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000003501411623223530033270 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.simple; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; import javax.sql.DataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.jdbc.core.CallableStatementCreator; import org.springframework.jdbc.core.CallableStatementCreatorFactory; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.SqlParameter; import org.springframework.jdbc.core.metadata.CallMetaDataContext; import org.springframework.jdbc.core.namedparam.SqlParameterSource; import org.springframework.util.Assert; import org.springframework.util.StringUtils; /** * Abstract class to provide base functionality for easy stored procedure calls * based on configuration options and database metadata. * This class provides the base SPI for {@link SimpleJdbcCall}. * * @author Thomas Risberg * @since 2.5 */ public abstract class AbstractJdbcCall { /** Logger available to subclasses */ protected final Log logger = LogFactory.getLog(getClass()); /** Lower-level class used to execute SQL */ private final JdbcTemplate jdbcTemplate; /** List of SqlParameter objects */ private final List declaredParameters = new ArrayList(); /** List of RefCursor/ResultSet RowMapper objects */ private final Map declaredRowMappers = new LinkedHashMap(); /** * Has this operation been compiled? Compilation means at * least checking that a DataSource and sql have been provided, * but subclasses may also implement their own custom validation. */ private boolean compiled = false; /** the generated string used for call statement */ private String callString; /** context used to retrieve and manage database metadata */ private CallMetaDataContext callMetaDataContext = new CallMetaDataContext(); /** * Object enabling us to create CallableStatementCreators * efficiently, based on this class's declared parameters. */ private CallableStatementCreatorFactory callableStatementFactory; /** * Constructor to be used when initializing using a {@link DataSource}. * @param dataSource the DataSource to be used */ protected AbstractJdbcCall(DataSource dataSource) { this.jdbcTemplate = new JdbcTemplate(dataSource); } /** * Constructor to be used when initializing using a {@link JdbcTemplate}. * @param jdbcTemplate the JdbcTemplate to use */ protected AbstractJdbcCall(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } /** * Get the configured {@link JdbcTemplate} */ public JdbcTemplate getJdbcTemplate() { return this.jdbcTemplate; } /** * Get the {@link CallableStatementCreatorFactory} being used */ protected CallableStatementCreatorFactory getCallableStatementFactory() { return this.callableStatementFactory; } /** * Set the name of the stored procedure. */ public void setProcedureName(String procedureName) { this.callMetaDataContext.setProcedureName(procedureName); } /** * Get the name of the stored procedure. */ public String getProcedureName() { return this.callMetaDataContext.getProcedureName(); } /** * Set the names of in parameters to be used. */ public void setInParameterNames(Set inParameterNames) { this.callMetaDataContext.setLimitedInParameterNames(inParameterNames); } /** * Get the names of in parameters to be used. */ public Set getInParameterNames() { return this.callMetaDataContext.getLimitedInParameterNames(); } /** * Set the catalog name to use. */ public void setCatalogName(String catalogName) { this.callMetaDataContext.setCatalogName(catalogName); } /** * Get the catalog name used. */ public String getCatalogName() { return this.callMetaDataContext.getCatalogName(); } /** * Set the schema name to use, */ public void setSchemaName(String schemaName) { this.callMetaDataContext.setSchemaName(schemaName); } /** * Get the schema name used. */ public String getSchemaName() { return this.callMetaDataContext.getSchemaName(); } /** * Specify whether this call is a function call. */ public void setFunction(boolean function) { this.callMetaDataContext.setFunction(function); } /** * Is this call a function call? */ public boolean isFunction() { return this.callMetaDataContext.isFunction(); } /** * Specify whether the call requires a rerurn value. */ public void setReturnValueRequired(boolean b) { this.callMetaDataContext.setReturnValueRequired(b); } /** * Does the call require a return value? */ public boolean isReturnValueRequired() { return this.callMetaDataContext.isReturnValueRequired(); } /** * Add a declared parameter to the list of parameters for the call. * Only parameters declared as SqlParameter and SqlInOutParameter * will be used to provide input values. This is different from the StoredProcedure class * which for backwards compatibility reasons allows input values to be provided for parameters declared * as SqlOutParameter. * @param parameter the {@link SqlParameter} to add */ public void addDeclaredParameter(SqlParameter parameter) { Assert.notNull(parameter, "The supplied parameter must not be null"); if (!StringUtils.hasText(parameter.getName())) { throw new InvalidDataAccessApiUsageException( "You must specify a parameter name when declaring parameters for \"" + getProcedureName() + "\""); } this.declaredParameters.add(parameter); if (logger.isDebugEnabled()) { logger.debug("Added declared parameter for [" + getProcedureName() + "]: " + parameter.getName()); } } /** * Add a {@link org.springframework.jdbc.core.RowMapper} for the specified parameter or column. * @param parameterName name of parameter or column * @param rowMapper the RowMapper implementation to use */ public void addDeclaredRowMapper(String parameterName, RowMapper rowMapper) { this.declaredRowMappers.put(parameterName, rowMapper); if (logger.isDebugEnabled()) { logger.debug("Added row mapper for [" + getProcedureName() + "]: " + parameterName); } } /** * Add a {@link org.springframework.jdbc.core.RowMapper} for the specified parameter or column. * @deprecated in favor of {@link #addDeclaredRowMapper(String, org.springframework.jdbc.core.RowMapper)} */ @Deprecated public void addDeclaredRowMapper(String parameterName, ParameterizedRowMapper rowMapper) { addDeclaredRowMapper(parameterName, (RowMapper) rowMapper); } /** * Get the call string that should be used based on parameters and meta data */ public String getCallString() { return this.callString; } /** * Specify whether the parameter metadata for the call should be used. The default is true. */ public void setAccessCallParameterMetaData(boolean accessCallParameterMetaData) { this.callMetaDataContext.setAccessCallParameterMetaData(accessCallParameterMetaData); } //------------------------------------------------------------------------- // Methods handling compilation issues //------------------------------------------------------------------------- /** * Compile this JdbcCall using provided parameters and meta data plus other settings. This * finalizes the configuration for this object and subsequent attempts to compile are ignored. * This will be implicitly called the first time an un-compiled call is executed. * @throws org.springframework.dao.InvalidDataAccessApiUsageException if the object hasn't * been correctly initialized, for example if no DataSource has been provided */ public synchronized final void compile() throws InvalidDataAccessApiUsageException { if (!isCompiled()) { if (getProcedureName() == null) { throw new InvalidDataAccessApiUsageException("Procedure or Function name is required"); } try { this.jdbcTemplate.afterPropertiesSet(); } catch (IllegalArgumentException ex) { throw new InvalidDataAccessApiUsageException(ex.getMessage()); } compileInternal(); this.compiled = true; if (logger.isDebugEnabled()) { logger.debug("SqlCall for " + (isFunction() ? "function" : "procedure") + " [" + getProcedureName() + "] compiled"); } } } /** * Method to perform the actual compilation. Subclasses can override this template method to perform * their own compilation. Invoked after this base class's compilation is complete. */ protected void compileInternal() { this.callMetaDataContext.initializeMetaData(getJdbcTemplate().getDataSource()); // iterate over the declared RowMappers and register the corresponding SqlParameter for (Map.Entry entry : this.declaredRowMappers.entrySet()) { SqlParameter resultSetParameter = this.callMetaDataContext.createReturnResultSetParameter(entry.getKey(), entry.getValue()); this.declaredParameters.add(resultSetParameter); } callMetaDataContext.processParameters(this.declaredParameters); this.callString = this.callMetaDataContext.createCallString(); if (logger.isDebugEnabled()) { logger.debug("Compiled stored procedure. Call string is [" + this.callString + "]"); } this.callableStatementFactory = new CallableStatementCreatorFactory(getCallString(), this.callMetaDataContext.getCallParameters()); this.callableStatementFactory.setNativeJdbcExtractor(getJdbcTemplate().getNativeJdbcExtractor()); onCompileInternal(); } /** * Hook method that subclasses may override to react to compilation. * This implementation does nothing. */ protected void onCompileInternal() { } /** * Is this operation "compiled"? * @return whether this operation is compiled, and ready to use. */ public boolean isCompiled() { return this.compiled; } /** * Check whether this operation has been compiled already; * lazily compile it if not already compiled. *

Automatically called by doExecute. */ protected void checkCompiled() { if (!isCompiled()) { logger.debug("JdbcCall call not compiled before execution - invoking compile"); compile(); } } //------------------------------------------------------------------------- // Methods handling execution //------------------------------------------------------------------------- /** * Method that provides execution of the call using the passed in {@link SqlParameterSource} * @param parameterSource parameter names and values to be used in call * @return Map of out parameters */ protected Map doExecute(SqlParameterSource parameterSource) { checkCompiled(); Map params = matchInParameterValuesWithCallParameters(parameterSource); return executeCallInternal(params); } /** * Method that provides execution of the call using the passed in array of parameters * @param args array of parameter values; order must match the order declared for the stored procedure * @return Map of out parameters */ protected Map doExecute(Object[] args) { checkCompiled(); Map params = matchInParameterValuesWithCallParameters(args); return executeCallInternal(params); } /** * Method that provides execution of the call using the passed in Map of parameters * @param args Map of parameter name and values * @return Map of out parameters */ protected Map doExecute(Map args) { checkCompiled(); Map params = matchInParameterValuesWithCallParameters(args); return executeCallInternal(params); } /** * Method to perform the actual call processing */ private Map executeCallInternal(Map params) { CallableStatementCreator csc = getCallableStatementFactory().newCallableStatementCreator(params); if (logger.isDebugEnabled()) { logger.debug("The following parameters are used for call " + getCallString() + " with: " + params); int i = 1; for (SqlParameter p : getCallParameters()) { logger.debug(i++ + ": " + p.getName() + " SQL Type "+ p.getSqlType() + " Type Name " + p.getTypeName() + " " + p.getClass().getName()); } } return getJdbcTemplate().call(csc, getCallParameters()); } /** * Get the name of a single out parameter or return value. * Used for functions or procedures with one out parameter. */ protected String getScalarOutParameterName() { return this.callMetaDataContext.getScalarOutParameterName(); } /** * Match the provided in parameter values with registered parameters and * parameters defined via metadata processing. * @param parameterSource the parameter vakues provided as a {@link SqlParameterSource} * @return Map with parameter names and values */ protected Map matchInParameterValuesWithCallParameters(SqlParameterSource parameterSource) { return this.callMetaDataContext.matchInParameterValuesWithCallParameters(parameterSource); } /** * Match the provided in parameter values with registered parameters and * parameters defined via metadata processing. * @param args the parameter values provided as an array * @return Map with parameter names and values */ private Map matchInParameterValuesWithCallParameters(Object[] args) { return this.callMetaDataContext.matchInParameterValuesWithCallParameters(args); } /** * Match the provided in parameter values with registered parameters and * parameters defined via metadata processing. * @param args the parameter values provided in a Map * @return Map with parameter names and values */ protected Map matchInParameterValuesWithCallParameters(Map args) { return this.callMetaDataContext.matchInParameterValuesWithCallParameters(args); } /** * Get a List of all the call parameters to be used for call. This includes any parameters added * based on meta data processing. */ protected List getCallParameters() { return this.callMetaDataContext.getCallParameters(); } } ././@LongLink0000000000000000000000000000022000000000000011557 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/simple/SimpleJdbcCallOperations.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000002047111623223526033276 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.simple; import java.util.Map; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.SqlParameter; import org.springframework.jdbc.core.namedparam.SqlParameterSource; /** * Interface specifying the API for a Simple JDBC Call implemented by {@link SimpleJdbcCall}. * This interface is not often used directly, but provides the * option to enhance testability, as it can easily be mocked or stubbed. * * @author Thomas Risberg * @since 2.5 */ public interface SimpleJdbcCallOperations { /** * Specify the procedure name to be used - this implies that we will be calling a stored procedure. * @param procedureName the name of the stored procedure * @return the instance of this SimpleJdbcCall */ SimpleJdbcCallOperations withProcedureName(String procedureName); /** * Specify the procedure name to be used - this implies that we will be calling a stored function. * @param functionName the name of the stored function * @return the instance of this SimpleJdbcCall */ SimpleJdbcCallOperations withFunctionName(String functionName); /** * Optionally, specify the name of the schema that contins the stored procedure. * @param schemaName the name of the schema * @return the instance of this SimpleJdbcCall */ SimpleJdbcCallOperations withSchemaName(String schemaName); /** * Optionally, specify the name of the catalog that contins the stored procedure. * To provide consistency with the Oracle DatabaseMetaData, this is used to specify the package name if * the procedure is declared as part of a package. * @param catalogName the catalog or package name * @return the instance of this SimpleJdbcCall */ SimpleJdbcCallOperations withCatalogName(String catalogName); /** * Indicates the procedure's return value should be included in the results returned. * @return the instance of this SimpleJdbcCall */ SimpleJdbcCallOperations withReturnValue(); /** * Specify one or more parameters if desired. These parameters will be supplemented with any * parameter information retrieved from the database meta data. * Note that only parameters declared as SqlParameter and SqlInOutParameter * will be used to provide input values. This is different from the StoredProcedure class * which for backwards compatibility reasons allows input values to be provided for parameters declared * as SqlOutParameter. * @param sqlParameters the parameters to use * @return the instance of this SimpleJdbcCall */ SimpleJdbcCallOperations declareParameters(SqlParameter... sqlParameters); /** Not used yet */ SimpleJdbcCallOperations useInParameterNames(String... inParameterNames); /** * Used to specify when a ResultSet is returned by the stored procedure and you want it mapped * by a RowMapper. The results will be returned using the parameter name specified. Multiple * ResultSets must be declared in the correct order. If the database you are using uses ref cursors * then the name specified must match the name of the parameter declared for the procedure in the * database. * @param parameterName the name of the returned results and/or the name of the ref cursor parameter * @param rowMapper the RowMapper implementation that will map the data returned for each row * */ SimpleJdbcCallOperations returningResultSet(String parameterName, RowMapper rowMapper); /** * Used to specify when a ResultSet is returned by the stored procedure and you want it mapped * by a RowMapper. The results will be returned using the parameter name specified. Multiple * ResultSets must be declared in the correct order. If the database you are using uses ref cursors * then the name specified must match the name of the parameter declared for the procedure in the * database. * @deprecated in favor of {@link #returningResultSet(String, org.springframework.jdbc.core.RowMapper)} */ @Deprecated SimpleJdbcCallOperations returningResultSet(String parameterName, ParameterizedRowMapper rowMapper); /** * Turn off any processing of parameter meta data information obtained via JDBC. * @return the instance of this SimpleJdbcCall */ SimpleJdbcCallOperations withoutProcedureColumnMetaDataAccess(); /** * Execute the stored function and return the results obtained as an Object of the specified return type. * @param returnType the type of the value to return * @param args optional array containing the in parameter values to be used in the call. * Parameter values must be provided in the same order as the parameters are defined * for the stored procedure. */ T executeFunction(Class returnType, Object... args); /** * Execute the stored function and return the results obtained as an Object of the specified return type. * @param returnType the type of the value to return * @param args Map containing the parameter values to be used in the call. */ T executeFunction(Class returnType, Map args); /** * Execute the stored function and return the results obtained as an Object of the specified return type. * @param returnType the type of the value to return * @param args MapSqlParameterSource containing the parameter values to be used in the call. */ T executeFunction(Class returnType, SqlParameterSource args); /** * Execute the stored procedure and return the single out parameter as an Object of the specified return type. * In the case where there are multiple out parameters, the first one is returned and additional out parameters * are ignored. * @param returnType the type of the value to return * @param args optional array containing the in parameter values to be used in the call. Parameter values must * be provided in the same order as the parameters are defined for the stored procedure. */ T executeObject(Class returnType, Object... args); /** * Execute the stored procedure and return the single out parameter as an Object of the specified return type. * In the case where there are multiple out parameters, the first one is returned and additional out parameters * are ignored. * @param returnType the type of the value to return * @param args Map containing the parameter values to be used in the call. */ T executeObject(Class returnType, Map args); /** * Execute the stored procedure and return the single out parameter as an Object of the specified return type. * In the case where there are multiple out parameters, the first one is returned and additional out parameters * are ignored. * @param returnType the type of the value to return * @param args MapSqlParameterSource containing the parameter values to be used in the call. */ T executeObject(Class returnType, SqlParameterSource args); /** * Execute the stored procedure and return a map of output params, keyed by name as in parameter declarations. * @param args optional array containing the in parameter values to be used in the call. Parameter values must * be provided in the same order as the parameters are defined for the stored procedure. * @return map of output params. */ Map execute(Object... args); /** * Execute the stored procedure and return a map of output params, keyed by name as in parameter declarations.. * @param args Map containing the parameter values to be used in the call. * @return map of output params. */ Map execute(Map args); /** * Execute the stored procedure and return a map of output params, keyed by name as in parameter declarations.. * @param args SqlParameterSource containing the parameter values to be used in the call. * @return map of output params. */ Map execute(SqlParameterSource args); } ././@LongLink0000000000000000000000000000020400000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/simple/package-info.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000130011623223526033264 0ustar drazzibdrazzib /** * * Simplification layer over JdbcTemplate for Java 5 and above. * *

SimpleJdbcTemplate is a wrapper around JdbcTemplate that takes advantage * of varargs and autoboxing. It also offers only a subset of the methods * available on JdbcTemplate: Hence, it does not implement the JdbcOperations * interface or extend JdbcTemplate, but implements the dedicated * SimpleJdbcOperations interface. * *

If you need the full power of Spring JDBC for less common operations, * use the getJdbcOperations() method of SimpleJdbcTemplate and work * with the returned classic template, or use a JdbcTemplate instance directly. * */ package org.springframework.jdbc.core.simple; ././@LongLink0000000000000000000000000000021000000000000011556 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/simple/SimpleJdbcInsert.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001110711623223530033265 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.simple; import java.util.Arrays; import java.util.Map; import javax.sql.DataSource; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.namedparam.SqlParameterSource; import org.springframework.jdbc.support.KeyHolder; import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor; /** * A SimpleJdbcInsert is a multi-threaded, reusable object providing easy insert * capabilities for a table. It provides meta data processing to simplify the code * needed to construct a basic insert statement. All you need to provide is the * name of the table and a Map containing the column names and the column values. * *

The meta data processing is based on the DatabaseMetaData provided by the * JDBC driver. As long as the JBDC driver can provide the names of the columns * for a specified table than we can rely on this auto-detection feature. If that * is not the case then the column names must be specified explicitly. * *

The actual insert is being handled using Spring's * {@link org.springframework.jdbc.core.JdbcTemplate}. * *

Many of the configuration methods return the current instance of the SimpleJdbcInsert * to provide the ability to string multiple ones together in a "fluid" interface style. * * @author Thomas Risberg * @since 2.5 * @see java.sql.DatabaseMetaData * @see org.springframework.jdbc.core.JdbcTemplate */ public class SimpleJdbcInsert extends AbstractJdbcInsert implements SimpleJdbcInsertOperations { /** * Constructor that takes one parameter with the JDBC DataSource to use when creating the * JdbcTemplate. * @param dataSource the DataSource to use * @see org.springframework.jdbc.core.JdbcTemplate#setDataSource */ public SimpleJdbcInsert(DataSource dataSource) { super(dataSource); } /** * Alternative Constructor that takes one parameter with the JdbcTemplate to be used. * @param jdbcTemplate the JdbcTemplate to use * @see org.springframework.jdbc.core.JdbcTemplate#setDataSource */ public SimpleJdbcInsert(JdbcTemplate jdbcTemplate) { super(jdbcTemplate); } public SimpleJdbcInsert withTableName(String tableName) { setTableName(tableName); return this; } public SimpleJdbcInsert withSchemaName(String schemaName) { setSchemaName(schemaName); return this; } public SimpleJdbcInsert withCatalogName(String catalogName) { setCatalogName(catalogName); return this; } public SimpleJdbcInsert usingColumns(String... columnNames) { setColumnNames(Arrays.asList(columnNames)); return this; } public SimpleJdbcInsert usingGeneratedKeyColumns(String... columnNames) { setGeneratedKeyNames(columnNames); return this; } public SimpleJdbcInsertOperations withoutTableColumnMetaDataAccess() { setAccessTableColumnMetaData(false); return this; } public SimpleJdbcInsertOperations includeSynonymsForTableColumnMetaData() { setOverrideIncludeSynonymsDefault(true); return this; } public SimpleJdbcInsertOperations useNativeJdbcExtractorForMetaData(NativeJdbcExtractor nativeJdbcExtractor) { setNativeJdbcExtractor(nativeJdbcExtractor); return this; } public int execute(Map args) { return doExecute(args); } public int execute(SqlParameterSource parameterSource) { return doExecute(parameterSource); } public Number executeAndReturnKey(Map args) { return doExecuteAndReturnKey(args); } public Number executeAndReturnKey(SqlParameterSource parameterSource) { return doExecuteAndReturnKey(parameterSource); } public KeyHolder executeAndReturnKeyHolder(Map args) { return doExecuteAndReturnKeyHolder(args); } public KeyHolder executeAndReturnKeyHolder(SqlParameterSource parameterSource) { return doExecuteAndReturnKeyHolder(parameterSource); } public int[] executeBatch(Map[] batch) { return doExecuteBatch(batch); } public int[] executeBatch(SqlParameterSource[] batch) { return doExecuteBatch(batch); } } ././@LongLink0000000000000000000000000000020600000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/simple/SimpleJdbcCall.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001420211623223526033271 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.simple; import java.util.Arrays; import java.util.HashSet; import java.util.Map; import javax.sql.DataSource; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.SqlParameter; import org.springframework.jdbc.core.namedparam.SqlParameterSource; /** * A SimpleJdbcCall is a multi-threaded, reusable object representing a call * to a stored procedure or a stored function. It provides meta data processing * to simplify the code needed to access basic stored procedures/functions. * All you need to provide is the name of the procedure/function and a Map * containing the parameters when you execute the call. The names of the * supplied parameters will be matched up with in and out parameters declared * when the stored procedure was created. * *

The meta data processing is based on the DatabaseMetaData provided by * the JDBC driver. Since we rely on the JDBC driver this "auto-detection" * can only be used for databases that are known to provide accurate meta data. * These currently include Derby, MySQL, Microsoft SQL Server, Oracle, DB2, * Sybase and PostgreSQL. For any other databases you are required to declare all * parameters explicitly. You can of course declare all parameters explicitly even * if the database provides the necessary meta data. In that case your declared * parameters will take precedence. You can also turn off any mete data processing * if you want to use parameter names that do not match what is declared during * the stored procedure compilation. * *

The actual insert is being handled using Spring's * {@link org.springframework.jdbc.core.JdbcTemplate}. * *

Many of the configuration methods return the current instance of the SimpleJdbcCall * to provide the ability to string multiple ones together in a "fluid" interface style. * * @author Thomas Risberg * @since 2.5 * @see java.sql.DatabaseMetaData * @see org.springframework.jdbc.core.JdbcTemplate */ public class SimpleJdbcCall extends AbstractJdbcCall implements SimpleJdbcCallOperations { /** * Constructor that takes one parameter with the JDBC DataSource to use when creating the * JdbcTemplate. * @param dataSource the DataSource to use * @see org.springframework.jdbc.core.JdbcTemplate#setDataSource */ public SimpleJdbcCall(DataSource dataSource) { super(dataSource); } /** * Alternative Constructor that takes one parameter with the JdbcTemplate to be used. * @param jdbcTemplate the JdbcTemplate to use * @see org.springframework.jdbc.core.JdbcTemplate#setDataSource */ public SimpleJdbcCall(JdbcTemplate jdbcTemplate) { super(jdbcTemplate); } public SimpleJdbcCall withProcedureName(String procedureName) { setProcedureName(procedureName); setFunction(false); return this; } public SimpleJdbcCall withFunctionName(String functionName) { setProcedureName(functionName); setFunction(true); return this; } public SimpleJdbcCall withSchemaName(String schemaName) { setSchemaName(schemaName); return this; } public SimpleJdbcCall withCatalogName(String catalogName) { setCatalogName(catalogName); return this; } public SimpleJdbcCall withReturnValue() { setReturnValueRequired(true); return this; } public SimpleJdbcCall declareParameters(SqlParameter... sqlParameters) { for (SqlParameter sqlParameter : sqlParameters) { if (sqlParameter != null) { addDeclaredParameter(sqlParameter); } } return this; } public SimpleJdbcCall useInParameterNames(String... inParameterNames) { setInParameterNames(new HashSet(Arrays.asList(inParameterNames))); return this; } public SimpleJdbcCall returningResultSet(String parameterName, RowMapper rowMapper) { addDeclaredRowMapper(parameterName, rowMapper); return this; } /** * @deprecated in favor of {@link #returningResultSet(String, org.springframework.jdbc.core.RowMapper)} */ @Deprecated public SimpleJdbcCall returningResultSet(String parameterName, ParameterizedRowMapper rowMapper) { addDeclaredRowMapper(parameterName, rowMapper); return this; } public SimpleJdbcCall withoutProcedureColumnMetaDataAccess() { setAccessCallParameterMetaData(false); return this; } @SuppressWarnings("unchecked") public T executeFunction(Class returnType, Object... args) { return (T) doExecute(args).get(getScalarOutParameterName()); } @SuppressWarnings("unchecked") public T executeFunction(Class returnType, Map args) { return (T) doExecute(args).get(getScalarOutParameterName()); } @SuppressWarnings("unchecked") public T executeFunction(Class returnType, SqlParameterSource args) { return (T) doExecute(args).get(getScalarOutParameterName()); } @SuppressWarnings("unchecked") public T executeObject(Class returnType, Object... args) { return (T) doExecute(args).get(getScalarOutParameterName()); } @SuppressWarnings("unchecked") public T executeObject(Class returnType, Map args) { return (T) doExecute(args).get(getScalarOutParameterName()); } @SuppressWarnings("unchecked") public T executeObject(Class returnType, SqlParameterSource args) { return (T) doExecute(args).get(getScalarOutParameterName()); } public Map execute(Object... args) { return doExecute(args); } public Map execute(Map args) { return doExecute(args); } public Map execute(SqlParameterSource parameterSource) { return doExecute(parameterSource); } } ././@LongLink0000000000000000000000000000021600000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/simple/ParameterizedRowMapper.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000214211623223530033264 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.simple; import org.springframework.jdbc.core.RowMapper; /** * Extension of the {@link org.springframework.jdbc.core.RowMapper} interface, * adding type parameterization. As of Spring 3.0, this is equivalent to * using the RowMapper interface directly. * * @author Rob Harrop * @author Juergen Hoeller * @since 2.0 * @see org.springframework.jdbc.core.simple.SimpleJdbcOperations */ public interface ParameterizedRowMapper extends RowMapper { } ././@LongLink0000000000000000000000000000021400000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/simple/SimpleJdbcOperations.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000005607211623223530033277 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.simple; import java.util.List; import java.util.Map; import org.springframework.dao.DataAccessException; import org.springframework.jdbc.core.JdbcOperations; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; import org.springframework.jdbc.core.namedparam.SqlParameterSource; /** * JDBC operations interface usable on Java 5 and above, exposing a * set of common JDBC operations, whose interface is simplified * through the use of varargs and autoboxing. * * @author Rod Johnson * @author Rob Harrop * @author Thomas Risberg * @since 2.0 * @see org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate * @see SimpleJdbcTemplate * @see org.springframework.jdbc.core.JdbcOperations */ public interface SimpleJdbcOperations { /** * Expose the classic Spring JdbcTemplate to allow invocation of less * commonly used methods. */ JdbcOperations getJdbcOperations(); /** * Expose the Spring NamedParameterJdbcTemplate to allow invocation of less * commonly used methods. */ NamedParameterJdbcOperations getNamedParameterJdbcOperations(); /** * Query for an int passing in a SQL query * using the named parameter support provided by the * {@link org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate} * and a map containing the arguments. * @param sql the SQL query to run. * @param args the map containing the arguments for the query */ int queryForInt(String sql, Map args) throws DataAccessException; /** * Query for an int passing in a SQL query * using the named parameter support provided by the * {@link org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate} * and a SqlParameterSource containing the arguments. * @param sql the SQL query to run. * @param args the SqlParameterSource containing the arguments for the query. */ int queryForInt(String sql, SqlParameterSource args) throws DataAccessException; /** * Query for an int passing in a SQL query * using the standard '?' placeholders for parameters * and a variable number of arguments. * @param sql the SQL query to run. * @param args the variable number of arguments for the query */ int queryForInt(String sql, Object... args) throws DataAccessException; /** * Query for an long passing in a SQL query * using the named parameter support provided by the * {@link org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate} * and a map containing the arguments. * @param sql the SQL query to run. * @param args the map containing the arguments for the query */ long queryForLong(String sql, Map args) throws DataAccessException; /** * Query for an long passing in a SQL query * using the named parameter support provided by the * {@link org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate} * and a SqlParameterSource containing the arguments. * @param sql the SQL query to run. * @param args the SqlParameterSource containing the arguments for the query */ long queryForLong(String sql, SqlParameterSource args) throws DataAccessException; /** * Query for an long passing in a SQL query * using the standard '?' placeholders for parameters * and a variable number of arguments. * @param sql the SQL query to run. * @param args the variable number of arguments for the query */ long queryForLong(String sql, Object... args) throws DataAccessException; /** * Query for an object of type T identified by the supplied @{@link Class}. * Uses sql with the named parameter support provided by the * {@link org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate} * @param sql the SQL query to run * @param requiredType the required type of the return value * @param args the map containing the arguments for the query * @see JdbcOperations#queryForObject(String, Class) * @see JdbcOperations#queryForObject(String, Object[], Class) */ T queryForObject(String sql, Class requiredType, Map args) throws DataAccessException; /** * Query for an object of type T identified by the supplied @{@link Class}. * Uses sql with the named parameter support provided by the * {@link org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate} * @param sql the SQL query to run * @param requiredType the required type of the return value * @param args the SqlParameterSource containing the arguments for the query * @see JdbcOperations#queryForObject(String, Class) * @see JdbcOperations#queryForObject(String, Object[], Class) */ T queryForObject(String sql, Class requiredType, SqlParameterSource args) throws DataAccessException; /** * Query for an object of type T identified by the supplied @{@link Class}. * Uses sql with the standard '?' placeholders for parameters * @param sql the SQL query to run * @param requiredType the required type of the return value * @param args the variable number of arguments for the query * @see JdbcOperations#queryForObject(String, Class) * @see JdbcOperations#queryForObject(String, Object[], Class) */ T queryForObject(String sql, Class requiredType, Object... args) throws DataAccessException; /** * Query for an object of type T using the supplied * {@link RowMapper} to the query results to the object. * Uses sql with the named parameter support provided by the * {@link org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate} * @param sql the SQL query to run * @param rm the @{@link RowMapper} to use for result mapping * @param args the map containing the arguments for the query * @see JdbcOperations#queryForObject(String, org.springframework.jdbc.core.RowMapper) * @see JdbcOperations#queryForObject(String, Object[], org.springframework.jdbc.core.RowMapper) */ T queryForObject(String sql, RowMapper rm, Map args) throws DataAccessException; /** * Query for an object of type T using the supplied * {@link ParameterizedRowMapper} to the query results to the object. * Uses sql with the named parameter support provided by the * {@link org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate} * @param sql the SQL query to run * @param rm the @{@link ParameterizedRowMapper} to use for result mapping * @param args the map containing the arguments for the query * @see JdbcOperations#queryForObject(String, org.springframework.jdbc.core.RowMapper) * @see JdbcOperations#queryForObject(String, Object[], org.springframework.jdbc.core.RowMapper) * @deprecated as of Spring 3.0: Use the method using the newly genericized RowMapper interface * instead since the RowMapper and ParameterizedRowMapper interfaces are equivalent now. */ @Deprecated T queryForObject(String sql, ParameterizedRowMapper rm, Map args) throws DataAccessException; /** * Query for an object of type T using the supplied * {@link RowMapper} to the query results to the object. * Uses sql with the named parameter support provided by the * {@link org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate} * @param sql the SQL query to run * @param rm the @{@link RowMapper} to use for result mapping * @param args the SqlParameterSource containing the arguments for the query * @see JdbcOperations#queryForObject(String, org.springframework.jdbc.core.RowMapper) * @see JdbcOperations#queryForObject(String, Object[], org.springframework.jdbc.core.RowMapper) */ T queryForObject(String sql, RowMapper rm, SqlParameterSource args) throws DataAccessException; /** * Query for an object of type T using the supplied * {@link ParameterizedRowMapper} to the query results to the object. * Uses sql with the named parameter support provided by the * {@link org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate} * @param sql the SQL query to run * @param rm the @{@link ParameterizedRowMapper} to use for result mapping * @param args the SqlParameterSource containing the arguments for the query * @see JdbcOperations#queryForObject(String, org.springframework.jdbc.core.RowMapper) * @see JdbcOperations#queryForObject(String, Object[], org.springframework.jdbc.core.RowMapper) * @deprecated as of Spring 3.0: Use the method using the newly genericized RowMapper interface * instead since the RowMapper and ParameterizedRowMapper interfaces are equivalent now. */ @Deprecated T queryForObject(String sql, ParameterizedRowMapper rm, SqlParameterSource args) throws DataAccessException; /** * Query for an object of type T using the supplied * {@link RowMapper} to the query results to the object. * Uses sql with the standard '?' placeholders for parameters * @param sql the SQL query to run * @param rm the @{@link RowMapper} to use for result mapping * @param args the variable number of arguments for the query * @see JdbcOperations#queryForObject(String, org.springframework.jdbc.core.RowMapper) * @see JdbcOperations#queryForObject(String, Object[], org.springframework.jdbc.core.RowMapper) */ T queryForObject(String sql, RowMapper rm, Object... args) throws DataAccessException; /** * Query for an object of type T using the supplied * {@link ParameterizedRowMapper} to the query results to the object. * Uses sql with the standard '?' placeholders for parameters * @param sql the SQL query to run * @param rm the @{@link ParameterizedRowMapper} to use for result mapping * @param args the variable number of arguments for the query * @see JdbcOperations#queryForObject(String, org.springframework.jdbc.core.RowMapper) * @see JdbcOperations#queryForObject(String, Object[], org.springframework.jdbc.core.RowMapper) * @deprecated as of Spring 3.0: Use the method using the newly genericized RowMapper interface * instead since the RowMapper and ParameterizedRowMapper interfaces are equivalent now. */ @Deprecated T queryForObject(String sql, ParameterizedRowMapper rm, Object... args) throws DataAccessException; /** * Query for a {@link List} of Objects of type T using * the supplied {@link RowMapper} to the query results to the object. * Uses sql with the named parameter support provided by the * {@link org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate} * @param sql the SQL query to run * @param rm the @{@link RowMapper} to use for result mapping * @param args the map containing the arguments for the query * @see JdbcOperations#queryForObject(String, org.springframework.jdbc.core.RowMapper) * @see JdbcOperations#queryForObject(String, Object[], org.springframework.jdbc.core.RowMapper) */ List query(String sql, RowMapper rm, Map args) throws DataAccessException; /** * Query for a {@link List} of Objects of type T using * the supplied {@link ParameterizedRowMapper} to the query results to the object. * Uses sql with the named parameter support provided by the * {@link org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate} * @param sql the SQL query to run * @param rm the @{@link ParameterizedRowMapper} to use for result mapping * @param args the map containing the arguments for the query * @see JdbcOperations#queryForObject(String, org.springframework.jdbc.core.RowMapper) * @see JdbcOperations#queryForObject(String, Object[], org.springframework.jdbc.core.RowMapper) * @deprecated as of Spring 3.0: Use the method using the newly genericized RowMapper interface * instead since the RowMapper and ParameterizedRowMapper interfaces are equivalent now. */ @Deprecated List query(String sql, ParameterizedRowMapper rm, Map args) throws DataAccessException; /** * Query for a {@link List} of Objects of type T using * the supplied {@link RowMapper} to the query results to the object. * Uses sql with the named parameter support provided by the * {@link org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate} * @param sql the SQL query to run * @param rm the @{@link RowMapper} to use for result mapping * @param args the SqlParameterSource containing the arguments for the query * @see JdbcOperations#queryForObject(String, org.springframework.jdbc.core.RowMapper) * @see JdbcOperations#queryForObject(String, Object[], org.springframework.jdbc.core.RowMapper) */ List query(String sql, RowMapper rm, SqlParameterSource args) throws DataAccessException; /** * Query for a {@link List} of Objects of type T using * the supplied {@link ParameterizedRowMapper} to the query results to the object. * Uses sql with the named parameter support provided by the * {@link org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate} * @param sql the SQL query to run * @param rm the @{@link ParameterizedRowMapper} to use for result mapping * @param args the SqlParameterSource containing the arguments for the query * @see JdbcOperations#queryForObject(String, org.springframework.jdbc.core.RowMapper) * @see JdbcOperations#queryForObject(String, Object[], org.springframework.jdbc.core.RowMapper) * @deprecated as of Spring 3.0: Use the method using the newly genericized RowMapper interface * instead since the RowMapper and ParameterizedRowMapper interfaces are equivalent now. */ @Deprecated List query(String sql, ParameterizedRowMapper rm, SqlParameterSource args) throws DataAccessException; /** * Query for a {@link List} of Objects of type T using * the supplied {@link RowMapper} to the query results to the object. * Uses sql with the standard '?' placeholders for parameters * @param sql the SQL query to run * @param rm the @{@link RowMapper} to use for result mapping * @param args the variable number of arguments for the query * @see JdbcOperations#queryForObject(String, org.springframework.jdbc.core.RowMapper) * @see JdbcOperations#queryForObject(String, Object[], org.springframework.jdbc.core.RowMapper) */ List query(String sql, RowMapper rm, Object... args) throws DataAccessException; /** * Query for a {@link List} of Objects of type T using * the supplied {@link ParameterizedRowMapper} to the query results to the object. * Uses sql with the standard '?' placeholders for parameters * @param sql the SQL query to run * @param rm the @{@link ParameterizedRowMapper} to use for result mapping * @param args the variable number of arguments for the query * @see JdbcOperations#queryForObject(String, org.springframework.jdbc.core.RowMapper) * @see JdbcOperations#queryForObject(String, Object[], org.springframework.jdbc.core.RowMapper) * @deprecated as of Spring 3.0: Use the method using the newly genericized RowMapper interface * instead since the RowMapper and ParameterizedRowMapper interfaces are equivalent now. */ @Deprecated List query(String sql, ParameterizedRowMapper rm, Object... args) throws DataAccessException; /** * Execute the supplied query with the supplied arguments. *

The query is expected to be a single row query; the result row will be * mapped to a Map (one entry for each column, using the column name as the key). * Uses sql with the named parameter support provided by the * {@link org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate} * @param sql the SQL query to run * @param args the map containing the arguments for the query * @see JdbcOperations#queryForMap(String) * @see JdbcOperations#queryForMap(String, Object[]) */ Map queryForMap(String sql, Map args) throws DataAccessException; /** * Execute the supplied query with the supplied arguments. *

The query is expected to be a single row query; the result row will be * mapped to a Map (one entry for each column, using the column name as the key). * Uses sql with the named parameter support provided by the * {@link org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate} * @param sql the SQL query to run * @param args the SqlParameterSource containing the arguments for the query * @see JdbcOperations#queryForMap(String) * @see JdbcOperations#queryForMap(String, Object[]) */ Map queryForMap(String sql, SqlParameterSource args) throws DataAccessException; /** * Execute the supplied query with the (optional) supplied arguments. *

The query is expected to be a single row query; the result row will be * mapped to a Map (one entry for each column, using the column name as the key). * Uses sql with the standard '?' placeholders for parameters * @param sql the SQL query to run * @param args the variable number of arguments for the query * @see JdbcOperations#queryForMap(String) * @see JdbcOperations#queryForMap(String, Object[]) */ Map queryForMap(String sql, Object... args) throws DataAccessException; /** * Execute the supplied query with the supplied arguments. *

Each element in the returned {@link List} is constructed as a {@link Map} * as described in {@link #queryForMap} * Uses sql with the named parameter support provided by the * {@link org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate} * @param sql the SQL query to run * @param args the map containing the arguments for the query * @see JdbcOperations#queryForList(String) * @see JdbcOperations#queryForList(String, Object[]) */ List> queryForList(String sql, Map args) throws DataAccessException; /** * Execute the supplied query with the supplied arguments. *

Each element in the returned {@link List} is constructed as a {@link Map} * as described in {@link #queryForMap} * Uses sql with the named parameter support provided by the * {@link org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate} * @param sql the SQL query to run * @param args the SqlParameterSource containing the arguments for the query * @see JdbcOperations#queryForList(String) * @see JdbcOperations#queryForList(String, Object[]) */ List> queryForList(String sql, SqlParameterSource args) throws DataAccessException; /** * Execute the supplied query with the (optional) supplied arguments. *

Each element in the returned {@link List} is constructed as a {@link Map} * as described in {@link #queryForMap} * Uses sql with the standard '?' placeholders for parameters * @param sql the SQL query to run * @param args the variable number of arguments for the query * @see JdbcOperations#queryForList(String) * @see JdbcOperations#queryForList(String, Object[]) */ List> queryForList(String sql, Object... args) throws DataAccessException; /** * Execute the supplied SQL statement with (optional) supplied arguments. * Uses sql with the named parameter support provided by the * {@link org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate} * @param sql the SQL statement to execute * @param args the map containing the arguments for the query * @return the numbers of rows affected by the update * @see NamedParameterJdbcOperations#update(String, Map) */ int update(String sql, Map args) throws DataAccessException; /** * Execute the supplied SQL statement with supplied arguments. * Uses sql with the named parameter support provided by the * {@link org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate} * @param sql the SQL statement to execute * @param args the SqlParameterSource containing the arguments for the statement * @return the numbers of rows affected by the update * @see NamedParameterJdbcOperations#update(String, SqlParameterSource) */ int update(String sql, SqlParameterSource args) throws DataAccessException; /** * Execute the supplied SQL statement with supplied arguments. * Uses sql with the standard '?' placeholders for parameters * @param sql the SQL statement to execute * @param args the variable number of arguments for the query * @return the numbers of rows affected by the update * @see JdbcOperations#update(String) * @see JdbcOperations#update(String, Object[]) */ int update(String sql, Object... args) throws DataAccessException; /** * Executes a batch using the supplied SQL statement with the batch of supplied arguments. * Uses sql with the named parameter support. * @param sql the SQL statement to execute * @param batchValues the array of Maps containing the batch of arguments for the query * @return an array containing the numbers of rows affected by each update in the batch */ public int[] batchUpdate(String sql, Map[] batchValues); /** * Execute a batch using the supplied SQL statement with the batch of supplied arguments. * Uses sql with the named parameter support. * @param sql the SQL statement to execute * @param batchArgs the array of {@link SqlParameterSource} containing the batch of arguments for the query * @return an array containing the numbers of rows affected by each update in the batch */ public int[] batchUpdate(String sql, SqlParameterSource[] batchArgs); /** * Execute a batch using the supplied SQL statement with the batch of supplied arguments. * Uses sql with the standard '?' placeholders for parameters * @param sql the SQL statement to execute * @param batchArgs the List of Object arrays containing the batch of arguments for the query * @return an array containing the numbers of rows affected by each update in the batch */ public int[] batchUpdate(String sql, List batchArgs); /** * Execute a batch using the supplied SQL statement with the batch of supplied arguments. * Uses sql with the standard '?' placeholders for parameters * @param sql the SQL statement to execute. * @param batchArgs the List of Object arrays containing the batch of arguments for the query * @param argTypes SQL types of the arguments * (constants from java.sql.Types) * @return an array containing the numbers of rows affected by each update in the batch */ public int[] batchUpdate(String sql, List batchArgs, int[] argTypes); } ././@LongLink0000000000000000000000000000022200000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/simple/SimpleJdbcInsertOperations.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001447711623223530033302 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.simple; import java.util.Map; import org.springframework.jdbc.core.namedparam.SqlParameterSource; import org.springframework.jdbc.support.KeyHolder; import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor; /** * Interface specifying the API for a Simple JDBC Insert implemented by {@link SimpleJdbcInsert}. * This interface is not often used directly, but provides the * option to enhance testability, as it can easily be mocked or stubbed. * * @author Thomas Risberg * @since 2.5 */ public interface SimpleJdbcInsertOperations { /** * Specify the table name to be used for the insert. * @param tableName the name of the stored table * @return the instance of this SimpleJdbcInsert */ SimpleJdbcInsertOperations withTableName(String tableName); /** * Specify the shema name, if any, to be used for the insert. * @param schemaName the name of the schema * @return the instance of this SimpleJdbcInsert */ SimpleJdbcInsertOperations withSchemaName(String schemaName); /** * Specify the catalog name, if any, to be used for the insert. * @param catalogName the name of the catalog * @return the instance of this SimpleJdbcInsert */ SimpleJdbcInsertOperations withCatalogName(String catalogName); /** * Specify the column names that the insert statement should be limited to use. * @param columnNames one or more column names * @return the instance of this SimpleJdbcInsert */ SimpleJdbcInsertOperations usingColumns(String... columnNames); /** * Specify the name sof any columns that have auto generated keys. * @param columnNames one or more column names * @return the instance of this SimpleJdbcInsert */ SimpleJdbcInsertOperations usingGeneratedKeyColumns(String... columnNames); /** * Turn off any processing of column meta data information obtained via JDBC. * @return the instance of this SimpleJdbcInsert */ SimpleJdbcInsertOperations withoutTableColumnMetaDataAccess(); /** * Include synonyms for the column meta data lookups via JDBC. * Note: this is only necessary to include for Oracle since other * databases supporting synonyms seems to include the synonyms * automatically. * @return the instance of this SimpleJdbcInsert */ SimpleJdbcInsertOperations includeSynonymsForTableColumnMetaData(); /** * Use a the provided NativeJdbcExtractor during the column meta data * lookups via JDBC. * Note: this is only necessary to include when running with a connection pool * that wraps the meta data connection and when using a database like Oracle * where it is necessary to access the native connection to include synonyms. * @return the instance of this SimpleJdbcInsert */ SimpleJdbcInsertOperations useNativeJdbcExtractorForMetaData(NativeJdbcExtractor nativeJdbcExtractor); /** * Execute the insert using the values passed in. * @param args Map containing column names and corresponding value * @return the number of rows affected as returned by the JDBC driver */ int execute(Map args); /** * Execute the insert using the values passed in. * @param parameterSource SqlParameterSource containing values to use for insert * @return the number of rows affected as returned by the JDBC driver */ int execute(SqlParameterSource parameterSource); /** * Execute the insert using the values passed in and return the generated key. This requires that * the name of the columns with auto generated keys have been specified. This method will always * return a key or throw an exception if a key was not returned. * @param args Map containing column names and corresponding value * @return the generated key value */ Number executeAndReturnKey(Map args); /** * Execute the insert using the values passed in and return the generated key. This requires that * the name of the columns with auto generated keys have been specified. This method will always * return a key or throw an exception if a key was not returned. * @param parameterSource SqlParameterSource containing values to use for insert * @return the generated key value. */ Number executeAndReturnKey(SqlParameterSource parameterSource); /** * Execute the insert using the values passed in and return the generated keys. This requires that * the name of the columns with auto generated keys have been specified. This method will always return * a KeyHolder but the caller must verify that it actually contains the generated keys. * @param args Map containing column names and corresponding value * @return the KeyHolder containing all generated keys */ KeyHolder executeAndReturnKeyHolder(Map args); /** * Execute the insert using the values passed in and return the generated keys. This requires that * the name of the columns with auto generated keys have been specified. This method will always return * a KeyHolder but the caller must verify that it actually contains the generated keys. * @param parameterSource SqlParameterSource containing values to use for insert * @return the KeyHolder containing all generated keys */ KeyHolder executeAndReturnKeyHolder(SqlParameterSource parameterSource); /** * Execute a batch insert using the batch of values passed in. * @param batch an array of Maps containing a batch of column names and corresponding value * @return the array of number of rows affected as returned by the JDBC driver */ int[] executeBatch(Map[] batch); /** * Execute a batch insert using the batch of values passed in. * @param batch an array of SqlParameterSource containing values for the batch * @return the array of number of rows affected as returned by the JDBC driver */ int[] executeBatch(SqlParameterSource[] batch); } ././@LongLink0000000000000000000000000000023200000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/simple/ParameterizedSingleColumnRowMapper.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000360611623223526033277 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.simple; import org.springframework.jdbc.core.SingleColumnRowMapper; /** * {@link ParameterizedRowMapper} implementation that converts a single column * into a single result value per row. Expects to operate on a * java.sql.ResultSet that just contains a single column. * *

The type of the result value for each row can be specified. The value * for the single column will be extracted from the ResultSet * and converted into the specified target type. * *

Uses Java 5 covariant return types to override the return type of the * {@link #mapRow} method to be the type parameter T. * * @author Juergen Hoeller * @since 2.5.2 */ public class ParameterizedSingleColumnRowMapper extends SingleColumnRowMapper implements ParameterizedRowMapper { /** * Static factory method to create a new ParameterizedSingleColumnRowMapper * (with the required type specified only once). * @param requiredType the type that each result object is expected to match */ public static ParameterizedSingleColumnRowMapper newInstance(Class requiredType) { ParameterizedSingleColumnRowMapper rm = new ParameterizedSingleColumnRowMapper(); rm.setRequiredType(requiredType); return rm; } } ././@LongLink0000000000000000000000000000023200000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/simple/ParameterizedBeanPropertyRowMapper.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000555711623223526033306 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.simple; import org.springframework.jdbc.core.BeanPropertyRowMapper; /** * {@link ParameterizedRowMapper} implementation that converts a row into a new instance * of the specified mapped target class. The mapped target class must be a top-level class * and it must have a default or no-arg constructor. * *

Uses Java 5 covariant return types to override the return type of the {@link #mapRow} * method to be the type parameter T. * *

Column values are mapped based on matching the column name as obtained from result set * metadata to public setters for the corresponding properties. The names are matched either * directly or by transforming a name separating the parts with underscores to the same name * using "camel" case. * *

Mapping is provided for fields in the target class for many common types, e.g.: * String, boolean, Boolean, byte, Byte, short, Short, int, Integer, long, Long, * float, Float, double, Double, BigDecimal, java.util.Date, etc. * *

The mapper can be configured to use the primitives default value when mapping null values * by setting the {@link #setPrimitivesDefaultedForNullValue 'primitivesDefaultedForNullValue'} * flag to 'true'. * *

To facilitate mapping between columns and fields that don't have matching names, * try using column aliases in the SQL statement like "select fname as first_name from customer". * *

Please note that this class is designed to provide convenience rather than high performance. * For best performance consider using a custom RowMapper. * * @author Thomas Risberg * @author Juergen Hoeller * @since 2.5 * @see ParameterizedRowMapper */ public class ParameterizedBeanPropertyRowMapper extends BeanPropertyRowMapper implements ParameterizedRowMapper { /** * Static factory method to create a new ParameterizedBeanPropertyRowMapper * (with the mapped class specified only once). * @param mappedClass the class that each row should be mapped to */ public static ParameterizedBeanPropertyRowMapper newInstance(Class mappedClass) { ParameterizedBeanPropertyRowMapper newInstance = new ParameterizedBeanPropertyRowMapper(); newInstance.setMappedClass(mappedClass); return newInstance; } } ././@LongLink0000000000000000000000000000021200000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/simple/SimpleJdbcTemplate.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000002452011623223530033270 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.simple; import java.util.List; import java.util.Map; import javax.sql.DataSource; import org.springframework.dao.DataAccessException; import org.springframework.jdbc.core.JdbcOperations; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.BatchUpdateUtils; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.jdbc.core.namedparam.SqlParameterSource; import org.springframework.util.ObjectUtils; /** * Java-5-based convenience wrapper for the classic Spring * {@link org.springframework.jdbc.core.JdbcTemplate}, * taking advantage of varargs and autoboxing, and exposing only the most * commonly required operations in order to simplify JdbcTemplate usage. * *

Use the {@link #getJdbcOperations()} method (or a straight JdbcTemplate) * if you need to invoke less commonly used template methods. This includes * any methods specifying SQL types, methods using less commonly used callbacks * such as RowCallbackHandler, updates with PreparedStatementSetters rather than * argument arrays, and stored procedures as well as batch operations. * * @author Rod Johnson * @author Rob Harrop * @author Juergen Hoeller * @author Thomas Risberg * @since 2.0 * @see ParameterizedRowMapper * @see SimpleJdbcDaoSupport * @see org.springframework.jdbc.core.JdbcTemplate */ public class SimpleJdbcTemplate implements SimpleJdbcOperations { /** The NamedParameterJdbcTemplate that we are wrapping */ private final NamedParameterJdbcOperations namedParameterJdbcOperations; /** * Create a new SimpleJdbcTemplate for the given DataSource. *

Creates a classic Spring JdbcTemplate and wraps it. * @param dataSource the JDBC DataSource to access */ public SimpleJdbcTemplate(DataSource dataSource) { this.namedParameterJdbcOperations = new NamedParameterJdbcTemplate(dataSource); } /** * Create a new SimpleJdbcTemplate for the given classic Spring JdbcTemplate. * @param classicJdbcTemplate the classic Spring JdbcTemplate to wrap */ public SimpleJdbcTemplate(JdbcOperations classicJdbcTemplate) { this.namedParameterJdbcOperations = new NamedParameterJdbcTemplate(classicJdbcTemplate); } /** * Create a new SimpleJdbcTemplate for the given Spring NamedParameterJdbcTemplate. * @param namedParameterJdbcTemplate the Spring NamedParameterJdbcTemplate to wrap */ public SimpleJdbcTemplate(NamedParameterJdbcOperations namedParameterJdbcTemplate) { this.namedParameterJdbcOperations = namedParameterJdbcTemplate; } /** * Expose the classic Spring JdbcTemplate to allow invocation of * less commonly used methods. */ public JdbcOperations getJdbcOperations() { return this.namedParameterJdbcOperations.getJdbcOperations(); } /** * Expose the Spring NamedParameterJdbcTemplate to allow invocation of * less commonly used methods. */ public NamedParameterJdbcOperations getNamedParameterJdbcOperations() { return this.namedParameterJdbcOperations; } public int queryForInt(String sql, Map args) throws DataAccessException { return getNamedParameterJdbcOperations().queryForInt(sql, args); } public int queryForInt(String sql, SqlParameterSource args) throws DataAccessException { return getNamedParameterJdbcOperations().queryForInt(sql, args); } public int queryForInt(String sql, Object... args) throws DataAccessException { return (ObjectUtils.isEmpty(args) ? getJdbcOperations().queryForInt(sql) : getJdbcOperations().queryForInt(sql, getArguments(args))); } public long queryForLong(String sql, Map args) throws DataAccessException { return getNamedParameterJdbcOperations().queryForLong(sql, args); } public long queryForLong(String sql, SqlParameterSource args) throws DataAccessException { return getNamedParameterJdbcOperations().queryForLong(sql, args); } public long queryForLong(String sql, Object... args) throws DataAccessException { return (ObjectUtils.isEmpty(args) ? getJdbcOperations().queryForLong(sql) : getJdbcOperations().queryForLong(sql, getArguments(args))); } public T queryForObject(String sql, Class requiredType, Map args) throws DataAccessException { return getNamedParameterJdbcOperations().queryForObject(sql, args, requiredType); } public T queryForObject(String sql, Class requiredType, SqlParameterSource args) throws DataAccessException { return getNamedParameterJdbcOperations().queryForObject(sql, args, requiredType); } public T queryForObject(String sql, Class requiredType, Object... args) throws DataAccessException { return (ObjectUtils.isEmpty(args) ? getJdbcOperations().queryForObject(sql, requiredType) : getJdbcOperations().queryForObject(sql, getArguments(args), requiredType)); } public T queryForObject(String sql, RowMapper rm, Map args) throws DataAccessException { return getNamedParameterJdbcOperations().queryForObject(sql, args, rm); } @Deprecated public T queryForObject(String sql, ParameterizedRowMapper rm, Map args) throws DataAccessException { return queryForObject(sql, (RowMapper) rm, args); } public T queryForObject(String sql, RowMapper rm, SqlParameterSource args) throws DataAccessException { return getNamedParameterJdbcOperations().queryForObject(sql, args, rm); } @Deprecated public T queryForObject(String sql, ParameterizedRowMapper rm, SqlParameterSource args) throws DataAccessException { return queryForObject(sql, (RowMapper) rm, args); } public T queryForObject(String sql, RowMapper rm, Object... args) throws DataAccessException { return (ObjectUtils.isEmpty(args) ? getJdbcOperations().queryForObject(sql, rm): getJdbcOperations().queryForObject(sql, getArguments(args), rm)); } @Deprecated public T queryForObject(String sql, ParameterizedRowMapper rm, Object... args) throws DataAccessException { return queryForObject(sql, (RowMapper) rm, args); } public List query(String sql, RowMapper rm, Map args) throws DataAccessException { return getNamedParameterJdbcOperations().query(sql, args, rm); } @Deprecated public List query(String sql, ParameterizedRowMapper rm, Map args) throws DataAccessException { return query(sql, (RowMapper) rm, args); } public List query(String sql, RowMapper rm, SqlParameterSource args) throws DataAccessException { return getNamedParameterJdbcOperations().query(sql, args, rm); } @Deprecated public List query(String sql, ParameterizedRowMapper rm, SqlParameterSource args) throws DataAccessException { return query(sql, (RowMapper) rm, args); } public List query(String sql, RowMapper rm, Object... args) throws DataAccessException { return (ObjectUtils.isEmpty(args) ? getJdbcOperations().query(sql, rm) : getJdbcOperations().query(sql, getArguments(args), rm)); } @Deprecated public List query(String sql, ParameterizedRowMapper rm, Object... args) throws DataAccessException { return query(sql, (RowMapper) rm, args); } public Map queryForMap(String sql, Map args) throws DataAccessException { return getNamedParameterJdbcOperations().queryForMap(sql, args); } public Map queryForMap(String sql, SqlParameterSource args) throws DataAccessException { return getNamedParameterJdbcOperations().queryForMap(sql, args); } public Map queryForMap(String sql, Object... args) throws DataAccessException { return (ObjectUtils.isEmpty(args) ? getJdbcOperations().queryForMap(sql) : getJdbcOperations().queryForMap(sql, getArguments(args))); } public List> queryForList(String sql, Map args) throws DataAccessException { return getNamedParameterJdbcOperations().queryForList(sql, args); } public List> queryForList(String sql, SqlParameterSource args) throws DataAccessException { return getNamedParameterJdbcOperations().queryForList(sql, args); } public List> queryForList(String sql, Object... args) throws DataAccessException { return (ObjectUtils.isEmpty(args) ? getJdbcOperations().queryForList(sql) : getJdbcOperations().queryForList(sql, getArguments(args))); } public int update(String sql, Map args) throws DataAccessException { return getNamedParameterJdbcOperations().update(sql, args); } public int update(String sql, SqlParameterSource args) throws DataAccessException { return getNamedParameterJdbcOperations().update(sql, args); } public int update(String sql, Object ... args) throws DataAccessException { return (ObjectUtils.isEmpty(args) ? getJdbcOperations().update(sql) : getJdbcOperations().update(sql, getArguments(args))); } public int[] batchUpdate(String sql, List batchArgs) { return batchUpdate(sql, batchArgs, new int[0]); } public int[] batchUpdate(String sql, List batchArgs, int[] argTypes) { return BatchUpdateUtils.executeBatchUpdate(sql, batchArgs, argTypes, getJdbcOperations()); } public int[] batchUpdate(String sql, Map[] batchValues) { return getNamedParameterJdbcOperations().batchUpdate(sql, batchValues); } public int[] batchUpdate(String sql, SqlParameterSource[] batchArgs) { return getNamedParameterJdbcOperations().batchUpdate(sql, batchArgs); } /* * Considers an Object array passed into a varargs parameter as * collection of arguments rather than as single argument. */ private Object[] getArguments(Object[] varArgs) { if (varArgs.length == 1 && varArgs[0] instanceof Object[]) { return (Object[]) varArgs[0]; } else { return varArgs; } } } ././@LongLink0000000000000000000000000000021400000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/simple/SimpleJdbcDaoSupport.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000275411623223530033275 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.simple; import org.springframework.jdbc.core.support.JdbcDaoSupport; /** * Extension of {@link org.springframework.jdbc.core.support.JdbcDaoSupport} * that exposes a {@link #getSimpleJdbcTemplate() SimpleJdbcTemplate} as well. * Only usable on Java 5 and above. * * @author Rod Johnson * @author Juergen Hoeller * @since 2.0 * @see SimpleJdbcTemplate */ public class SimpleJdbcDaoSupport extends JdbcDaoSupport { private SimpleJdbcTemplate simpleJdbcTemplate; /** * Create a SimpleJdbcTemplate based on the configured JdbcTemplate. */ @Override protected void initTemplateConfig() { this.simpleJdbcTemplate = new SimpleJdbcTemplate(getJdbcTemplate()); } /** * Return a SimpleJdbcTemplate wrapping the configured JdbcTemplate. */ public SimpleJdbcTemplate getSimpleJdbcTemplate() { return this.simpleJdbcTemplate; } } ././@LongLink0000000000000000000000000000021200000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/simple/AbstractJdbcInsert.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000005300511623223530033270 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.simple; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.sql.DataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.dao.DataAccessException; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.dao.InvalidDataAccessResourceUsageException; import org.springframework.jdbc.core.BatchPreparedStatementSetter; import org.springframework.jdbc.core.ConnectionCallback; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.PreparedStatementCreator; import org.springframework.jdbc.core.SqlTypeValue; import org.springframework.jdbc.core.StatementCreatorUtils; import org.springframework.jdbc.core.metadata.TableMetaDataContext; import org.springframework.jdbc.core.namedparam.SqlParameterSource; import org.springframework.jdbc.support.GeneratedKeyHolder; import org.springframework.jdbc.support.JdbcUtils; import org.springframework.jdbc.support.KeyHolder; import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor; import org.springframework.util.Assert; /** * Abstract class to provide base functionality for easy inserts * based on configuration options and database metadata. * This class provides the base SPI for {@link SimpleJdbcInsert}. * * @author Thomas Risberg * @author Juergen Hoeller * @since 2.5 */ public abstract class AbstractJdbcInsert { /** Logger available to subclasses */ protected final Log logger = LogFactory.getLog(getClass()); /** Lower-level class used to execute SQL */ private final JdbcTemplate jdbcTemplate; /** Context used to retrieve and manage database metadata */ private final TableMetaDataContext tableMetaDataContext = new TableMetaDataContext(); /** List of columns objects to be used in insert statement */ private final List declaredColumns = new ArrayList(); /** * Has this operation been compiled? Compilation means at * least checking that a DataSource or JdbcTemplate has been provided, * but subclasses may also implement their own custom validation. */ private boolean compiled = false; /** The generated string used for insert statement */ private String insertString; /** The SQL type information for the insert columns */ private int[] insertTypes; /** The names of the columns holding the generated key */ private String[] generatedKeyNames = new String[0]; /** * Constructor for sublasses to delegate to for setting the DataSource. */ protected AbstractJdbcInsert(DataSource dataSource) { this.jdbcTemplate = new JdbcTemplate(dataSource); } /** * Constructor for sublasses to delegate to for setting the JdbcTemplate. */ protected AbstractJdbcInsert(JdbcTemplate jdbcTemplate) { Assert.notNull(jdbcTemplate, "JdbcTemplate must not be null"); this.jdbcTemplate = jdbcTemplate; setNativeJdbcExtractor(jdbcTemplate.getNativeJdbcExtractor()); } //------------------------------------------------------------------------- // Methods dealing with configuaration properties //------------------------------------------------------------------------- /** * Set the name of the table for this insert */ public void setTableName(String tableName) { checkIfConfigurationModificationIsAllowed(); this.tableMetaDataContext.setTableName(tableName); } /** * Get the name of the table for this insert */ public String getTableName() { return this.tableMetaDataContext.getTableName(); } /** * Set the name of the schema for this insert */ public void setSchemaName(String schemaName) { checkIfConfigurationModificationIsAllowed(); this.tableMetaDataContext.setSchemaName(schemaName); } /** * Get the name of the schema for this insert */ public String getSchemaName() { return this.tableMetaDataContext.getSchemaName(); } /** * Set the name of the catalog for this insert */ public void setCatalogName(String catalogName) { checkIfConfigurationModificationIsAllowed(); this.tableMetaDataContext.setCatalogName(catalogName); } /** * Get the name of the catalog for this insert */ public String getCatalogName() { return this.tableMetaDataContext.getCatalogName(); } /** * Set the names of the columns to be used */ public void setColumnNames(List columnNames) { checkIfConfigurationModificationIsAllowed(); this.declaredColumns.clear(); this.declaredColumns.addAll(columnNames); } /** * Get the names of the columns used */ public List getColumnNames() { return Collections.unmodifiableList(this.declaredColumns); } /** * Get the names of any generated keys */ public String[] getGeneratedKeyNames() { return this.generatedKeyNames; } /** * Set the names of any generated keys */ public void setGeneratedKeyNames(String[] generatedKeyNames) { checkIfConfigurationModificationIsAllowed(); this.generatedKeyNames = generatedKeyNames; } /** * Specify the name of a single generated key column */ public void setGeneratedKeyName(String generatedKeyName) { checkIfConfigurationModificationIsAllowed(); this.generatedKeyNames = new String[] {generatedKeyName}; } /** * Specify whether the parameter metadata for the call should be used. The default is true. */ public void setAccessTableColumnMetaData(boolean accessTableColumnMetaData) { this.tableMetaDataContext.setAccessTableColumnMetaData(accessTableColumnMetaData); } /** * Specify whether the default for including synonyms should be changed. The default is false. */ public void setOverrideIncludeSynonymsDefault(boolean override) { this.tableMetaDataContext.setOverrideIncludeSynonymsDefault(override); } /** * Set the {@link NativeJdbcExtractor} to use to retrieve the native connection if necessary */ public void setNativeJdbcExtractor(NativeJdbcExtractor nativeJdbcExtractor) { this.tableMetaDataContext.setNativeJdbcExtractor(nativeJdbcExtractor); } /** * Get the insert string to be used */ public String getInsertString() { return this.insertString; } /** * Get the array of {@link java.sql.Types} to be used for insert */ public int[] getInsertTypes() { return this.insertTypes; } /** * Get the {@link JdbcTemplate} that is configured to be used */ protected JdbcTemplate getJdbcTemplate() { return this.jdbcTemplate; } //------------------------------------------------------------------------- // Methods handling compilation issues //------------------------------------------------------------------------- /** * Compile this JdbcInsert using provided parameters and meta data plus other settings. This * finalizes the configuration for this object and subsequent attempts to compile are ignored. * This will be implicitly called the first time an un-compiled insert is executed. * @throws org.springframework.dao.InvalidDataAccessApiUsageException if the object hasn't * been correctly initialized, for example if no DataSource has been provided */ public synchronized final void compile() throws InvalidDataAccessApiUsageException { if (!isCompiled()) { if (getTableName() == null) { throw new InvalidDataAccessApiUsageException("Table name is required"); } try { this.jdbcTemplate.afterPropertiesSet(); } catch (IllegalArgumentException ex) { throw new InvalidDataAccessApiUsageException(ex.getMessage()); } compileInternal(); this.compiled = true; if (logger.isDebugEnabled()) { logger.debug("JdbcInsert for table [" + getTableName() + "] compiled"); } } } /** * Method to perform the actual compilation. Subclasses can override this template method to perform * their own compilation. Invoked after this base class's compilation is complete. */ protected void compileInternal() { tableMetaDataContext.processMetaData(getJdbcTemplate().getDataSource(), getColumnNames(), getGeneratedKeyNames()); insertString = tableMetaDataContext.createInsertString(getGeneratedKeyNames()); insertTypes = tableMetaDataContext.createInsertTypes(); if (logger.isDebugEnabled()) { logger.debug("Compiled JdbcInsert. Insert string is [" + getInsertString() + "]"); } onCompileInternal(); } /** * Hook method that subclasses may override to react to compilation. * This implementation does nothing. */ protected void onCompileInternal() { } /** * Is this operation "compiled"? * @return whether this operation is compiled, and ready to use. */ public boolean isCompiled() { return this.compiled; } /** * Check whether this operation has been compiled already; * lazily compile it if not already compiled. *

Automatically called by validateParameters. */ protected void checkCompiled() { if (!isCompiled()) { logger.debug("JdbcInsert not compiled before execution - invoking compile"); compile(); } } /** * Method to check whether we are allowd to make any configuration changes at this time. If the class has been * compiled, then no further changes to the configuration are allowed. */ protected void checkIfConfigurationModificationIsAllowed() { if (isCompiled()) { throw new InvalidDataAccessApiUsageException("Configuration can't be altered once the class has been compiled or used."); } } //------------------------------------------------------------------------- // Methods handling execution //------------------------------------------------------------------------- /** * Method that provides execution of the insert using the passed in Map of parameters * * @param args Map with parameter names and values to be used in insert * @return number of rows affected */ protected int doExecute(Map args) { checkCompiled(); List values = matchInParameterValuesWithInsertColumns(args); return executeInsertInternal(values); } /** * Method that provides execution of the insert using the passed in {@link SqlParameterSource} * * @param parameterSource parameter names and values to be used in insert * @return number of rows affected */ protected int doExecute(SqlParameterSource parameterSource) { checkCompiled(); List values = matchInParameterValuesWithInsertColumns(parameterSource); return executeInsertInternal(values); } /** * Method to execute the insert */ private int executeInsertInternal(List values) { if (logger.isDebugEnabled()) { logger.debug("The following parameters are used for insert " + getInsertString() + " with: " + values); } int updateCount = jdbcTemplate.update(getInsertString(), values.toArray(), getInsertTypes()); return updateCount; } /** * Method that provides execution of the insert using the passed in Map of parameters * and returning a generated key * * @param args Map with parameter names and values to be used in insert * @return the key generated by the insert */ protected Number doExecuteAndReturnKey(Map args) { checkCompiled(); List values = matchInParameterValuesWithInsertColumns(args); return executeInsertAndReturnKeyInternal(values); } /** * Method that provides execution of the insert using the passed in {@link SqlParameterSource} * and returning a generated key * * @param parameterSource parameter names and values to be used in insert * @return the key generated by the insert */ protected Number doExecuteAndReturnKey(SqlParameterSource parameterSource) { checkCompiled(); List values = matchInParameterValuesWithInsertColumns(parameterSource); return executeInsertAndReturnKeyInternal(values); } /** * Method that provides execution of the insert using the passed in Map of parameters * and returning all generated keys * * @param args Map with parameter names and values to be used in insert * @return the KeyHolder containing keys generated by the insert */ protected KeyHolder doExecuteAndReturnKeyHolder(Map args) { checkCompiled(); List values = matchInParameterValuesWithInsertColumns(args); return executeInsertAndReturnKeyHolderInternal(values); } /** * Method that provides execution of the insert using the passed in {@link SqlParameterSource} * and returning all generated keys * * @param parameterSource parameter names and values to be used in insert * @return the KeyHolder containing keys generated by the insert */ protected KeyHolder doExecuteAndReturnKeyHolder(SqlParameterSource parameterSource) { checkCompiled(); List values = matchInParameterValuesWithInsertColumns(parameterSource); return executeInsertAndReturnKeyHolderInternal(values); } /** * Method to execute the insert generating single key */ private Number executeInsertAndReturnKeyInternal(final List values) { KeyHolder kh = executeInsertAndReturnKeyHolderInternal(values); if (kh != null && kh.getKey() != null) { return kh.getKey(); } else { throw new DataIntegrityViolationException("Unable to retrieve the generated key for the insert: " + getInsertString()); } } /** * Method to execute the insert generating any number of keys */ private KeyHolder executeInsertAndReturnKeyHolderInternal(final List values) { if (logger.isDebugEnabled()) { logger.debug("The following parameters are used for call " + getInsertString() + " with: " + values); } final KeyHolder keyHolder = new GeneratedKeyHolder(); if (this.tableMetaDataContext.isGetGeneratedKeysSupported()) { jdbcTemplate.update( new PreparedStatementCreator() { public PreparedStatement createPreparedStatement(Connection con) throws SQLException { PreparedStatement ps = prepareStatementForGeneratedKeys(con); setParameterValues(ps, values, getInsertTypes()); return ps; } }, keyHolder); } else { if (!this.tableMetaDataContext.isGetGeneratedKeysSimulated()) { throw new InvalidDataAccessResourceUsageException( "The getGeneratedKeys feature is not supported by this database"); } if (getGeneratedKeyNames().length < 1) { throw new InvalidDataAccessApiUsageException("Generated Key Name(s) not specificed. " + "Using the generated keys features requires specifying the name(s) of the generated column(s)"); } if (getGeneratedKeyNames().length > 1) { throw new InvalidDataAccessApiUsageException( "Current database only supports retreiving the key for a single column. There are " + getGeneratedKeyNames().length + " columns specified: " + Arrays.asList(getGeneratedKeyNames())); } // This is a hack to be able to get the generated key from a database that doesn't support // get generated keys feature. HSQL is one, PostgreSQL is another. Postgres uses a RETURNING // clause while HSQL uses a second query that has to be executed with the same connection. final String keyQuery = tableMetaDataContext.getSimulationQueryForGetGeneratedKey( tableMetaDataContext.getTableName(), getGeneratedKeyNames()[0]); Assert.notNull(keyQuery, "Query for simulating get generated keys can't be null"); if (keyQuery.toUpperCase().startsWith("RETURNING")) { Long key = jdbcTemplate.queryForLong( getInsertString() + " " + keyQuery, values.toArray(new Object[values.size()])); HashMap keys = new HashMap(1); keys.put(getGeneratedKeyNames()[0], key); keyHolder.getKeyList().add(keys); } else { jdbcTemplate.execute(new ConnectionCallback() { public Object doInConnection(Connection con) throws SQLException, DataAccessException { // Do the insert PreparedStatement ps = null; try { ps = con.prepareStatement(getInsertString()); setParameterValues(ps, values, getInsertTypes()); ps.executeUpdate(); } finally { JdbcUtils.closeStatement(ps); } //Get the key Statement keyStmt = null; ResultSet rs = null; HashMap keys = new HashMap(1); try { keyStmt = con.createStatement(); rs = keyStmt.executeQuery(keyQuery); if (rs.next()) { long key = rs.getLong(1); keys.put(getGeneratedKeyNames()[0], key); keyHolder.getKeyList().add(keys); } } finally { JdbcUtils.closeResultSet(rs); JdbcUtils.closeStatement(keyStmt); } return null; } }); } return keyHolder; } return keyHolder; } /** * Create the PreparedStatement to be used for insert that have generated keys * * @param con the connection used * @return PreparedStatement to use * @throws SQLException */ private PreparedStatement prepareStatementForGeneratedKeys(Connection con) throws SQLException { if (getGeneratedKeyNames().length < 1) { throw new InvalidDataAccessApiUsageException("Generated Key Name(s) not specificed. " + "Using the generated keys features requires specifying the name(s) of the generated column(s)"); } PreparedStatement ps; if (this.tableMetaDataContext.isGeneratedKeysColumnNameArraySupported()) { if (logger.isDebugEnabled()) { logger.debug("Using generated keys support with array of column names."); } ps = con.prepareStatement(getInsertString(), getGeneratedKeyNames()); } else { if (logger.isDebugEnabled()) { logger.debug("Using generated keys support with Statement.RETURN_GENERATED_KEYS."); } ps = con.prepareStatement(getInsertString(), Statement.RETURN_GENERATED_KEYS); } return ps; } /** * Method that provides execution of a batch insert using the passed in Maps of parameters * * @param batch array of Maps with parameter names and values to be used in batch insert * @return array of number of rows affected */ protected int[] doExecuteBatch(Map[] batch) { checkCompiled(); List[] batchValues = new ArrayList[batch.length]; int i = 0; for (Map args : batch) { List values = matchInParameterValuesWithInsertColumns(args); batchValues[i++] = values; } return executeBatchInternal(batchValues); } /** * Method that provides execution of a batch insert using the passed in array of {@link SqlParameterSource} * * @param batch array of SqlParameterSource with parameter names and values to be used in insert * @return array of number of rows affected */ protected int[] doExecuteBatch(SqlParameterSource[] batch) { checkCompiled(); List[] batchValues = new ArrayList[batch.length]; int i = 0; for (SqlParameterSource parameterSource : batch) { List values = matchInParameterValuesWithInsertColumns(parameterSource); batchValues[i++] = values; } return executeBatchInternal(batchValues); } /** * Method to execute the batch insert */ //TODO synchronize parameter setters with the SimpleJdbcTemplate private int[] executeBatchInternal(final List[] batchValues) { if (logger.isDebugEnabled()) { logger.debug("Executing statement " + getInsertString() + " with batch of size: " + batchValues.length); } int[] updateCounts = jdbcTemplate.batchUpdate( getInsertString(), new BatchPreparedStatementSetter() { public void setValues(PreparedStatement ps, int i) throws SQLException { List values = batchValues[i]; setParameterValues(ps, values, getInsertTypes()); } public int getBatchSize() { return batchValues.length; } }); return updateCounts; } /** * Internal implementation for setting parameter values * @param preparedStatement the PreparedStatement * @param values the values to be set */ private void setParameterValues(PreparedStatement preparedStatement, List values, int[] columnTypes) throws SQLException { int colIndex = 0; for (Object value : values) { colIndex++; if (columnTypes == null || colIndex > columnTypes.length) { StatementCreatorUtils.setParameterValue(preparedStatement, colIndex, SqlTypeValue.TYPE_UNKNOWN, value); } else { StatementCreatorUtils.setParameterValue(preparedStatement, colIndex, columnTypes[colIndex - 1], value); } } } /** * Match the provided in parameter values with regitered parameters and parameters defined via metedata * processing. * * @param parameterSource the parameter vakues provided as a {@link SqlParameterSource} * @return Map with parameter names and values */ protected List matchInParameterValuesWithInsertColumns(SqlParameterSource parameterSource) { return tableMetaDataContext.matchInParameterValuesWithInsertColumns(parameterSource); } /** * Match the provided in parameter values with regitered parameters and parameters defined via metedata * processing. * * @param args the parameter values provided in a Map * @return Map with parameter names and values */ protected List matchInParameterValuesWithInsertColumns(Map args) { return tableMetaDataContext.matchInParameterValuesWithInsertColumns(args); } } ././@LongLink0000000000000000000000000000020200000000000011557 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/StatementCallback.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000615711623223526033303 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; import java.sql.SQLException; import java.sql.Statement; import org.springframework.dao.DataAccessException; /** * Generic callback interface for code that operates on a JDBC Statement. * Allows to execute any number of operations on a single Statement, * for example a single executeUpdate call or repeated * executeUpdate calls with varying SQL. * *

Used internally by JdbcTemplate, but also useful for application code. * * @author Juergen Hoeller * @since 16.03.2004 * @see JdbcTemplate#execute(StatementCallback) */ public interface StatementCallback { /** * Gets called by JdbcTemplate.execute with an active JDBC * Statement. Does not need to care about closing the Statement or the * Connection, or about handling transactions: this will all be handled * by Spring's JdbcTemplate. * *

NOTE: Any ResultSets opened should be closed in finally blocks * within the callback implementation. Spring will close the Statement * object after the callback returned, but this does not necessarily imply * that the ResultSet resources will be closed: the Statement objects might * get pooled by the connection pool, with close calls only * returning the object to the pool but not physically closing the resources. * *

If called without a thread-bound JDBC transaction (initiated by * DataSourceTransactionManager), the code will simply get executed on the * JDBC connection with its transactional semantics. If JdbcTemplate is * configured to use a JTA-aware DataSource, the JDBC connection and thus * the callback code will be transactional if a JTA transaction is active. * *

Allows for returning a result object created within the callback, i.e. * a domain object or a collection of domain objects. Note that there's * special support for single step actions: see JdbcTemplate.queryForObject etc. * A thrown RuntimeException is treated as application exception, it gets * propagated to the caller of the template. * * @param stmt active JDBC Statement * @return a result object, or null if none * @throws SQLException if thrown by a JDBC method, to be auto-converted * to a DataAccessException by a SQLExceptionTranslator * @throws DataAccessException in case of custom exceptions * @see JdbcTemplate#queryForObject(String, Class) * @see JdbcTemplate#queryForRowSet(String) */ T doInStatement(Statement stmt) throws SQLException, DataAccessException; } ././@LongLink0000000000000000000000000000021000000000000011556 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/PreparedStatementSetter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000403511623223526033274 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; import java.sql.PreparedStatement; import java.sql.SQLException; /** * General callback interface used by the {@link JdbcTemplate} class. * *

This interface sets values on a {@link java.sql.PreparedStatement} provided * by the JdbcTemplate class, for each of a number of updates in a batch using the * same SQL. Implementations are responsible for setting any necessary parameters. * SQL with placeholders will already have been supplied. * *

It's easier to use this interface than {@link PreparedStatementCreator}: * The JdbcTemplate will create the PreparedStatement, with the callback * only being responsible for setting parameter values. * *

Implementations do not need to concern themselves with * SQLExceptions that may be thrown from operations they attempt. * The JdbcTemplate class will catch and handle SQLExceptions appropriately. * * @author Rod Johnson * @since March 2, 2003 * @see JdbcTemplate#update(String, PreparedStatementSetter) * @see JdbcTemplate#query(String, PreparedStatementSetter, ResultSetExtractor) */ public interface PreparedStatementSetter { /** * Set parameter values on the given PreparedStatement. * @param ps the PreparedStatement to invoke setter methods on * @throws SQLException if a SQLException is encountered * (i.e. there is no need to catch SQLException) */ void setValues(PreparedStatement ps) throws SQLException; } ././@LongLink0000000000000000000000000000020600000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/SingleColumnRowMapper.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001604211623223530033270 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import org.springframework.dao.TypeMismatchDataAccessException; import org.springframework.jdbc.IncorrectResultSetColumnCountException; import org.springframework.jdbc.support.JdbcUtils; import org.springframework.util.NumberUtils; /** * {@link RowMapper} implementation that converts a single column into a single * result value per row. Expects to operate on a java.sql.ResultSet * that just contains a single column. * *

The type of the result value for each row can be specified. The value * for the single column will be extracted from the ResultSet * and converted into the specified target type. * * @author Juergen Hoeller * @since 1.2 * @see JdbcTemplate#queryForList(String, Class) * @see JdbcTemplate#queryForObject(String, Class) */ public class SingleColumnRowMapper implements RowMapper { private Class requiredType; /** * Create a new SingleColumnRowMapper. * @see #setRequiredType */ public SingleColumnRowMapper() { } /** * Create a new SingleColumnRowMapper. * @param requiredType the type that each result object is expected to match */ public SingleColumnRowMapper(Class requiredType) { this.requiredType = requiredType; } /** * Set the type that each result object is expected to match. *

If not specified, the column value will be exposed as * returned by the JDBC driver. */ public void setRequiredType(Class requiredType) { this.requiredType = requiredType; } /** * Extract a value for the single column in the current row. *

Validates that there is only one column selected, * then delegates to getColumnValue() and also * convertValueToRequiredType, if necessary. * @see java.sql.ResultSetMetaData#getColumnCount() * @see #getColumnValue(java.sql.ResultSet, int, Class) * @see #convertValueToRequiredType(Object, Class) */ @SuppressWarnings("unchecked") public T mapRow(ResultSet rs, int rowNum) throws SQLException { // Validate column count. ResultSetMetaData rsmd = rs.getMetaData(); int nrOfColumns = rsmd.getColumnCount(); if (nrOfColumns != 1) { throw new IncorrectResultSetColumnCountException(1, nrOfColumns); } // Extract column value from JDBC ResultSet. Object result = getColumnValue(rs, 1, this.requiredType); if (result != null && this.requiredType != null && !this.requiredType.isInstance(result)) { // Extracted value does not match already: try to convert it. try { return (T) convertValueToRequiredType(result, this.requiredType); } catch (IllegalArgumentException ex) { throw new TypeMismatchDataAccessException( "Type mismatch affecting row number " + rowNum + " and column type '" + rsmd.getColumnTypeName(1) + "': " + ex.getMessage()); } } return (T) result; } /** * Retrieve a JDBC object value for the specified column. *

The default implementation calls * {@link JdbcUtils#getResultSetValue(java.sql.ResultSet, int, Class)}. * If no required type has been specified, this method delegates to * getColumnValue(rs, index), which basically calls * ResultSet.getObject(index) but applies some additional * default conversion to appropriate value types. * @param rs is the ResultSet holding the data * @param index is the column index * @param requiredType the type that each result object is expected to match * (or null if none specified) * @return the Object value * @throws SQLException in case of extraction failure * @see org.springframework.jdbc.support.JdbcUtils#getResultSetValue(java.sql.ResultSet, int, Class) * @see #getColumnValue(java.sql.ResultSet, int) */ protected Object getColumnValue(ResultSet rs, int index, Class requiredType) throws SQLException { if (requiredType != null) { return JdbcUtils.getResultSetValue(rs, index, requiredType); } else { // No required type specified -> perform default extraction. return getColumnValue(rs, index); } } /** * Retrieve a JDBC object value for the specified column, using the most * appropriate value type. Called if no required type has been specified. *

The default implementation delegates to JdbcUtils.getResultSetValue(), * which uses the ResultSet.getObject(index) method. Additionally, * it includes a "hack" to get around Oracle returning a non-standard object for * their TIMESTAMP datatype. See the JdbcUtils#getResultSetValue() * javadoc for details. * @param rs is the ResultSet holding the data * @param index is the column index * @return the Object value * @throws SQLException in case of extraction failure * @see org.springframework.jdbc.support.JdbcUtils#getResultSetValue(java.sql.ResultSet, int) */ protected Object getColumnValue(ResultSet rs, int index) throws SQLException { return JdbcUtils.getResultSetValue(rs, index); } /** * Convert the given column value to the specified required type. * Only called if the extracted column value does not match already. *

If the required type is String, the value will simply get stringified * via toString(). In case of a Number, the value will be * converted into a Number, either through number conversion or through * String parsing (depending on the value type). * @param value the column value as extracted from getColumnValue() * (never null) * @param requiredType the type that each result object is expected to match * (never null) * @return the converted value * @see #getColumnValue(java.sql.ResultSet, int, Class) */ @SuppressWarnings("unchecked") protected Object convertValueToRequiredType(Object value, Class requiredType) { if (String.class.equals(requiredType)) { return value.toString(); } else if (Number.class.isAssignableFrom(requiredType)) { if (value instanceof Number) { // Convert original Number to target Number class. return NumberUtils.convertNumberToTargetClass(((Number) value), requiredType); } else { // Convert stringified value to target Number class. return NumberUtils.parseNumber(value.toString(), requiredType); } } else { throw new IllegalArgumentException( "Value [" + value + "] is of type [" + value.getClass().getName() + "] and cannot be converted to required type [" + requiredType.getName() + "]"); } } } ././@LongLink0000000000000000000000000000020300000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/RowCallbackHandler.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000446311623223530033274 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; import java.sql.ResultSet; import java.sql.SQLException; /** * An interface used by {@link JdbcTemplate} for processing rows of a * {@link java.sql.ResultSet} on a per-row basis. Implementations of * this interface perform the actual work of processing each row * but don't need to worry about exception handling. * {@link java.sql.SQLException SQLExceptions} will be caught and handled * by the calling JdbcTemplate. * *

In contrast to a {@link ResultSetExtractor}, a RowCallbackHandler * object is typically stateful: It keeps the result state within the * object, to be available for later inspection. See * {@link RowCountCallbackHandler} for a usage example. * *

Consider using a {@link RowMapper} instead if you need to map * exactly one result object per row, assembling them into a List. * * @author Rod Johnson * @author Juergen Hoeller * @see JdbcTemplate * @see RowMapper * @see ResultSetExtractor * @see RowCountCallbackHandler */ public interface RowCallbackHandler { /** * Implementations must implement this method to process each row of data * in the ResultSet. This method should not call next() on * the ResultSet; it is only supposed to extract values of the current row. *

Exactly what the implementation chooses to do is up to it: * A trivial implementation might simply count rows, while another * implementation might build an XML document. * @param rs the ResultSet to process (pre-initialized for the current row) * @throws SQLException if a SQLException is encountered getting * column values (that is, there's no need to catch SQLException) */ void processRow(ResultSet rs) throws SQLException; } ././@LongLink0000000000000000000000000000020300000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/ColumnMapRowMapper.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000735311623223526033302 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.util.Map; import org.springframework.jdbc.support.JdbcUtils; import org.springframework.util.LinkedCaseInsensitiveMap; /** * {@link RowMapper} implementation that creates a java.util.Map * for each row, representing all columns as key-value pairs: one * entry for each column, with the column name as key. * *

The Map implementation to use and the key to use for each column * in the column Map can be customized through overriding * {@link #createColumnMap} and {@link #getColumnKey}, respectively. * *

Note: By default, ColumnMapRowMapper will try to build a linked Map * with case-insensitive keys, to preserve column order as well as allow any * casing to be used for column names. This requires Commons Collections on the * classpath (which will be autodetected). Else, the fallback is a standard linked * HashMap, which will still preserve column order but requires the application * to specify the column names in the same casing as exposed by the driver. * * @author Juergen Hoeller * @since 1.2 * @see JdbcTemplate#queryForList(String) * @see JdbcTemplate#queryForMap(String) */ public class ColumnMapRowMapper implements RowMapper> { public Map mapRow(ResultSet rs, int rowNum) throws SQLException { ResultSetMetaData rsmd = rs.getMetaData(); int columnCount = rsmd.getColumnCount(); Map mapOfColValues = createColumnMap(columnCount); for (int i = 1; i <= columnCount; i++) { String key = getColumnKey(JdbcUtils.lookupColumnName(rsmd, i)); Object obj = getColumnValue(rs, i); mapOfColValues.put(key, obj); } return mapOfColValues; } /** * Create a Map instance to be used as column map. *

By default, a linked case-insensitive Map will be created. * @param columnCount the column count, to be used as initial * capacity for the Map * @return the new Map instance * @see org.springframework.util.LinkedCaseInsensitiveMap */ @SuppressWarnings("unchecked") protected Map createColumnMap(int columnCount) { return new LinkedCaseInsensitiveMap(columnCount); } /** * Determine the key to use for the given column in the column Map. * @param columnName the column name as returned by the ResultSet * @return the column key to use * @see java.sql.ResultSetMetaData#getColumnName */ protected String getColumnKey(String columnName) { return columnName; } /** * Retrieve a JDBC object value for the specified column. *

The default implementation uses the getObject method. * Additionally, this implementation includes a "hack" to get around Oracle * returning a non standard object for their TIMESTAMP datatype. * @param rs is the ResultSet holding the data * @param index is the column index * @return the Object returned * @see org.springframework.jdbc.support.JdbcUtils#getResultSetValue */ protected Object getColumnValue(ResultSet rs, int index) throws SQLException { return JdbcUtils.getResultSetValue(rs, index); } } ././@LongLink0000000000000000000000000000020100000000000011556 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/BatchUpdateUtils.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000412711623223530033271 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; import java.util.List; import java.sql.PreparedStatement; import java.sql.SQLException; /** * Generic utility methods for working with JDBC batch statements. Mainly for internal use * within the framework. * * @author Thomas Risberg */ public abstract class BatchUpdateUtils { public static int[] executeBatchUpdate(String sql, final List batchValues, final int[] columnTypes, JdbcOperations jdbcOperations) { return jdbcOperations.batchUpdate( sql, new BatchPreparedStatementSetter() { public void setValues(PreparedStatement ps, int i) throws SQLException { Object[] values = batchValues.get(i); setStatementParameters(values, ps, columnTypes); } public int getBatchSize() { return batchValues.size(); } }); } protected static void setStatementParameters(Object[] values, PreparedStatement ps, int[] columnTypes) throws SQLException { int colIndex = 0; for (Object value : values) { colIndex++; if (value instanceof SqlParameterValue) { SqlParameterValue paramValue = (SqlParameterValue) value; StatementCreatorUtils.setParameterValue(ps, colIndex, paramValue, paramValue.getValue()); } else { int colType; if (columnTypes == null || columnTypes.length < colIndex) { colType = SqlTypeValue.TYPE_UNKNOWN; } else { colType = columnTypes[colIndex - 1]; } StatementCreatorUtils.setParameterValue(ps, colIndex, colType, value); } } } } ././@LongLink0000000000000000000000000000021200000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/CallableStatementCallback.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000670711623223530033277 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; import java.sql.CallableStatement; import java.sql.SQLException; import org.springframework.dao.DataAccessException; /** * Generic callback interface for code that operates on a CallableStatement. * Allows to execute any number of operations on a single CallableStatement, * for example a single execute call or repeated execute calls with varying * parameters. * *

Used internally by JdbcTemplate, but also useful for application code. * Note that the passed-in CallableStatement can have been created by the * framework or by a custom CallableStatementCreator. However, the latter is * hardly ever necessary, as most custom callback actions will perform updates * in which case a standard CallableStatement is fine. Custom actions will * always set parameter values themselves, so that CallableStatementCreator * capability is not needed either. * * @author Juergen Hoeller * @since 16.03.2004 * @see JdbcTemplate#execute(String, CallableStatementCallback) * @see JdbcTemplate#execute(CallableStatementCreator, CallableStatementCallback) */ public interface CallableStatementCallback { /** * Gets called by JdbcTemplate.execute with an active JDBC * CallableStatement. Does not need to care about closing the Statement * or the Connection, or about handling transactions: this will all be * handled by Spring's JdbcTemplate. * *

NOTE: Any ResultSets opened should be closed in finally blocks * within the callback implementation. Spring will close the Statement * object after the callback returned, but this does not necessarily imply * that the ResultSet resources will be closed: the Statement objects might * get pooled by the connection pool, with close calls only * returning the object to the pool but not physically closing the resources. * *

If called without a thread-bound JDBC transaction (initiated by * DataSourceTransactionManager), the code will simply get executed on the * JDBC connection with its transactional semantics. If JdbcTemplate is * configured to use a JTA-aware DataSource, the JDBC connection and thus * the callback code will be transactional if a JTA transaction is active. * *

Allows for returning a result object created within the callback, i.e. * a domain object or a collection of domain objects. A thrown RuntimeException * is treated as application exception: it gets propagated to the caller of * the template. * * @param cs active JDBC CallableStatement * @return a result object, or null if none * @throws SQLException if thrown by a JDBC method, to be auto-converted * into a DataAccessException by a SQLExceptionTranslator * @throws DataAccessException in case of custom exceptions */ T doInCallableStatement(CallableStatement cs) throws SQLException, DataAccessException; } ././@LongLink0000000000000000000000000000020200000000000011557 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/SqlInOutParameter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000736011623223530033273 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; /** * Subclass of {@link SqlOutParameter} to represent an INOUT parameter. * Will return true for SqlParameter's {@link #isInputValueProvided} * test, in contrast to a standard SqlOutParameter. * *

Output parameters - like all stored procedure parameters - * must have names. * * @author Thomas Risberg * @author Juergen Hoeller * @since 2.0 */ public class SqlInOutParameter extends SqlOutParameter { /** * Create a new SqlInOutParameter. * @param name name of the parameter, as used in input and output maps * @param sqlType SQL type of the parameter according to java.sql.Types */ public SqlInOutParameter(String name, int sqlType) { super(name, sqlType); } /** * Create a new SqlInOutParameter. * @param name name of the parameter, as used in input and output maps * @param sqlType SQL type of the parameter according to java.sql.Types * @param scale the number of digits after the decimal point * (for DECIMAL and NUMERIC types) */ public SqlInOutParameter(String name, int sqlType, int scale) { super(name, sqlType, scale); } /** * Create a new SqlInOutParameter. * @param name name of the parameter, as used in input and output maps * @param sqlType SQL type of the parameter according to java.sql.Types * @param typeName the type name of the parameter (optional) */ public SqlInOutParameter(String name, int sqlType, String typeName) { super(name, sqlType, typeName); } /** * Create a new SqlInOutParameter. * @param name name of the parameter, as used in input and output maps * @param sqlType SQL type of the parameter according to java.sql.Types * @param typeName the type name of the parameter (optional) * @param sqlReturnType custom value handler for complex type (optional) */ public SqlInOutParameter(String name, int sqlType, String typeName, SqlReturnType sqlReturnType) { super(name, sqlType, typeName, sqlReturnType); } /** * Create a new SqlInOutParameter. * @param name name of the parameter, as used in input and output maps * @param sqlType SQL type of the parameter according to java.sql.Types * @param rse ResultSetExtractor to use for parsing the ResultSet */ public SqlInOutParameter(String name, int sqlType, ResultSetExtractor rse) { super(name, sqlType, rse); } /** * Create a new SqlInOutParameter. * @param name name of the parameter, as used in input and output maps * @param sqlType SQL type of the parameter according to java.sql.Types * @param rch RowCallbackHandler to use for parsing the ResultSet */ public SqlInOutParameter(String name, int sqlType, RowCallbackHandler rch) { super(name, sqlType, rch); } /** * Create a new SqlInOutParameter. * @param name name of the parameter, as used in input and output maps * @param sqlType SQL type of the parameter according to java.sql.Types * @param rm RowMapper to use for parsing the ResultSet */ public SqlInOutParameter(String name, int sqlType, RowMapper rm) { super(name, sqlType, rm); } /** * This implementation always returns true. */ @Override public boolean isInputValueProvided() { return true; } } ././@LongLink0000000000000000000000000000021400000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/SqlRowSetResultSetExtractor.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000555311623223530033275 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; import java.sql.ResultSet; import java.sql.SQLException; import javax.sql.rowset.CachedRowSet; import com.sun.rowset.CachedRowSetImpl; import org.springframework.jdbc.support.rowset.ResultSetWrappingSqlRowSet; import org.springframework.jdbc.support.rowset.SqlRowSet; /** * ResultSetExtractor implementation that returns a Spring SqlRowSet * representation for each given ResultSet. * *

The default implementation uses a standard JDBC CachedRowSet underneath. * This means that JDBC RowSet support needs to be available at runtime: * by default, Sun's com.sun.rowset.CachedRowSetImpl class. * * @author Juergen Hoeller * @since 1.2 * @see #newCachedRowSet * @see org.springframework.jdbc.support.rowset.SqlRowSet * @see JdbcTemplate#queryForRowSet(String) * @see javax.sql.rowset.CachedRowSet */ public class SqlRowSetResultSetExtractor implements ResultSetExtractor { public SqlRowSet extractData(ResultSet rs) throws SQLException { return createSqlRowSet(rs); } /** * Create a SqlRowSet that wraps the given ResultSet, * representing its data in a disconnected fashion. *

This implementation creates a Spring ResultSetWrappingSqlRowSet * instance that wraps a standard JDBC CachedRowSet instance. * Can be overridden to use a different implementation. * @param rs the original ResultSet (connected) * @return the disconnected SqlRowSet * @throws SQLException if thrown by JDBC methods * @see #newCachedRowSet * @see org.springframework.jdbc.support.rowset.ResultSetWrappingSqlRowSet */ protected SqlRowSet createSqlRowSet(ResultSet rs) throws SQLException { CachedRowSet rowSet = newCachedRowSet(); rowSet.populate(rs); return new ResultSetWrappingSqlRowSet(rowSet); } /** * Create a new CachedRowSet instance, to be populated by * the createSqlRowSet implementation. *

The default implementation creates a new instance of * Sun's com.sun.rowset.CachedRowSetImpl class. * @return a new CachedRowSet instance * @throws SQLException if thrown by JDBC methods * @see #createSqlRowSet * @see com.sun.rowset.CachedRowSetImpl */ protected CachedRowSet newCachedRowSet() throws SQLException { return new CachedRowSetImpl(); } } ././@LongLink0000000000000000000000000000020600000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/StatementCreatorUtils.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000003515511623223526033303 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; import java.io.StringWriter; import java.math.BigDecimal; import java.math.BigInteger; import java.sql.Blob; import java.sql.Clob; import java.sql.DatabaseMetaData; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Types; import java.util.Arrays; import java.util.Calendar; import java.util.Collection; import java.util.HashMap; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.jdbc.support.SqlValue; /** * Utility methods for PreparedStatementSetter/Creator and CallableStatementCreator * implementations, providing sophisticated parameter management (including support * for LOB values). * *

Used by PreparedStatementCreatorFactory and CallableStatementCreatorFactory, * but also available for direct use in custom setter/creator implementations. * * @author Thomas Risberg * @author Juergen Hoeller * @since 1.1 * @see PreparedStatementSetter * @see PreparedStatementCreator * @see CallableStatementCreator * @see PreparedStatementCreatorFactory * @see CallableStatementCreatorFactory * @see SqlParameter * @see SqlTypeValue * @see org.springframework.jdbc.core.support.SqlLobValue */ public abstract class StatementCreatorUtils { private static final Log logger = LogFactory.getLog(StatementCreatorUtils.class); private static Map javaTypeToSqlTypeMap = new HashMap(32); static { /* JDBC 3.0 only - not compatible with e.g. MySQL at present javaTypeToSqlTypeMap.put(boolean.class, new Integer(Types.BOOLEAN)); javaTypeToSqlTypeMap.put(Boolean.class, new Integer(Types.BOOLEAN)); */ javaTypeToSqlTypeMap.put(byte.class, Types.TINYINT); javaTypeToSqlTypeMap.put(Byte.class, Types.TINYINT); javaTypeToSqlTypeMap.put(short.class, Types.SMALLINT); javaTypeToSqlTypeMap.put(Short.class, Types.SMALLINT); javaTypeToSqlTypeMap.put(int.class, Types.INTEGER); javaTypeToSqlTypeMap.put(Integer.class, Types.INTEGER); javaTypeToSqlTypeMap.put(long.class, Types.BIGINT); javaTypeToSqlTypeMap.put(Long.class, Types.BIGINT); javaTypeToSqlTypeMap.put(BigInteger.class, Types.BIGINT); javaTypeToSqlTypeMap.put(float.class, Types.FLOAT); javaTypeToSqlTypeMap.put(Float.class, Types.FLOAT); javaTypeToSqlTypeMap.put(double.class, Types.DOUBLE); javaTypeToSqlTypeMap.put(Double.class, Types.DOUBLE); javaTypeToSqlTypeMap.put(BigDecimal.class, Types.DECIMAL); javaTypeToSqlTypeMap.put(java.sql.Date.class, Types.DATE); javaTypeToSqlTypeMap.put(java.sql.Time.class, Types.TIME); javaTypeToSqlTypeMap.put(java.sql.Timestamp.class, Types.TIMESTAMP); javaTypeToSqlTypeMap.put(Blob.class, Types.BLOB); javaTypeToSqlTypeMap.put(Clob.class, Types.CLOB); } /** * Derive a default SQL type from the given Java type. * @param javaType the Java type to translate * @return the corresponding SQL type, or null if none found */ public static int javaTypeToSqlParameterType(Class javaType) { Integer sqlType = javaTypeToSqlTypeMap.get(javaType); if (sqlType != null) { return sqlType; } if (Number.class.isAssignableFrom(javaType)) { return Types.NUMERIC; } if (isStringValue(javaType)) { return Types.VARCHAR; } if (isDateValue(javaType) || Calendar.class.isAssignableFrom(javaType)) { return Types.TIMESTAMP; } return SqlTypeValue.TYPE_UNKNOWN; } /** * Set the value for a parameter. The method used is based on the SQL type * of the parameter and we can handle complex types like arrays and LOBs. * @param ps the prepared statement or callable statement * @param paramIndex index of the parameter we are setting * @param param the parameter as it is declared including type * @param inValue the value to set * @throws SQLException if thrown by PreparedStatement methods */ public static void setParameterValue( PreparedStatement ps, int paramIndex, SqlParameter param, Object inValue) throws SQLException { setParameterValueInternal(ps, paramIndex, param.getSqlType(), param.getTypeName(), param.getScale(), inValue); } /** * Set the value for a parameter. The method used is based on the SQL type * of the parameter and we can handle complex types like arrays and LOBs. * @param ps the prepared statement or callable statement * @param paramIndex index of the parameter we are setting * @param sqlType the SQL type of the parameter * @param inValue the value to set (plain value or a SqlTypeValue) * @throws SQLException if thrown by PreparedStatement methods * @see SqlTypeValue */ public static void setParameterValue( PreparedStatement ps, int paramIndex, int sqlType, Object inValue) throws SQLException { setParameterValueInternal(ps, paramIndex, sqlType, null, null, inValue); } /** * Set the value for a parameter. The method used is based on the SQL type * of the parameter and we can handle complex types like arrays and LOBs. * @param ps the prepared statement or callable statement * @param paramIndex index of the parameter we are setting * @param sqlType the SQL type of the parameter * @param typeName the type name of the parameter * (optional, only used for SQL NULL and SqlTypeValue) * @param inValue the value to set (plain value or a SqlTypeValue) * @throws SQLException if thrown by PreparedStatement methods * @see SqlTypeValue */ public static void setParameterValue( PreparedStatement ps, int paramIndex, int sqlType, String typeName, Object inValue) throws SQLException { setParameterValueInternal(ps, paramIndex, sqlType, typeName, null, inValue); } /** * Set the value for a parameter. The method used is based on the SQL type * of the parameter and we can handle complex types like arrays and LOBs. * @param ps the prepared statement or callable statement * @param paramIndex index of the parameter we are setting * @param sqlType the SQL type of the parameter * @param typeName the type name of the parameter * (optional, only used for SQL NULL and SqlTypeValue) * @param scale the number of digits after the decimal point * (for DECIMAL and NUMERIC types) * @param inValue the value to set (plain value or a SqlTypeValue) * @throws SQLException if thrown by PreparedStatement methods * @see SqlTypeValue */ private static void setParameterValueInternal( PreparedStatement ps, int paramIndex, int sqlType, String typeName, Integer scale, Object inValue) throws SQLException { String typeNameToUse = typeName; int sqlTypeToUse = sqlType; Object inValueToUse = inValue; // override type info? if (inValue instanceof SqlParameterValue) { SqlParameterValue parameterValue = (SqlParameterValue) inValue; if (logger.isDebugEnabled()) { logger.debug("Overriding typeinfo with runtime info from SqlParameterValue: column index " + paramIndex + ", SQL type " + parameterValue.getSqlType() + ", Type name " + parameterValue.getTypeName()); } if (parameterValue.getSqlType() != SqlTypeValue.TYPE_UNKNOWN) { sqlTypeToUse = parameterValue.getSqlType(); } if (parameterValue.getTypeName() != null) { typeNameToUse = parameterValue.getTypeName(); } inValueToUse = parameterValue.getValue(); } if (logger.isTraceEnabled()) { logger.trace("Setting SQL statement parameter value: column index " + paramIndex + ", parameter value [" + inValueToUse + "], value class [" + (inValueToUse != null ? inValueToUse.getClass().getName() : "null") + "], SQL type " + (sqlTypeToUse == SqlTypeValue.TYPE_UNKNOWN ? "unknown" : Integer.toString(sqlTypeToUse))); } if (inValueToUse == null) { setNull(ps, paramIndex, sqlTypeToUse, typeNameToUse); } else { setValue(ps, paramIndex, sqlTypeToUse, typeNameToUse, scale, inValueToUse); } } /** * Set the specified PreparedStatement parameter to null, * respecting database-specific peculiarities. */ private static void setNull(PreparedStatement ps, int paramIndex, int sqlType, String typeName) throws SQLException { if (sqlType == SqlTypeValue.TYPE_UNKNOWN) { boolean useSetObject = false; sqlType = Types.NULL; try { DatabaseMetaData dbmd = ps.getConnection().getMetaData(); String databaseProductName = dbmd.getDatabaseProductName(); String jdbcDriverName = dbmd.getDriverName(); if (databaseProductName.startsWith("Informix") || jdbcDriverName.startsWith("Microsoft SQL Server")) { useSetObject = true; } else if (databaseProductName.startsWith("DB2") || jdbcDriverName.startsWith("jConnect") || jdbcDriverName.startsWith("SQLServer")|| jdbcDriverName.startsWith("Apache Derby")) { sqlType = Types.VARCHAR; } } catch (Throwable ex) { logger.debug("Could not check database or driver name", ex); } if (useSetObject) { ps.setObject(paramIndex, null); } else { ps.setNull(paramIndex, sqlType); } } else if (typeName != null) { ps.setNull(paramIndex, sqlType, typeName); } else { ps.setNull(paramIndex, sqlType); } } private static void setValue(PreparedStatement ps, int paramIndex, int sqlType, String typeName, Integer scale, Object inValue) throws SQLException { if (inValue instanceof SqlTypeValue) { ((SqlTypeValue) inValue).setTypeValue(ps, paramIndex, sqlType, typeName); } else if (inValue instanceof SqlValue) { ((SqlValue) inValue).setValue(ps, paramIndex); } else if (sqlType == Types.VARCHAR || sqlType == Types.LONGVARCHAR || (sqlType == Types.CLOB && isStringValue(inValue.getClass()))) { ps.setString(paramIndex, inValue.toString()); } else if (sqlType == Types.DECIMAL || sqlType == Types.NUMERIC) { if (inValue instanceof BigDecimal) { ps.setBigDecimal(paramIndex, (BigDecimal) inValue); } else if (scale != null) { ps.setObject(paramIndex, inValue, sqlType, scale); } else { ps.setObject(paramIndex, inValue, sqlType); } } else if (sqlType == Types.DATE) { if (inValue instanceof java.util.Date) { if (inValue instanceof java.sql.Date) { ps.setDate(paramIndex, (java.sql.Date) inValue); } else { ps.setDate(paramIndex, new java.sql.Date(((java.util.Date) inValue).getTime())); } } else if (inValue instanceof Calendar) { Calendar cal = (Calendar) inValue; ps.setDate(paramIndex, new java.sql.Date(cal.getTime().getTime()), cal); } else { ps.setObject(paramIndex, inValue, Types.DATE); } } else if (sqlType == Types.TIME) { if (inValue instanceof java.util.Date) { if (inValue instanceof java.sql.Time) { ps.setTime(paramIndex, (java.sql.Time) inValue); } else { ps.setTime(paramIndex, new java.sql.Time(((java.util.Date) inValue).getTime())); } } else if (inValue instanceof Calendar) { Calendar cal = (Calendar) inValue; ps.setTime(paramIndex, new java.sql.Time(cal.getTime().getTime()), cal); } else { ps.setObject(paramIndex, inValue, Types.TIME); } } else if (sqlType == Types.TIMESTAMP) { if (inValue instanceof java.util.Date) { if (inValue instanceof java.sql.Timestamp) { ps.setTimestamp(paramIndex, (java.sql.Timestamp) inValue); } else { ps.setTimestamp(paramIndex, new java.sql.Timestamp(((java.util.Date) inValue).getTime())); } } else if (inValue instanceof Calendar) { Calendar cal = (Calendar) inValue; ps.setTimestamp(paramIndex, new java.sql.Timestamp(cal.getTime().getTime()), cal); } else { ps.setObject(paramIndex, inValue, Types.TIMESTAMP); } } else if (sqlType == SqlTypeValue.TYPE_UNKNOWN) { if (isStringValue(inValue.getClass())) { ps.setString(paramIndex, inValue.toString()); } else if (isDateValue(inValue.getClass())) { ps.setTimestamp(paramIndex, new java.sql.Timestamp(((java.util.Date) inValue).getTime())); } else if (inValue instanceof Calendar) { Calendar cal = (Calendar) inValue; ps.setTimestamp(paramIndex, new java.sql.Timestamp(cal.getTime().getTime()), cal); } else { // Fall back to generic setObject call without SQL type specified. ps.setObject(paramIndex, inValue); } } else { // Fall back to generic setObject call with SQL type specified. ps.setObject(paramIndex, inValue, sqlType); } } /** * Check whether the given value can be treated as a String value. */ private static boolean isStringValue(Class inValueType) { // Consider any CharSequence (including StringBuffer and StringBuilder) as a String. return (CharSequence.class.isAssignableFrom(inValueType) || StringWriter.class.isAssignableFrom(inValueType)); } /** * Check whether the given value is a java.util.Date * (but not one of the JDBC-specific subclasses). */ private static boolean isDateValue(Class inValueType) { return (java.util.Date.class.isAssignableFrom(inValueType) && !(java.sql.Date.class.isAssignableFrom(inValueType) || java.sql.Time.class.isAssignableFrom(inValueType) || java.sql.Timestamp.class.isAssignableFrom(inValueType))); } /** * Clean up all resources held by parameter values which were passed to an * execute method. This is for example important for closing LOB values. * @param paramValues parameter values supplied. May be null. * @see DisposableSqlTypeValue#cleanup() * @see org.springframework.jdbc.core.support.SqlLobValue#cleanup() */ public static void cleanupParameters(Object[] paramValues) { if (paramValues != null) { cleanupParameters(Arrays.asList(paramValues)); } } /** * Clean up all resources held by parameter values which were passed to an * execute method. This is for example important for closing LOB values. * @param paramValues parameter values supplied. May be null. * @see DisposableSqlTypeValue#cleanup() * @see org.springframework.jdbc.core.support.SqlLobValue#cleanup() */ public static void cleanupParameters(Collection paramValues) { if (paramValues != null) { for (Object inValue : paramValues) { if (inValue instanceof DisposableSqlTypeValue) { ((DisposableSqlTypeValue) inValue).cleanup(); } else if (inValue instanceof SqlValue) { ((SqlValue) inValue).cleanup(); } } } } } ././@LongLink0000000000000000000000000000020600000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/BeanPropertyRowMapper.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000002712411623223530033273 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; import java.beans.PropertyDescriptor; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanWrapper; import org.springframework.beans.NotWritablePropertyException; import org.springframework.beans.PropertyAccessorFactory; import org.springframework.beans.TypeMismatchException; import org.springframework.dao.DataRetrievalFailureException; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.jdbc.support.JdbcUtils; import org.springframework.util.Assert; /** * {@link RowMapper} implementation that converts a row into a new instance * of the specified mapped target class. The mapped target class must be a * top-level class and it must have a default or no-arg constructor. * *

Column values are mapped based on matching the column name as obtained from result set * metadata to public setters for the corresponding properties. The names are matched either * directly or by transforming a name separating the parts with underscores to the same name * using "camel" case. * *

Mapping is provided for fields in the target class for many common types, e.g.: * String, boolean, Boolean, byte, Byte, short, Short, int, Integer, long, Long, * float, Float, double, Double, BigDecimal, java.util.Date, etc. * *

To facilitate mapping between columns and fields that don't have matching names, * try using column aliases in the SQL statement like "select fname as first_name from customer". * *

For 'null' values read from the databasem, we will attempt to call the setter, but in the case of * Java primitives, this causes a TypeMismatchException. This class can be configured (using the * primitivesDefaultedForNullValue property) to trap this exception and use the primitives default value. * Be aware that if you use the values from the generated bean to update the database the primitive value * will have been set to the primitive's default value instead of null. * *

Please note that this class is designed to provide convenience rather than high performance. * For best performance consider using a custom RowMapper. * * @author Thomas Risberg * @author Juergen Hoeller * @since 2.5 */ public class BeanPropertyRowMapper implements RowMapper { /** Logger available to subclasses */ protected final Log logger = LogFactory.getLog(getClass()); /** The class we are mapping to */ private Class mappedClass; /** Whether we're strictly validating */ private boolean checkFullyPopulated = false; /** Whether we're defaulting primitives when mapping a null value */ private boolean primitivesDefaultedForNullValue = false; /** Map of the fields we provide mapping for */ private Map mappedFields; /** Set of bean properties we provide mapping for */ private Set mappedProperties; /** * Create a new BeanPropertyRowMapper for bean-style configuration. * @see #setMappedClass * @see #setCheckFullyPopulated */ public BeanPropertyRowMapper() { } /** * Create a new BeanPropertyRowMapper, accepting unpopulated properties * in the target bean. *

Consider using the {@link #newInstance} factory method instead, * which allows for specifying the mapped type once only. * @param mappedClass the class that each row should be mapped to */ public BeanPropertyRowMapper(Class mappedClass) { initialize(mappedClass); } /** * Create a new BeanPropertyRowMapper. * @param mappedClass the class that each row should be mapped to * @param checkFullyPopulated whether we're strictly validating that * all bean properties have been mapped from corresponding database fields */ public BeanPropertyRowMapper(Class mappedClass, boolean checkFullyPopulated) { initialize(mappedClass); this.checkFullyPopulated = checkFullyPopulated; } /** * Set the class that each row should be mapped to. */ public void setMappedClass(Class mappedClass) { if (this.mappedClass == null) { initialize(mappedClass); } else { if (!this.mappedClass.equals(mappedClass)) { throw new InvalidDataAccessApiUsageException("The mapped class can not be reassigned to map to " + mappedClass + " since it is already providing mapping for " + this.mappedClass); } } } /** * Initialize the mapping metadata for the given class. * @param mappedClass the mapped class. */ protected void initialize(Class mappedClass) { this.mappedClass = mappedClass; this.mappedFields = new HashMap(); this.mappedProperties = new HashSet(); PropertyDescriptor[] pds = BeanUtils.getPropertyDescriptors(mappedClass); for (PropertyDescriptor pd : pds) { if (pd.getWriteMethod() != null) { this.mappedFields.put(pd.getName().toLowerCase(), pd); String underscoredName = underscoreName(pd.getName()); if (!pd.getName().toLowerCase().equals(underscoredName)) { this.mappedFields.put(underscoredName, pd); } this.mappedProperties.add(pd.getName()); } } } /** * Convert a name in camelCase to an underscored name in lower case. * Any upper case letters are converted to lower case with a preceding underscore. * @param name the string containing original name * @return the converted name */ private String underscoreName(String name) { StringBuilder result = new StringBuilder(); if (name != null && name.length() > 0) { result.append(name.substring(0, 1).toLowerCase()); for (int i = 1; i < name.length(); i++) { String s = name.substring(i, i + 1); if (s.equals(s.toUpperCase())) { result.append("_"); result.append(s.toLowerCase()); } else { result.append(s); } } } return result.toString(); } /** * Get the class that we are mapping to. */ public final Class getMappedClass() { return this.mappedClass; } /** * Set whether we're strictly validating that all bean properties have been * mapped from corresponding database fields. *

Default is false, accepting unpopulated properties in the * target bean. */ public void setCheckFullyPopulated(boolean checkFullyPopulated) { this.checkFullyPopulated = checkFullyPopulated; } /** * Return whether we're strictly validating that all bean properties have been * mapped from corresponding database fields. */ public boolean isCheckFullyPopulated() { return this.checkFullyPopulated; } /** * Set whether we're defaulting Java primitives in the case of mapping a null value * from corresponding database fields. *

Default is false, throwing an exception when nulls are mapped to Java primitives. */ public void setPrimitivesDefaultedForNullValue(boolean primitivesDefaultedForNullValue) { this.primitivesDefaultedForNullValue = primitivesDefaultedForNullValue; } /** * Return whether we're defaulting Java primitives in the case of mapping a null value * from corresponding database fields. */ public boolean isPrimitivesDefaultedForNullValue() { return primitivesDefaultedForNullValue; } /** * Extract the values for all columns in the current row. *

Utilizes public setters and result set metadata. * @see java.sql.ResultSetMetaData */ public T mapRow(ResultSet rs, int rowNumber) throws SQLException { Assert.state(this.mappedClass != null, "Mapped class was not specified"); T mappedObject = BeanUtils.instantiate(this.mappedClass); BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(mappedObject); initBeanWrapper(bw); ResultSetMetaData rsmd = rs.getMetaData(); int columnCount = rsmd.getColumnCount(); Set populatedProperties = (isCheckFullyPopulated() ? new HashSet() : null); for (int index = 1; index <= columnCount; index++) { String column = JdbcUtils.lookupColumnName(rsmd, index); PropertyDescriptor pd = this.mappedFields.get(column.replaceAll(" ", "").toLowerCase()); if (pd != null) { try { Object value = getColumnValue(rs, index, pd); if (logger.isDebugEnabled() && rowNumber == 0) { logger.debug("Mapping column '" + column + "' to property '" + pd.getName() + "' of type " + pd.getPropertyType()); } try { bw.setPropertyValue(pd.getName(), value); } catch (TypeMismatchException e) { if (value == null && primitivesDefaultedForNullValue) { logger.debug("Intercepted TypeMismatchException for row " + rowNumber + " and column '" + column + "' with value " + value + " when setting property '" + pd.getName() + "' of type " + pd.getPropertyType() + " on object: " + mappedObject); } else { throw e; } } if (populatedProperties != null) { populatedProperties.add(pd.getName()); } } catch (NotWritablePropertyException ex) { throw new DataRetrievalFailureException( "Unable to map column " + column + " to property " + pd.getName(), ex); } } } if (populatedProperties != null && !populatedProperties.equals(this.mappedProperties)) { throw new InvalidDataAccessApiUsageException("Given ResultSet does not contain all fields " + "necessary to populate object of class [" + this.mappedClass + "]: " + this.mappedProperties); } return mappedObject; } /** * Initialize the given BeanWrapper to be used for row mapping. * To be called for each row. *

The default implementation is empty. Can be overridden in subclasses. * @param bw the BeanWrapper to initialize */ protected void initBeanWrapper(BeanWrapper bw) { } /** * Retrieve a JDBC object value for the specified column. *

The default implementation calls * {@link JdbcUtils#getResultSetValue(java.sql.ResultSet, int, Class)}. * Subclasses may override this to check specific value types upfront, * or to post-process values return from getResultSetValue. * @param rs is the ResultSet holding the data * @param index is the column index * @param pd the bean property that each result object is expected to match * (or null if none specified) * @return the Object value * @throws SQLException in case of extraction failure * @see org.springframework.jdbc.support.JdbcUtils#getResultSetValue(java.sql.ResultSet, int, Class) */ protected Object getColumnValue(ResultSet rs, int index, PropertyDescriptor pd) throws SQLException { return JdbcUtils.getResultSetValue(rs, index, pd.getPropertyType()); } /** * Static factory method to create a new BeanPropertyRowMapper * (with the mapped class specified only once). * @param mappedClass the class that each row should be mapped to */ public static BeanPropertyRowMapper newInstance(Class mappedClass) { BeanPropertyRowMapper newInstance = new BeanPropertyRowMapper(); newInstance.setMappedClass(mappedClass); return newInstance; } } ././@LongLink0000000000000000000000000000020300000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/ResultSetExtractor.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000500711623223530033267 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; import java.sql.ResultSet; import java.sql.SQLException; import org.springframework.dao.DataAccessException; /** * Callback interface used by {@link JdbcTemplate}'s query methods. * Implementations of this interface perform the actual work of extracting * results from a {@link java.sql.ResultSet}, but don't need to worry * about exception handling. {@link java.sql.SQLException SQLExceptions} * will be caught and handled by the calling JdbcTemplate. * *

This interface is mainly used within the JDBC framework itself. * A {@link RowMapper} is usually a simpler choice for ResultSet processing, * mapping one result object per row instead of one result object for * the entire ResultSet. * *

Note: In contrast to a {@link RowCallbackHandler}, a ResultSetExtractor * object is typically stateless and thus reusable, as long as it doesn't * access stateful resources (such as output streams when streaming LOB * contents) or keep result state within the object. * * @author Rod Johnson * @author Juergen Hoeller * @since April 24, 2003 * @see JdbcTemplate * @see RowCallbackHandler * @see RowMapper * @see org.springframework.jdbc.core.support.AbstractLobStreamingResultSetExtractor */ public interface ResultSetExtractor { /** * Implementations must implement this method to process the entire ResultSet. * @param rs ResultSet to extract data from. Implementations should * not close this: it will be closed by the calling JdbcTemplate. * @return an arbitrary result object, or null if none * (the extractor will typically be stateful in the latter case). * @throws SQLException if a SQLException is encountered getting column * values or navigating (that is, there's no need to catch SQLException) * @throws DataAccessException in case of custom exceptions */ T extractData(ResultSet rs) throws SQLException, DataAccessException; } ././@LongLink0000000000000000000000000000016500000000000011567 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000755000175000017500000000000011623223530033263 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000021600000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataContext.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000002670711623223530033301 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.metadata; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import javax.sql.DataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.jdbc.core.SqlTypeValue; import org.springframework.jdbc.core.namedparam.SqlParameterSource; import org.springframework.jdbc.core.namedparam.SqlParameterSourceUtils; import org.springframework.jdbc.support.JdbcUtils; import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor; /** * Class to manage context metadata used for the configuration * and execution of operations on a database table. * * @author Thomas Risberg * @since 2.5 */ public class TableMetaDataContext { /** Logger available to subclasses */ protected final Log logger = LogFactory.getLog(getClass()); /** name of procedure to call **/ private String tableName; /** name of catalog for call **/ private String catalogName; /** name of schema for call **/ private String schemaName; /** List of columns objects to be used in this context */ private List tableColumns = new ArrayList(); /** should we access insert parameter meta data info or not */ private boolean accessTableColumnMetaData = true; /** should we override default for including synonyms for meta data lookups */ private boolean overrideIncludeSynonymsDefault = false; /** the provider of table meta data */ private TableMetaDataProvider metaDataProvider; /** are we using generated key columns */ private boolean generatedKeyColumnsUsed = false; /** NativeJdbcExtractor to be used to retrieve the native connection */ NativeJdbcExtractor nativeJdbcExtractor; /** * Set the name of the table for this context. */ public void setTableName(String tableName) { this.tableName = tableName; } /** * Get the name of the table for this context. */ public String getTableName() { return this.tableName; } /** * Set the name of the catalog for this context. */ public void setCatalogName(String catalogName) { this.catalogName = catalogName; } /** * Get the name of the catalog for this context. */ public String getCatalogName() { return this.catalogName; } /** * Set the name of the schema for this context. */ public void setSchemaName(String schemaName) { this.schemaName = schemaName; } /** * Get the name of the schema for this context. */ public String getSchemaName() { return this.schemaName; } /** * Specify whether we should access table column meta data. */ public void setAccessTableColumnMetaData(boolean accessTableColumnMetaData) { this.accessTableColumnMetaData = accessTableColumnMetaData; } /** * Are we accessing table meta data? */ public boolean isAccessTableColumnMetaData() { return this.accessTableColumnMetaData; } /** * Specify whether we should override default for accessing synonyms. */ public void setOverrideIncludeSynonymsDefault(boolean override) { this.overrideIncludeSynonymsDefault = override; } /** * Are we overriding include synonyms default? */ public boolean isOverrideIncludeSynonymsDefault() { return this.overrideIncludeSynonymsDefault; } /** * Get a List of the table column names. */ public List getTableColumns() { return this.tableColumns; } /** * Does this database support the JDBC 3.0 feature of retrieving generated keys * {@link java.sql.DatabaseMetaData#supportsGetGeneratedKeys()}? */ public boolean isGetGeneratedKeysSupported() { return this.metaDataProvider.isGetGeneratedKeysSupported(); } /** * Does this database support simple query to retrieve generated keys * when the JDBC 3.0 feature is not supported. * {@link java.sql.DatabaseMetaData#supportsGetGeneratedKeys()}? */ public boolean isGetGeneratedKeysSimulated() { return this.metaDataProvider.isGetGeneratedKeysSimulated(); } /** * Does this database support simple query to retrieve generated keys * when the JDBC 3.0 feature is not supported. * {@link java.sql.DatabaseMetaData#supportsGetGeneratedKeys()}? */ public String getSimulationQueryForGetGeneratedKey(String tableName, String keyColumnName) { return this.metaDataProvider.getSimpleQueryForGetGeneratedKey(tableName, keyColumnName); } /** * Is a column name String array for retrieving generated keys supported? * {@link java.sql.Connection#createStruct(String, Object[])}? */ public boolean isGeneratedKeysColumnNameArraySupported() { return this.metaDataProvider.isGeneratedKeysColumnNameArraySupported(); } /** * Set {@link NativeJdbcExtractor} to be used to retrieve the native connection. */ public void setNativeJdbcExtractor(NativeJdbcExtractor nativeJdbcExtractor) { this.nativeJdbcExtractor = nativeJdbcExtractor; } /** * Process the current meta data with the provided configuration options. * @param dataSource the DataSource being used * @param declaredColumns any columns that are declared * @param generatedKeyNames name of generated keys */ public void processMetaData(DataSource dataSource, List declaredColumns, String[] generatedKeyNames) { this.metaDataProvider = TableMetaDataProviderFactory.createMetaDataProvider(dataSource, this, this.nativeJdbcExtractor); this.tableColumns = reconcileColumnsToUse(declaredColumns, generatedKeyNames); } /** * Compare columns created from metadata with declared columns and return a reconciled list. * @param declaredColumns declared column names * @param generatedKeyNames names of generated key columns */ protected List reconcileColumnsToUse(List declaredColumns, String[] generatedKeyNames) { if (generatedKeyNames.length > 0) { this.generatedKeyColumnsUsed = true; } if (declaredColumns.size() > 0) { return new ArrayList(declaredColumns); } Set keys = new HashSet(generatedKeyNames.length); for (String key : generatedKeyNames) { keys.add(key.toUpperCase()); } List columns = new ArrayList(); for (TableParameterMetaData meta : metaDataProvider.getTableParameterMetaData()) { if (!keys.contains(meta.getParameterName().toUpperCase())) { columns.add(meta.getParameterName()); } } return columns; } /** * Match the provided column names and values with the list of columns used. * @param parameterSource the parameter names and values */ public List matchInParameterValuesWithInsertColumns(SqlParameterSource parameterSource) { List values = new ArrayList(); // for parameter source lookups we need to provide caseinsensitive lookup support since the // database metadata is not necessarily providing case sensitive column names Map caseInsensitiveParameterNames = SqlParameterSourceUtils.extractCaseInsensitiveParameterNames(parameterSource); for (String column : this.tableColumns) { if (parameterSource.hasValue(column)) { values.add(SqlParameterSourceUtils.getTypedValue(parameterSource, column)); } else { String lowerCaseName = column.toLowerCase(); if (parameterSource.hasValue(lowerCaseName)) { values.add(SqlParameterSourceUtils.getTypedValue(parameterSource, lowerCaseName)); } else { String propertyName = JdbcUtils.convertUnderscoreNameToPropertyName(column); if (parameterSource.hasValue(propertyName)) { values.add(SqlParameterSourceUtils.getTypedValue(parameterSource, propertyName)); } else { if (caseInsensitiveParameterNames.containsKey(lowerCaseName)) { values.add( SqlParameterSourceUtils.getTypedValue(parameterSource, (String) caseInsensitiveParameterNames.get(lowerCaseName))); } else { values.add(null); } } } } } return values; } /** * Match the provided column names and values with the list of columns used. * @param inParameters the parameter names and values */ public List matchInParameterValuesWithInsertColumns(Map inParameters) { List values = new ArrayList(); Map source = new HashMap(); for (String key : inParameters.keySet()) { source.put(key.toLowerCase(), inParameters.get(key)); } for (String column : this.tableColumns) { values.add(source.get(column.toLowerCase())); } return values; } /** * Build the insert string based on configuration and metadata information * @return the insert string to be used */ public String createInsertString(String[] generatedKeyNames) { HashSet keys = new HashSet(generatedKeyNames.length); for (String key : generatedKeyNames) { keys.add(key.toUpperCase()); } StringBuilder insertStatement = new StringBuilder(); insertStatement.append("INSERT INTO "); if (this.getSchemaName() != null) { insertStatement.append(this.getSchemaName()); insertStatement.append("."); } insertStatement.append(this.getTableName()); insertStatement.append(" ("); int columnCount = 0; for (String columnName : this.getTableColumns()) { if (!keys.contains(columnName.toUpperCase())) { columnCount++; if (columnCount > 1) { insertStatement.append(", "); } insertStatement.append(columnName); } } insertStatement.append(") VALUES("); if (columnCount < 1) { if (this.generatedKeyColumnsUsed) { logger.info("Unable to locate non-key columns for table '" + this.getTableName() + "' so an empty insert statement is generated"); } else { throw new InvalidDataAccessApiUsageException("Unable to locate columns for table '" + this.getTableName() + "' so an insert statement can't be generated"); } } for (int i = 0; i < columnCount; i++) { if (i > 0) { insertStatement.append(", "); } insertStatement.append("?"); } insertStatement.append(")"); return insertStatement.toString(); } /** * Build the array of {@link java.sql.Types} based on configuration and metadata information * @return the array of types to be used */ public int[] createInsertTypes() { int[] types = new int[this.getTableColumns().size()]; List parameters = this.metaDataProvider.getTableParameterMetaData(); Map parameterMap = new HashMap(parameters.size()); for (TableParameterMetaData tpmd : parameters) { parameterMap.put(tpmd.getParameterName().toUpperCase(), tpmd); } int typeIndx = 0; for (String column : this.getTableColumns()) { if (column == null) { types[typeIndx] = SqlTypeValue.TYPE_UNKNOWN; } else { TableParameterMetaData tpmd = parameterMap.get(column.toUpperCase()); if (tpmd != null) { types[typeIndx] = tpmd.getSqlType(); } else { types[typeIndx] = SqlTypeValue.TYPE_UNKNOWN; } } typeIndx++; } return types; } } ././@LongLink0000000000000000000000000000020600000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/package-info.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000024011623223530033261 0ustar drazzibdrazzib /** * * Context metadata abstraction for the configuration and execution of a stored procedure call. * */ package org.springframework.jdbc.core.metadata; ././@LongLink0000000000000000000000000000022300000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/DerbyCallMetaDataProvider.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000270711623223530033273 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.metadata; import java.sql.DatabaseMetaData; import java.sql.SQLException; /** * Derby specific implementation for the {@link CallMetaDataProvider} interface. * This class is intended for internal use by the Simple JDBC classes. * * @author Thomas Risberg * @author Juergen Hoeller * @since 2.5 */ public class DerbyCallMetaDataProvider extends GenericCallMetaDataProvider { public DerbyCallMetaDataProvider(DatabaseMetaData databaseMetaData) throws SQLException { super(databaseMetaData); } @Override public String metaDataSchemaNameToUse(String schemaName) { if (schemaName != null) { return super.metaDataSchemaNameToUse(schemaName); } // Use current user schema if no schema specified... String userName = getUserName(); return (userName != null ? userName.toUpperCase() : null); } } ././@LongLink0000000000000000000000000000022500000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericCallMetaDataProvider.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000002565011623223526033302 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.metadata; import java.sql.DatabaseMetaData; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; import java.util.ArrayList; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.jdbc.core.SqlInOutParameter; import org.springframework.jdbc.core.SqlOutParameter; import org.springframework.jdbc.core.SqlParameter; import org.springframework.util.StringUtils; /** * Generic implementation for the {@link CallMetaDataProvider} interface. * This class can be extended to provide database specific behavior. * * @author Thomas Risberg * @since 2.5 */ public class GenericCallMetaDataProvider implements CallMetaDataProvider { /** Logger available to subclasses */ protected static final Log logger = LogFactory.getLog(CallMetaDataProvider.class); private boolean procedureColumnMetaDataUsed = false; private String userName; private boolean supportsCatalogsInProcedureCalls = true; private boolean supportsSchemasInProcedureCalls = true; private boolean storesUpperCaseIdentifiers = true; private boolean storesLowerCaseIdentifiers = false; private List callParameterMetaData = new ArrayList(); /** * Constructor used to initialize with provided database meta data. * @param databaseMetaData meta data to be used */ protected GenericCallMetaDataProvider(DatabaseMetaData databaseMetaData) throws SQLException { this.userName = databaseMetaData.getUserName(); } public void initializeWithMetaData(DatabaseMetaData databaseMetaData) throws SQLException { try { setSupportsCatalogsInProcedureCalls(databaseMetaData.supportsCatalogsInProcedureCalls()); } catch (SQLException se) { logger.warn("Error retrieving 'DatabaseMetaData.supportsCatalogsInProcedureCalls' - " + se.getMessage()); } try { setSupportsSchemasInProcedureCalls(databaseMetaData.supportsSchemasInProcedureCalls()); } catch (SQLException se) { logger.warn("Error retrieving 'DatabaseMetaData.supportsSchemasInProcedureCalls' - " + se.getMessage()); } try { setStoresUpperCaseIdentifiers(databaseMetaData.storesUpperCaseIdentifiers()); } catch (SQLException se) { logger.warn("Error retrieving 'DatabaseMetaData.storesUpperCaseIdentifiers' - " + se.getMessage()); } try { setStoresLowerCaseIdentifiers(databaseMetaData.storesLowerCaseIdentifiers()); } catch (SQLException se) { logger.warn("Error retrieving 'DatabaseMetaData.storesLowerCaseIdentifiers' - " + se.getMessage()); } } public void initializeWithProcedureColumnMetaData(DatabaseMetaData databaseMetaData, String catalogName, String schemaName, String procedureName) throws SQLException { this.procedureColumnMetaDataUsed = true; processProcedureColumns(databaseMetaData, catalogName, schemaName, procedureName); } public List getCallParameterMetaData() { return callParameterMetaData; } public String procedureNameToUse(String procedureName) { if (procedureName == null) return null; else if (isStoresUpperCaseIdentifiers()) return procedureName.toUpperCase(); else if(isStoresLowerCaseIdentifiers()) return procedureName.toLowerCase(); else return procedureName; } public String catalogNameToUse(String catalogName) { if (catalogName == null) return null; else if (isStoresUpperCaseIdentifiers()) return catalogName.toUpperCase(); else if(isStoresLowerCaseIdentifiers()) return catalogName.toLowerCase(); else return catalogName; } public String schemaNameToUse(String schemaName) { if (schemaName == null) return null; else if (isStoresUpperCaseIdentifiers()) return schemaName.toUpperCase(); else if(isStoresLowerCaseIdentifiers()) return schemaName.toLowerCase(); else return schemaName; } public String metaDataCatalogNameToUse(String catalogName) { if (isSupportsCatalogsInProcedureCalls()) { return catalogNameToUse(catalogName); } else { return null; } } public String metaDataSchemaNameToUse(String schemaName) { if (isSupportsSchemasInProcedureCalls()) { return schemaNameToUse(schemaName); } else { return null; } } public String parameterNameToUse(String parameterName) { if (parameterName == null) { return null; } else if (isStoresUpperCaseIdentifiers()) { return parameterName.toUpperCase(); } else if(isStoresLowerCaseIdentifiers()) { return parameterName.toLowerCase(); } else { return parameterName; } } public boolean byPassReturnParameter(String parameterName) { return false; } public SqlParameter createDefaultOutParameter(String parameterName, CallParameterMetaData meta) { return new SqlOutParameter(parameterName, meta.getSqlType()); } public SqlParameter createDefaultInOutParameter(String parameterName, CallParameterMetaData meta) { return new SqlInOutParameter(parameterName, meta.getSqlType()); } public SqlParameter createDefaultInParameter(String parameterName, CallParameterMetaData meta) { return new SqlParameter(parameterName, meta.getSqlType()); } public String getUserName() { return this.userName; } public boolean isReturnResultSetSupported() { return true; } public boolean isRefCursorSupported() { return false; } public int getRefCursorSqlType() { return Types.OTHER; } public boolean isProcedureColumnMetaDataUsed() { return this.procedureColumnMetaDataUsed; } /** * Specify whether the database supports the use of catalog name in procedure calls */ protected void setSupportsCatalogsInProcedureCalls(boolean supportsCatalogsInProcedureCalls) { this.supportsCatalogsInProcedureCalls = supportsCatalogsInProcedureCalls; } /** * Does the database support the use of catalog name in procedure calls */ public boolean isSupportsCatalogsInProcedureCalls() { return this.supportsCatalogsInProcedureCalls; } /** * Specify whether the database supports the use of schema name in procedure calls */ protected void setSupportsSchemasInProcedureCalls(boolean supportsSchemasInProcedureCalls) { this.supportsSchemasInProcedureCalls = supportsSchemasInProcedureCalls; } /** * Does the database support the use of schema name in procedure calls */ public boolean isSupportsSchemasInProcedureCalls() { return this.supportsSchemasInProcedureCalls; } /** * Specify whether the database uses upper case for identifiers */ protected void setStoresUpperCaseIdentifiers(boolean storesUpperCaseIdentifiers) { this.storesUpperCaseIdentifiers = storesUpperCaseIdentifiers; } /** * Does the database use upper case for identifiers */ protected boolean isStoresUpperCaseIdentifiers() { return this.storesUpperCaseIdentifiers; } /** * Specify whether the database uses lower case for identifiers */ protected void setStoresLowerCaseIdentifiers(boolean storesLowerCaseIdentifiers) { this.storesLowerCaseIdentifiers = storesLowerCaseIdentifiers; } /** * Does the database use lower case for identifiers */ protected boolean isStoresLowerCaseIdentifiers() { return this.storesLowerCaseIdentifiers; } /** * Process the procedure column metadata */ private void processProcedureColumns(DatabaseMetaData databaseMetaData, String catalogName, String schemaName, String procedureName) { ResultSet procs = null; String metaDataCatalogName = metaDataCatalogNameToUse(catalogName); String metaDataSchemaName = metaDataSchemaNameToUse(schemaName); String metaDataProcedureName = procedureNameToUse(procedureName); if (logger.isDebugEnabled()) { logger.debug("Retrieving metadata for " + metaDataCatalogName + "/" + metaDataSchemaName + "/" + metaDataProcedureName); } try { procs = databaseMetaData.getProcedures(metaDataCatalogName, metaDataSchemaName, metaDataProcedureName); List found = new ArrayList(); while (procs.next()) { found.add(procs.getString("PROCEDURE_CAT") + "." + procs.getString("PROCEDURE_SCHEM") + "." + procs.getString("PROCEDURE_NAME")); } procs.close(); if (found.size() > 1) { throw new InvalidDataAccessApiUsageException("Unable to determine the correct call signature - " + "multiple procedures/functions/signatures for " + metaDataProcedureName + " found " + found); } if (found.size() < 1) { if (metaDataProcedureName.contains(".") && !StringUtils.hasText(metaDataCatalogName)) { String packageName = metaDataProcedureName.substring(0, metaDataProcedureName.indexOf(".")); throw new InvalidDataAccessApiUsageException("Unable to determine the correct call signature for " + metaDataProcedureName + " - package name should be specified separately using " + "'.withCatalogName(\"" + packageName + "\")'"); } } procs = databaseMetaData.getProcedureColumns( metaDataCatalogName, metaDataSchemaName, metaDataProcedureName, null); while (procs.next()) { String columnName = procs.getString("COLUMN_NAME"); int columnType = procs.getInt("COLUMN_TYPE"); if (columnName == null && ( columnType == DatabaseMetaData.procedureColumnIn || columnType == DatabaseMetaData.procedureColumnInOut || columnType == DatabaseMetaData.procedureColumnOut)) { if (logger.isDebugEnabled()) { logger.debug("Skipping metadata for: " + columnName + " " + columnType + " " + procs.getInt("DATA_TYPE") + " " + procs.getString("TYPE_NAME") + " " + procs.getBoolean("NULLABLE") + " (probably a member of a collection)" ); } } else { CallParameterMetaData meta = new CallParameterMetaData(columnName, columnType, procs.getInt("DATA_TYPE"), procs.getString("TYPE_NAME"), procs.getBoolean("NULLABLE") ); callParameterMetaData.add(meta); if (logger.isDebugEnabled()) { logger.debug("Retrieved metadata: " + meta.getParameterName() + " " + meta.getParameterType() + " " + meta.getSqlType() + " " + meta.getTypeName() + " " + meta.isNullable() ); } } } } catch (SQLException ex) { logger.warn("Error while retrieving metadata for procedure columns: " + ex); } finally { try { if (procs != null) { procs.close(); } } catch (SQLException ex) { logger.warn("Problem closing ResultSet for procedure column metadata: " + ex); } } } } ././@LongLink0000000000000000000000000000021600000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataProvider.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001432411623223526033276 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.metadata; import java.sql.DatabaseMetaData; import java.sql.SQLException; import java.util.List; import org.springframework.jdbc.core.SqlParameter; /** * Interface specifying the API to be implemented by a class providing call metadata. * This is intended for internal use by Spring's * {@link org.springframework.jdbc.core.simple.SimpleJdbcTemplate}. * * @author Thomas Risberg * @since 2.5 */ public interface CallMetaDataProvider { /** * Initialize using the provided DatabaseMetData. * @param databaseMetaData used to retrieve database specific information * @throws SQLException in case of initialization failure */ void initializeWithMetaData(DatabaseMetaData databaseMetaData) throws SQLException; /** * Initialize the database specific management of procedure column meta data. * This is only called for databases that are supported. This initalization * can be turned off by specifying that column meta data should not be used. * @param databaseMetaData used to retrieve database specific information * @param catalogName name of catalog to use or null * @param schemaName name of schema name to use or null * @param procedureName name of the stored procedure * @throws SQLException in case of initialization failure * @see org.springframework.jdbc.core.simple.SimpleJdbcCall#withoutProcedureColumnMetaDataAccess() */ void initializeWithProcedureColumnMetaData( DatabaseMetaData databaseMetaData, String catalogName, String schemaName, String procedureName) throws SQLException; /** * Provide any modification of the procedure name passed in to match the meta data currently used. * This could include alterig the case. */ String procedureNameToUse(String procedureName); /** * Provide any modification of the catalog name passed in to match the meta data currently used. * This could include alterig the case. */ String catalogNameToUse(String catalogName); /** * Provide any modification of the schema name passed in to match the meta data currently used. * This could include alterig the case. */ String schemaNameToUse(String schemaName); /** * Provide any modification of the catalog name passed in to match the meta data currently used. * The reyurned value will be used for meta data lookups. This could include alterig the case used * or providing a base catalog if mone provided. */ String metaDataCatalogNameToUse(String catalogName) ; /** * Provide any modification of the schema name passed in to match the meta data currently used. * The reyurned value will be used for meta data lookups. This could include alterig the case used * or providing a base schema if mone provided. */ String metaDataSchemaNameToUse(String schemaName) ; /** * Provide any modification of the column name passed in to match the meta data currently used. * This could include altering the case. * @param parameterName name of the parameter of column */ String parameterNameToUse(String parameterName); /** * Create a default out parameter based on the provided meta data. This is used when no * explicit parameter declaration has been made. * @param parameterName the name of the parameter * @param meta meta data used for this call * @return the configured SqlOutParameter */ SqlParameter createDefaultOutParameter(String parameterName, CallParameterMetaData meta); /** * Create a default inout parameter based on the provided meta data. This is used when no * explicit parameter declaration has been made. * @param parameterName the name of the parameter * @param meta meta data used for this call * @return the configured SqlInOutParameter */ SqlParameter createDefaultInOutParameter(String parameterName, CallParameterMetaData meta); /** * Create a default in parameter based on the provided meta data. This is used when no * explicit parameter declaration has been made. * @param parameterName the name of the parameter * @param meta meta data used for this call * @return the configured SqlParameter */ SqlParameter createDefaultInParameter(String parameterName, CallParameterMetaData meta); /** * Get the name of the current user. Useful for meta data lookups etc. * @return current user name from database connection */ String getUserName(); /** * Does this database support returning resultsets that should be retrieved with the JDBC call * {@link java.sql.Statement#getResultSet()} */ boolean isReturnResultSetSupported(); /** * Does this database support returning resultsets as ref cursors to be retrieved with * {@link java.sql.CallableStatement#getObject(int)} for the specified column. */ boolean isRefCursorSupported(); /** * Get the {@link java.sql.Types} type for columns that return resultsets as ref cursors if this feature * is supported. */ int getRefCursorSqlType(); /** * Are we using the meta data for the procedure columns? */ boolean isProcedureColumnMetaDataUsed(); /** * Should we bypass the return parameter with the specified name. * This allows the database specific implementation to skip the processing * for specific results returned by the database call. */ boolean byPassReturnParameter(String parameterName); /** * Get the call parameter metadata that is currently used. * @return List of {@link CallParameterMetaData} */ List getCallParameterMetaData(); /** * Does the database support the use of catalog name in procedure calls */ boolean isSupportsCatalogsInProcedureCalls(); /** * Does the database support the use of schema name in procedure calls */ boolean isSupportsSchemasInProcedureCalls(); } ././@LongLink0000000000000000000000000000021500000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataContext.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000005317111623223526033301 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.metadata; import java.sql.DatabaseMetaData; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; import javax.sql.DataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.SqlOutParameter; import org.springframework.jdbc.core.SqlParameter; import org.springframework.jdbc.core.SqlParameterValue; import org.springframework.jdbc.core.SqlReturnResultSet; import org.springframework.jdbc.core.namedparam.SqlParameterSource; import org.springframework.jdbc.core.namedparam.SqlParameterSourceUtils; import org.springframework.jdbc.support.JdbcUtils; import org.springframework.util.StringUtils; /** * Class to manage context metadata used for the configuration and execution of the call. * * @author Thomas Risberg * @author Juergen Hoeller * @since 2.5 */ public class CallMetaDataContext { /** Logger available to subclasses */ protected final Log logger = LogFactory.getLog(getClass()); /** name of procedure to call **/ private String procedureName; /** name of catalog for call **/ private String catalogName; /** name of schema for call **/ private String schemaName; /** List of SqlParameter objects to be used in call execution */ private List callParameters = new ArrayList(); /** Default name to use for the return value in the output map */ private String defaultFunctionReturnName = "return"; /** Actual name to use for the return value in the output map */ private String actualFunctionReturnName = null; /** Set of in parameter names to exclude use for any not listed */ private Set limitedInParameterNames = new HashSet(); /** List of SqlParameter names for out parameters */ private List outParameterNames = new ArrayList(); /** should we access call parameter meta data info or not */ private boolean accessCallParameterMetaData = true; /** indicates whether this is a procedure or a function **/ private boolean function; /** indicates whether this procedure's return value should be included **/ private boolean returnValueRequired; /** the provider of call meta data */ private CallMetaDataProvider metaDataProvider; /** * Specify the name used for the return value of the function. */ public void setFunctionReturnName(String functionReturnName) { this.actualFunctionReturnName = functionReturnName; } /** * Get the name used for the return value of the function. */ public String getFunctionReturnName() { return this.actualFunctionReturnName != null ? this.actualFunctionReturnName : this.defaultFunctionReturnName; } /** * Specify a limited set of in parameters to be used. */ public void setLimitedInParameterNames(Set limitedInParameterNames) { this.limitedInParameterNames = limitedInParameterNames; } /** * Get a limited set of in parameters to be used. */ public Set getLimitedInParameterNames() { return this.limitedInParameterNames; } /** * Specify the names of the out parameters. */ public void setOutParameterNames(List outParameterNames) { this.outParameterNames = outParameterNames; } /** * Get a list of the out parameter names. */ public List getOutParameterNames() { return this.outParameterNames; } /** * Specify the name of the procedure. */ public void setProcedureName(String procedureName) { this.procedureName = procedureName; } /** * Get the name of the procedure. */ public String getProcedureName() { return this.procedureName; } /** * Specify the name of the catalog. */ public void setCatalogName(String catalogName) { this.catalogName = catalogName; } /** * Get the name of the catalog. */ public String getCatalogName() { return this.catalogName; } /** * Secify the name of the schema. */ public void setSchemaName(String schemaName) { this.schemaName = schemaName; } /** * Get the name of the schema. */ public String getSchemaName() { return this.schemaName; } /** * Specify whether this call is a function call. */ public void setFunction(boolean function) { this.function = function; } /** * Check whether this call is a function call. */ public boolean isFunction() { return this.function; } /** * Specify whether a return value is required. */ public void setReturnValueRequired(boolean returnValueRequired) { this.returnValueRequired = returnValueRequired; } /** * Check whether a return value is required. */ public boolean isReturnValueRequired() { return this.returnValueRequired; } /** * Specify whether call parameter metadata should be accessed. */ public void setAccessCallParameterMetaData(boolean accessCallParameterMetaData) { this.accessCallParameterMetaData = accessCallParameterMetaData; } /** * Check whether call parameter metadata should be accessed. */ public boolean isAccessCallParameterMetaData() { return this.accessCallParameterMetaData; } /** * Create a ReturnResultSetParameter/SqlOutParameter depending on the support provided * by the JDBC driver used for the database in use. * @param parameterName the name of the parameter (also used as the name of the List returned in the output) * @param rowMapper a RowMapper implementation used to map the data returned in the result set * @return the appropriate SqlParameter */ public SqlParameter createReturnResultSetParameter(String parameterName, RowMapper rowMapper) { if (this.metaDataProvider.isReturnResultSetSupported()) { return new SqlReturnResultSet(parameterName, rowMapper); } else { if (this.metaDataProvider.isRefCursorSupported()) { return new SqlOutParameter(parameterName, this.metaDataProvider.getRefCursorSqlType(), rowMapper); } else { throw new InvalidDataAccessApiUsageException("Return of a ResultSet from a stored procedure is not supported."); } } } /** * Get the name of the single out parameter for this call. If there are multiple parameters then the name of * the first one is returned. */ public String getScalarOutParameterName() { if (isFunction()) { return getFunctionReturnName(); } else { if (this.outParameterNames.size() > 1) { logger.warn("Accessing single output value when procedure has more than one output parameter"); } return (this.outParameterNames.size() > 0 ? this.outParameterNames.get(0) : null); } } /** * Get the List of SqlParameter objects to be used in call execution */ public List getCallParameters() { return this.callParameters; } /** * Initialize this class with metadata from the database * @param dataSource the DataSource used to retrieve metadata */ public void initializeMetaData(DataSource dataSource) { this.metaDataProvider = CallMetaDataProviderFactory.createMetaDataProvider(dataSource, this); } /** * Process the list of parameters provided and if procedure column metadata is used the * parameters will be matched against the metadata information and any missing ones will * be automatically included * @param parameters the list of parameters to use as a base */ public void processParameters(List parameters) { this.callParameters = reconcileParameters(parameters); } /** * Reconcile the provided parameters with available metadata and add new ones where appropriate */ protected List reconcileParameters(List parameters) { final List declaredReturnParameters = new ArrayList(); final Map declaredParameters = new LinkedHashMap(); boolean returnDeclared = false; List outParameterNames = new ArrayList(); List metaDataParameterNames = new ArrayList(); // get the names of the meta data parameters for (CallParameterMetaData meta : this.metaDataProvider.getCallParameterMetaData()) { if (meta.getParameterType() != DatabaseMetaData.procedureColumnReturn) { metaDataParameterNames.add(meta.getParameterName().toLowerCase()); } } // Separate implicit return parameters from explicit parameters... for (SqlParameter parameter : parameters) { if (parameter.isResultsParameter()) { declaredReturnParameters.add(parameter); } else { String parameterNameToMatch = this.metaDataProvider.parameterNameToUse(parameter.getName()).toLowerCase(); declaredParameters.put(parameterNameToMatch, parameter); if (parameter instanceof SqlOutParameter) { outParameterNames.add(parameter.getName()); if (isFunction() && !metaDataParameterNames.contains(parameterNameToMatch)) { if (!returnDeclared) { if (logger.isDebugEnabled()) { logger.debug("Using declared out parameter '" + parameter.getName() + "' for function return value"); } setFunctionReturnName(parameter.getName()); returnDeclared = true; } } } } } setOutParameterNames(outParameterNames); List workParameters = new ArrayList(); workParameters.addAll(declaredReturnParameters); if (!this.metaDataProvider.isProcedureColumnMetaDataUsed()) { workParameters.addAll(declaredParameters.values()); return workParameters; } Map limitedInParamNamesMap = new HashMap(this.limitedInParameterNames.size()); for (String limitedParameterName : this.limitedInParameterNames) { limitedInParamNamesMap.put( this.metaDataProvider.parameterNameToUse(limitedParameterName).toLowerCase(), limitedParameterName); } for (CallParameterMetaData meta : this.metaDataProvider.getCallParameterMetaData()) { String parNameToCheck = null; if (meta.getParameterName() != null) { parNameToCheck = this.metaDataProvider.parameterNameToUse(meta.getParameterName()).toLowerCase(); } String parNameToUse = this.metaDataProvider.parameterNameToUse(meta.getParameterName()); if (declaredParameters.containsKey(parNameToCheck) || (meta.getParameterType() == DatabaseMetaData.procedureColumnReturn && returnDeclared)) { SqlParameter parameter; if (meta.getParameterType() == DatabaseMetaData.procedureColumnReturn) { parameter = declaredParameters.get(getFunctionReturnName()); if (parameter == null && getOutParameterNames().size() > 0) { parameter = declaredParameters.get(getOutParameterNames().get(0).toLowerCase()); } if (parameter == null) { throw new InvalidDataAccessApiUsageException( "Unable to locate declared parameter for function return value - " + " add a SqlOutParameter with name \"" + getFunctionReturnName() +"\""); } else { setFunctionReturnName(parameter.getName()); } } else { parameter = declaredParameters.get(parNameToCheck); } if (parameter != null) { workParameters.add(parameter); if (logger.isDebugEnabled()) { logger.debug("Using declared parameter for: " + (parNameToUse == null ? getFunctionReturnName() : parNameToUse)); } } } else { if (meta.getParameterType() == DatabaseMetaData.procedureColumnReturn) { if (!isFunction() && !isReturnValueRequired() && this.metaDataProvider.byPassReturnParameter(meta.getParameterName())) { if (logger.isDebugEnabled()) { logger.debug("Bypassing metadata return parameter for: " + meta.getParameterName()); } } else { String returnNameToUse =(StringUtils.hasLength(meta.getParameterName()) ? parNameToUse : getFunctionReturnName()); workParameters.add(new SqlOutParameter(returnNameToUse, meta.getSqlType())); if (isFunction()) { setFunctionReturnName(returnNameToUse); outParameterNames.add(returnNameToUse); } if (logger.isDebugEnabled()) { logger.debug("Added metadata return parameter for: " + returnNameToUse); } } } else { if (meta.getParameterType() == DatabaseMetaData.procedureColumnOut) { workParameters.add(this.metaDataProvider.createDefaultOutParameter(parNameToUse, meta)); outParameterNames.add(parNameToUse); if (logger.isDebugEnabled()) { logger.debug("Added metadata out parameter for: " + parNameToUse); } } else if (meta.getParameterType() == DatabaseMetaData.procedureColumnInOut) { workParameters.add(this.metaDataProvider.createDefaultInOutParameter(parNameToUse, meta)); outParameterNames.add(parNameToUse); if (logger.isDebugEnabled()) { logger.debug("Added metadata in out parameter for: " + parNameToUse); } } else { if (this.limitedInParameterNames.isEmpty() || limitedInParamNamesMap.containsKey(parNameToUse.toLowerCase())) { workParameters.add(this.metaDataProvider.createDefaultInParameter(parNameToUse, meta)); if (logger.isDebugEnabled()) { logger.debug("Added metadata in parameter for: " + parNameToUse); } } else { if (logger.isDebugEnabled()) { logger.debug("Limited set of parameters " + limitedInParamNamesMap.keySet() + " skipped parameter for: " + parNameToUse); } } } } } } return workParameters; } /** * Match input parameter values with the parameters declared to be used in the call. * @param parameterSource the input values * @return a Map containing the matched parameter names with the value taken from the input */ public Map matchInParameterValuesWithCallParameters(SqlParameterSource parameterSource) { // For parameter source lookups we need to provide case-insensitive lookup support // since the database metadata is not necessarily providing case sensitive parameter names. Map caseInsensitiveParameterNames = SqlParameterSourceUtils.extractCaseInsensitiveParameterNames(parameterSource); Map callParameterNames = new HashMap(this.callParameters.size()); Map matchedParameters = new HashMap(this.callParameters.size()); for (SqlParameter parameter : this.callParameters) { if (parameter.isInputValueProvided()) { String parameterName = parameter.getName(); String parameterNameToMatch = this.metaDataProvider.parameterNameToUse(parameterName); if (parameterNameToMatch != null) { callParameterNames.put(parameterNameToMatch.toLowerCase(), parameterName); } if (parameterName != null) { if (parameterSource.hasValue(parameterName)) { matchedParameters.put(parameterName, SqlParameterSourceUtils.getTypedValue(parameterSource, parameterName)); } else { String lowerCaseName = parameterName.toLowerCase(); if (parameterSource.hasValue(lowerCaseName)) { matchedParameters.put(parameterName, SqlParameterSourceUtils.getTypedValue(parameterSource, lowerCaseName)); } else { String englishLowerCaseName = parameterName.toLowerCase(Locale.ENGLISH); if (parameterSource.hasValue(englishLowerCaseName)) { matchedParameters.put(parameterName, SqlParameterSourceUtils.getTypedValue(parameterSource, englishLowerCaseName)); } else { String propertyName = JdbcUtils.convertUnderscoreNameToPropertyName(parameterName); if (parameterSource.hasValue(propertyName)) { matchedParameters.put(parameterName, SqlParameterSourceUtils.getTypedValue(parameterSource, propertyName)); } else { if (caseInsensitiveParameterNames.containsKey(lowerCaseName)) { String sourceName = (String) caseInsensitiveParameterNames.get(lowerCaseName); matchedParameters.put(parameterName, SqlParameterSourceUtils.getTypedValue(parameterSource, sourceName)); } else { logger.warn("Unable to locate the corresponding parameter value for '" + parameterName + "' within the parameter values provided: " + caseInsensitiveParameterNames.values()); } } } } } } } } if (logger.isDebugEnabled()) { logger.debug("Matching " + caseInsensitiveParameterNames.values() + " with " + callParameterNames.values()); logger.debug("Found match for " + matchedParameters.keySet()); } return matchedParameters; } /** * Match input parameter values with the parameters declared to be used in the call. * @param inParameters the input values * @return a Map containing the matched parameter names with the value taken from the input */ public Map matchInParameterValuesWithCallParameters(Map inParameters) { if (!this.metaDataProvider.isProcedureColumnMetaDataUsed()) { return inParameters; } Map callParameterNames = new HashMap(this.callParameters.size()); for (SqlParameter parameter : this.callParameters) { if (parameter.isInputValueProvided()) { String parameterName = parameter.getName(); String parameterNameToMatch = this.metaDataProvider.parameterNameToUse(parameterName); if (parameterNameToMatch != null) { callParameterNames.put(parameterNameToMatch.toLowerCase(), parameterName); } } } Map matchedParameters = new HashMap(inParameters.size()); for (String parameterName : inParameters.keySet()) { String parameterNameToMatch = this.metaDataProvider.parameterNameToUse(parameterName); String callParameterName = callParameterNames.get(parameterNameToMatch.toLowerCase()); if (callParameterName == null) { if (logger.isDebugEnabled()) { Object value = inParameters.get(parameterName); if (value instanceof SqlParameterValue) { value = ((SqlParameterValue)value).getValue(); } if (value != null) { logger.debug("Unable to locate the corresponding IN or IN-OUT parameter for \"" + parameterName + "\" in the parameters used: " + callParameterNames.keySet()); } } } else { matchedParameters.put(callParameterName, inParameters.get(parameterName)); } } if (matchedParameters.size() < callParameterNames.size()) { for (String parameterName : callParameterNames.keySet()) { String parameterNameToMatch = this.metaDataProvider.parameterNameToUse(parameterName); String callParameterName = callParameterNames.get(parameterNameToMatch.toLowerCase()); if (!matchedParameters.containsKey(callParameterName)) { logger.warn("Unable to locate the corresponding parameter value for '" + parameterName + "' within the parameter values provided: " + inParameters.keySet()); } } } if (logger.isDebugEnabled()) { logger.debug("Matching " + inParameters.keySet() + " with " + callParameterNames.values()); logger.debug("Found match for " + matchedParameters.keySet()); } return matchedParameters; } public Map matchInParameterValuesWithCallParameters(Object[] parameterValues) { Map matchedParameters = new HashMap(parameterValues.length); int i = 0; for (SqlParameter parameter : this.callParameters) { if (parameter.isInputValueProvided()) { String parameterName = parameter.getName(); matchedParameters.put(parameterName, parameterValues[i++]); } } return matchedParameters; } /** * Build the call string based on configuration and metadata information. * @return the call string to be used */ public String createCallString() { String callString; int parameterCount = 0; String catalogNameToUse = null; String schemaNameToUse = null; // For Oracle where catalogs are not supported we need to reverse the schema name // and the catalog name since the cataog is used for the package name if (this.metaDataProvider.isSupportsSchemasInProcedureCalls() && !this.metaDataProvider.isSupportsCatalogsInProcedureCalls()) { schemaNameToUse = this.metaDataProvider.catalogNameToUse(this.getCatalogName()); catalogNameToUse = this.metaDataProvider.schemaNameToUse(this.getSchemaName()); } else { catalogNameToUse = this.metaDataProvider.catalogNameToUse(this.getCatalogName()); schemaNameToUse = this.metaDataProvider.schemaNameToUse(this.getSchemaName()); } String procedureNameToUse = this.metaDataProvider.procedureNameToUse(this.getProcedureName()); if (this.isFunction() || this.isReturnValueRequired()) { callString = "{? = call " + (StringUtils.hasLength(catalogNameToUse) ? catalogNameToUse + "." : "") + (StringUtils.hasLength(schemaNameToUse) ? schemaNameToUse + "." : "") + procedureNameToUse + "("; parameterCount = -1; } else { callString = "{call " + (StringUtils.hasLength(catalogNameToUse) ? catalogNameToUse + "." : "") + (StringUtils.hasLength(schemaNameToUse) ? schemaNameToUse + "." : "") + procedureNameToUse + "("; } for (SqlParameter parameter : this.callParameters) { if (!(parameter.isResultsParameter())) { if (parameterCount > 0) { callString += ", "; } if (parameterCount >= 0) { callString += "?"; } parameterCount++; } } callString += ")}"; return callString; } } ././@LongLink0000000000000000000000000000022600000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataProviderFactory.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001025311623223526033273 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.metadata; import java.sql.DatabaseMetaData; import java.sql.SQLException; import javax.sql.DataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.jdbc.support.DatabaseMetaDataCallback; import org.springframework.jdbc.support.JdbcUtils; import org.springframework.jdbc.support.MetaDataAccessException; import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor; /** * Factory used to create a {@link TableMetaDataProvider} implementation based on the type of databse being used. * * @author Thomas Risberg * @since 2.5 */ public class TableMetaDataProviderFactory { private static final Log logger = LogFactory.getLog(TableMetaDataProviderFactory.class); /** * Create a TableMetaDataProvider based on the database metedata * @param dataSource used to retrieve metedata * @param context the class that holds configuration and metedata * @return instance of the TableMetaDataProvider implementation to be used */ public static TableMetaDataProvider createMetaDataProvider(DataSource dataSource, TableMetaDataContext context) { return createMetaDataProvider(dataSource, context, null); } /** * Create a TableMetaDataProvider based on the database metedata * @param dataSource used to retrieve metedata * @param context the class that holds configuration and metedata * @param nativeJdbcExtractor the NativeJdbcExtractor to be used * @return instance of the TableMetaDataProvider implementation to be used */ public static TableMetaDataProvider createMetaDataProvider(DataSource dataSource, final TableMetaDataContext context, final NativeJdbcExtractor nativeJdbcExtractor) { try { return (TableMetaDataProvider) JdbcUtils.extractDatabaseMetaData(dataSource, new DatabaseMetaDataCallback() { public Object processMetaData(DatabaseMetaData databaseMetaData) throws SQLException { String databaseProductName = JdbcUtils.commonDatabaseName(databaseMetaData.getDatabaseProductName()); boolean accessTableColumnMetaData = context.isAccessTableColumnMetaData(); TableMetaDataProvider provider; if ("Oracle".equals(databaseProductName)) { provider = new OracleTableMetaDataProvider(databaseMetaData, context.isOverrideIncludeSynonymsDefault()); } else if ("HSQL Database Engine".equals(databaseProductName)) { provider = new HsqlTableMetaDataProvider(databaseMetaData); } else if ("PostgreSQL".equals(databaseProductName)) { provider = new PostgresTableMetaDataProvider(databaseMetaData); } else if ("Apache Derby".equals(databaseProductName)) { provider = new DerbyTableMetaDataProvider(databaseMetaData); } else { provider = new GenericTableMetaDataProvider(databaseMetaData); } if (nativeJdbcExtractor != null) { provider.setNativeJdbcExtractor(nativeJdbcExtractor); } if (logger.isDebugEnabled()) { logger.debug("Using " + provider.getClass().getSimpleName()); } provider.initializeWithMetaData(databaseMetaData); if (accessTableColumnMetaData) { provider.initializeWithTableColumnMetaData(databaseMetaData, context.getCatalogName(), context.getSchemaName(), context.getTableName()); } return provider; } }); } catch (MetaDataAccessException ex) { throw new DataAccessResourceFailureException("Error retrieving database metadata", ex); } } } ././@LongLink0000000000000000000000000000022600000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/PostgresCallMetaDataProvider.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000340611623223526033275 0ustar drazzibdrazzibpackage org.springframework.jdbc.core.metadata; import org.springframework.jdbc.core.SqlParameter; import org.springframework.jdbc.core.SqlOutParameter; import org.springframework.jdbc.core.ColumnMapRowMapper; import java.sql.DatabaseMetaData; import java.sql.SQLException; import java.sql.Types; /** * Oracle specific implementation for the {@link org.springframework.jdbc.core.metadata.CallMetaDataProvider} interface. * This class is intended for internal use by the Simple JDBC classes. * * @author Thomas Risberg * @since 2.5 */ public class PostgresCallMetaDataProvider extends GenericCallMetaDataProvider { private static final String RETURN_VALUE_NAME = "returnValue"; public PostgresCallMetaDataProvider(DatabaseMetaData databaseMetaData) throws SQLException { super(databaseMetaData); } @Override public boolean isReturnResultSetSupported() { return false; } @Override public boolean isRefCursorSupported() { return true; } @Override public int getRefCursorSqlType() { return Types.OTHER; } @Override public String metaDataSchemaNameToUse(String schemaName) { // Use public schema if no schema specified return schemaName == null ? "public" : super.metaDataSchemaNameToUse(schemaName); } @Override public SqlParameter createDefaultOutParameter(String parameterName, CallParameterMetaData meta) { if (meta.getSqlType() == Types.OTHER && "refcursor".equals(meta.getTypeName())) { return new SqlOutParameter(parameterName, getRefCursorSqlType(), new ColumnMapRowMapper()); } else { return super.createDefaultOutParameter(parameterName, meta); } } @Override public boolean byPassReturnParameter(String parameterName) { return (RETURN_VALUE_NAME.equals(parameterName) || super.byPassReturnParameter(parameterName)); } } ././@LongLink0000000000000000000000000000022400000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/DerbyTableMetaDataProvider.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000370211623223530033267 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.metadata; import java.sql.DatabaseMetaData; import java.sql.SQLException; /** * The Derby specific implementation of the {@link org.springframework.jdbc.core.metadata.TableMetaDataProvider}. * Overrides the Derby metadata info regarding retreiving generated keys. It seems to work OK so not sure why they * claim it's not supported. * * @author Thomas Risberg * @since 3.0 */ public class DerbyTableMetaDataProvider extends GenericTableMetaDataProvider { private boolean supportsGeneratedKeysOverride = false; public DerbyTableMetaDataProvider(DatabaseMetaData databaseMetaData) throws SQLException { super(databaseMetaData); } @Override public void initializeWithMetaData(DatabaseMetaData databaseMetaData) throws SQLException { super.initializeWithMetaData(databaseMetaData); if (!databaseMetaData.supportsGetGeneratedKeys()) { logger.warn("Overriding supportsGetGeneratedKeys from DatabaseMetaData to 'true'; it was reported as " + "'false' by " + databaseMetaData.getDriverName() + " " + databaseMetaData.getDriverVersion()); supportsGeneratedKeysOverride = true; } } @Override public boolean isGetGeneratedKeysSupported() { boolean derbysAnswer = super.isGetGeneratedKeysSupported(); if (!derbysAnswer) { return supportsGeneratedKeysOverride; } return derbysAnswer; } }././@LongLink0000000000000000000000000000022700000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/SqlServerCallMetaDataProvider.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000342111623223526033272 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.metadata; import java.sql.DatabaseMetaData; import java.sql.SQLException; /** * SQL Server specific implementation for the {@link CallMetaDataProvider} interface. * This class is intended for internal use by the Simple JDBC classes. * * @author Thomas Risberg * @since 2.5 */ public class SqlServerCallMetaDataProvider extends GenericCallMetaDataProvider { private static final String REMOVABLE_COLUMN_PREFIX = "@"; private static final String RETURN_VALUE_NAME = "@RETURN_VALUE"; public SqlServerCallMetaDataProvider(DatabaseMetaData databaseMetaData) throws SQLException { super(databaseMetaData); } @Override public String parameterNameToUse(String parameterName) { if (parameterName == null) { return null; } else if (parameterName.length() > 1 && parameterName.startsWith(REMOVABLE_COLUMN_PREFIX)) { return super.parameterNameToUse(parameterName.substring(1)); } else { return super.parameterNameToUse(parameterName); } } @Override public boolean byPassReturnParameter(String parameterName) { return (RETURN_VALUE_NAME.equals(parameterName) || super.byPassReturnParameter(parameterName)); } } ././@LongLink0000000000000000000000000000022100000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/Db2CallMetaDataProvider.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000474311623223526033302 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.metadata; import java.sql.DatabaseMetaData; import java.sql.SQLException; /** * DB2 specific implementation for the {@link CallMetaDataProvider} interface. * This class is intended for internal use by the Simple JDBC classes. * * @author Thomas Risberg * @author Juergen Hoeller * @since 2.5 */ public class Db2CallMetaDataProvider extends GenericCallMetaDataProvider { public Db2CallMetaDataProvider(DatabaseMetaData databaseMetaData) throws SQLException { super(databaseMetaData); } @Override public void initializeWithMetaData(DatabaseMetaData databaseMetaData) throws SQLException { try { setSupportsCatalogsInProcedureCalls(databaseMetaData.supportsCatalogsInProcedureCalls()); } catch (SQLException se) { logger.debug("Error retrieving 'DatabaseMetaData.supportsCatalogsInProcedureCalls' - " + se.getMessage()); } try { setSupportsSchemasInProcedureCalls(databaseMetaData.supportsSchemasInProcedureCalls()); } catch (SQLException se) { logger.debug("Error retrieving 'DatabaseMetaData.supportsSchemasInProcedureCalls' - " + se.getMessage()); } try { setStoresUpperCaseIdentifiers(databaseMetaData.storesUpperCaseIdentifiers()); } catch (SQLException se) { logger.debug("Error retrieving 'DatabaseMetaData.storesUpperCaseIdentifiers' - " + se.getMessage()); } try { setStoresLowerCaseIdentifiers(databaseMetaData.storesLowerCaseIdentifiers()); } catch (SQLException se) { logger.debug("Error retrieving 'DatabaseMetaData.storesLowerCaseIdentifiers' - " + se.getMessage()); } } @Override public String metaDataSchemaNameToUse(String schemaName) { if (schemaName != null) { return super.metaDataSchemaNameToUse(schemaName); } // Use current user schema if no schema specified... String userName = getUserName(); return (userName != null ? userName.toUpperCase() : null); } } ././@LongLink0000000000000000000000000000022500000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataProviderFactory.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001233311623223530033267 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.metadata; import java.sql.DatabaseMetaData; import java.sql.SQLException; import java.util.Arrays; import java.util.List; import javax.sql.DataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.jdbc.support.DatabaseMetaDataCallback; import org.springframework.jdbc.support.JdbcUtils; import org.springframework.jdbc.support.MetaDataAccessException; /** * Factory used to create a {@link CallMetaDataProvider} implementation based on the type of databse being used. * * @author Thomas Risberg * @since 2.5 */ public class CallMetaDataProviderFactory { /** Logger */ private static final Log logger = LogFactory.getLog(CallMetaDataProviderFactory.class); /** List of supported database products for procedure calls */ public static final List supportedDatabaseProductsForProcedures = Arrays.asList( "Apache Derby", "DB2", "MySQL", "Microsoft SQL Server", "Oracle", "PostgreSQL", "Sybase" ); /** List of supported database products for function calls */ public static final List supportedDatabaseProductsForFunctions = Arrays.asList( "MySQL", "Microsoft SQL Server", "Oracle", "PostgreSQL" ); /** * Create a CallMetaDataProvider based on the database metedata * @param dataSource used to retrieve metedata * @param context the class that holds configuration and metedata * @return instance of the CallMetaDataProvider implementation to be used */ static public CallMetaDataProvider createMetaDataProvider(DataSource dataSource, final CallMetaDataContext context) { try { return (CallMetaDataProvider) JdbcUtils.extractDatabaseMetaData(dataSource, new DatabaseMetaDataCallback() { public Object processMetaData(DatabaseMetaData databaseMetaData) throws SQLException, MetaDataAccessException { String databaseProductName = JdbcUtils.commonDatabaseName(databaseMetaData.getDatabaseProductName()); boolean accessProcedureColumnMetaData = context.isAccessCallParameterMetaData(); if (context.isFunction()) { if (!supportedDatabaseProductsForFunctions.contains(databaseProductName)) { if (logger.isWarnEnabled()) { logger.warn(databaseProductName + " is not one of the databases fully supported for function calls " + "-- supported are: " + supportedDatabaseProductsForFunctions); } if (accessProcedureColumnMetaData) { logger.warn("Metadata processing disabled - you must specify all parameters explicitly"); accessProcedureColumnMetaData = false; } } } else { if (!supportedDatabaseProductsForProcedures.contains(databaseProductName)) { if (logger.isWarnEnabled()) { logger.warn(databaseProductName + " is not one of the databases fully supported for procedure calls " + "-- supported are: " + supportedDatabaseProductsForProcedures); } if (accessProcedureColumnMetaData) { logger.warn("Metadata processing disabled - you must specify all parameters explicitly"); accessProcedureColumnMetaData = false; } } } CallMetaDataProvider provider; if ("Oracle".equals(databaseProductName)) { provider = new OracleCallMetaDataProvider(databaseMetaData); } else if ("DB2".equals(databaseProductName)) { provider = new Db2CallMetaDataProvider((databaseMetaData)); } else if ("Apache Derby".equals(databaseProductName)) { provider = new DerbyCallMetaDataProvider((databaseMetaData)); } else if ("PostgreSQL".equals(databaseProductName)) { provider = new PostgresCallMetaDataProvider((databaseMetaData)); } else if ("Sybase".equals(databaseProductName)) { provider = new SybaseCallMetaDataProvider((databaseMetaData)); } else if ("Microsoft SQL Server".equals(databaseProductName)) { provider = new SqlServerCallMetaDataProvider((databaseMetaData)); } else { provider = new GenericCallMetaDataProvider(databaseMetaData); } if (logger.isDebugEnabled()) { logger.debug("Using " + provider.getClass().getName()); } provider.initializeWithMetaData(databaseMetaData); if (accessProcedureColumnMetaData) { provider.initializeWithProcedureColumnMetaData( databaseMetaData, context.getCatalogName(), context.getSchemaName(), context.getProcedureName()); } return provider; } }); } catch (MetaDataAccessException ex) { throw new DataAccessResourceFailureException("Error retreiving database metadata", ex); } } } ././@LongLink0000000000000000000000000000022400000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/OracleCallMetaDataProvider.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000466311623223530033276 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.metadata; import java.sql.DatabaseMetaData; import java.sql.SQLException; import java.sql.Types; import org.springframework.jdbc.core.ColumnMapRowMapper; import org.springframework.jdbc.core.SqlOutParameter; import org.springframework.jdbc.core.SqlParameter; import org.springframework.jdbc.core.SqlInOutParameter; /** * Oracle specific implementation for the {@link CallMetaDataProvider} interface. * This class is intended for internal use by the Simple JDBC classes. * * @author Thomas Risberg * @since 2.5 */ public class OracleCallMetaDataProvider extends GenericCallMetaDataProvider { private static final String REF_CURSOR_NAME = "REF CURSOR"; public OracleCallMetaDataProvider(DatabaseMetaData databaseMetaData) throws SQLException { super(databaseMetaData); } @Override public boolean isReturnResultSetSupported() { return false; } @Override public boolean isRefCursorSupported() { return true; } @Override public int getRefCursorSqlType() { return -10; } @Override public String metaDataCatalogNameToUse(String catalogName) { // Oracle uses catalog name for package name or an empty string if no package return catalogName == null ? "" : catalogNameToUse(catalogName); } @Override public String metaDataSchemaNameToUse(String schemaName) { // Use current user schema if no schema specified return schemaName == null ? getUserName() : super.metaDataSchemaNameToUse(schemaName); } @Override public SqlParameter createDefaultOutParameter(String parameterName, CallParameterMetaData meta) { if (meta.getSqlType() == Types.OTHER && REF_CURSOR_NAME.equals(meta.getTypeName())) { return new SqlOutParameter(parameterName, getRefCursorSqlType(), new ColumnMapRowMapper()); } else { return super.createDefaultOutParameter(parameterName, meta); } } } ././@LongLink0000000000000000000000000000021700000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallParameterMetaData.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000340311623223530033265 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.metadata; /** * Holder of metadata for a specific parameter that is used for call processing. * * @author Thomas Risberg * @since 2.5 */ public class CallParameterMetaData { private String parameterName; private int parameterType; private int sqlType; private String typeName; private boolean nullable; /** * Constructor taking all the properties */ public CallParameterMetaData(String columnName, int columnType, int sqlType, String typeName, boolean nullable) { this.parameterName = columnName; this.parameterType = columnType; this.sqlType = sqlType; this.typeName = typeName; this.nullable = nullable; } /** * Get the parameter name. */ public String getParameterName() { return parameterName; } /** * Get the parameter type. */ public int getParameterType() { return parameterType; } /** * Get the parameter SQL type. */ public int getSqlType() { return sqlType; } /** * Get the parameter type name. */ public String getTypeName() { return typeName; } /** * Get whether the parameter is nullable. */ public boolean isNullable() { return nullable; } }././@LongLink0000000000000000000000000000022000000000000011557 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableParameterMetaData.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000273311623223530033272 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.metadata; /** * Holder of metadata for a specific parameter that is used for table processing. * * @author Thomas Risberg * @since 2.5 */ public class TableParameterMetaData { private final String parameterName; private final int sqlType; private final boolean nullable; /** * Constructor taking all the properties. */ public TableParameterMetaData(String columnName, int sqlType, boolean nullable) { this.parameterName = columnName; this.sqlType = sqlType; this.nullable = nullable; } /** * Get the parameter name. */ public String getParameterName() { return this.parameterName; } /** * Get the parameter SQL type. */ public int getSqlType() { return this.sqlType; } /** * Get whether the parameter/column is nullable. */ public boolean isNullable() { return this.nullable; } } ././@LongLink0000000000000000000000000000022300000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/HsqlTableMetaDataProvider.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000257011623223530033271 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.metadata; import java.sql.DatabaseMetaData; import java.sql.SQLException; /** * The HSQL specific implementation of the {@link TableMetaDataProvider}. Suports a feature for * retreiving generated keys without the JDBC 3.0 getGeneratedKeys support. * * @author Thomas Risberg * @since 2.5 */ public class HsqlTableMetaDataProvider extends GenericTableMetaDataProvider { public HsqlTableMetaDataProvider(DatabaseMetaData databaseMetaData) throws SQLException { super(databaseMetaData); } @Override public boolean isGetGeneratedKeysSimulated() { return true; } @Override public String getSimpleQueryForGetGeneratedKey(String tableName, String keyColumnName) { return "select max(identity()) from " + tableName; } } ././@LongLink0000000000000000000000000000022500000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/OracleTableMetaDataProvider.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000756211623223530033277 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.metadata; import java.lang.reflect.Method; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.SQLException; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor; import org.springframework.util.ReflectionUtils; /** * Oracle-specific implementation of the {@link org.springframework.jdbc.core.metadata.TableMetaDataProvider}. * Supports a feature for including synonyms in the metadata lookup. * * @author Thomas Risberg * @author Juergen Hoeller * @since 3.0 */ public class OracleTableMetaDataProvider extends GenericTableMetaDataProvider { private final boolean includeSynonyms; public OracleTableMetaDataProvider(DatabaseMetaData databaseMetaData) throws SQLException { this(databaseMetaData, false); } public OracleTableMetaDataProvider(DatabaseMetaData databaseMetaData, boolean includeSynonyms) throws SQLException { super(databaseMetaData); this.includeSynonyms = includeSynonyms; } @Override public void initializeWithTableColumnMetaData(DatabaseMetaData databaseMetaData, String catalogName, String schemaName, String tableName) throws SQLException { if (!this.includeSynonyms) { logger.debug("Defaulting to no synonyms in table metadata lookup"); super.initializeWithTableColumnMetaData(databaseMetaData, catalogName, schemaName, tableName); return; } Connection con = databaseMetaData.getConnection(); NativeJdbcExtractor nativeJdbcExtractor = getNativeJdbcExtractor(); if (nativeJdbcExtractor != null) { con = nativeJdbcExtractor.getNativeConnection(con); } boolean isOracleCon; try { Class oracleConClass = getClass().getClassLoader().loadClass("oracle.jdbc.OracleConnection"); isOracleCon = oracleConClass.isInstance(con); } catch (ClassNotFoundException ex) { if (logger.isInfoEnabled()) { logger.info("Couldn't find Oracle JDBC API: " + ex); } isOracleCon = false; } if (!isOracleCon) { logger.warn("Unable to include synonyms in table metadata lookup. Connection used for " + "DatabaseMetaData is not recognized as an Oracle connection: " + con); super.initializeWithTableColumnMetaData(databaseMetaData, catalogName, schemaName, tableName); return; } logger.debug("Including synonyms in table metadata lookup"); Method setIncludeSynonyms; Boolean originalValueForIncludeSynonyms; try { Method getIncludeSynonyms = con.getClass().getMethod("getIncludeSynonyms", (Class[]) null); ReflectionUtils.makeAccessible(getIncludeSynonyms); originalValueForIncludeSynonyms = (Boolean) getIncludeSynonyms.invoke(con); setIncludeSynonyms = con.getClass().getMethod("setIncludeSynonyms", new Class[] {boolean.class}); ReflectionUtils.makeAccessible(setIncludeSynonyms); setIncludeSynonyms.invoke(con, Boolean.TRUE); } catch (Exception ex) { throw new InvalidDataAccessApiUsageException("Couldn't prepare Oracle Connection", ex); } super.initializeWithTableColumnMetaData(databaseMetaData, catalogName, schemaName, tableName); try { setIncludeSynonyms.invoke(con, originalValueForIncludeSynonyms); } catch (Exception ex) { throw new InvalidDataAccessApiUsageException("Couldn't reset Oracle Connection", ex); } } } ././@LongLink0000000000000000000000000000022600000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericTableMetaDataProvider.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000003255611623223530033300 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.metadata; import java.sql.DatabaseMetaData; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor; /** * A generic implementation of the {@link TableMetaDataProvider} that should provide * enough features for all supported databases. * * @author Thomas Risberg * @since 2.5 */ public class GenericTableMetaDataProvider implements TableMetaDataProvider { /** Logger available to subclasses */ protected static final Log logger = LogFactory.getLog(TableMetaDataProvider.class); /** indicator whether column metadata should be used */ private boolean tableColumnMetaDataUsed = false; /** the version of the database */ private String databaseVersion; /** the name of the user currently connected */ private String userName; /** indicates whether the identifiers are uppercased */ private boolean storesUpperCaseIdentifiers = true; /** indicates whether the identifiers are lowercased */ private boolean storesLowerCaseIdentifiers = false; /** indicates whether generated keys retrieval is supported */ private boolean getGeneratedKeysSupported = true; /** indicates whether the use of a String[] for generated keys is supported */ private boolean generatedKeysColumnNameArraySupported = true; /** database products we know not supporting the use of a String[] for generated keys */ private List productsNotSupportingGeneratedKeysColumnNameArray = Arrays.asList("Apache Derby", "HSQL Database Engine"); /** Collection of TableParameterMetaData objects */ private List insertParameterMetaData = new ArrayList(); /** NativeJdbcExtractor that can be used to retrieve the native connection */ private NativeJdbcExtractor nativeJdbcExtractor; /** * Constructor used to initialize with provided database meta data. * @param databaseMetaData meta data to be used */ protected GenericTableMetaDataProvider(DatabaseMetaData databaseMetaData) throws SQLException { this.userName = databaseMetaData.getUserName(); } /** * Specify whether identifiers use upper case */ public void setStoresUpperCaseIdentifiers(boolean storesUpperCaseIdentifiers) { this.storesUpperCaseIdentifiers = storesUpperCaseIdentifiers; } /** * Get whether identifiers use upper case */ public boolean isStoresUpperCaseIdentifiers() { return this.storesUpperCaseIdentifiers; } /** * Specify whether identifiers use lower case. */ public void setStoresLowerCaseIdentifiers(boolean storesLowerCaseIdentifiers) { this.storesLowerCaseIdentifiers = storesLowerCaseIdentifiers; } /** * Get whether identifiers use lower case */ public boolean isStoresLowerCaseIdentifiers() { return this.storesLowerCaseIdentifiers; } public boolean isTableColumnMetaDataUsed() { return this.tableColumnMetaDataUsed; } public List getTableParameterMetaData() { return this.insertParameterMetaData; } public boolean isGetGeneratedKeysSupported() { return this.getGeneratedKeysSupported; } public boolean isGetGeneratedKeysSimulated(){ return false; } public String getSimpleQueryForGetGeneratedKey(String tableName, String keyColumnName) { return null; } /** * Specify whether a column name array is supported for generated keys */ public void setGetGeneratedKeysSupported(boolean getGeneratedKeysSupported) { this.getGeneratedKeysSupported = getGeneratedKeysSupported; } /** * Specify whether a column name array is supported for generated keys */ public void setGeneratedKeysColumnNameArraySupported(boolean generatedKeysColumnNameArraySupported) { this.generatedKeysColumnNameArraySupported = generatedKeysColumnNameArraySupported; } public boolean isGeneratedKeysColumnNameArraySupported() { return this.generatedKeysColumnNameArraySupported; } public void setNativeJdbcExtractor(NativeJdbcExtractor nativeJdbcExtractor) { this.nativeJdbcExtractor = nativeJdbcExtractor; } protected NativeJdbcExtractor getNativeJdbcExtractor() { return this.nativeJdbcExtractor; } public void initializeWithMetaData(DatabaseMetaData databaseMetaData) throws SQLException { try { if (databaseMetaData.supportsGetGeneratedKeys()) { logger.debug("GetGeneratedKeys is supported"); setGetGeneratedKeysSupported(true); } else { logger.debug("GetGeneratedKeys is not supported"); setGetGeneratedKeysSupported(false); } } catch (SQLException se) { logger.warn("Error retrieving 'DatabaseMetaData.getGeneratedKeys' - " + se.getMessage()); } try { String databaseProductName = databaseMetaData.getDatabaseProductName(); if (this.productsNotSupportingGeneratedKeysColumnNameArray.contains(databaseProductName)) { logger.debug("GeneratedKeysColumnNameArray is not supported for " + databaseProductName); setGeneratedKeysColumnNameArraySupported(false); } else { logger.debug("GeneratedKeysColumnNameArray is supported for " + databaseProductName); setGeneratedKeysColumnNameArraySupported(true); } } catch (SQLException se) { logger.warn("Error retrieving 'DatabaseMetaData.getDatabaseProductName' - " + se.getMessage()); } try { this.databaseVersion = databaseMetaData.getDatabaseProductVersion(); } catch (SQLException se) { logger.warn("Error retrieving 'DatabaseMetaData.getDatabaseProductVersion' - " + se.getMessage()); } try { setStoresUpperCaseIdentifiers(databaseMetaData.storesUpperCaseIdentifiers()); } catch (SQLException se) { logger.warn("Error retrieving 'DatabaseMetaData.storesUpperCaseIdentifiers' - " + se.getMessage()); } try { setStoresLowerCaseIdentifiers(databaseMetaData.storesLowerCaseIdentifiers()); } catch (SQLException se) { logger.warn("Error retrieving 'DatabaseMetaData.storesLowerCaseIdentifiers' - " + se.getMessage()); } } public void initializeWithTableColumnMetaData(DatabaseMetaData databaseMetaData, String catalogName, String schemaName, String tableName) throws SQLException { this.tableColumnMetaDataUsed = true; locateTableAndProcessMetaData(databaseMetaData, catalogName, schemaName, tableName); } public String tableNameToUse(String tableName) { if (tableName == null) { return null; } else if (isStoresUpperCaseIdentifiers()) { return tableName.toUpperCase(); } else if(isStoresLowerCaseIdentifiers()) { return tableName.toLowerCase(); } else { return tableName; } } public String catalogNameToUse(String catalogName) { if (catalogName == null) { return null; } else if (isStoresUpperCaseIdentifiers()) { return catalogName.toUpperCase(); } else if(isStoresLowerCaseIdentifiers()) { return catalogName.toLowerCase(); } else { return catalogName; } } public String schemaNameToUse(String schemaName) { if (schemaName == null) { return null; } else if (isStoresUpperCaseIdentifiers()) { return schemaName.toUpperCase(); } else if(isStoresLowerCaseIdentifiers()) { return schemaName.toLowerCase(); } else { return schemaName; } } public String metaDataCatalogNameToUse(String catalogName) { return catalogNameToUse(catalogName); } public String metaDataSchemaNameToUse(String schemaName) { if (schemaName == null) { return schemaNameToUse(userName); } return schemaNameToUse(schemaName); } /** * Provide access to version info for subclasses. */ protected String getDatabaseVersion() { return this.databaseVersion; } /** * Method supporting the metedata processing for a table. */ private void locateTableAndProcessMetaData(DatabaseMetaData databaseMetaData, String catalogName, String schemaName, String tableName) { Map tableMeta = new HashMap(); ResultSet tables = null; try { tables = databaseMetaData.getTables( catalogNameToUse(catalogName), schemaNameToUse(schemaName), tableNameToUse(tableName), null); while (tables != null && tables.next()) { TableMetaData tmd = new TableMetaData(); tmd.setCatalogName(tables.getString("TABLE_CAT")); tmd.setSchemaName(tables.getString("TABLE_SCHEM")); tmd.setTableName(tables.getString("TABLE_NAME")); tmd.setType(tables.getString("TABLE_TYPE")); if (tmd.getSchemaName() == null) { tableMeta.put(userName.toUpperCase(), tmd); } else { tableMeta.put(tmd.getSchemaName().toUpperCase(), tmd); } } } catch (SQLException se) { logger.warn("Error while accessing table meta data results" + se.getMessage()); } finally { if (tables != null) { try { tables.close(); } catch (SQLException e) { logger.warn("Error while closing table meta data reults" + e.getMessage()); } } } if (tableMeta.size() < 1) { logger.warn("Unable to locate table meta data for '" + tableName +"' -- column names must be provided"); } else { TableMetaData tmd; if (schemaName == null) { tmd = tableMeta.get(userName.toUpperCase()); if (tmd == null) { tmd = tableMeta.get("PUBLIC"); if (tmd == null) { tmd = tableMeta.get("DBO"); } if (tmd == null) { throw new DataAccessResourceFailureException("Unable to locate table meta data for '" + tableName + "' in the default schema"); } } } else { tmd = tableMeta.get(schemaName.toUpperCase()); if (tmd == null) { throw new DataAccessResourceFailureException("Unable to locate table meta data for '" + tableName + "' in the '" + schemaName + "' schema"); } } processTableColumns(databaseMetaData, tmd); } } /** * Method supporting the metedata processing for a table's columns */ private void processTableColumns(DatabaseMetaData databaseMetaData, TableMetaData tmd) { ResultSet tableColumns = null; String metaDataCatalogName = metaDataCatalogNameToUse(tmd.getCatalogName()); String metaDataSchemaName = metaDataSchemaNameToUse(tmd.getSchemaName()); String metaDataTableName = tableNameToUse(tmd.getTableName()); if (logger.isDebugEnabled()) { logger.debug("Retrieving metadata for " + metaDataCatalogName + "/" + metaDataSchemaName + "/" + metaDataTableName); } try { tableColumns = databaseMetaData.getColumns( metaDataCatalogName, metaDataSchemaName, metaDataTableName, null); while (tableColumns.next()) { String columnName = tableColumns.getString("COLUMN_NAME"); int dataType = tableColumns.getInt("DATA_TYPE"); if (dataType == Types.DECIMAL) { String typeName = tableColumns.getString("TYPE_NAME"); int decimalDigits = tableColumns.getInt("DECIMAL_DIGITS"); // override a DECIMAL data type for no-decimal numerics // (this is for better Oracle support where there have been issues // using DECIMAL for certain inserts (see SPR-6912)) if ("NUMBER".equals(typeName) && decimalDigits == 0) { dataType = Types.NUMERIC; if (logger.isDebugEnabled()) { logger.debug("Overriding metadata: " + columnName + " now using NUMERIC instead of DECIMAL" ); } } } boolean nullable = tableColumns.getBoolean("NULLABLE"); TableParameterMetaData meta = new TableParameterMetaData( columnName, dataType, nullable ); this.insertParameterMetaData.add(meta); if (logger.isDebugEnabled()) { logger.debug("Retrieved metadata: " + meta.getParameterName() + " " + meta.getSqlType() + " " + meta.isNullable() ); } } } catch (SQLException se) { logger.warn("Error while retrieving metadata for table columns: " + se.getMessage()); } finally { try { if (tableColumns != null) tableColumns.close(); } catch (SQLException se) { logger.warn("Problem closing ResultSet for table column metadata " + se.getMessage()); } } } /** * Inner class representing table meta data. */ private static class TableMetaData { private String catalogName; private String schemaName; private String tableName; private String type; public void setCatalogName(String catalogName) { this.catalogName = catalogName; } public String getCatalogName() { return this.catalogName; } public void setSchemaName(String schemaName) { this.schemaName = schemaName; } public String getSchemaName() { return this.schemaName; } public void setTableName(String tableName) { this.tableName = tableName; } public String getTableName() { return this.tableName; } public void setType(String type) { this.type = type; } public String getType() { return this.type; } } } ././@LongLink0000000000000000000000000000022700000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/PostgresTableMetaDataProvider.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000200411623223530033261 0ustar drazzibdrazzibpackage org.springframework.jdbc.core.metadata; import java.sql.DatabaseMetaData; import java.sql.SQLException; /** * The PostgreSQL specific implementation of the {@link org.springframework.jdbc.core.metadata.TableMetaDataProvider}. * Suports a feature for retreiving generated keys without the JDBC 3.0 getGeneratedKeys support. * * @author Thomas Risberg * @since 2.5 */ public class PostgresTableMetaDataProvider extends GenericTableMetaDataProvider { public PostgresTableMetaDataProvider(DatabaseMetaData databaseMetaData) throws SQLException { super(databaseMetaData); } @Override public boolean isGetGeneratedKeysSimulated() { if (getDatabaseVersion().compareTo("8.2.0") >= 0) { return true; } else { logger.warn("PostgreSQL does not support getGeneratedKeys or INSERT ... RETURNING in version " + getDatabaseVersion()); return false; } } @Override public String getSimpleQueryForGetGeneratedKey(String tableName, String keyColumnName) { return "RETURNING " + keyColumnName; } } ././@LongLink0000000000000000000000000000021700000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataProvider.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001071611623223530033272 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.metadata; import java.sql.DatabaseMetaData; import java.sql.SQLException; import java.util.List; import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor; /** * Interface specifying the API to be implemented by a class providing table metedata. This is intended for internal use * by the Simple JDBC classes. * * @author Thomas Risberg * @since 2.5 */ public interface TableMetaDataProvider { /** * Initialize using the database metedata provided * @param databaseMetaData * @throws SQLException */ void initializeWithMetaData(DatabaseMetaData databaseMetaData) throws SQLException; /** * Initialize using provided database metadata, table and column information. This initalization can be * turned off by specifying that column meta data should not be used. * @param databaseMetaData used to retrieve database specific information * @param catalogName name of catalog to use or null * @param schemaName name of schema name to use or null * @param tableName name of the table * @throws SQLException */ void initializeWithTableColumnMetaData(DatabaseMetaData databaseMetaData, String catalogName, String schemaName, String tableName) throws SQLException; /** * Get the table name formatted based on metadata information. This could include altering the case. * * @param tableName * @return table name formatted */ String tableNameToUse(String tableName); /** * Get the catalog name formatted based on metadata information. This could include altering the case. * * @param catalogName * @return catalog name formatted */ String catalogNameToUse(String catalogName); /** * Get the schema name formatted based on metadata information. This could include altering the case. * * @param schemaName * @return schema name formatted */ String schemaNameToUse(String schemaName); /** * Provide any modification of the catalog name passed in to match the meta data currently used. * The reyurned value will be used for meta data lookups. This could include alterig the case used or * providing a base catalog if mone provided. * * @param catalogName * @return catalog name to use */ String metaDataCatalogNameToUse(String catalogName) ; /** * Provide any modification of the schema name passed in to match the meta data currently used. * The reyurned value will be used for meta data lookups. This could include alterig the case used or * providing a base schema if mone provided. * * @param schemaName * @return schema name to use */ String metaDataSchemaNameToUse(String schemaName) ; /** * Are we using the meta data for the table columns? */ boolean isTableColumnMetaDataUsed(); /** * Does this database support the JDBC 3.0 feature of retreiving generated keys * {@link java.sql.DatabaseMetaData#supportsGetGeneratedKeys()} */ boolean isGetGeneratedKeysSupported(); /** * Does this database support a simple quey to retrieve the generated key whe the JDBC 3.0 feature * of retreiving generated keys is not supported * {@link java.sql.DatabaseMetaData#supportsGetGeneratedKeys()} */ boolean isGetGeneratedKeysSimulated(); /** * Get the simple query to retrieve a generated key */ String getSimpleQueryForGetGeneratedKey(String tableName, String keyColumnName); /** * Does this database support a column name String array for retreiving generated keys * {@link java.sql.Connection#createStruct(String, Object[])} */ boolean isGeneratedKeysColumnNameArraySupported(); /** * Get the table parameter metadata that is currently used. * @return List of {@link TableParameterMetaData} */ List getTableParameterMetaData(); /** * Set the {@link NativeJdbcExtractor} to use to retrieve the native connection if necessary */ void setNativeJdbcExtractor(NativeJdbcExtractor nativeJdbcExtractor); } ././@LongLink0000000000000000000000000000022400000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/metadata/SybaseCallMetaDataProvider.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000351511623223526033276 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.metadata; import java.sql.DatabaseMetaData; import java.sql.SQLException; /** * Sybase specific implementation for the {@link CallMetaDataProvider} interface. * This class is intended for internal use by the Simple JDBC classes. * * @author Thomas Risberg * @since 2.5 */ public class SybaseCallMetaDataProvider extends GenericCallMetaDataProvider { private static final String REMOVABLE_COLUMN_PREFIX = "@"; private static final String RETURN_VALUE_NAME = "RETURN_VALUE"; public SybaseCallMetaDataProvider(DatabaseMetaData databaseMetaData) throws SQLException { super(databaseMetaData); } @Override public String parameterNameToUse(String parameterName) { if (parameterName == null) { return null; } else if (parameterName.length() > 1 && parameterName.startsWith(REMOVABLE_COLUMN_PREFIX)) { return super.parameterNameToUse(parameterName.substring(1)); } else { return super.parameterNameToUse(parameterName); } } @Override public boolean byPassReturnParameter(String parameterName) { return (RETURN_VALUE_NAME.equals(parameterName) || RETURN_VALUE_NAME.equals(parameterNameToUse(parameterName)) || super.byPassReturnParameter(parameterName)); } } ././@LongLink0000000000000000000000000000021100000000000011557 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/CallableStatementCreator.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000416411623223526033277 0ustar drazzibdrazzib/* * Copyright 2002-2005 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.SQLException; /** * One of the three central callback interfaces used by the JdbcTemplate class. * This interface creates a CallableStatement given a connection, provided * by the JdbcTemplate class. Implementations are responsible for providing * SQL and any necessary parameters. * *

Implementations do not need to concern themselves with * SQLExceptions that may be thrown from operations they attempt. * The JdbcTemplate class will catch and handle SQLExceptions appropriately. * *

A PreparedStatementCreator should also implement the SqlProvider interface * if it is able to provide the SQL it uses for PreparedStatement creation. * This allows for better contextual information in case of exceptions. * * @author Rod Johnson * @author Thomas Risberg * @see JdbcTemplate#execute(CallableStatementCreator, CallableStatementCallback) * @see JdbcTemplate#call * @see SqlProvider */ public interface CallableStatementCreator { /** * Create a callable statement in this connection. Allows implementations to use * CallableStatements. * @param con Connection to use to create statement * @return a callable statement * @throws SQLException there is no need to catch SQLExceptions * that may be thrown in the implementation of this method. * The JdbcTemplate class will handle them. */ CallableStatement createCallableStatement(Connection con) throws SQLException; } ././@LongLink0000000000000000000000000000022000000000000011557 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/PreparedStatementCreatorFactory.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000002474311623223526033304 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.dao.InvalidDataAccessResourceUsageException; import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor; import org.springframework.util.Assert; /** * Helper class that efficiently creates multiple {@link PreparedStatementCreator} * objects with different parameters based on a SQL statement and a single * set of parameter declarations. * * @author Rod Johnson * @author Thomas Risberg * @author Juergen Hoeller */ public class PreparedStatementCreatorFactory { /** The SQL, which won't change when the parameters change */ private final String sql; /** List of SqlParameter objects. May not be null. */ private final List declaredParameters; private int resultSetType = ResultSet.TYPE_FORWARD_ONLY; private boolean updatableResults = false; private boolean returnGeneratedKeys = false; private String[] generatedKeysColumnNames = null; private NativeJdbcExtractor nativeJdbcExtractor; /** * Create a new factory. Will need to add parameters via the * {@link #addParameter} method or have no parameters. */ public PreparedStatementCreatorFactory(String sql) { this.sql = sql; this.declaredParameters = new LinkedList(); } /** * Create a new factory with the given SQL and JDBC types. * @param sql SQL to execute * @param types int array of JDBC types */ public PreparedStatementCreatorFactory(String sql, int[] types) { this.sql = sql; this.declaredParameters = SqlParameter.sqlTypesToAnonymousParameterList(types); } /** * Create a new factory with the given SQL and parameters. * @param sql SQL * @param declaredParameters list of {@link SqlParameter} objects * @see SqlParameter */ public PreparedStatementCreatorFactory(String sql, List declaredParameters) { this.sql = sql; this.declaredParameters = declaredParameters; } /** * Add a new declared parameter. *

Order of parameter addition is significant. * @param param the parameter to add to the list of declared parameters */ public void addParameter(SqlParameter param) { this.declaredParameters.add(param); } /** * Set whether to use prepared statements that return a specific type of ResultSet. * @param resultSetType the ResultSet type * @see java.sql.ResultSet#TYPE_FORWARD_ONLY * @see java.sql.ResultSet#TYPE_SCROLL_INSENSITIVE * @see java.sql.ResultSet#TYPE_SCROLL_SENSITIVE */ public void setResultSetType(int resultSetType) { this.resultSetType = resultSetType; } /** * Set whether to use prepared statements capable of returning updatable ResultSets. */ public void setUpdatableResults(boolean updatableResults) { this.updatableResults = updatableResults; } /** * Set whether prepared statements should be capable of returning auto-generated keys. */ public void setReturnGeneratedKeys(boolean returnGeneratedKeys) { this.returnGeneratedKeys = returnGeneratedKeys; } /** * Set the column names of the auto-generated keys. */ public void setGeneratedKeysColumnNames(String[] names) { this.generatedKeysColumnNames = names; } /** * Specify the NativeJdbcExtractor to use for unwrapping PreparedStatements, if any. */ public void setNativeJdbcExtractor(NativeJdbcExtractor nativeJdbcExtractor) { this.nativeJdbcExtractor = nativeJdbcExtractor; } /** * Return a new PreparedStatementSetter for the given parameters. * @param params list of parameters (may be null) */ public PreparedStatementSetter newPreparedStatementSetter(List params) { return new PreparedStatementCreatorImpl(params != null ? params : Collections.emptyList()); } /** * Return a new PreparedStatementSetter for the given parameters. * @param params the parameter array (may be null) */ public PreparedStatementSetter newPreparedStatementSetter(Object[] params) { return new PreparedStatementCreatorImpl(params != null ? Arrays.asList(params) : Collections.emptyList()); } /** * Return a new PreparedStatementCreator for the given parameters. * @param params list of parameters (may be null) */ public PreparedStatementCreator newPreparedStatementCreator(List params) { return new PreparedStatementCreatorImpl(params != null ? params : Collections.emptyList()); } /** * Return a new PreparedStatementCreator for the given parameters. * @param params the parameter array (may be null) */ public PreparedStatementCreator newPreparedStatementCreator(Object[] params) { return new PreparedStatementCreatorImpl(params != null ? Arrays.asList(params) : Collections.emptyList()); } /** * Return a new PreparedStatementCreator for the given parameters. * @param sqlToUse the actual SQL statement to use (if different from * the factory's, for example because of named parameter expanding) * @param params the parameter array (may be null) */ public PreparedStatementCreator newPreparedStatementCreator(String sqlToUse, Object[] params) { return new PreparedStatementCreatorImpl( sqlToUse, params != null ? Arrays.asList(params) : Collections.emptyList()); } /** * PreparedStatementCreator implementation returned by this class. */ private class PreparedStatementCreatorImpl implements PreparedStatementCreator, PreparedStatementSetter, SqlProvider, ParameterDisposer { private final String actualSql; private final List parameters; public PreparedStatementCreatorImpl(List parameters) { this(sql, parameters); } public PreparedStatementCreatorImpl(String actualSql, List parameters) { this.actualSql = actualSql; Assert.notNull(parameters, "Parameters List must not be null"); this.parameters = parameters; if (this.parameters.size() != declaredParameters.size()) { // account for named parameters being used multiple times Set names = new HashSet(); for (int i = 0; i < parameters.size(); i++) { Object param = parameters.get(i); if (param instanceof SqlParameterValue) { names.add(((SqlParameterValue) param).getName()); } else { names.add("Parameter #" + i); } } if (names.size() != declaredParameters.size()) { throw new InvalidDataAccessApiUsageException( "SQL [" + sql + "]: given " + names.size() + " parameters but expected " + declaredParameters.size()); } } } public PreparedStatement createPreparedStatement(Connection con) throws SQLException { PreparedStatement ps = null; if (generatedKeysColumnNames != null || returnGeneratedKeys) { try { if (generatedKeysColumnNames != null) { ps = con.prepareStatement(this.actualSql, generatedKeysColumnNames); } else { ps = con.prepareStatement(this.actualSql, PreparedStatement.RETURN_GENERATED_KEYS); } } catch (AbstractMethodError ex) { throw new InvalidDataAccessResourceUsageException( "The JDBC driver is not compliant to JDBC 3.0 and thus " + "does not support retrieval of auto-generated keys", ex); } } else if (resultSetType == ResultSet.TYPE_FORWARD_ONLY && !updatableResults) { ps = con.prepareStatement(this.actualSql); } else { ps = con.prepareStatement(this.actualSql, resultSetType, updatableResults ? ResultSet.CONCUR_UPDATABLE : ResultSet.CONCUR_READ_ONLY); } setValues(ps); return ps; } public void setValues(PreparedStatement ps) throws SQLException { // Determine PreparedStatement to pass to custom types. PreparedStatement psToUse = ps; if (nativeJdbcExtractor != null) { psToUse = nativeJdbcExtractor.getNativePreparedStatement(ps); } // Set arguments: Does nothing if there are no parameters. int sqlColIndx = 1; for (int i = 0; i < this.parameters.size(); i++) { Object in = this.parameters.get(i); SqlParameter declaredParameter = null; // SqlParameterValue overrides declared parameter metadata, in particular for // independence from the declared parameter position in case of named parameters. if (in instanceof SqlParameterValue) { SqlParameterValue paramValue = (SqlParameterValue) in; in = paramValue.getValue(); declaredParameter = paramValue; } else { if (declaredParameters.size() <= i) { throw new InvalidDataAccessApiUsageException( "SQL [" + sql + "]: unable to access parameter number " + (i + 1) + " given only " + declaredParameters.size() + " parameters"); } declaredParameter = declaredParameters.get(i); } if (in instanceof Collection && declaredParameter.getSqlType() != Types.ARRAY) { Collection entries = (Collection) in; for (Object entry : entries) { if (entry instanceof Object[]) { Object[] valueArray = ((Object[])entry); for (Object argValue : valueArray) { StatementCreatorUtils.setParameterValue(psToUse, sqlColIndx++, declaredParameter, argValue); } } else { StatementCreatorUtils.setParameterValue(psToUse, sqlColIndx++, declaredParameter, entry); } } } else { StatementCreatorUtils.setParameterValue(psToUse, sqlColIndx++, declaredParameter, in); } } } public String getSql() { return sql; } public void cleanupParameters() { StatementCreatorUtils.cleanupParameters(this.parameters); } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("PreparedStatementCreatorFactory.PreparedStatementCreatorImpl: sql=["); sb.append(sql).append("]; parameters=").append(this.parameters); return sb.toString(); } } } ././@LongLink0000000000000000000000000000016400000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/support/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000755000175000017500000000000011623223530033263 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000020700000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/support/JdbcDaoSupport.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001140311623223530033264 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.support; import java.sql.Connection; import javax.sql.DataSource; import org.springframework.dao.support.DaoSupport; import org.springframework.jdbc.CannotGetJdbcConnectionException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.DataSourceUtils; import org.springframework.jdbc.support.SQLExceptionTranslator; /** * Convenient super class for JDBC-based data access objects. * *

Requires a {@link javax.sql.DataSource} to be set, providing a * {@link org.springframework.jdbc.core.JdbcTemplate} based on it to * subclasses through the {@link #getJdbcTemplate()} method. * *

This base class is mainly intended for JdbcTemplate usage but can * also be used when working with a Connection directly or when using * org.springframework.jdbc.object operation objects. * * @author Juergen Hoeller * @since 28.07.2003 * @see #setDataSource * @see #getJdbcTemplate * @see org.springframework.jdbc.core.JdbcTemplate */ public abstract class JdbcDaoSupport extends DaoSupport { private JdbcTemplate jdbcTemplate; /** * Set the JDBC DataSource to be used by this DAO. */ public final void setDataSource(DataSource dataSource) { if (this.jdbcTemplate == null || dataSource != this.jdbcTemplate.getDataSource()) { this.jdbcTemplate = createJdbcTemplate(dataSource); initTemplateConfig(); } } /** * Create a JdbcTemplate for the given DataSource. * Only invoked if populating the DAO with a DataSource reference! *

Can be overridden in subclasses to provide a JdbcTemplate instance * with different configuration, or a custom JdbcTemplate subclass. * @param dataSource the JDBC DataSource to create a JdbcTemplate for * @return the new JdbcTemplate instance * @see #setDataSource */ protected JdbcTemplate createJdbcTemplate(DataSource dataSource) { return new JdbcTemplate(dataSource); } /** * Return the JDBC DataSource used by this DAO. */ public final DataSource getDataSource() { return (this.jdbcTemplate != null ? this.jdbcTemplate.getDataSource() : null); } /** * Set the JdbcTemplate for this DAO explicitly, * as an alternative to specifying a DataSource. */ public final void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; initTemplateConfig(); } /** * Return the JdbcTemplate for this DAO, * pre-initialized with the DataSource or set explicitly. */ public final JdbcTemplate getJdbcTemplate() { return this.jdbcTemplate; } /** * Initialize the template-based configuration of this DAO. * Called after a new JdbcTemplate has been set, either directly * or through a DataSource. *

This implementation is empty. Subclasses may override this * to configure further objects based on the JdbcTemplate. * @see #getJdbcTemplate() */ protected void initTemplateConfig() { } @Override protected void checkDaoConfig() { if (this.jdbcTemplate == null) { throw new IllegalArgumentException("'dataSource' or 'jdbcTemplate' is required"); } } /** * Return the SQLExceptionTranslator of this DAO's JdbcTemplate, * for translating SQLExceptions in custom JDBC access code. * @see org.springframework.jdbc.core.JdbcTemplate#getExceptionTranslator() */ protected final SQLExceptionTranslator getExceptionTranslator() { return getJdbcTemplate().getExceptionTranslator(); } /** * Get a JDBC Connection, either from the current transaction or a new one. * @return the JDBC Connection * @throws CannotGetJdbcConnectionException if the attempt to get a Connection failed * @see org.springframework.jdbc.datasource.DataSourceUtils#getConnection(javax.sql.DataSource) */ protected final Connection getConnection() throws CannotGetJdbcConnectionException { return DataSourceUtils.getConnection(getDataSource()); } /** * Close the given JDBC Connection, created via this DAO's DataSource, * if it isn't bound to the thread. * @param con Connection to close * @see org.springframework.jdbc.datasource.DataSourceUtils#releaseConnection */ protected final void releaseConnection(Connection con) { DataSourceUtils.releaseConnection(con, getDataSource()); } } ././@LongLink0000000000000000000000000000020500000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/support/package-info.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000030211623223526033265 0ustar drazzibdrazzib /** * * Classes supporting the org.springframework.jdbc.core package. * Contains a DAO base class for JdbcTemplate usage. * */ package org.springframework.jdbc.core.support; ././@LongLink0000000000000000000000000000023700000000000011567 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/support/AbstractLobStreamingResultSetExtractor.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001076711623223526033305 0ustar drazzibdrazzib/* * Copyright 2002-2005 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.support; import java.io.IOException; import java.sql.ResultSet; import java.sql.SQLException; import org.springframework.dao.DataAccessException; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.dao.IncorrectResultSizeDataAccessException; import org.springframework.jdbc.LobRetrievalFailureException; import org.springframework.jdbc.core.ResultSetExtractor; /** * Abstract ResultSetExtractor implementation that assumes streaming of LOB data. * Typically used as inner class, with access to surrounding method arguments. * *

Delegates to the streamData template method for streaming LOB * content to some OutputStream, typically using a LobHandler. Converts an * IOException thrown during streaming to a LobRetrievalFailureException. * *

A usage example with JdbcTemplate: * *

JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);  // reusable object
 * final LobHandler lobHandler = new DefaultLobHandler();  // reusable object
 *
 * jdbcTemplate.query(
 *		 "SELECT content FROM imagedb WHERE image_name=?", new Object[] {name},
 *		 new AbstractLobStreamingResultSetExtractor() {
 *			 public void streamData(ResultSet rs) throws SQLException, IOException {
 *				 FileCopyUtils.copy(lobHandler.getBlobAsBinaryStream(rs, 1), contentStream);
 *			 }
 *		 }
 * );
* * @author Juergen Hoeller * @since 1.0.2 * @see org.springframework.jdbc.support.lob.LobHandler * @see org.springframework.jdbc.LobRetrievalFailureException */ public abstract class AbstractLobStreamingResultSetExtractor implements ResultSetExtractor { /** * Delegates to handleNoRowFound, handleMultipleRowsFound and streamData, * according to the ResultSet state. Converts an IOException thrown by * streamData to a LobRetrievalFailureException. * @see #handleNoRowFound * @see #handleMultipleRowsFound * @see #streamData * @see org.springframework.jdbc.LobRetrievalFailureException */ public final Object extractData(ResultSet rs) throws SQLException, DataAccessException { if (!rs.next()) { handleNoRowFound(); } else { try { streamData(rs); if (rs.next()) { handleMultipleRowsFound(); } } catch (IOException ex) { throw new LobRetrievalFailureException("Couldn't stream LOB content", ex); } } return null; } /** * Handle the case where the ResultSet does not contain a row. * @throws DataAccessException a corresponding exception, * by default an EmptyResultDataAccessException * @see org.springframework.dao.EmptyResultDataAccessException */ protected void handleNoRowFound() throws DataAccessException { throw new EmptyResultDataAccessException( "LobStreamingResultSetExtractor did not find row in database", 1); } /** * Handle the case where the ResultSet contains multiple rows. * @throws DataAccessException a corresponding exception, * by default an IncorrectResultSizeDataAccessException * @see org.springframework.dao.IncorrectResultSizeDataAccessException */ protected void handleMultipleRowsFound() throws DataAccessException { throw new IncorrectResultSizeDataAccessException( "LobStreamingResultSetExtractor found multiple rows in database", 1); } /** * Stream LOB content from the given ResultSet to some OutputStream. *

Typically used as inner class, with access to surrounding method arguments * and to a LobHandler instance variable of the surrounding class. * @param rs the ResultSet to take the LOB content from * @throws SQLException if thrown by JDBC methods * @throws IOException if thrown by stream access methods * @throws DataAccessException in case of custom exceptions * @see org.springframework.jdbc.support.lob.LobHandler#getBlobAsBinaryStream * @see org.springframework.util.FileCopyUtils */ protected abstract void streamData(ResultSet rs) throws SQLException, IOException, DataAccessException; } ././@LongLink0000000000000000000000000000022100000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/support/JdbcBeanDefinitionReader.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001042311623223530033265 0ustar drazzibdrazzib/* * Copyright 2002-2006 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.support; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Properties; import javax.sql.DataSource; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.PropertiesBeanDefinitionReader; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowCallbackHandler; import org.springframework.util.Assert; /** * Bean definition reader that reads values from a database table, * based on a given SQL statement. * *

Expects columns for bean name, property name and value as String. * Formats for each are identical to the properties format recognized * by PropertiesBeanDefinitionReader. * *

NOTE: This is mainly intended as an example for a custom * JDBC-based bean definition reader. It does not aim to offer * comprehensive functionality. * * @author Rod Johnson * @author Juergen Hoeller * @see #loadBeanDefinitions * @see org.springframework.beans.factory.support.PropertiesBeanDefinitionReader */ public class JdbcBeanDefinitionReader { private final PropertiesBeanDefinitionReader propReader; private JdbcTemplate jdbcTemplate; /** * Create a new JdbcBeanDefinitionReader for the given bean factory, * using a default PropertiesBeanDefinitionReader underneath. *

DataSource or JdbcTemplate still need to be set. * @see #setDataSource * @see #setJdbcTemplate */ public JdbcBeanDefinitionReader(BeanDefinitionRegistry beanFactory) { this.propReader = new PropertiesBeanDefinitionReader(beanFactory); } /** * Create a new JdbcBeanDefinitionReader that delegates to the * given PropertiesBeanDefinitionReader underneath. *

DataSource or JdbcTemplate still need to be set. * @see #setDataSource * @see #setJdbcTemplate */ public JdbcBeanDefinitionReader(PropertiesBeanDefinitionReader beanDefinitionReader) { Assert.notNull(beanDefinitionReader, "Bean definition reader must not be null"); this.propReader = beanDefinitionReader; } /** * Set the DataSource to use to obtain database connections. * Will implicitly create a new JdbcTemplate with the given DataSource. */ public void setDataSource(DataSource dataSource) { this.jdbcTemplate = new JdbcTemplate(dataSource); } /** * Set the JdbcTemplate to be used by this bean factory. * Contains settings for DataSource, SQLExceptionTranslator, NativeJdbcExtractor, etc. */ public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { Assert.notNull(jdbcTemplate, "JdbcTemplate must not be null"); this.jdbcTemplate = jdbcTemplate; } /** * Load bean definitions from the database via the given SQL string. * @param sql SQL query to use for loading bean definitions. * The first three columns must be bean name, property name and value. * Any join and any other columns are permitted: e.g. * SELECT BEAN_NAME, PROPERTY, VALUE FROM CONFIG WHERE CONFIG.APP_ID = 1 * It's also possible to perform a join. Column names are not significant -- * only the ordering of these first three columns. */ public void loadBeanDefinitions(String sql) { Assert.notNull(this.jdbcTemplate, "Not fully configured - specify DataSource or JdbcTemplate"); final Properties props = new Properties(); this.jdbcTemplate.query(sql, new RowCallbackHandler() { public void processRow(ResultSet rs) throws SQLException { String beanName = rs.getString(1); String property = rs.getString(2); String value = rs.getString(3); // Make a properties entry by combining bean name and property. props.setProperty(beanName + "." + property, value); } }); this.propReader.registerBeanDefinitions(props); } } ././@LongLink0000000000000000000000000000021500000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/support/AbstractSqlTypeValue.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000572511623223530033276 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.support; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import org.springframework.jdbc.core.SqlTypeValue; /** * Abstract implementation of the SqlTypeValue interface, for convenient * creation of type values that are supposed to be passed into the * PreparedStatement.setObject method. The createTypeValue * callback method has access to the underlying Connection, if that should * be needed to create any database-specific objects. * *

A usage example from a StoredProcedure (compare this to the plain * SqlTypeValue version in the superclass javadoc): * *

proc.declareParameter(new SqlParameter("myarray", Types.ARRAY, "NUMBERS"));
 * ...
 *
 * Map<String, Object> in = new HashMap<String, Object>();
 * in.put("myarray", new AbstractSqlTypeValue() {
 *   public Object createTypeValue(Connection con, int sqlType, String typeName) throws SQLException {
 *	   oracle.sql.ArrayDescriptor desc = new oracle.sql.ArrayDescriptor(typeName, con);
 *	   return new oracle.sql.ARRAY(desc, con, seats);
 *   }
 * });
 * Map out = execute(in);
 * 
* * @author Juergen Hoeller * @since 1.1 * @see java.sql.PreparedStatement#setObject(int, Object, int) * @see org.springframework.jdbc.object.StoredProcedure */ public abstract class AbstractSqlTypeValue implements SqlTypeValue { public final void setTypeValue(PreparedStatement ps, int paramIndex, int sqlType, String typeName) throws SQLException { Object value = createTypeValue(ps.getConnection(), sqlType, typeName); if (sqlType == TYPE_UNKNOWN) { ps.setObject(paramIndex, value); } else { ps.setObject(paramIndex, value, sqlType); } } /** * Create the type value to be passed into PreparedStatement.setObject. * @param con the JDBC Connection, if needed to create any database-specific objects * @param sqlType SQL type of the parameter we are setting * @param typeName the type name of the parameter * @return the type value * @throws SQLException if a SQLException is encountered setting * parameter values (that is, there's no need to catch SQLException) * @see java.sql.PreparedStatement#setObject(int, Object, int) */ protected abstract Object createTypeValue(Connection con, int sqlType, String typeName) throws SQLException; } ././@LongLink0000000000000000000000000000025200000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/support/AbstractInterruptibleBatchPreparedStatementSetter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000504511623223530033271 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.support; import java.sql.PreparedStatement; import java.sql.SQLException; import org.springframework.jdbc.core.InterruptibleBatchPreparedStatementSetter; /** * Abstract implementation of the {@link InterruptibleBatchPreparedStatementSetter} * interface, combining the check for available values and setting of those * into a single callback method {@link #setValuesIfAvailable}. * * @author Juergen Hoeller * @since 2.0 * @see #setValuesIfAvailable */ public abstract class AbstractInterruptibleBatchPreparedStatementSetter implements InterruptibleBatchPreparedStatementSetter { private boolean exhausted; /** * This implementation calls {@link #setValuesIfAvailable} * and sets this instance's exhaustion flag accordingly. */ public final void setValues(PreparedStatement ps, int i) throws SQLException { this.exhausted = !setValuesIfAvailable(ps, i); } /** * This implementation return this instance's current exhaustion flag. */ public final boolean isBatchExhausted(int i) { return this.exhausted; } /** * This implementation returns Integer.MAX_VALUE. * Can be overridden in subclasses to lower the maximum batch size. */ public int getBatchSize() { return Integer.MAX_VALUE; } /** * Check for available values and set them on the given PreparedStatement. * If no values are available anymore, return false. * @param ps PreparedStatement we'll invoke setter methods on * @param i index of the statement we're issuing in the batch, starting from 0 * @return whether there were values to apply (that is, whether the applied * parameters should be added to the batch and this method should be called * for a further iteration) * @throws SQLException if a SQLException is encountered * (i.e. there is no need to catch SQLException) */ protected abstract boolean setValuesIfAvailable(PreparedStatement ps, int i) throws SQLException; } ././@LongLink0000000000000000000000000000020400000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/support/SqlLobValue.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001654611623223526033306 0ustar drazzibdrazzib/* * Copyright 2002-2006 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.support; import java.io.InputStream; import java.io.Reader; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Types; import org.springframework.jdbc.core.DisposableSqlTypeValue; import org.springframework.jdbc.support.lob.DefaultLobHandler; import org.springframework.jdbc.support.lob.LobCreator; import org.springframework.jdbc.support.lob.LobHandler; /** * Object to represent an SQL BLOB/CLOB value parameter. BLOBs can either be an * InputStream or a byte array. CLOBs can be in the form of a Reader, InputStream * or String. Each CLOB/BLOB value will be stored together with its length. * The type is based on which constructor is used. Objects of this class are * immutable except for the LobCreator reference. Use them and discard them. * *

This class holds a reference to a LocCreator that must be closed after the * update has completed. This is done via a call to the closeLobCreator method. * All handling of the LobCreator is done by the framework classes that use it - * no need to set or close the LobCreator for end users of this class. * *

A usage example: * *

JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);  // reusable object
 * LobHandler lobHandler = new DefaultLobHandler();  // reusable object
 *
 * jdbcTemplate.update(
 *     "INSERT INTO imagedb (image_name, content, description) VALUES (?, ?, ?)",
 *     new Object[] {
 *       name,
 *       new SqlLobValue(contentStream, contentLength, lobHandler),
 *       new SqlLobValue(description, lobHandler)
 *     },
 *     new int[] {Types.VARCHAR, Types.BLOB, Types.CLOB});
 * 
* * @author Thomas Risberg * @author Juergen Hoeller * @since 1.1 * @see org.springframework.jdbc.support.lob.LobHandler * @see org.springframework.jdbc.support.lob.LobCreator * @see org.springframework.jdbc.core.JdbcTemplate#update(String, Object[], int[]) * @see org.springframework.jdbc.object.SqlUpdate#update(Object[]) * @see org.springframework.jdbc.object.StoredProcedure#execute(java.util.Map) */ public class SqlLobValue implements DisposableSqlTypeValue { private final Object content; private final int length; /** * This contains a reference to the LobCreator - so we can close it * once the update is done. */ private final LobCreator lobCreator; /** * Create a new BLOB value with the given byte array, * using a DefaultLobHandler. * @param bytes the byte array containing the BLOB value * @see org.springframework.jdbc.support.lob.DefaultLobHandler */ public SqlLobValue(byte[] bytes) { this(bytes, new DefaultLobHandler()); } /** * Create a new BLOB value with the given byte array. * @param bytes the byte array containing the BLOB value * @param lobHandler the LobHandler to be used */ public SqlLobValue(byte[] bytes, LobHandler lobHandler) { this.content = bytes; this.length = (bytes != null ? bytes.length : 0); this.lobCreator = lobHandler.getLobCreator(); } /** * Create a new CLOB value with the given content string, * using a DefaultLobHandler. * @param content the String containing the CLOB value * @see org.springframework.jdbc.support.lob.DefaultLobHandler */ public SqlLobValue(String content) { this(content, new DefaultLobHandler()); } /** * Create a new CLOB value with the given content string. * @param content the String containing the CLOB value * @param lobHandler the LobHandler to be used */ public SqlLobValue(String content, LobHandler lobHandler) { this.content = content; this.length = (content != null ? content.length() : 0); this.lobCreator = lobHandler.getLobCreator(); } /** * Create a new BLOB/CLOB value with the given stream, * using a DefaultLobHandler. * @param stream the stream containing the LOB value * @param length the length of the LOB value * @see org.springframework.jdbc.support.lob.DefaultLobHandler */ public SqlLobValue(InputStream stream, int length) { this(stream, length, new DefaultLobHandler()); } /** * Create a new BLOB/CLOB value with the given stream. * @param stream the stream containing the LOB value * @param length the length of the LOB value * @param lobHandler the LobHandler to be used */ public SqlLobValue(InputStream stream, int length, LobHandler lobHandler) { this.content = stream; this.length = length; this.lobCreator = lobHandler.getLobCreator(); } /** * Create a new CLOB value with the given character stream, * using a DefaultLobHandler. * @param reader the character stream containing the CLOB value * @param length the length of the CLOB value * @see org.springframework.jdbc.support.lob.DefaultLobHandler */ public SqlLobValue(Reader reader, int length) { this(reader, length, new DefaultLobHandler()); } /** * Create a new CLOB value with the given character stream. * @param reader the character stream containing the CLOB value * @param length the length of the CLOB value * @param lobHandler the LobHandler to be used */ public SqlLobValue(Reader reader, int length, LobHandler lobHandler) { this.content = reader; this.length = length; this.lobCreator = lobHandler.getLobCreator(); } /** * Set the specified content via the LobCreator. */ public void setTypeValue(PreparedStatement ps, int paramIndex, int sqlType, String typeName) throws SQLException { if (sqlType == Types.BLOB) { if (this.content instanceof byte[] || this.content == null) { this.lobCreator.setBlobAsBytes(ps, paramIndex, (byte[]) this.content); } else if (this.content instanceof String) { this.lobCreator.setBlobAsBytes(ps, paramIndex, ((String) this.content).getBytes()); } else if (this.content instanceof InputStream) { this.lobCreator.setBlobAsBinaryStream(ps, paramIndex, (InputStream) this.content, this.length); } else { throw new IllegalArgumentException( "Content type [" + this.content.getClass().getName() + "] not supported for BLOB columns"); } } else if (sqlType == Types.CLOB) { if (this.content instanceof String || this.content == null) { this.lobCreator.setClobAsString(ps, paramIndex, (String) this.content); } else if (this.content instanceof InputStream) { this.lobCreator.setClobAsAsciiStream(ps, paramIndex, (InputStream) this.content, this.length); } else if (this.content instanceof Reader) { this.lobCreator.setClobAsCharacterStream(ps, paramIndex, (Reader) this.content, this.length); } else { throw new IllegalArgumentException( "Content type [" + this.content.getClass().getName() + "] not supported for CLOB columns"); } } else { throw new IllegalArgumentException("SqlLobValue only supports SQL types BLOB and CLOB"); } } /** * Close the LobCreator, if any. */ public void cleanup() { this.lobCreator.close(); } } ././@LongLink0000000000000000000000000000024500000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/support/AbstractLobCreatingPreparedStatementCallback.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000627711623223530033301 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.support; import java.sql.PreparedStatement; import java.sql.SQLException; import org.springframework.dao.DataAccessException; import org.springframework.jdbc.core.PreparedStatementCallback; import org.springframework.jdbc.support.lob.LobCreator; import org.springframework.jdbc.support.lob.LobHandler; /** * Abstract PreparedStatementCallback implementation that manages a LobCreator. * Typically used as inner class, with access to surrounding method arguments. * *

Delegates to the setValues template method for setting values * on the PreparedStatement, using a given LobCreator for BLOB/CLOB arguments. * *

A usage example with JdbcTemplate: * *

JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);  // reusable object
 * LobHandler lobHandler = new DefaultLobHandler();  // reusable object
 *
 * jdbcTemplate.execute(
 *     "INSERT INTO imagedb (image_name, content, description) VALUES (?, ?, ?)",
 *     new AbstractLobCreatingPreparedStatementCallback(lobHandler) {
 *       protected void setValues(PreparedStatement ps, LobCreator lobCreator) throws SQLException {
 *         ps.setString(1, name);
 *         lobCreator.setBlobAsBinaryStream(ps, 2, contentStream, contentLength);
 *         lobCreator.setClobAsString(ps, 3, description);
 *       }
 *     }
 * );
* * @author Juergen Hoeller * @since 1.0.2 * @see org.springframework.jdbc.support.lob.LobCreator */ public abstract class AbstractLobCreatingPreparedStatementCallback implements PreparedStatementCallback { private final LobHandler lobHandler; /** * Create a new AbstractLobCreatingPreparedStatementCallback for the * given LobHandler. * @param lobHandler the LobHandler to create LobCreators with */ public AbstractLobCreatingPreparedStatementCallback(LobHandler lobHandler) { this.lobHandler = lobHandler; } public final Integer doInPreparedStatement(PreparedStatement ps) throws SQLException, DataAccessException { LobCreator lobCreator = this.lobHandler.getLobCreator(); try { setValues(ps, lobCreator); return ps.executeUpdate(); } finally { lobCreator.close(); } } /** * Set values on the given PreparedStatement, using the given * LobCreator for BLOB/CLOB arguments. * @param ps the PreparedStatement to use * @param lobCreator the LobCreator to use * @throws SQLException if thrown by JDBC methods * @throws DataAccessException in case of custom exceptions */ protected abstract void setValues(PreparedStatement ps, LobCreator lobCreator) throws SQLException, DataAccessException; } ././@LongLink0000000000000000000000000000020200000000000011557 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/ParameterDisposer.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000277611623223526033306 0ustar drazzibdrazzib/* * Copyright 2002-2005 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; /** * Interface to be implemented by objects that can close resources * allocated by parameters like SqlLobValues. * *

Typically implemented by PreparedStatementCreators and * PreparedStatementSetters that support DisposableSqlTypeValue * objects (e.g. SqlLobValue) as parameters. * * @author Thomas Risberg * @author Juergen Hoeller * @since 1.1 * @see PreparedStatementCreator * @see PreparedStatementSetter * @see DisposableSqlTypeValue * @see org.springframework.jdbc.core.support.SqlLobValue */ public interface ParameterDisposer { /** * Close the resources allocated by parameters that the implementing * object holds, for example in case of a DisposableSqlTypeValue * (like a SqlLobValue). * @see DisposableSqlTypeValue#cleanup * @see org.springframework.jdbc.core.support.SqlLobValue#cleanup */ public void cleanupParameters(); } ././@LongLink0000000000000000000000000000021300000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/ArgPreparedStatementSetter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000432111623223530033265 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; import java.sql.PreparedStatement; import java.sql.SQLException; /** * Simple adapter for PreparedStatementSetter that applies * a given array of arguments. * * @author Juergen Hoeller */ class ArgPreparedStatementSetter implements PreparedStatementSetter, ParameterDisposer { private final Object[] args; /** * Create a new ArgPreparedStatementSetter for the given arguments. * @param args the arguments to set */ public ArgPreparedStatementSetter(Object[] args) { this.args = args; } public void setValues(PreparedStatement ps) throws SQLException { if (this.args != null) { for (int i = 0; i < this.args.length; i++) { Object arg = this.args[i]; doSetValue(ps, i + 1, arg); } } } /** * Set the value for prepared statements specified parameter index using the passed in value. * This method can be overridden by sub-classes if needed. * @param ps the PreparedStatement * @param parameterPosition index of the parameter position * @param argValue the value to set * @throws SQLException */ protected void doSetValue(PreparedStatement ps, int parameterPosition, Object argValue) throws SQLException { if (argValue instanceof SqlParameterValue) { SqlParameterValue paramValue = (SqlParameterValue) argValue; StatementCreatorUtils.setParameterValue(ps, parameterPosition, paramValue, paramValue.getValue()); } else { StatementCreatorUtils.setParameterValue(ps, parameterPosition, SqlTypeValue.TYPE_UNKNOWN, argValue); } } public void cleanupParameters() { StatementCreatorUtils.cleanupParameters(this.args); } } ././@LongLink0000000000000000000000000000022000000000000011557 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/CallableStatementCreatorFactory.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001753411623223526033304 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor; /** * Helper class that efficiently creates multiple {@link CallableStatementCreator} * objects with different parameters based on a SQL statement and a single * set of parameter declarations. * * @author Rod Johnson * @author Thomas Risberg * @author Juergen Hoeller */ public class CallableStatementCreatorFactory { /** The SQL call string, which won't change when the parameters change. */ private final String callString; /** List of SqlParameter objects. May not be null. */ private final List declaredParameters; private int resultSetType = ResultSet.TYPE_FORWARD_ONLY; private boolean updatableResults = false; private NativeJdbcExtractor nativeJdbcExtractor; /** * Create a new factory. Will need to add parameters via the * {@link #addParameter} method or have no parameters. */ public CallableStatementCreatorFactory(String callString) { this.callString = callString; this.declaredParameters = new LinkedList(); } /** * Create a new factory with the given SQL and the given parameters. * @param callString the SQL call string * @param declaredParameters list of {@link SqlParameter} objects */ public CallableStatementCreatorFactory(String callString, List declaredParameters) { this.callString = callString; this.declaredParameters = declaredParameters; } /** * Add a new declared parameter. *

Order of parameter addition is significant. * @param param the parameter to add to the list of declared parameters */ public void addParameter(SqlParameter param) { this.declaredParameters.add(param); } /** * Set whether to use prepared statements that return a specific type of ResultSet. * specific type of ResultSet. * @param resultSetType the ResultSet type * @see java.sql.ResultSet#TYPE_FORWARD_ONLY * @see java.sql.ResultSet#TYPE_SCROLL_INSENSITIVE * @see java.sql.ResultSet#TYPE_SCROLL_SENSITIVE */ public void setResultSetType(int resultSetType) { this.resultSetType = resultSetType; } /** * Set whether to use prepared statements capable of returning updatable ResultSets. */ public void setUpdatableResults(boolean updatableResults) { this.updatableResults = updatableResults; } /** * Specify the NativeJdbcExtractor to use for unwrapping CallableStatements, if any. */ public void setNativeJdbcExtractor(NativeJdbcExtractor nativeJdbcExtractor) { this.nativeJdbcExtractor = nativeJdbcExtractor; } /** * Return a new CallableStatementCreator instance given this parameters. * @param params list of parameters (may be null) */ public CallableStatementCreator newCallableStatementCreator(Map params) { return new CallableStatementCreatorImpl(params != null ? params : new HashMap()); } /** * Return a new CallableStatementCreator instance given this parameter mapper. * @param inParamMapper ParameterMapper implementation that will return a Map of parameters */ public CallableStatementCreator newCallableStatementCreator(ParameterMapper inParamMapper) { return new CallableStatementCreatorImpl(inParamMapper); } /** * CallableStatementCreator implementation returned by this class. */ private class CallableStatementCreatorImpl implements CallableStatementCreator, SqlProvider, ParameterDisposer { private ParameterMapper inParameterMapper; private Map inParameters; /** * Create a new CallableStatementCreatorImpl. * @param inParamMapper ParameterMapper implementation for mapping input parameters */ public CallableStatementCreatorImpl(ParameterMapper inParamMapper) { this.inParameterMapper = inParamMapper; } /** * Create a new CallableStatementCreatorImpl. * @param inParams list of SqlParameter objects */ public CallableStatementCreatorImpl(Map inParams) { this.inParameters = inParams; } public CallableStatement createCallableStatement(Connection con) throws SQLException { // If we were given a ParameterMapper, we must let the mapper do its thing to create the Map. if (this.inParameterMapper != null) { this.inParameters = this.inParameterMapper.createMap(con); } else { if (this.inParameters == null) { throw new InvalidDataAccessApiUsageException( "A ParameterMapper or a Map of parameters must be provided"); } } CallableStatement cs = null; if (resultSetType == ResultSet.TYPE_FORWARD_ONLY && !updatableResults) { cs = con.prepareCall(callString); } else { cs = con.prepareCall(callString, resultSetType, updatableResults ? ResultSet.CONCUR_UPDATABLE : ResultSet.CONCUR_READ_ONLY); } // Determine CallabeStatement to pass to custom types. CallableStatement csToUse = cs; if (nativeJdbcExtractor != null) { csToUse = nativeJdbcExtractor.getNativeCallableStatement(cs); } int sqlColIndx = 1; for (SqlParameter declaredParam : declaredParameters) { if (!declaredParam.isResultsParameter()) { // So, it's a call parameter - part of the call string. // Get the value - it may still be null. Object inValue = this.inParameters.get(declaredParam.getName()); if (declaredParam instanceof ResultSetSupportingSqlParameter) { // It's an output parameter: SqlReturnResultSet parameters already excluded. // It need not (but may be) supplied by the caller. if (declaredParam instanceof SqlOutParameter) { if (declaredParam.getTypeName() != null) { cs.registerOutParameter(sqlColIndx, declaredParam.getSqlType(), declaredParam.getTypeName()); } else { if (declaredParam.getScale() != null) { cs.registerOutParameter(sqlColIndx, declaredParam.getSqlType(), declaredParam.getScale()); } else { cs.registerOutParameter(sqlColIndx, declaredParam.getSqlType()); } } if (declaredParam.isInputValueProvided()) { StatementCreatorUtils.setParameterValue(csToUse, sqlColIndx, declaredParam, inValue); } } } else { // It's an input parameter; must be supplied by the caller. if (!this.inParameters.containsKey(declaredParam.getName())) { throw new InvalidDataAccessApiUsageException( "Required input parameter '" + declaredParam.getName() + "' is missing"); } StatementCreatorUtils.setParameterValue(csToUse, sqlColIndx, declaredParam, inValue); } sqlColIndx++; } } return cs; } public String getSql() { return callString; } public void cleanupParameters() { if (this.inParameters != null) { StatementCreatorUtils.cleanupParameters(this.inParameters.values()); } } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("CallableStatementCreatorFactory.CallableStatementCreatorImpl: sql=["); sb.append(callString).append("]; parameters=").append(this.inParameters); return sb.toString(); } } } ././@LongLink0000000000000000000000000000017500000000000011570 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/SqlTypeValue.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000507111623223530033270 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; import java.sql.PreparedStatement; import java.sql.SQLException; import org.springframework.jdbc.support.JdbcUtils; /** * Interface to be implemented for setting values for more complex database-specific * types not supported by the standard setObject method. This is * effectively an extended variant of {@link org.springframework.jdbc.support.SqlValue}. * *

Implementations perform the actual work of setting the actual values. They must * implement the callback method setTypeValue which can throw SQLExceptions * that will be caught and translated by the calling code. This callback method has * access to the underlying Connection via the given PreparedStatement object, if that * should be needed to create any database-specific objects. * * @author Thomas Risberg * @author Juergen Hoeller * @since 1.1 * @see java.sql.Types * @see java.sql.PreparedStatement#setObject * @see JdbcOperations#update(String, Object[], int[]) * @see org.springframework.jdbc.support.SqlValue */ public interface SqlTypeValue { /** * Constant that indicates an unknown (or unspecified) SQL type. * Passed into setTypeValue if the original operation method * does not specify a SQL type. * @see java.sql.Types * @see JdbcOperations#update(String, Object[]) */ int TYPE_UNKNOWN = JdbcUtils.TYPE_UNKNOWN; /** * Set the type value on the given PreparedStatement. * @param ps the PreparedStatement to work on * @param paramIndex the index of the parameter for which we need to set the value * @param sqlType SQL type of the parameter we are setting * @param typeName the type name of the parameter (optional) * @throws SQLException if a SQLException is encountered while setting parameter values * @see java.sql.Types * @see java.sql.PreparedStatement#setObject */ void setTypeValue(PreparedStatement ps, int paramIndex, int sqlType, String typeName) throws SQLException; } ././@LongLink0000000000000000000000000000021700000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/ArgTypePreparedStatementSetter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000646011623223526033300 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Types; import java.util.Collection; import java.util.Iterator; import org.springframework.dao.InvalidDataAccessApiUsageException; /** * Simple adapter for PreparedStatementSetter that applies * given arrays of arguments and JDBC argument types. * * @author Juergen Hoeller */ class ArgTypePreparedStatementSetter implements PreparedStatementSetter, ParameterDisposer { private final Object[] args; private final int[] argTypes; /** * Create a new ArgTypePreparedStatementSetter for the given arguments. * @param args the arguments to set * @param argTypes the corresponding SQL types of the arguments */ public ArgTypePreparedStatementSetter(Object[] args, int[] argTypes) { if ((args != null && argTypes == null) || (args == null && argTypes != null) || (args != null && args.length != argTypes.length)) { throw new InvalidDataAccessApiUsageException("args and argTypes parameters must match"); } this.args = args; this.argTypes = argTypes; } public void setValues(PreparedStatement ps) throws SQLException { int parameterPosition = 1; if (this.args != null) { for (int i = 0; i < this.args.length; i++) { Object arg = this.args[i]; if (arg instanceof Collection && this.argTypes[i] != Types.ARRAY) { Collection entries = (Collection) arg; for (Iterator it = entries.iterator(); it.hasNext();) { Object entry = it.next(); if (entry instanceof Object[]) { Object[] valueArray = ((Object[])entry); for (int k = 0; k < valueArray.length; k++) { Object argValue = valueArray[k]; doSetValue(ps, parameterPosition, this.argTypes[i], argValue); parameterPosition++; } } else { doSetValue(ps, parameterPosition, this.argTypes[i], entry); parameterPosition++; } } } else { doSetValue(ps, parameterPosition, this.argTypes[i], arg); parameterPosition++; } } } } /** * Set the value for the prepared statement's specified parameter position using the passed in * value and type. This method can be overridden by sub-classes if needed. * @param ps the PreparedStatement * @param parameterPosition index of the parameter position * @param argType the argument type * @param argValue the argument value * @throws SQLException */ protected void doSetValue(PreparedStatement ps, int parameterPosition, int argType, Object argValue) throws SQLException { StatementCreatorUtils.setParameterValue(ps, parameterPosition, argType, argValue); } public void cleanupParameters() { StatementCreatorUtils.cleanupParameters(this.args); } } ././@LongLink0000000000000000000000000000021100000000000011557 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/PreparedStatementCreator.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000434611623223530033274 0ustar drazzibdrazzib/* * Copyright 2002-2005 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; /** * One of the two central callback interfaces used by the JdbcTemplate class. * This interface creates a PreparedStatement given a connection, provided * by the JdbcTemplate class. Implementations are responsible for providing * SQL and any necessary parameters. * *

Implementations do not need to concern themselves with * SQLExceptions that may be thrown from operations they attempt. * The JdbcTemplate class will catch and handle SQLExceptions appropriately. * *

A PreparedStatementCreator should also implement the SqlProvider interface * if it is able to provide the SQL it uses for PreparedStatement creation. * This allows for better contextual information in case of exceptions. * * @author Rod Johnson * @see JdbcTemplate#execute(PreparedStatementCreator, PreparedStatementCallback) * @see JdbcTemplate#query(PreparedStatementCreator, RowCallbackHandler) * @see JdbcTemplate#update(PreparedStatementCreator) * @see SqlProvider */ public interface PreparedStatementCreator { /** * Create a statement in this connection. Allows implementations to use * PreparedStatements. The JdbcTemplate will close the created statement. * @param con Connection to use to create statement * @return a prepared statement * @throws SQLException there is no need to catch SQLExceptions * that may be thrown in the implementation of this method. * The JdbcTemplate class will handle them. */ PreparedStatement createPreparedStatement(Connection con) throws SQLException; } ././@LongLink0000000000000000000000000000020300000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/ConnectionCallback.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000551011623223530033266 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; import java.sql.Connection; import java.sql.SQLException; import org.springframework.dao.DataAccessException; /** * Generic callback interface for code that operates on a JDBC Connection. * Allows to execute any number of operations on a single Connection, * using any type and number of Statements. * *

This is particularly useful for delegating to existing data access code * that expects a Connection to work on and throws SQLException. For newly * written code, it is strongly recommended to use JdbcTemplate's more specific * operations, for example a query or update variant. * * @author Juergen Hoeller * @since 1.1.3 * @see JdbcTemplate#execute(ConnectionCallback) * @see JdbcTemplate#query * @see JdbcTemplate#update */ public interface ConnectionCallback { /** * Gets called by JdbcTemplate.execute with an active JDBC * Connection. Does not need to care about activating or closing the * Connection, or handling transactions. * *

If called without a thread-bound JDBC transaction (initiated by * DataSourceTransactionManager), the code will simply get executed on the * JDBC connection with its transactional semantics. If JdbcTemplate is * configured to use a JTA-aware DataSource, the JDBC Connection and thus * the callback code will be transactional if a JTA transaction is active. * *

Allows for returning a result object created within the callback, i.e. * a domain object or a collection of domain objects. Note that there's special * support for single step actions: see JdbcTemplate.queryForObject * etc. A thrown RuntimeException is treated as application exception: * it gets propagated to the caller of the template. * * @param con active JDBC Connection * @return a result object, or null if none * @throws SQLException if thrown by a JDBC method, to be auto-converted * to a DataAccessException by a SQLExceptionTranslator * @throws DataAccessException in case of custom exceptions * @see JdbcTemplate#queryForObject(String, Class) * @see JdbcTemplate#queryForRowSet(String) */ T doInConnection(Connection con) throws SQLException, DataAccessException; } ././@LongLink0000000000000000000000000000021000000000000011556 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/RowCountCallbackHandler.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001030311623223526033267 0ustar drazzibdrazzib/* * Copyright 2002-2006 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; import org.springframework.jdbc.support.JdbcUtils; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; /** * Implementation of RowCallbackHandler. Convenient superclass for callback handlers. * An instance can only be used once. * *

We can either use this on its own (for example, in a test case, to ensure * that our result sets have valid dimensions), or use it as a superclass * for callback handlers that actually do something, and will benefit * from the dimension information it provides. * *

A usage example with JdbcTemplate: * *

JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);  // reusable object
 * 
 * RowCountCallbackHandler countCallback = new RowCountCallbackHandler();  // not reusable
 * jdbcTemplate.query("select * from user", countCallback);
 * int rowCount = countCallback.getRowCount();
* * @author Rod Johnson * @since May 3, 2001 */ public class RowCountCallbackHandler implements RowCallbackHandler { /** Rows we've seen so far */ private int rowCount; /** Columns we've seen so far */ private int columnCount; /** * Indexed from 0. Type (as in java.sql.Types) for the columns * as returned by ResultSetMetaData object. */ private int[] columnTypes; /** * Indexed from 0. Column name as returned by ResultSetMetaData object. */ private String[] columnNames; /** * Implementation of ResultSetCallbackHandler. * Work out column size if this is the first row, otherwise just count rows. *

Subclasses can perform custom extraction or processing * by overriding the processRow(ResultSet, int) method. * @see #processRow(java.sql.ResultSet, int) */ public final void processRow(ResultSet rs) throws SQLException { if (this.rowCount == 0) { ResultSetMetaData rsmd = rs.getMetaData(); this.columnCount = rsmd.getColumnCount(); this.columnTypes = new int[this.columnCount]; this.columnNames = new String[this.columnCount]; for (int i = 0; i < this.columnCount; i++) { this.columnTypes[i] = rsmd.getColumnType(i + 1); this.columnNames[i] = JdbcUtils.lookupColumnName(rsmd, i + 1); } // could also get column names } processRow(rs, this.rowCount++); } /** * Subclasses may override this to perform custom extraction * or processing. This class's implementation does nothing. * @param rs ResultSet to extract data from. This method is * invoked for each row * @param rowNum number of the current row (starting from 0) */ protected void processRow(ResultSet rs, int rowNum) throws SQLException { } /** * Return the types of the columns as java.sql.Types constants * Valid after processRow is invoked the first time. * @return the types of the columns as java.sql.Types constants. * Indexed from 0 to n-1. */ public final int[] getColumnTypes() { return columnTypes; } /** * Return the names of the columns. * Valid after processRow is invoked the first time. * @return the names of the columns. * Indexed from 0 to n-1. */ public final String[] getColumnNames() { return columnNames; } /** * Return the row count of this ResultSet * Only valid after processing is complete * @return the number of rows in this ResultSet */ public final int getRowCount() { return rowCount; } /** * Return the number of columns in this result set. * Valid once we've seen the first row, * so subclasses can use it during processing * @return the number of columns in this result set */ public final int getColumnCount() { return columnCount; } } ././@LongLink0000000000000000000000000000017500000000000011570 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000014367711623223530033307 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.SQLWarning; import java.sql.Statement; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import javax.sql.DataSource; import org.springframework.dao.DataAccessException; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.dao.support.DataAccessUtils; import org.springframework.jdbc.SQLWarningException; import org.springframework.jdbc.datasource.ConnectionProxy; import org.springframework.jdbc.datasource.DataSourceUtils; import org.springframework.jdbc.support.JdbcAccessor; import org.springframework.jdbc.support.JdbcUtils; import org.springframework.jdbc.support.KeyHolder; import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor; import org.springframework.jdbc.support.rowset.SqlRowSet; import org.springframework.util.Assert; import org.springframework.util.LinkedCaseInsensitiveMap; /** * This is the central class in the JDBC core package. * It simplifies the use of JDBC and helps to avoid common errors. * It executes core JDBC workflow, leaving application code to provide SQL * and extract results. This class executes SQL queries or updates, initiating * iteration over ResultSets and catching JDBC exceptions and translating * them to the generic, more informative exception hierarchy defined in the * org.springframework.dao package. * *

Code using this class need only implement callback interfaces, giving * them a clearly defined contract. The {@link PreparedStatementCreator} callback * interface creates a prepared statement given a Connection, providing SQL and * any necessary parameters. The {@link ResultSetExtractor} interface extracts * values from a ResultSet. See also {@link PreparedStatementSetter} and * {@link RowMapper} for two popular alternative callback interfaces. * *

Can be used within a service implementation via direct instantiation * with a DataSource reference, or get prepared in an application context * and given to services as bean reference. Note: The DataSource should * always be configured as a bean in the application context, in the first case * given to the service directly, in the second case to the prepared template. * *

Because this class is parameterizable by the callback interfaces and * the {@link org.springframework.jdbc.support.SQLExceptionTranslator} * interface, there should be no need to subclass it. * *

All SQL operations performed by this class are logged at debug level, * using "org.springframework.jdbc.core.JdbcTemplate" as log category. * * @author Rod Johnson * @author Juergen Hoeller * @author Thomas Risberg * @since May 3, 2001 * @see PreparedStatementCreator * @see PreparedStatementSetter * @see CallableStatementCreator * @see PreparedStatementCallback * @see CallableStatementCallback * @see ResultSetExtractor * @see RowCallbackHandler * @see RowMapper * @see org.springframework.jdbc.support.SQLExceptionTranslator */ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations { private static final String RETURN_RESULT_SET_PREFIX = "#result-set-"; private static final String RETURN_UPDATE_COUNT_PREFIX = "#update-count-"; /** Custom NativeJdbcExtractor */ private NativeJdbcExtractor nativeJdbcExtractor; /** If this variable is false, we will throw exceptions on SQL warnings */ private boolean ignoreWarnings = true; /** * If this variable is set to a non-zero value, it will be used for setting the * fetchSize property on statements used for query processing. */ private int fetchSize = 0; /** * If this variable is set to a non-zero value, it will be used for setting the * maxRows property on statements used for query processing. */ private int maxRows = 0; /** * If this variable is set to a non-zero value, it will be used for setting the * queryTimeout property on statements used for query processing. */ private int queryTimeout = 0; /** * If this variable is set to true then all results checking will be bypassed for any * callable statement processing. This can be used to avoid a bug in some older Oracle * JDBC drivers like 10.1.0.2. */ private boolean skipResultsProcessing = false; /** * If this variable is set to true then all results from a stored procedure call * that don't have a corresponding SqlOutParameter declaration will be bypassed. * All other results processng will be take place unless the variable * skipResultsProcessing is set to true */ private boolean skipUndeclaredResults = false; /** * If this variable is set to true then execution of a CallableStatement will return * the results in a Map that uses case insensitive names for the parameters if * Commons Collections is available on the classpath. */ private boolean resultsMapCaseInsensitive = false; /** * Construct a new JdbcTemplate for bean usage. *

Note: The DataSource has to be set before using the instance. * @see #setDataSource */ public JdbcTemplate() { } /** * Construct a new JdbcTemplate, given a DataSource to obtain connections from. *

Note: This will not trigger initialization of the exception translator. * @param dataSource the JDBC DataSource to obtain connections from */ public JdbcTemplate(DataSource dataSource) { setDataSource(dataSource); afterPropertiesSet(); } /** * Construct a new JdbcTemplate, given a DataSource to obtain connections from. *

Note: Depending on the "lazyInit" flag, initialization of the exception translator * will be triggered. * @param dataSource the JDBC DataSource to obtain connections from * @param lazyInit whether to lazily initialize the SQLExceptionTranslator */ public JdbcTemplate(DataSource dataSource, boolean lazyInit) { setDataSource(dataSource); setLazyInit(lazyInit); afterPropertiesSet(); } /** * Set a NativeJdbcExtractor to extract native JDBC objects from wrapped handles. * Useful if native Statement and/or ResultSet handles are expected for casting * to database-specific implementation classes, but a connection pool that wraps * JDBC objects is used (note: any pool will return wrapped Connections). */ public void setNativeJdbcExtractor(NativeJdbcExtractor extractor) { this.nativeJdbcExtractor = extractor; } /** * Return the current NativeJdbcExtractor implementation. */ public NativeJdbcExtractor getNativeJdbcExtractor() { return this.nativeJdbcExtractor; } /** * Set whether or not we want to ignore SQLWarnings. *

Default is "true", swallowing and logging all warnings. Switch this flag * to "false" to make the JdbcTemplate throw a SQLWarningException instead. * @see java.sql.SQLWarning * @see org.springframework.jdbc.SQLWarningException * @see #handleWarnings */ public void setIgnoreWarnings(boolean ignoreWarnings) { this.ignoreWarnings = ignoreWarnings; } /** * Return whether or not we ignore SQLWarnings. */ public boolean isIgnoreWarnings() { return this.ignoreWarnings; } /** * Set the fetch size for this JdbcTemplate. This is important for processing * large result sets: Setting this higher than the default value will increase * processing speed at the cost of memory consumption; setting this lower can * avoid transferring row data that will never be read by the application. *

Default is 0, indicating to use the JDBC driver's default. * @see java.sql.Statement#setFetchSize */ public void setFetchSize(int fetchSize) { this.fetchSize = fetchSize; } /** * Return the fetch size specified for this JdbcTemplate. */ public int getFetchSize() { return this.fetchSize; } /** * Set the maximum number of rows for this JdbcTemplate. This is important * for processing subsets of large result sets, avoiding to read and hold * the entire result set in the database or in the JDBC driver if we're * never interested in the entire result in the first place (for example, * when performing searches that might return a large number of matches). *

Default is 0, indicating to use the JDBC driver's default. * @see java.sql.Statement#setMaxRows */ public void setMaxRows(int maxRows) { this.maxRows = maxRows; } /** * Return the maximum number of rows specified for this JdbcTemplate. */ public int getMaxRows() { return this.maxRows; } /** * Set the query timeout for statements that this JdbcTemplate executes. *

Default is 0, indicating to use the JDBC driver's default. *

Note: Any timeout specified here will be overridden by the remaining * transaction timeout when executing within a transaction that has a * timeout specified at the transaction level. * @see java.sql.Statement#setQueryTimeout */ public void setQueryTimeout(int queryTimeout) { this.queryTimeout = queryTimeout; } /** * Return the query timeout for statements that this JdbcTemplate executes. */ public int getQueryTimeout() { return this.queryTimeout; } /** * Set whether results processing should be skipped. Can be used to optimize callable * statement processing when we know that no results are being passed back - the processing * of out parameter will still take place. This can be used to avoid a bug in some older * Oracle JDBC drivers like 10.1.0.2. */ public void setSkipResultsProcessing(boolean skipResultsProcessing) { this.skipResultsProcessing = skipResultsProcessing; } /** * Return whether results processing should be skipped. */ public boolean isSkipResultsProcessing() { return this.skipResultsProcessing; } /** * Set whether undelared results should be skipped. */ public void setSkipUndeclaredResults(boolean skipUndeclaredResults) { this.skipUndeclaredResults = skipUndeclaredResults; } /** * Return whether undeclared results should be skipped. */ public boolean isSkipUndeclaredResults() { return this.skipUndeclaredResults; } /** * Set whether execution of a CallableStatement will return the results in a Map * that uses case insensitive names for the parameters. */ public void setResultsMapCaseInsensitive(boolean resultsMapCaseInsensitive) { this.resultsMapCaseInsensitive = resultsMapCaseInsensitive; } /** * Return whether execution of a CallableStatement will return the results in a Map * that uses case insensitive names for the parameters. */ public boolean isResultsMapCaseInsensitive() { return this.resultsMapCaseInsensitive; } //------------------------------------------------------------------------- // Methods dealing with a plain java.sql.Connection //------------------------------------------------------------------------- public T execute(ConnectionCallback action) throws DataAccessException { Assert.notNull(action, "Callback object must not be null"); Connection con = DataSourceUtils.getConnection(getDataSource()); try { Connection conToUse = con; if (this.nativeJdbcExtractor != null) { // Extract native JDBC Connection, castable to OracleConnection or the like. conToUse = this.nativeJdbcExtractor.getNativeConnection(con); } else { // Create close-suppressing Connection proxy, also preparing returned Statements. conToUse = createConnectionProxy(con); } return action.doInConnection(conToUse); } catch (SQLException ex) { // Release Connection early, to avoid potential connection pool deadlock // in the case when the exception translator hasn't been initialized yet. DataSourceUtils.releaseConnection(con, getDataSource()); con = null; throw getExceptionTranslator().translate("ConnectionCallback", getSql(action), ex); } finally { DataSourceUtils.releaseConnection(con, getDataSource()); } } /** * Create a close-suppressing proxy for the given JDBC Connection. * Called by the execute method. *

The proxy also prepares returned JDBC Statements, applying * statement settings such as fetch size, max rows, and query timeout. * @param con the JDBC Connection to create a proxy for * @return the Connection proxy * @see java.sql.Connection#close() * @see #execute(ConnectionCallback) * @see #applyStatementSettings */ protected Connection createConnectionProxy(Connection con) { return (Connection) Proxy.newProxyInstance( ConnectionProxy.class.getClassLoader(), new Class[] {ConnectionProxy.class}, new CloseSuppressingInvocationHandler(con)); } //------------------------------------------------------------------------- // Methods dealing with static SQL (java.sql.Statement) //------------------------------------------------------------------------- public T execute(StatementCallback action) throws DataAccessException { Assert.notNull(action, "Callback object must not be null"); Connection con = DataSourceUtils.getConnection(getDataSource()); Statement stmt = null; try { Connection conToUse = con; if (this.nativeJdbcExtractor != null && this.nativeJdbcExtractor.isNativeConnectionNecessaryForNativeStatements()) { conToUse = this.nativeJdbcExtractor.getNativeConnection(con); } stmt = conToUse.createStatement(); applyStatementSettings(stmt); Statement stmtToUse = stmt; if (this.nativeJdbcExtractor != null) { stmtToUse = this.nativeJdbcExtractor.getNativeStatement(stmt); } T result = action.doInStatement(stmtToUse); handleWarnings(stmt); return result; } catch (SQLException ex) { // Release Connection early, to avoid potential connection pool deadlock // in the case when the exception translator hasn't been initialized yet. JdbcUtils.closeStatement(stmt); stmt = null; DataSourceUtils.releaseConnection(con, getDataSource()); con = null; throw getExceptionTranslator().translate("StatementCallback", getSql(action), ex); } finally { JdbcUtils.closeStatement(stmt); DataSourceUtils.releaseConnection(con, getDataSource()); } } public void execute(final String sql) throws DataAccessException { if (logger.isDebugEnabled()) { logger.debug("Executing SQL statement [" + sql + "]"); } class ExecuteStatementCallback implements StatementCallback, SqlProvider { public Object doInStatement(Statement stmt) throws SQLException { stmt.execute(sql); return null; } public String getSql() { return sql; } } execute(new ExecuteStatementCallback()); } public T query(final String sql, final ResultSetExtractor rse) throws DataAccessException { Assert.notNull(sql, "SQL must not be null"); Assert.notNull(rse, "ResultSetExtractor must not be null"); if (logger.isDebugEnabled()) { logger.debug("Executing SQL query [" + sql + "]"); } class QueryStatementCallback implements StatementCallback, SqlProvider { public T doInStatement(Statement stmt) throws SQLException { ResultSet rs = null; try { rs = stmt.executeQuery(sql); ResultSet rsToUse = rs; if (nativeJdbcExtractor != null) { rsToUse = nativeJdbcExtractor.getNativeResultSet(rs); } return rse.extractData(rsToUse); } finally { JdbcUtils.closeResultSet(rs); } } public String getSql() { return sql; } } return execute(new QueryStatementCallback()); } public void query(String sql, RowCallbackHandler rch) throws DataAccessException { query(sql, new RowCallbackHandlerResultSetExtractor(rch)); } public List query(String sql, RowMapper rowMapper) throws DataAccessException { return query(sql, new RowMapperResultSetExtractor(rowMapper)); } public Map queryForMap(String sql) throws DataAccessException { return queryForObject(sql, getColumnMapRowMapper()); } public T queryForObject(String sql, RowMapper rowMapper) throws DataAccessException { List results = query(sql, rowMapper); return DataAccessUtils.requiredSingleResult(results); } public T queryForObject(String sql, Class requiredType) throws DataAccessException { return queryForObject(sql, getSingleColumnRowMapper(requiredType)); } public long queryForLong(String sql) throws DataAccessException { Number number = queryForObject(sql, Long.class); return (number != null ? number.longValue() : 0); } public int queryForInt(String sql) throws DataAccessException { Number number = queryForObject(sql, Integer.class); return (number != null ? number.intValue() : 0); } public List queryForList(String sql, Class elementType) throws DataAccessException { return query(sql, getSingleColumnRowMapper(elementType)); } public List> queryForList(String sql) throws DataAccessException { return query(sql, getColumnMapRowMapper()); } public SqlRowSet queryForRowSet(String sql) throws DataAccessException { return query(sql, new SqlRowSetResultSetExtractor()); } public int update(final String sql) throws DataAccessException { Assert.notNull(sql, "SQL must not be null"); if (logger.isDebugEnabled()) { logger.debug("Executing SQL update [" + sql + "]"); } class UpdateStatementCallback implements StatementCallback, SqlProvider { public Integer doInStatement(Statement stmt) throws SQLException { int rows = stmt.executeUpdate(sql); if (logger.isDebugEnabled()) { logger.debug("SQL update affected " + rows + " rows"); } return rows; } public String getSql() { return sql; } } return execute(new UpdateStatementCallback()); } public int[] batchUpdate(final String[] sql) throws DataAccessException { Assert.notEmpty(sql, "SQL array must not be empty"); if (logger.isDebugEnabled()) { logger.debug("Executing SQL batch update of " + sql.length + " statements"); } class BatchUpdateStatementCallback implements StatementCallback, SqlProvider { private String currSql; public int[] doInStatement(Statement stmt) throws SQLException, DataAccessException { int[] rowsAffected = new int[sql.length]; if (JdbcUtils.supportsBatchUpdates(stmt.getConnection())) { for (String sqlStmt : sql) { this.currSql = sqlStmt; stmt.addBatch(sqlStmt); } rowsAffected = stmt.executeBatch(); } else { for (int i = 0; i < sql.length; i++) { this.currSql = sql[i]; if (!stmt.execute(sql[i])) { rowsAffected[i] = stmt.getUpdateCount(); } else { throw new InvalidDataAccessApiUsageException("Invalid batch SQL statement: " + sql[i]); } } } return rowsAffected; } public String getSql() { return this.currSql; } } return execute(new BatchUpdateStatementCallback()); } //------------------------------------------------------------------------- // Methods dealing with prepared statements //------------------------------------------------------------------------- public T execute(PreparedStatementCreator psc, PreparedStatementCallback action) throws DataAccessException { Assert.notNull(psc, "PreparedStatementCreator must not be null"); Assert.notNull(action, "Callback object must not be null"); if (logger.isDebugEnabled()) { String sql = getSql(psc); logger.debug("Executing prepared SQL statement" + (sql != null ? " [" + sql + "]" : "")); } Connection con = DataSourceUtils.getConnection(getDataSource()); PreparedStatement ps = null; try { Connection conToUse = con; if (this.nativeJdbcExtractor != null && this.nativeJdbcExtractor.isNativeConnectionNecessaryForNativePreparedStatements()) { conToUse = this.nativeJdbcExtractor.getNativeConnection(con); } ps = psc.createPreparedStatement(conToUse); applyStatementSettings(ps); PreparedStatement psToUse = ps; if (this.nativeJdbcExtractor != null) { psToUse = this.nativeJdbcExtractor.getNativePreparedStatement(ps); } T result = action.doInPreparedStatement(psToUse); handleWarnings(ps); return result; } catch (SQLException ex) { // Release Connection early, to avoid potential connection pool deadlock // in the case when the exception translator hasn't been initialized yet. if (psc instanceof ParameterDisposer) { ((ParameterDisposer) psc).cleanupParameters(); } String sql = getSql(psc); psc = null; JdbcUtils.closeStatement(ps); ps = null; DataSourceUtils.releaseConnection(con, getDataSource()); con = null; throw getExceptionTranslator().translate("PreparedStatementCallback", sql, ex); } finally { if (psc instanceof ParameterDisposer) { ((ParameterDisposer) psc).cleanupParameters(); } JdbcUtils.closeStatement(ps); DataSourceUtils.releaseConnection(con, getDataSource()); } } public T execute(String sql, PreparedStatementCallback action) throws DataAccessException { return execute(new SimplePreparedStatementCreator(sql), action); } /** * Query using a prepared statement, allowing for a PreparedStatementCreator * and a PreparedStatementSetter. Most other query methods use this method, * but application code will always work with either a creator or a setter. * @param psc Callback handler that can create a PreparedStatement given a * Connection * @param pss object that knows how to set values on the prepared statement. * If this is null, the SQL will be assumed to contain no bind parameters. * @param rse object that will extract results. * @return an arbitrary result object, as returned by the ResultSetExtractor * @throws DataAccessException if there is any problem */ public T query( PreparedStatementCreator psc, final PreparedStatementSetter pss, final ResultSetExtractor rse) throws DataAccessException { Assert.notNull(rse, "ResultSetExtractor must not be null"); logger.debug("Executing prepared SQL query"); return execute(psc, new PreparedStatementCallback() { public T doInPreparedStatement(PreparedStatement ps) throws SQLException { ResultSet rs = null; try { if (pss != null) { pss.setValues(ps); } rs = ps.executeQuery(); ResultSet rsToUse = rs; if (nativeJdbcExtractor != null) { rsToUse = nativeJdbcExtractor.getNativeResultSet(rs); } return rse.extractData(rsToUse); } finally { JdbcUtils.closeResultSet(rs); if (pss instanceof ParameterDisposer) { ((ParameterDisposer) pss).cleanupParameters(); } } } }); } public T query(PreparedStatementCreator psc, ResultSetExtractor rse) throws DataAccessException { return query(psc, null, rse); } public T query(String sql, PreparedStatementSetter pss, ResultSetExtractor rse) throws DataAccessException { return query(new SimplePreparedStatementCreator(sql), pss, rse); } public T query(String sql, Object[] args, int[] argTypes, ResultSetExtractor rse) throws DataAccessException { return query(sql, newArgTypePreparedStatementSetter(args, argTypes), rse); } public T query(String sql, Object[] args, ResultSetExtractor rse) throws DataAccessException { return query(sql, newArgPreparedStatementSetter(args), rse); } public T query(String sql, ResultSetExtractor rse, Object... args) throws DataAccessException { return query(sql, newArgPreparedStatementSetter(args), rse); } public void query(PreparedStatementCreator psc, RowCallbackHandler rch) throws DataAccessException { query(psc, new RowCallbackHandlerResultSetExtractor(rch)); } public void query(String sql, PreparedStatementSetter pss, RowCallbackHandler rch) throws DataAccessException { query(sql, pss, new RowCallbackHandlerResultSetExtractor(rch)); } public void query(String sql, Object[] args, int[] argTypes, RowCallbackHandler rch) throws DataAccessException { query(sql, newArgTypePreparedStatementSetter(args, argTypes), rch); } public void query(String sql, Object[] args, RowCallbackHandler rch) throws DataAccessException { query(sql, newArgPreparedStatementSetter(args), rch); } public void query(String sql, RowCallbackHandler rch, Object... args) throws DataAccessException { query(sql, newArgPreparedStatementSetter(args), rch); } public List query(PreparedStatementCreator psc, RowMapper rowMapper) throws DataAccessException { return query(psc, new RowMapperResultSetExtractor(rowMapper)); } public List query(String sql, PreparedStatementSetter pss, RowMapper rowMapper) throws DataAccessException { return query(sql, pss, new RowMapperResultSetExtractor(rowMapper)); } public List query(String sql, Object[] args, int[] argTypes, RowMapper rowMapper) throws DataAccessException { return query(sql, args, argTypes, new RowMapperResultSetExtractor(rowMapper)); } public List query(String sql, Object[] args, RowMapper rowMapper) throws DataAccessException { return query(sql, args, new RowMapperResultSetExtractor(rowMapper)); } public List query(String sql, RowMapper rowMapper, Object... args) throws DataAccessException { return query(sql, args, new RowMapperResultSetExtractor(rowMapper)); } public T queryForObject(String sql, Object[] args, int[] argTypes, RowMapper rowMapper) throws DataAccessException { List results = query(sql, args, argTypes, new RowMapperResultSetExtractor(rowMapper, 1)); return DataAccessUtils.requiredSingleResult(results); } public T queryForObject(String sql, Object[] args, RowMapper rowMapper) throws DataAccessException { List results = query(sql, args, new RowMapperResultSetExtractor(rowMapper, 1)); return DataAccessUtils.requiredSingleResult(results); } public T queryForObject(String sql, RowMapper rowMapper, Object... args) throws DataAccessException { List results = query(sql, args, new RowMapperResultSetExtractor(rowMapper, 1)); return DataAccessUtils.requiredSingleResult(results); } public T queryForObject(String sql, Object[] args, int[] argTypes, Class requiredType) throws DataAccessException { return queryForObject(sql, args, argTypes, getSingleColumnRowMapper(requiredType)); } public T queryForObject(String sql, Object[] args, Class requiredType) throws DataAccessException { return queryForObject(sql, args, getSingleColumnRowMapper(requiredType)); } public T queryForObject(String sql, Class requiredType, Object... args) throws DataAccessException { return queryForObject(sql, args, getSingleColumnRowMapper(requiredType)); } public Map queryForMap(String sql, Object[] args, int[] argTypes) throws DataAccessException { return queryForObject(sql, args, argTypes, getColumnMapRowMapper()); } public Map queryForMap(String sql, Object... args) throws DataAccessException { return queryForObject(sql, args, getColumnMapRowMapper()); } public long queryForLong(String sql, Object[] args, int[] argTypes) throws DataAccessException { Number number = queryForObject(sql, args, argTypes, Long.class); return (number != null ? number.longValue() : 0); } public long queryForLong(String sql, Object... args) throws DataAccessException { Number number = queryForObject(sql, args, Long.class); return (number != null ? number.longValue() : 0); } public int queryForInt(String sql, Object[] args, int[] argTypes) throws DataAccessException { Number number = queryForObject(sql, args, argTypes, Integer.class); return (number != null ? number.intValue() : 0); } public int queryForInt(String sql, Object... args) throws DataAccessException { Number number = queryForObject(sql, args, Integer.class); return (number != null ? number.intValue() : 0); } public List queryForList(String sql, Object[] args, int[] argTypes, Class elementType) throws DataAccessException { return query(sql, args, argTypes, getSingleColumnRowMapper(elementType)); } public List queryForList(String sql, Object[] args, Class elementType) throws DataAccessException { return query(sql, args, getSingleColumnRowMapper(elementType)); } public List queryForList(String sql, Class elementType, Object... args) throws DataAccessException { return query(sql, args, getSingleColumnRowMapper(elementType)); } public List> queryForList(String sql, Object[] args, int[] argTypes) throws DataAccessException { return query(sql, args, argTypes, getColumnMapRowMapper()); } public List> queryForList(String sql, Object... args) throws DataAccessException { return query(sql, args, getColumnMapRowMapper()); } public SqlRowSet queryForRowSet(String sql, Object[] args, int[] argTypes) throws DataAccessException { return query(sql, args, argTypes, new SqlRowSetResultSetExtractor()); } public SqlRowSet queryForRowSet(String sql, Object... args) throws DataAccessException { return query(sql, args, new SqlRowSetResultSetExtractor()); } protected int update(final PreparedStatementCreator psc, final PreparedStatementSetter pss) throws DataAccessException { logger.debug("Executing prepared SQL update"); return execute(psc, new PreparedStatementCallback() { public Integer doInPreparedStatement(PreparedStatement ps) throws SQLException { try { if (pss != null) { pss.setValues(ps); } int rows = ps.executeUpdate(); if (logger.isDebugEnabled()) { logger.debug("SQL update affected " + rows + " rows"); } return rows; } finally { if (pss instanceof ParameterDisposer) { ((ParameterDisposer) pss).cleanupParameters(); } } } }); } public int update(PreparedStatementCreator psc) throws DataAccessException { return update(psc, (PreparedStatementSetter) null); } public int update(final PreparedStatementCreator psc, final KeyHolder generatedKeyHolder) throws DataAccessException { Assert.notNull(generatedKeyHolder, "KeyHolder must not be null"); logger.debug("Executing SQL update and returning generated keys"); return execute(psc, new PreparedStatementCallback() { public Integer doInPreparedStatement(PreparedStatement ps) throws SQLException { int rows = ps.executeUpdate(); List> generatedKeys = generatedKeyHolder.getKeyList(); generatedKeys.clear(); ResultSet keys = ps.getGeneratedKeys(); if (keys != null) { try { RowMapperResultSetExtractor> rse = new RowMapperResultSetExtractor>(getColumnMapRowMapper(), 1); generatedKeys.addAll(rse.extractData(keys)); } finally { JdbcUtils.closeResultSet(keys); } } if (logger.isDebugEnabled()) { logger.debug("SQL update affected " + rows + " rows and returned " + generatedKeys.size() + " keys"); } return rows; } }); } public int update(String sql, PreparedStatementSetter pss) throws DataAccessException { return update(new SimplePreparedStatementCreator(sql), pss); } public int update(String sql, Object[] args, int[] argTypes) throws DataAccessException { return update(sql, newArgTypePreparedStatementSetter(args, argTypes)); } public int update(String sql, Object... args) throws DataAccessException { return update(sql, newArgPreparedStatementSetter(args)); } public int[] batchUpdate(String sql, final BatchPreparedStatementSetter pss) throws DataAccessException { if (logger.isDebugEnabled()) { logger.debug("Executing SQL batch update [" + sql + "]"); } return execute(sql, new PreparedStatementCallback() { public int[] doInPreparedStatement(PreparedStatement ps) throws SQLException { try { int batchSize = pss.getBatchSize(); InterruptibleBatchPreparedStatementSetter ipss = (pss instanceof InterruptibleBatchPreparedStatementSetter ? (InterruptibleBatchPreparedStatementSetter) pss : null); if (JdbcUtils.supportsBatchUpdates(ps.getConnection())) { for (int i = 0; i < batchSize; i++) { pss.setValues(ps, i); if (ipss != null && ipss.isBatchExhausted(i)) { break; } ps.addBatch(); } return ps.executeBatch(); } else { List rowsAffected = new ArrayList(); for (int i = 0; i < batchSize; i++) { pss.setValues(ps, i); if (ipss != null && ipss.isBatchExhausted(i)) { break; } rowsAffected.add(ps.executeUpdate()); } int[] rowsAffectedArray = new int[rowsAffected.size()]; for (int i = 0; i < rowsAffectedArray.length; i++) { rowsAffectedArray[i] = rowsAffected.get(i); } return rowsAffectedArray; } } finally { if (pss instanceof ParameterDisposer) { ((ParameterDisposer) pss).cleanupParameters(); } } } }); } //------------------------------------------------------------------------- // Methods dealing with callable statements //------------------------------------------------------------------------- public T execute(CallableStatementCreator csc, CallableStatementCallback action) throws DataAccessException { Assert.notNull(csc, "CallableStatementCreator must not be null"); Assert.notNull(action, "Callback object must not be null"); if (logger.isDebugEnabled()) { String sql = getSql(csc); logger.debug("Calling stored procedure" + (sql != null ? " [" + sql + "]" : "")); } Connection con = DataSourceUtils.getConnection(getDataSource()); CallableStatement cs = null; try { Connection conToUse = con; if (this.nativeJdbcExtractor != null) { conToUse = this.nativeJdbcExtractor.getNativeConnection(con); } cs = csc.createCallableStatement(conToUse); applyStatementSettings(cs); CallableStatement csToUse = cs; if (this.nativeJdbcExtractor != null) { csToUse = this.nativeJdbcExtractor.getNativeCallableStatement(cs); } T result = action.doInCallableStatement(csToUse); handleWarnings(cs); return result; } catch (SQLException ex) { // Release Connection early, to avoid potential connection pool deadlock // in the case when the exception translator hasn't been initialized yet. if (csc instanceof ParameterDisposer) { ((ParameterDisposer) csc).cleanupParameters(); } String sql = getSql(csc); csc = null; JdbcUtils.closeStatement(cs); cs = null; DataSourceUtils.releaseConnection(con, getDataSource()); con = null; throw getExceptionTranslator().translate("CallableStatementCallback", sql, ex); } finally { if (csc instanceof ParameterDisposer) { ((ParameterDisposer) csc).cleanupParameters(); } JdbcUtils.closeStatement(cs); DataSourceUtils.releaseConnection(con, getDataSource()); } } public T execute(String callString, CallableStatementCallback action) throws DataAccessException { return execute(new SimpleCallableStatementCreator(callString), action); } public Map call(CallableStatementCreator csc, List declaredParameters) throws DataAccessException { final List updateCountParameters = new ArrayList(); final List resultSetParameters = new ArrayList(); final List callParameters = new ArrayList(); for (SqlParameter parameter : declaredParameters) { if (parameter.isResultsParameter()) { if (parameter instanceof SqlReturnResultSet) { resultSetParameters.add(parameter); } else { updateCountParameters.add(parameter); } } else { callParameters.add(parameter); } } return execute(csc, new CallableStatementCallback>() { public Map doInCallableStatement(CallableStatement cs) throws SQLException { boolean retVal = cs.execute(); int updateCount = cs.getUpdateCount(); if (logger.isDebugEnabled()) { logger.debug("CallableStatement.execute() returned '" + retVal + "'"); logger.debug("CallableStatement.getUpdateCount() returned " + updateCount); } Map returnedResults = createResultsMap(); if (retVal || updateCount != -1) { returnedResults.putAll(extractReturnedResults(cs, updateCountParameters, resultSetParameters, updateCount)); } returnedResults.putAll(extractOutputParameters(cs, callParameters)); return returnedResults; } }); } /** * Extract returned ResultSets from the completed stored procedure. * @param cs JDBC wrapper for the stored procedure * @param updateCountParameters Parameter list of declared update count parameters for the stored procedure * @param resultSetParameters Parameter list of declared resturn resultSet parameters for the stored procedure * @return Map that contains returned results */ protected Map extractReturnedResults( CallableStatement cs, List updateCountParameters, List resultSetParameters, int updateCount) throws SQLException { Map returnedResults = new HashMap(); int rsIndex = 0; int updateIndex = 0; boolean moreResults; if (!skipResultsProcessing) { do { if (updateCount == -1) { if (resultSetParameters != null && resultSetParameters.size() > rsIndex) { SqlReturnResultSet declaredRsParam = (SqlReturnResultSet)resultSetParameters.get(rsIndex); returnedResults.putAll(processResultSet(cs.getResultSet(), declaredRsParam)); rsIndex++; } else { if (!skipUndeclaredResults) { String rsName = RETURN_RESULT_SET_PREFIX + (rsIndex + 1); SqlReturnResultSet undeclaredRsParam = new SqlReturnResultSet(rsName, new ColumnMapRowMapper()); logger.info("Added default SqlReturnResultSet parameter named " + rsName); returnedResults.putAll(processResultSet(cs.getResultSet(), undeclaredRsParam)); rsIndex++; } } } else { if (updateCountParameters != null && updateCountParameters.size() > updateIndex) { SqlReturnUpdateCount ucParam = (SqlReturnUpdateCount)updateCountParameters.get(updateIndex); String declaredUcName = ucParam.getName(); returnedResults.put(declaredUcName, updateCount); updateIndex++; } else { if (!skipUndeclaredResults) { String undeclaredUcName = RETURN_UPDATE_COUNT_PREFIX + (updateIndex + 1); logger.info("Added default SqlReturnUpdateCount parameter named " + undeclaredUcName); returnedResults.put(undeclaredUcName, updateCount); updateIndex++; } } } moreResults = cs.getMoreResults(); updateCount = cs.getUpdateCount(); if (logger.isDebugEnabled()) { logger.debug("CallableStatement.getUpdateCount() returned " + updateCount); } } while (moreResults || updateCount != -1); } return returnedResults; } /** * Extract output parameters from the completed stored procedure. * @param cs JDBC wrapper for the stored procedure * @param parameters parameter list for the stored procedure * @return Map that contains returned results */ protected Map extractOutputParameters(CallableStatement cs, List parameters) throws SQLException { Map returnedResults = new HashMap(); int sqlColIndex = 1; for (SqlParameter param : parameters) { if (param instanceof SqlOutParameter) { SqlOutParameter outParam = (SqlOutParameter) param; if (outParam.isReturnTypeSupported()) { Object out = outParam.getSqlReturnType().getTypeValue( cs, sqlColIndex, outParam.getSqlType(), outParam.getTypeName()); returnedResults.put(outParam.getName(), out); } else { Object out = cs.getObject(sqlColIndex); if (out instanceof ResultSet) { if (outParam.isResultSetSupported()) { returnedResults.putAll(processResultSet((ResultSet) out, outParam)); } else { String rsName = outParam.getName(); SqlReturnResultSet rsParam = new SqlReturnResultSet(rsName, new ColumnMapRowMapper()); returnedResults.putAll(processResultSet(cs.getResultSet(), rsParam)); logger.info("Added default SqlReturnResultSet parameter named " + rsName); } } else { returnedResults.put(outParam.getName(), out); } } } if (!(param.isResultsParameter())) { sqlColIndex++; } } return returnedResults; } /** * Process the given ResultSet from a stored procedure. * @param rs the ResultSet to process * @param param the corresponding stored procedure parameter * @return Map that contains returned results */ @SuppressWarnings("unchecked") protected Map processResultSet(ResultSet rs, ResultSetSupportingSqlParameter param) throws SQLException { if (rs == null) { return Collections.emptyMap(); } Map returnedResults = new HashMap(); try { ResultSet rsToUse = rs; if (this.nativeJdbcExtractor != null) { rsToUse = this.nativeJdbcExtractor.getNativeResultSet(rs); } if (param.getRowMapper() != null) { RowMapper rowMapper = param.getRowMapper(); Object result = (new RowMapperResultSetExtractor(rowMapper)).extractData(rsToUse); returnedResults.put(param.getName(), result); } else if (param.getRowCallbackHandler() != null) { RowCallbackHandler rch = param.getRowCallbackHandler(); (new RowCallbackHandlerResultSetExtractor(rch)).extractData(rsToUse); returnedResults.put(param.getName(), "ResultSet returned from stored procedure was processed"); } else if (param.getResultSetExtractor() != null) { Object result = param.getResultSetExtractor().extractData(rsToUse); returnedResults.put(param.getName(), result); } } finally { JdbcUtils.closeResultSet(rs); } return returnedResults; } //------------------------------------------------------------------------- // Implementation hooks and helper methods //------------------------------------------------------------------------- /** * Create a new RowMapper for reading columns as key-value pairs. * @return the RowMapper to use * @see ColumnMapRowMapper */ protected RowMapper> getColumnMapRowMapper() { return new ColumnMapRowMapper(); } /** * Create a new RowMapper for reading result objects from a single column. * @param requiredType the type that each result object is expected to match * @return the RowMapper to use * @see SingleColumnRowMapper */ protected RowMapper getSingleColumnRowMapper(Class requiredType) { return new SingleColumnRowMapper(requiredType); } /** * Create a Map instance to be used as results map. *

If "isResultsMapCaseInsensitive" has been set to true, * a linked case-insensitive Map will be created. * @return the results Map instance * @see #setResultsMapCaseInsensitive */ protected Map createResultsMap() { if (isResultsMapCaseInsensitive()) { return new LinkedCaseInsensitiveMap(); } else { return new LinkedHashMap(); } } /** * Prepare the given JDBC Statement (or PreparedStatement or CallableStatement), * applying statement settings such as fetch size, max rows, and query timeout. * @param stmt the JDBC Statement to prepare * @throws SQLException if thrown by JDBC API * @see #setFetchSize * @see #setMaxRows * @see #setQueryTimeout * @see org.springframework.jdbc.datasource.DataSourceUtils#applyTransactionTimeout */ protected void applyStatementSettings(Statement stmt) throws SQLException { int fetchSize = getFetchSize(); if (fetchSize > 0) { stmt.setFetchSize(fetchSize); } int maxRows = getMaxRows(); if (maxRows > 0) { stmt.setMaxRows(maxRows); } DataSourceUtils.applyTimeout(stmt, getDataSource(), getQueryTimeout()); } /** * Create a new ArgPreparedStatementSetter using the args passed in. This method allows the * creation to be overridden by sub-classes. * @param args object array woth arguments * @return the new PreparedStatementSetter */ protected PreparedStatementSetter newArgPreparedStatementSetter(Object[] args) { return new ArgPreparedStatementSetter(args); } /** * Create a new ArgTypePreparedStatementSetter using the args and argTypes passed in. * This method allows the creation to be overridden by sub-classes. * @param args object array woth arguments * @param argTypes int array of SQLTypes for arguments * @return the new PreparedStatementSetter */ protected PreparedStatementSetter newArgTypePreparedStatementSetter(Object[] args, int[] argTypes) { return new ArgTypePreparedStatementSetter(args, argTypes); } /** * Throw an SQLWarningException if we're not ignoring warnings, * else log the warnings (at debug level). * @param stmt the current JDBC statement * @throws SQLWarningException if not ignoring warnings * @see org.springframework.jdbc.SQLWarningException */ protected void handleWarnings(Statement stmt) throws SQLException { if (isIgnoreWarnings()) { if (logger.isDebugEnabled()) { SQLWarning warningToLog = stmt.getWarnings(); while (warningToLog != null) { logger.debug("SQLWarning ignored: SQL state '" + warningToLog.getSQLState() + "', error code '" + warningToLog.getErrorCode() + "', message [" + warningToLog.getMessage() + "]"); warningToLog = warningToLog.getNextWarning(); } } } else { handleWarnings(stmt.getWarnings()); } } /** * Throw an SQLWarningException if encountering an actual warning. * @param warning the warnings object from the current statement. * May be null, in which case this method does nothing. * @throws SQLWarningException in case of an actual warning to be raised */ protected void handleWarnings(SQLWarning warning) throws SQLWarningException { if (warning != null) { throw new SQLWarningException("Warning not ignored", warning); } } /** * Determine SQL from potential provider object. * @param sqlProvider object that's potentially a SqlProvider * @return the SQL string, or null * @see SqlProvider */ private static String getSql(Object sqlProvider) { if (sqlProvider instanceof SqlProvider) { return ((SqlProvider) sqlProvider).getSql(); } else { return null; } } /** * Invocation handler that suppresses close calls on JDBC Connections. * Also prepares returned Statement (Prepared/CallbackStatement) objects. * @see java.sql.Connection#close() */ private class CloseSuppressingInvocationHandler implements InvocationHandler { private final Connection target; public CloseSuppressingInvocationHandler(Connection target) { this.target = target; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // Invocation on ConnectionProxy interface coming in... if (method.getName().equals("equals")) { // Only consider equal when proxies are identical. return (proxy == args[0]); } else if (method.getName().equals("hashCode")) { // Use hashCode of PersistenceManager proxy. return System.identityHashCode(proxy); } else if (method.getName().equals("unwrap")) { if (((Class) args[0]).isInstance(proxy)) { return proxy; } } else if (method.getName().equals("isWrapperFor")) { if (((Class) args[0]).isInstance(proxy)) { return true; } } else if (method.getName().equals("close")) { // Handle close method: suppress, not valid. return null; } else if (method.getName().equals("isClosed")) { return false; } else if (method.getName().equals("getTargetConnection")) { // Handle getTargetConnection method: return underlying Connection. return this.target; } // Invoke method on target Connection. try { Object retVal = method.invoke(this.target, args); // If return value is a JDBC Statement, apply statement settings // (fetch size, max rows, transaction timeout). if (retVal instanceof Statement) { applyStatementSettings(((Statement) retVal)); } return retVal; } catch (InvocationTargetException ex) { throw ex.getTargetException(); } } } /** * Simple adapter for PreparedStatementCreator, allowing to use a plain SQL statement. */ private static class SimplePreparedStatementCreator implements PreparedStatementCreator, SqlProvider { private final String sql; public SimplePreparedStatementCreator(String sql) { Assert.notNull(sql, "SQL must not be null"); this.sql = sql; } public PreparedStatement createPreparedStatement(Connection con) throws SQLException { return con.prepareStatement(this.sql); } public String getSql() { return this.sql; } } /** * Simple adapter for CallableStatementCreator, allowing to use a plain SQL statement. */ private static class SimpleCallableStatementCreator implements CallableStatementCreator, SqlProvider { private final String callString; public SimpleCallableStatementCreator(String callString) { Assert.notNull(callString, "Call string must not be null"); this.callString = callString; } public CallableStatement createCallableStatement(Connection con) throws SQLException { return con.prepareCall(this.callString); } public String getSql() { return this.callString; } } /** * Adapter to enable use of a RowCallbackHandler inside a ResultSetExtractor. *

Uses a regular ResultSet, so we have to be careful when using it: * We don't use it for navigating since this could lead to unpredictable consequences. */ private static class RowCallbackHandlerResultSetExtractor implements ResultSetExtractor { private final RowCallbackHandler rch; public RowCallbackHandlerResultSetExtractor(RowCallbackHandler rch) { this.rch = rch; } public Object extractData(ResultSet rs) throws SQLException { while (rs.next()) { this.rch.processRow(rs); } return null; } } } ././@LongLink0000000000000000000000000000020000000000000011555 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/SqlOutParameter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000766311623223530033301 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; /** * Subclass of SqlParameter to represent an output parameter. * No additional properties: instanceof will be used to check * for such types. * *

Output parameters - like all stored procedure parameters - * must have names. * * @author Rod Johnson * @author Thomas Risberg * @author Juergen Hoeller * @see SqlReturnResultSet * @see SqlInOutParameter */ public class SqlOutParameter extends ResultSetSupportingSqlParameter { private SqlReturnType sqlReturnType; /** * Create a new SqlOutParameter. * @param name name of the parameter, as used in input and output maps * @param sqlType SQL type of the parameter according to java.sql.Types */ public SqlOutParameter(String name, int sqlType) { super(name, sqlType); } /** * Create a new SqlOutParameter. * @param name name of the parameter, as used in input and output maps * @param sqlType SQL type of the parameter according to java.sql.Types * @param scale the number of digits after the decimal point * (for DECIMAL and NUMERIC types) */ public SqlOutParameter(String name, int sqlType, int scale) { super(name, sqlType, scale); } /** * Create a new SqlOutParameter. * @param name name of the parameter, as used in input and output maps * @param sqlType SQL type of the parameter according to java.sql.Types * @param typeName the type name of the parameter (optional) */ public SqlOutParameter(String name, int sqlType, String typeName) { super(name, sqlType, typeName); } /** * Create a new SqlOutParameter. * @param name name of the parameter, as used in input and output maps * @param sqlType SQL type of the parameter according to java.sql.Types * @param typeName the type name of the parameter (optional) * @param sqlReturnType custom value handler for complex type (optional) */ public SqlOutParameter(String name, int sqlType, String typeName, SqlReturnType sqlReturnType) { super(name, sqlType, typeName); this.sqlReturnType = sqlReturnType; } /** * Create a new SqlOutParameter. * @param name name of the parameter, as used in input and output maps * @param sqlType SQL type of the parameter according to java.sql.Types * @param rse ResultSetExtractor to use for parsing the ResultSet */ public SqlOutParameter(String name, int sqlType, ResultSetExtractor rse) { super(name, sqlType, rse); } /** * Create a new SqlOutParameter. * @param name name of the parameter, as used in input and output maps * @param sqlType SQL type of the parameter according to java.sql.Types * @param rch RowCallbackHandler to use for parsing the ResultSet */ public SqlOutParameter(String name, int sqlType, RowCallbackHandler rch) { super(name, sqlType, rch); } /** * Create a new SqlOutParameter. * @param name name of the parameter, as used in input and output maps * @param sqlType SQL type of the parameter according to java.sql.Types * @param rm RowMapper to use for parsing the ResultSet */ public SqlOutParameter(String name, int sqlType, RowMapper rm) { super(name, sqlType, rm); } /** * Return the custom return type, if any. */ public SqlReturnType getSqlReturnType() { return this.sqlReturnType; } /** * Return whether this parameter holds a custom return type. */ public boolean isReturnTypeSupported() { return (this.sqlReturnType != null); } } ././@LongLink0000000000000000000000000000020300000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/SqlReturnResultSet.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000461511623223530033273 0ustar drazzibdrazzib/* * Copyright 2002-2006 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; /** * Represents a returned {@link java.sql.ResultSet} from a stored procedure call. * *

A {@link ResultSetExtractor}, {@link RowCallbackHandler} or {@link RowMapper} * must be provided to handle any returned rows. * *

Returned {@link java.sql.ResultSet ResultSets} - like all stored procedure * parameters - must have names. * * @author Thomas Risberg * @author Juergen Hoeller */ public class SqlReturnResultSet extends ResultSetSupportingSqlParameter { /** * Create a new instance of the {@link SqlReturnResultSet} class. * @param name name of the parameter, as used in input and output maps * @param extractor ResultSetExtractor to use for parsing the {@link java.sql.ResultSet} */ public SqlReturnResultSet(String name, ResultSetExtractor extractor) { super(name, 0, extractor); } /** * Create a new instance of the {@link SqlReturnResultSet} class. * @param name name of the parameter, as used in input and output maps * @param handler RowCallbackHandler to use for parsing the {@link java.sql.ResultSet} */ public SqlReturnResultSet(String name, RowCallbackHandler handler) { super(name, 0, handler); } /** * Create a new instance of the {@link SqlReturnResultSet} class. * @param name name of the parameter, as used in input and output maps * @param mapper RowMapper to use for parsing the {@link java.sql.ResultSet} */ public SqlReturnResultSet(String name, RowMapper mapper) { super(name, 0, mapper); } /** * Return whether this parameter is an implicit return parameter used during the * results preocessing of the CallableStatement.getMoreResults/getUpdateCount. *

This implementation always returns true. */ @Override public boolean isResultsParameter() { return true; } } ././@LongLink0000000000000000000000000000017500000000000011570 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/SqlParameter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001241711623223530033272 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; import java.util.LinkedList; import java.util.List; import org.springframework.util.Assert; /** * Object to represent a SQL parameter definition. * *

Parameters may be anonymous, in which case "name" is null. * However, all parameters must define a SQL type according to {@link java.sql.Types}. * * @author Rod Johnson * @author Thomas Risberg * @author Juergen Hoeller * @see java.sql.Types */ public class SqlParameter { /** The name of the parameter, if any */ private String name; /** SQL type constant from java.sql.Types */ private final int sqlType; /** Used for types that are user-named like: STRUCT, DISTINCT, JAVA_OBJECT, named array types */ private String typeName; /** The scale to apply in case of a NUMERIC or DECIMAL type, if any */ private Integer scale; /** * Create a new anonymous SqlParameter, supplying the SQL type. * @param sqlType SQL type of the parameter according to java.sql.Types */ public SqlParameter(int sqlType) { this.sqlType = sqlType; } /** * Create a new anonymous SqlParameter, supplying the SQL type. * @param sqlType SQL type of the parameter according to java.sql.Types * @param typeName the type name of the parameter (optional) */ public SqlParameter(int sqlType, String typeName) { this.sqlType = sqlType; this.typeName = typeName; } /** * Create a new anonymous SqlParameter, supplying the SQL type. * @param sqlType SQL type of the parameter according to java.sql.Types * @param scale the number of digits after the decimal point * (for DECIMAL and NUMERIC types) */ public SqlParameter(int sqlType, int scale) { this.sqlType = sqlType; this.scale = scale; } /** * Create a new SqlParameter, supplying name and SQL type. * @param name name of the parameter, as used in input and output maps * @param sqlType SQL type of the parameter according to java.sql.Types */ public SqlParameter(String name, int sqlType) { this.name = name; this.sqlType = sqlType; } /** * Create a new SqlParameter, supplying name and SQL type. * @param name name of the parameter, as used in input and output maps * @param sqlType SQL type of the parameter according to java.sql.Types * @param typeName the type name of the parameter (optional) */ public SqlParameter(String name, int sqlType, String typeName) { this.name = name; this.sqlType = sqlType; this.typeName = typeName; } /** * Create a new SqlParameter, supplying name and SQL type. * @param name name of the parameter, as used in input and output maps * @param sqlType SQL type of the parameter according to java.sql.Types * @param scale the number of digits after the decimal point * (for DECIMAL and NUMERIC types) */ public SqlParameter(String name, int sqlType, int scale) { this.name = name; this.sqlType = sqlType; this.scale = scale; } /** * Copy constructor. * @param otherParam the SqlParameter object to copy from */ public SqlParameter(SqlParameter otherParam) { Assert.notNull(otherParam, "SqlParameter object must not be null"); this.name = otherParam.name; this.sqlType = otherParam.sqlType; this.typeName = otherParam.typeName; this.scale = otherParam.scale; } /** * Return the name of the parameter. */ public String getName() { return this.name; } /** * Return the SQL type of the parameter. */ public int getSqlType() { return this.sqlType; } /** * Return the type name of the parameter, if any. */ public String getTypeName() { return this.typeName; } /** * Return the scale of the parameter, if any. */ public Integer getScale() { return this.scale; } /** * Return whether this parameter holds input values that should be set * before execution even if they are null. *

This implementation always returns true. */ public boolean isInputValueProvided() { return true; } /** * Return whether this parameter is an implicit return parameter used during the * results preocessing of the CallableStatement.getMoreResults/getUpdateCount. *

This implementation always returns false. */ public boolean isResultsParameter() { return false; } /** * Convert a list of JDBC types, as defined in java.sql.Types, * to a List of SqlParameter objects as used in this package. */ public static List sqlTypesToAnonymousParameterList(int[] types) { List result = new LinkedList(); if (types != null) { for (int type : types) { result.add(new SqlParameter(type)); } } return result; } } ././@LongLink0000000000000000000000000000020000000000000011555 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/ParameterMapper.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000351711623223526033300 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; import java.sql.Connection; import java.sql.SQLException; import java.util.Map; /** * Implement this interface when parameters need to be customized based * on the connection. We might need to do this to make use of proprietary * features, available only with a specific Connection type. * * @author Rod Johnson * @author Thomas Risberg * @see CallableStatementCreatorFactory#newCallableStatementCreator(ParameterMapper) * @see org.springframework.jdbc.object.StoredProcedure#execute(ParameterMapper) */ public interface ParameterMapper { /** * Create a Map of input parameters, keyed by name. * @param con JDBC connection. This is useful (and the purpose of this interface) * if we need to do something RDBMS-specific with a proprietary Connection * implementation class. This class conceals such proprietary details. However, * it is best to avoid using such proprietary RDBMS features if possible. * @throws SQLException if a SQLException is encountered setting * parameter values (that is, there's no need to catch SQLException) * @return Map of input parameters, keyed by name (never null) */ Map createMap(Connection con) throws SQLException; } ././@LongLink0000000000000000000000000000023200000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/InterruptibleBatchPreparedStatementSetter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000541511623223530033272 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; /** * Extension of the {@link BatchPreparedStatementSetter} interface, * adding a batch exhaustion check. * *

This interface allows you to signal the end of a batch rather than * having to determine the exact batch size upfront. Batch size is still * being honored but it is now the maximum size of the batch. * *

The {@link #isBatchExhausted} method is called after each call to * {@link #setValues} to determine whether there were some values added, * or if the batch was determined to be complete and no additional values * were provided during the last call to setValues. * *

Consider extending the * {@link org.springframework.jdbc.core.support.AbstractInterruptibleBatchPreparedStatementSetter} * base class instead of implementing this interface directly, using a single * setValuesIfAvailable callback method that checks for available * values and sets them, returning whether values have actually been provided. * * @author Thomas Risberg * @author Juergen Hoeller * @since 2.0 * @see JdbcTemplate#batchUpdate(String, BatchPreparedStatementSetter) * @see org.springframework.jdbc.core.support.AbstractInterruptibleBatchPreparedStatementSetter */ public interface InterruptibleBatchPreparedStatementSetter extends BatchPreparedStatementSetter { /** * Return whether the batch is complete, that is, whether there were no * additional values added during the last setValues call. *

NOTE: If this method returns true, any parameters * that might have been set during the last setValues call will * be ignored! Make sure that you set a corresponding internal flag if you * detect exhaustion at the beginning of your setValues * implementation, letting this method return true based on the flag. * @param i index of the statement we're issuing in the batch, starting from 0 * @return whether the batch is already exhausted * @see #setValues * @see org.springframework.jdbc.core.support.AbstractInterruptibleBatchPreparedStatementSetter#setValuesIfAvailable */ boolean isBatchExhausted(int i); } ././@LongLink0000000000000000000000000000022000000000000011557 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/ResultSetSupportingSqlParameter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001027711623223530033274 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; /** * Common base class for ResultSet-supporting SqlParameters like * {@link SqlOutParameter} and {@link SqlReturnResultSet}. * * @author Juergen Hoeller * @since 1.0.2 */ public class ResultSetSupportingSqlParameter extends SqlParameter { private ResultSetExtractor resultSetExtractor; private RowCallbackHandler rowCallbackHandler; private RowMapper rowMapper; /** * Create a new ResultSetSupportingSqlParameter. * @param name name of the parameter, as used in input and output maps * @param sqlType SQL type of the parameter according to java.sql.Types */ public ResultSetSupportingSqlParameter(String name, int sqlType) { super(name, sqlType); } /** * Create a new ResultSetSupportingSqlParameter. * @param name name of the parameter, as used in input and output maps * @param sqlType SQL type of the parameter according to java.sql.Types * @param scale the number of digits after the decimal point * (for DECIMAL and NUMERIC types) */ public ResultSetSupportingSqlParameter(String name, int sqlType, int scale) { super(name, sqlType, scale); } /** * Create a new ResultSetSupportingSqlParameter. * @param name name of the parameter, as used in input and output maps * @param sqlType SQL type of the parameter according to java.sql.Types * @param typeName the type name of the parameter (optional) */ public ResultSetSupportingSqlParameter(String name, int sqlType, String typeName) { super(name, sqlType, typeName); } /** * Create a new ResultSetSupportingSqlParameter. * @param name name of the parameter, as used in input and output maps * @param sqlType SQL type of the parameter according to java.sql.Types * @param rse ResultSetExtractor to use for parsing the ResultSet */ public ResultSetSupportingSqlParameter(String name, int sqlType, ResultSetExtractor rse) { super(name, sqlType); this.resultSetExtractor = rse; } /** * Create a new ResultSetSupportingSqlParameter. * @param name name of the parameter, as used in input and output maps * @param sqlType SQL type of the parameter according to java.sql.Types * @param rch RowCallbackHandler to use for parsing the ResultSet */ public ResultSetSupportingSqlParameter(String name, int sqlType, RowCallbackHandler rch) { super(name, sqlType); this.rowCallbackHandler = rch; } /** * Create a new ResultSetSupportingSqlParameter. * @param name name of the parameter, as used in input and output maps * @param sqlType SQL type of the parameter according to java.sql.Types * @param rm RowMapper to use for parsing the ResultSet */ public ResultSetSupportingSqlParameter(String name, int sqlType, RowMapper rm) { super(name, sqlType); this.rowMapper = rm; } /** * Does this parameter support a ResultSet, i.e. does it hold a * ResultSetExtractor, RowCallbackHandler or RowMapper? */ public boolean isResultSetSupported() { return (this.resultSetExtractor != null || this.rowCallbackHandler != null || this.rowMapper != null); } /** * Return the ResultSetExtractor held by this parameter, if any. */ public ResultSetExtractor getResultSetExtractor() { return this.resultSetExtractor; } /** * Return the RowCallbackHandler held by this parameter, if any. */ public RowCallbackHandler getRowCallbackHandler() { return this.rowCallbackHandler; } /** * Return the RowMapper held by this parameter, if any. */ public RowMapper getRowMapper() { return this.rowMapper; } /** *

This implementation always returns false. */ @Override public boolean isInputValueProvided() { return false; } } ././@LongLink0000000000000000000000000000021200000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/PreparedStatementCallback.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000730211623223530033267 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; import java.sql.PreparedStatement; import java.sql.SQLException; import org.springframework.dao.DataAccessException; /** * Generic callback interface for code that operates on a PreparedStatement. * Allows to execute any number of operations on a single PreparedStatement, * for example a single executeUpdate call or repeated * executeUpdate calls with varying parameters. * *

Used internally by JdbcTemplate, but also useful for application code. * Note that the passed-in PreparedStatement can have been created by the * framework or by a custom PreparedStatementCreator. However, the latter is * hardly ever necessary, as most custom callback actions will perform updates * in which case a standard PreparedStatement is fine. Custom actions will * always set parameter values themselves, so that PreparedStatementCreator * capability is not needed either. * * @author Juergen Hoeller * @since 16.03.2004 * @see JdbcTemplate#execute(String, PreparedStatementCallback) * @see JdbcTemplate#execute(PreparedStatementCreator, PreparedStatementCallback) */ public interface PreparedStatementCallback { /** * Gets called by JdbcTemplate.execute with an active JDBC * PreparedStatement. Does not need to care about closing the Statement * or the Connection, or about handling transactions: this will all be * handled by Spring's JdbcTemplate. * *

NOTE: Any ResultSets opened should be closed in finally blocks * within the callback implementation. Spring will close the Statement * object after the callback returned, but this does not necessarily imply * that the ResultSet resources will be closed: the Statement objects might * get pooled by the connection pool, with close calls only * returning the object to the pool but not physically closing the resources. * *

If called without a thread-bound JDBC transaction (initiated by * DataSourceTransactionManager), the code will simply get executed on the * JDBC connection with its transactional semantics. If JdbcTemplate is * configured to use a JTA-aware DataSource, the JDBC connection and thus * the callback code will be transactional if a JTA transaction is active. * *

Allows for returning a result object created within the callback, i.e. * a domain object or a collection of domain objects. Note that there's * special support for single step actions: see JdbcTemplate.queryForObject etc. * A thrown RuntimeException is treated as application exception, it gets * propagated to the caller of the template. * * @param ps active JDBC PreparedStatement * @return a result object, or null if none * @throws SQLException if thrown by a JDBC method, to be auto-converted * to a DataAccessException by a SQLExceptionTranslator * @throws DataAccessException in case of custom exceptions * @see JdbcTemplate#queryForObject(String, Object[], Class) * @see JdbcTemplate#queryForList(String, Object[]) */ T doInPreparedStatement(PreparedStatement ps) throws SQLException, DataAccessException; } ././@LongLink0000000000000000000000000000021400000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/RowMapperResultSetExtractor.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000643311623223530033273 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import org.springframework.util.Assert; /** * Adapter implementation of the ResultSetExtractor interface that delegates * to a RowMapper which is supposed to create an object for each row. * Each object is added to the results List of this ResultSetExtractor. * *

Useful for the typical case of one object per row in the database table. * The number of entries in the results list will match the number of rows. * *

Note that a RowMapper object is typically stateless and thus reusable; * just the RowMapperResultSetExtractor adapter is stateful. * *

A usage example with JdbcTemplate: * *

JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);  // reusable object
 * RowMapper rowMapper = new UserRowMapper();  // reusable object
 *
 * List allUsers = (List) jdbcTemplate.query(
 *     "select * from user",
 *     new RowMapperResultSetExtractor(rowMapper, 10));
 *
 * User user = (User) jdbcTemplate.queryForObject(
 *     "select * from user where id=?", new Object[] {id},
 *     new RowMapperResultSetExtractor(rowMapper, 1));
* *

Alternatively, consider subclassing MappingSqlQuery from the jdbc.object * package: Instead of working with separate JdbcTemplate and RowMapper objects, * you can have executable query objects (containing row-mapping logic) there. * * @author Juergen Hoeller * @since 1.0.2 * @see RowMapper * @see JdbcTemplate * @see org.springframework.jdbc.object.MappingSqlQuery */ public class RowMapperResultSetExtractor implements ResultSetExtractor> { private final RowMapper rowMapper; private final int rowsExpected; /** * Create a new RowMapperResultSetExtractor. * @param rowMapper the RowMapper which creates an object for each row */ public RowMapperResultSetExtractor(RowMapper rowMapper) { this(rowMapper, 0); } /** * Create a new RowMapperResultSetExtractor. * @param rowMapper the RowMapper which creates an object for each row * @param rowsExpected the number of expected rows * (just used for optimized collection handling) */ public RowMapperResultSetExtractor(RowMapper rowMapper, int rowsExpected) { Assert.notNull(rowMapper, "RowMapper is required"); this.rowMapper = rowMapper; this.rowsExpected = rowsExpected; } public List extractData(ResultSet rs) throws SQLException { List results = (this.rowsExpected > 0 ? new ArrayList(this.rowsExpected) : new ArrayList()); int rowNum = 0; while (rs.next()) { results.add(this.rowMapper.mapRow(rs, rowNum++)); } return results; } } ././@LongLink0000000000000000000000000000016700000000000011571 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/namedparam/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000755000175000017500000000000011623223530033263 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000020500000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/namedparam/ParsedSql.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000755611623223530033302 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.namedparam; import java.util.ArrayList; import java.util.List; /** * Holds information about a parsed SQL statement. * * @author Thomas Risberg * @author Juergen Hoeller * @since 2.0 */ public class ParsedSql { private String originalSql; private List parameterNames = new ArrayList(); private List parameterIndexes = new ArrayList(); private int namedParameterCount; private int unnamedParameterCount; private int totalParameterCount; /** * Create a new instance of the {@link ParsedSql} class. * @param originalSql the SQL statement that is being (or is to be) parsed */ ParsedSql(String originalSql) { this.originalSql = originalSql; } /** * Return the SQL statement that is being parsed. */ String getOriginalSql() { return this.originalSql; } /** * Add a named parameter parsed from this SQL statement. * @param parameterName the name of the parameter * @param startIndex the start index in the original SQL String * @param endIndex the end index in the original SQL String */ void addNamedParameter(String parameterName, int startIndex, int endIndex) { this.parameterNames.add(parameterName); this.parameterIndexes.add(new int[] {startIndex, endIndex}); } /** * Return all of the parameters (bind variables) in the parsed SQL statement. * Repeated occurences of the same parameter name are included here. */ List getParameterNames() { return this.parameterNames; } /** * Return the parameter indexes for the specified parameter. * @param parameterPosition the position of the parameter * (as index in the parameter names List) * @return the start index and end index, combined into * a int array of length 2 */ int[] getParameterIndexes(int parameterPosition) { return this.parameterIndexes.get(parameterPosition); } /** * Set the count of named parameters in the SQL statement. * Each parameter name counts once; repeated occurences do not count here. */ void setNamedParameterCount(int namedParameterCount) { this.namedParameterCount = namedParameterCount; } /** * Return the count of named parameters in the SQL statement. * Each parameter name counts once; repeated occurences do not count here. */ int getNamedParameterCount() { return this.namedParameterCount; } /** * Set the count of all of the unnamed parameters in the SQL statement. */ void setUnnamedParameterCount(int unnamedParameterCount) { this.unnamedParameterCount = unnamedParameterCount; } /** * Return the count of all of the unnamed parameters in the SQL statement. */ int getUnnamedParameterCount() { return this.unnamedParameterCount; } /** * Set the total count of all of the parameters in the SQL statement. * Repeated occurences of the same parameter name do count here. */ void setTotalParameterCount(int totalParameterCount) { this.totalParameterCount = totalParameterCount; } /** * Return the total count of all of the parameters in the SQL statement. * Repeated occurences of the same parameter name do count here. */ int getTotalParameterCount() { return this.totalParameterCount; } /** * Exposes the original SQL String. */ @Override public String toString() { return this.originalSql; } } ././@LongLink0000000000000000000000000000023000000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/namedparam/NamedParameterJdbcOperations.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000006273611623223530033303 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.namedparam; import java.util.List; import java.util.Map; import org.springframework.dao.DataAccessException; import org.springframework.jdbc.core.JdbcOperations; import org.springframework.jdbc.core.PreparedStatementCallback; import org.springframework.jdbc.core.ResultSetExtractor; import org.springframework.jdbc.core.RowCallbackHandler; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.support.KeyHolder; import org.springframework.jdbc.support.rowset.SqlRowSet; /** * Interface specifying a basic set of JDBC operations allowing the use * of named parameters rather than the traditional '?' placeholders. * *

This is an alternative to the classic * {@link org.springframework.jdbc.core.JdbcOperations} interface, * implemented by {@link NamedParameterJdbcTemplate}. This interface is not * often used directly, but provides a useful option to enhance testability, * as it can easily be mocked or stubbed. * * @author Thomas Risberg * @author Juergen Hoeller * @since 2.0 * @see NamedParameterJdbcTemplate * @see org.springframework.jdbc.core.JdbcOperations */ public interface NamedParameterJdbcOperations { /** * Expose the classic Spring JdbcTemplate to allow invocation of * classic JDBC operations. */ JdbcOperations getJdbcOperations(); /** * Execute a JDBC data access operation, implemented as callback action * working on a JDBC PreparedStatement. This allows for implementing arbitrary * data access operations on a single Statement, within Spring's managed * JDBC environment: that is, participating in Spring-managed transactions * and converting JDBC SQLExceptions into Spring's DataAccessException hierarchy. *

The callback action can return a result object, for example a * domain object or a collection of domain objects. * @param sql SQL to execute * @param paramSource container of arguments to bind to the query * @param action callback object that specifies the action * @return a result object returned by the action, or null * @throws DataAccessException if there is any problem */ T execute(String sql, SqlParameterSource paramSource, PreparedStatementCallback action) throws DataAccessException; /** * Execute a JDBC data access operation, implemented as callback action * working on a JDBC PreparedStatement. This allows for implementing arbitrary * data access operations on a single Statement, within Spring's managed * JDBC environment: that is, participating in Spring-managed transactions * and converting JDBC SQLExceptions into Spring's DataAccessException hierarchy. *

The callback action can return a result object, for example a * domain object or a collection of domain objects. * @param sql SQL to execute * @param paramMap map of parameters to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type) * @param action callback object that specifies the action * @return a result object returned by the action, or null * @throws DataAccessException if there is any problem */ T execute(String sql, Map paramMap, PreparedStatementCallback action) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a list * of arguments to bind to the query, reading the ResultSet with a * ResultSetExtractor. * @param sql SQL query to execute * @param paramSource container of arguments to bind to the query * @param rse object that will extract results * @return an arbitrary result object, as returned by the ResultSetExtractor * @throws DataAccessException if the query fails */ T query(String sql, SqlParameterSource paramSource, ResultSetExtractor rse) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a list * of arguments to bind to the query, reading the ResultSet with a * ResultSetExtractor. * @param sql SQL query to execute * @param paramMap map of parameters to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type) * @param rse object that will extract results * @return an arbitrary result object, as returned by the ResultSetExtractor * @throws org.springframework.dao.DataAccessException if the query fails */ T query(String sql, Map paramMap, ResultSetExtractor rse) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a list of * arguments to bind to the query, reading the ResultSet on a per-row basis * with a RowCallbackHandler. * @param sql SQL query to execute * @param paramSource container of arguments to bind to the query * @param rch object that will extract results, one row at a time * @throws DataAccessException if the query fails */ void query(String sql, SqlParameterSource paramSource, RowCallbackHandler rch) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a list of * arguments to bind to the query, reading the ResultSet on a per-row basis * with a RowCallbackHandler. * @param sql SQL query to execute * @param paramMap map of parameters to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type) * @param rch object that will extract results, one row at a time * @throws org.springframework.dao.DataAccessException if the query fails */ void query(String sql, Map paramMap, RowCallbackHandler rch) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a list * of arguments to bind to the query, mapping each row to a Java object * via a RowMapper. * @param sql SQL query to execute * @param paramSource container of arguments to bind to the query * @param rowMapper object that will map one object per row * @return the result List, containing mapped objects * @throws org.springframework.dao.DataAccessException if the query fails */ List query(String sql, SqlParameterSource paramSource, RowMapper rowMapper) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a list * of arguments to bind to the query, mapping each row to a Java object * via a RowMapper. * @param sql SQL query to execute * @param paramMap map of parameters to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type) * @param rowMapper object that will map one object per row * @return the result List, containing mapped objects * @throws org.springframework.dao.DataAccessException if the query fails */ List query(String sql, Map paramMap, RowMapper rowMapper) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a list * of arguments to bind to the query, mapping a single result row to a * Java object via a RowMapper. * @param sql SQL query to execute * @param paramSource container of arguments to bind to the query * @param rowMapper object that will map one object per row * @return the single mapped object * @throws org.springframework.dao.IncorrectResultSizeDataAccessException * if the query does not return exactly one row, or does not return exactly * one column in that row * @throws org.springframework.dao.DataAccessException if the query fails */ T queryForObject(String sql, SqlParameterSource paramSource, RowMapper rowMapper) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a list * of arguments to bind to the query, mapping a single result row to a * Java object via a RowMapper. * @param sql SQL query to execute * @param paramMap map of parameters to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type) * @param rowMapper object that will map one object per row * @return the single mapped object * @throws org.springframework.dao.IncorrectResultSizeDataAccessException * if the query does not return exactly one row, or does not return exactly * one column in that row * @throws org.springframework.dao.DataAccessException if the query fails */ T queryForObject(String sql, Map paramMap, RowMapper rowMapper) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a * list of arguments to bind to the query, expecting a result object. *

The query is expected to be a single row/single column query; the returned * result will be directly mapped to the corresponding object type. * @param sql SQL query to execute * @param paramSource container of arguments to bind to the query * @param requiredType the type that the result object is expected to match * @return the result object of the required type, or null in case of SQL NULL * @throws org.springframework.dao.IncorrectResultSizeDataAccessException * if the query does not return exactly one row, or does not return exactly * one column in that row * @throws org.springframework.dao.DataAccessException if the query fails * @see org.springframework.jdbc.core.JdbcTemplate#queryForObject(String, Class) */ T queryForObject(String sql, SqlParameterSource paramSource, Class requiredType) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a * list of arguments to bind to the query, expecting a result object. *

The query is expected to be a single row/single column query; the returned * result will be directly mapped to the corresponding object type. * @param sql SQL query to execute * @param paramMap map of parameters to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type) * @param requiredType the type that the result object is expected to match * @return the result object of the required type, or null in case of SQL NULL * @throws org.springframework.dao.IncorrectResultSizeDataAccessException * if the query does not return exactly one row, or does not return exactly * one column in that row * @throws org.springframework.dao.DataAccessException if the query fails * @see org.springframework.jdbc.core.JdbcTemplate#queryForObject(String, Class) */ T queryForObject(String sql, Map paramMap, Class requiredType) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a * list of arguments to bind to the query, expecting a result Map. *

The query is expected to be a single row query; the result row will be * mapped to a Map (one entry for each column, using the column name as the key). * @param sql SQL query to execute * @param paramSource container of arguments to bind to the query * @return the result Map (one entry for each column, using the column name as the key) * @throws org.springframework.dao.IncorrectResultSizeDataAccessException * if the query does not return exactly one row, or does not return exactly * one column in that row * @throws org.springframework.dao.DataAccessException if the query fails * @see org.springframework.jdbc.core.JdbcTemplate#queryForMap(String) * @see org.springframework.jdbc.core.ColumnMapRowMapper */ Map queryForMap(String sql, SqlParameterSource paramSource) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a * list of arguments to bind to the query, expecting a result Map. * The queryForMap() methods defined by this interface are appropriate * when you don't have a domain model. Otherwise, consider using * one of the queryForObject() methods. *

The query is expected to be a single row query; the result row will be * mapped to a Map (one entry for each column, using the column name as the key). * @param sql SQL query to execute * @param paramMap map of parameters to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type) * @return the result Map (one entry for each column, using the column name as the key) * @throws org.springframework.dao.IncorrectResultSizeDataAccessException * if the query does not return exactly one row, or does not return exactly * one column in that row * @throws org.springframework.dao.DataAccessException if the query fails * @see org.springframework.jdbc.core.JdbcTemplate#queryForMap(String) * @see org.springframework.jdbc.core.ColumnMapRowMapper */ Map queryForMap(String sql, Map paramMap) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a * list of arguments to bind to the query, resulting in a long value. *

The query is expected to be a single row/single column query that * results in a long value. * @param sql SQL query to execute * @param paramSource container of arguments to bind to the query * @return the long value, or 0 in case of SQL NULL * @throws org.springframework.dao.IncorrectResultSizeDataAccessException * if the query does not return exactly one row, or does not return exactly * one column in that row * @throws org.springframework.dao.DataAccessException if the query fails * @see org.springframework.jdbc.core.JdbcTemplate#queryForLong(String) */ long queryForLong(String sql, SqlParameterSource paramSource) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a * list of arguments to bind to the query, resulting in a long value. *

The query is expected to be a single row/single column query that * results in a long value. * @param sql SQL query to execute * @param paramMap map of parameters to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type) * @return the long value, or 0 in case of SQL NULL * @throws org.springframework.dao.IncorrectResultSizeDataAccessException * if the query does not return exactly one row, or does not return exactly * one column in that row * @throws org.springframework.dao.DataAccessException if the query fails * @see org.springframework.jdbc.core.JdbcTemplate#queryForLong(String) */ long queryForLong(String sql, Map paramMap) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a * list of arguments to bind to the query, resulting in an int value. *

The query is expected to be a single row/single column query that * results in an int value. * @param sql SQL query to execute * @param paramSource container of arguments to bind to the query * @return the int value, or 0 in case of SQL NULL * @throws org.springframework.dao.IncorrectResultSizeDataAccessException if the query does not return * exactly one row, or does not return exactly one column in that row * @throws org.springframework.dao.DataAccessException if the query fails * @see org.springframework.jdbc.core.JdbcTemplate#queryForInt(String) */ int queryForInt(String sql, SqlParameterSource paramSource) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a * list of arguments to bind to the query, resulting in an int value. *

The query is expected to be a single row/single column query that * results in an int value. * @param sql SQL query to execute * @param paramMap map of parameters to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type) * @return the int value, or 0 in case of SQL NULL * @throws org.springframework.dao.IncorrectResultSizeDataAccessException if the query does not return * exactly one row, or does not return exactly one column in that row * @throws org.springframework.dao.DataAccessException if the query fails * @see org.springframework.jdbc.core.JdbcTemplate#queryForInt(String) */ int queryForInt(String sql, Map paramMap) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a * list of arguments to bind to the query, expecting a result list. *

The results will be mapped to a List (one entry for each row) of * result objects, each of them matching the specified element type. * @param sql SQL query to execute * @param paramSource container of arguments to bind to the query * @param elementType the required type of element in the result list * (for example, Integer.class) * @return a List of objects that match the specified element type * @throws org.springframework.dao.DataAccessException if the query fails * @see org.springframework.jdbc.core.JdbcTemplate#queryForList(String, Class) * @see org.springframework.jdbc.core.SingleColumnRowMapper */ List queryForList(String sql, SqlParameterSource paramSource, Class elementType) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a * list of arguments to bind to the query, expecting a result list. *

The results will be mapped to a List (one entry for each row) of * result objects, each of them matching the specified element type. * @param sql SQL query to execute * @param paramMap map of parameters to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type) * @param elementType the required type of element in the result list * (for example, Integer.class) * @return a List of objects that match the specified element type * @throws org.springframework.dao.DataAccessException if the query fails * @see org.springframework.jdbc.core.JdbcTemplate#queryForList(String, Class) * @see org.springframework.jdbc.core.SingleColumnRowMapper */ List queryForList(String sql, Map paramMap, Class elementType) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a * list of arguments to bind to the query, expecting a result list. *

The results will be mapped to a List (one entry for each row) of * Maps (one entry for each column, using the column name as the key). * Thus Each element in the list will be of the form returned by this interface's * queryForMap() methods. * @param sql SQL query to execute * @param paramSource container of arguments to bind to the query * @return a List that contains a Map per row * @throws org.springframework.dao.DataAccessException if the query fails * @see org.springframework.jdbc.core.JdbcTemplate#queryForList(String) */ List> queryForList(String sql, SqlParameterSource paramSource) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a * list of arguments to bind to the query, expecting a result list. *

The results will be mapped to a List (one entry for each row) of * Maps (one entry for each column, using the column name as the key). * Each element in the list will be of the form returned by this interface's * queryForMap() methods. * @param sql SQL query to execute * @param paramMap map of parameters to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type) * @return a List that contains a Map per row * @throws org.springframework.dao.DataAccessException if the query fails * @see org.springframework.jdbc.core.JdbcTemplate#queryForList(String) */ List> queryForList(String sql, Map paramMap) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a * list of arguments to bind to the query, expecting a SqlRowSet. *

The results will be mapped to an SqlRowSet which holds the data in a * disconnected fashion. This wrapper will translate any SQLExceptions thrown. *

Note that that, for the default implementation, JDBC RowSet support needs to * be available at runtime: by default, Sun's com.sun.rowset.CachedRowSetImpl * class is used, which is part of JDK 1.5+ and also available separately as part of * Sun's JDBC RowSet Implementations download (rowset.jar). * @param sql SQL query to execute * @param paramSource container of arguments to bind to the query * @return a SqlRowSet representation (possibly a wrapper around a * javax.sql.rowset.CachedRowSet) * @throws org.springframework.dao.DataAccessException if there is any problem executing the query * @see org.springframework.jdbc.core.JdbcTemplate#queryForRowSet(String) * @see org.springframework.jdbc.core.SqlRowSetResultSetExtractor * @see javax.sql.rowset.CachedRowSet */ SqlRowSet queryForRowSet(String sql, SqlParameterSource paramSource) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a * list of arguments to bind to the query, expecting a SqlRowSet. *

The results will be mapped to an SqlRowSet which holds the data in a * disconnected fashion. This wrapper will translate any SQLExceptions thrown. *

Note that that, for the default implementation, JDBC RowSet support needs to * be available at runtime: by default, Sun's com.sun.rowset.CachedRowSetImpl * class is used, which is part of JDK 1.5+ and also available separately as part of * Sun's JDBC RowSet Implementations download (rowset.jar). * @param sql SQL query to execute * @param paramMap map of parameters to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type) * @return a SqlRowSet representation (possibly a wrapper around a * javax.sql.rowset.CachedRowSet) * @throws org.springframework.dao.DataAccessException if there is any problem executing the query * @see org.springframework.jdbc.core.JdbcTemplate#queryForRowSet(String) * @see org.springframework.jdbc.core.SqlRowSetResultSetExtractor * @see javax.sql.rowset.CachedRowSet */ SqlRowSet queryForRowSet(String sql, Map paramMap) throws DataAccessException; /** * Issue an update via a prepared statement, binding the given arguments. * @param sql SQL containing named parameters * @param paramSource container of arguments and SQL types to bind to the query * @return the number of rows affected * @throws org.springframework.dao.DataAccessException if there is any problem issuing the update */ int update(String sql, SqlParameterSource paramSource) throws DataAccessException; /** * Issue an update via a prepared statement, binding the given arguments. * @param sql SQL containing named parameters * @param paramMap map of parameters to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type) * @return the number of rows affected * @throws org.springframework.dao.DataAccessException if there is any problem issuing the update */ int update(String sql, Map paramMap) throws DataAccessException; /** * Issue an update via a prepared statement, binding the given arguments, * returning generated keys. * @param sql SQL containing named parameters * @param paramSource container of arguments and SQL types to bind to the query * @param generatedKeyHolder KeyHolder that will hold the generated keys * @return the number of rows affected * @throws org.springframework.dao.DataAccessException if there is any problem issuing the update * @see MapSqlParameterSource * @see org.springframework.jdbc.support.GeneratedKeyHolder */ int update(String sql, SqlParameterSource paramSource, KeyHolder generatedKeyHolder) throws DataAccessException; /** * Issue an update via a prepared statement, binding the given arguments, * returning generated keys. * @param sql SQL containing named parameters * @param paramSource container of arguments and SQL types to bind to the query * @param generatedKeyHolder KeyHolder that will hold the generated keys * @param keyColumnNames names of the columns that will have keys generated for them * @return the number of rows affected * @throws org.springframework.dao.DataAccessException if there is any problem issuing the update * @see MapSqlParameterSource * @see org.springframework.jdbc.support.GeneratedKeyHolder */ int update(String sql, SqlParameterSource paramSource, KeyHolder generatedKeyHolder, String[] keyColumnNames) throws DataAccessException; /** * Executes a batch using the supplied SQL statement with the batch of supplied arguments. * @param sql the SQL statement to execute * @param batchValues the array of Maps containing the batch of arguments for the query * @return an array containing the numbers of rows affected by each update in the batch */ public int[] batchUpdate(String sql, Map[] batchValues); /** * Execute a batch using the supplied SQL statement with the batch of supplied arguments. * @param sql the SQL statement to execute * @param batchArgs the array of {@link SqlParameterSource} containing the batch of arguments for the query * @return an array containing the numbers of rows affected by each update in the batch */ public int[] batchUpdate(String sql, SqlParameterSource[] batchArgs); } ././@LongLink0000000000000000000000000000021000000000000011556 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/namedparam/package-info.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000120011623223530033256 0ustar drazzibdrazzib /** * * JdbcTemplate variant with named parameter support. * *

NamedParameterJdbcTemplate is a wrapper around JdbcTemplate that adds * support for named parameter parsing. It does not implement the JdbcOperations * interface or extend JdbcTemplate, but implements the dedicated * NamedParameterJdbcOperations interface. * *

If you need the full power of Spring JDBC for less common operations, use * the getJdbcOperations() method of NamedParameterJdbcTemplate and * work with the returned classic template, or use a JdbcTemplate instance directly. * */ package org.springframework.jdbc.core.namedparam; ././@LongLink0000000000000000000000000000022600000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/namedparam/NamedParameterJdbcTemplate.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000003124411623223530033271 0ustar drazzibdrazzib/* * Copyright 2002-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.namedparam; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import javax.sql.DataSource; import org.springframework.dao.DataAccessException; import org.springframework.dao.support.DataAccessUtils; import org.springframework.jdbc.core.ColumnMapRowMapper; import org.springframework.jdbc.core.JdbcOperations; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.PreparedStatementCallback; import org.springframework.jdbc.core.PreparedStatementCreator; import org.springframework.jdbc.core.PreparedStatementCreatorFactory; import org.springframework.jdbc.core.ResultSetExtractor; import org.springframework.jdbc.core.RowCallbackHandler; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.SingleColumnRowMapper; import org.springframework.jdbc.core.SqlParameter; import org.springframework.jdbc.core.SqlRowSetResultSetExtractor; import org.springframework.jdbc.support.KeyHolder; import org.springframework.jdbc.support.rowset.SqlRowSet; import org.springframework.util.Assert; /** * Template class with a basic set of JDBC operations, allowing the use * of named parameters rather than traditional '?' placeholders. * *

This class delegates to a wrapped {@link #getJdbcOperations() JdbcTemplate} * once the substitution from named parameters to JDBC style '?' placeholders is * done at execution time. It also allows for expanding a {@link java.util.List} * of values to the appropriate number of placeholders. * *

The underlying {@link org.springframework.jdbc.core.JdbcTemplate} is * exposed to allow for convenient access to the traditional * {@link org.springframework.jdbc.core.JdbcTemplate} methods. * * @author Thomas Risberg * @author Juergen Hoeller * @since 2.0 * @see NamedParameterJdbcOperations * @see org.springframework.jdbc.core.JdbcTemplate */ public class NamedParameterJdbcTemplate implements NamedParameterJdbcOperations { /** Default maximum number of entries for this template's SQL cache: 256 */ public static final int DEFAULT_CACHE_LIMIT = 256; /** The JdbcTemplate we are wrapping */ private final JdbcOperations classicJdbcTemplate; private volatile int cacheLimit = DEFAULT_CACHE_LIMIT; /** Cache of original SQL String to ParsedSql representation */ private final Map parsedSqlCache = new LinkedHashMap(DEFAULT_CACHE_LIMIT, 0.75f, true) { @Override protected boolean removeEldestEntry(Map.Entry eldest) { return size() > getCacheLimit(); } }; /** * Create a new NamedParameterJdbcTemplate for the given {@link DataSource}. *

Creates a classic Spring {@link org.springframework.jdbc.core.JdbcTemplate} and wraps it. * @param dataSource the JDBC DataSource to access */ public NamedParameterJdbcTemplate(DataSource dataSource) { Assert.notNull(dataSource, "DataSource must not be null"); this.classicJdbcTemplate = new JdbcTemplate(dataSource); } /** * Create a new NamedParameterJdbcTemplate for the given classic * Spring {@link org.springframework.jdbc.core.JdbcTemplate}. * @param classicJdbcTemplate the classic Spring JdbcTemplate to wrap */ public NamedParameterJdbcTemplate(JdbcOperations classicJdbcTemplate) { Assert.notNull(classicJdbcTemplate, "JdbcTemplate must not be null"); this.classicJdbcTemplate = classicJdbcTemplate; } /** * Expose the classic Spring JdbcTemplate to allow invocation of * less commonly used methods. */ public JdbcOperations getJdbcOperations() { return this.classicJdbcTemplate; } /** * Specify the maximum number of entries for this template's SQL cache. * Default is 256. */ public void setCacheLimit(int cacheLimit) { this.cacheLimit = cacheLimit; } /** * Return the maximum number of entries for this template's SQL cache. */ public int getCacheLimit() { return this.cacheLimit; } public T execute(String sql, SqlParameterSource paramSource, PreparedStatementCallback action) throws DataAccessException { return getJdbcOperations().execute(getPreparedStatementCreator(sql, paramSource), action); } public T execute(String sql, Map paramMap, PreparedStatementCallback action) throws DataAccessException { return execute(sql, new MapSqlParameterSource(paramMap), action); } public T query(String sql, SqlParameterSource paramSource, ResultSetExtractor rse) throws DataAccessException { return getJdbcOperations().query(getPreparedStatementCreator(sql, paramSource), rse); } public T query(String sql, Map paramMap, ResultSetExtractor rse) throws DataAccessException { return query(sql, new MapSqlParameterSource(paramMap), rse); } public void query(String sql, SqlParameterSource paramSource, RowCallbackHandler rch) throws DataAccessException { getJdbcOperations().query(getPreparedStatementCreator(sql, paramSource), rch); } public void query(String sql, Map paramMap, RowCallbackHandler rch) throws DataAccessException { query(sql, new MapSqlParameterSource(paramMap), rch); } public List query(String sql, SqlParameterSource paramSource, RowMapper rowMapper) throws DataAccessException { return getJdbcOperations().query(getPreparedStatementCreator(sql, paramSource), rowMapper); } public List query(String sql, Map paramMap, RowMapper rowMapper) throws DataAccessException { return query(sql, new MapSqlParameterSource(paramMap), rowMapper); } public T queryForObject(String sql, SqlParameterSource paramSource, RowMapper rowMapper) throws DataAccessException { List results = getJdbcOperations().query(getPreparedStatementCreator(sql, paramSource), rowMapper); return DataAccessUtils.requiredSingleResult(results); } public T queryForObject(String sql, Map paramMap, RowMapperrowMapper) throws DataAccessException { return queryForObject(sql, new MapSqlParameterSource(paramMap), rowMapper); } public T queryForObject(String sql, SqlParameterSource paramSource, Class requiredType) throws DataAccessException { return queryForObject(sql, paramSource, new SingleColumnRowMapper(requiredType)); } public T queryForObject(String sql, Map paramMap, Class requiredType) throws DataAccessException { return queryForObject(sql, paramMap, new SingleColumnRowMapper(requiredType)); } public Map queryForMap(String sql, SqlParameterSource paramSource) throws DataAccessException { return queryForObject(sql, paramSource, new ColumnMapRowMapper()); } public Map queryForMap(String sql, Map paramMap) throws DataAccessException { return queryForObject(sql, paramMap, new ColumnMapRowMapper()); } public long queryForLong(String sql, SqlParameterSource paramSource) throws DataAccessException { Number number = queryForObject(sql, paramSource, Number.class); return (number != null ? number.longValue() : 0); } public long queryForLong(String sql, Map paramMap) throws DataAccessException { return queryForLong(sql, new MapSqlParameterSource(paramMap)); } public int queryForInt(String sql, SqlParameterSource paramSource) throws DataAccessException { Number number = queryForObject(sql, paramSource, Number.class); return (number != null ? number.intValue() : 0); } public int queryForInt(String sql, Map paramMap) throws DataAccessException { return queryForInt(sql, new MapSqlParameterSource(paramMap)); } public List queryForList(String sql, SqlParameterSource paramSource, Class elementType) throws DataAccessException { return query(sql, paramSource, new SingleColumnRowMapper(elementType)); } public List queryForList(String sql, Map paramMap, Class elementType) throws DataAccessException { return queryForList(sql, new MapSqlParameterSource(paramMap), elementType); } public List> queryForList(String sql, SqlParameterSource paramSource) throws DataAccessException { return query(sql, paramSource, new ColumnMapRowMapper()); } public List> queryForList(String sql, Map paramMap) throws DataAccessException { return queryForList(sql, new MapSqlParameterSource(paramMap)); } public SqlRowSet queryForRowSet(String sql, SqlParameterSource paramSource) throws DataAccessException { return getJdbcOperations().query( getPreparedStatementCreator(sql, paramSource), new SqlRowSetResultSetExtractor()); } public SqlRowSet queryForRowSet(String sql, Map paramMap) throws DataAccessException { return queryForRowSet(sql, new MapSqlParameterSource(paramMap)); } public int update(String sql, SqlParameterSource paramSource) throws DataAccessException { return getJdbcOperations().update(getPreparedStatementCreator(sql, paramSource)); } public int update(String sql, Map paramMap) throws DataAccessException { return update(sql, new MapSqlParameterSource(paramMap)); } public int update(String sql, SqlParameterSource paramSource, KeyHolder generatedKeyHolder) throws DataAccessException { return update(sql, paramSource, generatedKeyHolder, null); } public int update( String sql, SqlParameterSource paramSource, KeyHolder generatedKeyHolder, String[] keyColumnNames) throws DataAccessException { ParsedSql parsedSql = getParsedSql(sql); String sqlToUse = NamedParameterUtils.substituteNamedParameters(parsedSql, paramSource); Object[] params = NamedParameterUtils.buildValueArray(parsedSql, paramSource, null); List declaredParameters = NamedParameterUtils.buildSqlParameterList(parsedSql, paramSource); PreparedStatementCreatorFactory pscf = new PreparedStatementCreatorFactory(sqlToUse, declaredParameters); if (keyColumnNames != null) { pscf.setGeneratedKeysColumnNames(keyColumnNames); } else { pscf.setReturnGeneratedKeys(true); } return getJdbcOperations().update(pscf.newPreparedStatementCreator(params), generatedKeyHolder); } public int[] batchUpdate(String sql, Map[] batchValues) { SqlParameterSource[] batchArgs = new SqlParameterSource[batchValues.length]; int i = 0; for (Map values : batchValues) { batchArgs[i] = new MapSqlParameterSource(values); i++; } return batchUpdate(sql, batchArgs); } public int[] batchUpdate(String sql, SqlParameterSource[] batchArgs) { ParsedSql parsedSql = this.getParsedSql(sql); return NamedParameterBatchUpdateUtils.executeBatchUpdateWithNamedParameters(parsedSql, batchArgs, getJdbcOperations()); } /** * Build a PreparedStatementCreator based on the given SQL and named parameters. *

Note: Not used for the update variant with generated key handling. * @param sql SQL to execute * @param paramSource container of arguments to bind * @return the corresponding PreparedStatementCreator */ protected PreparedStatementCreator getPreparedStatementCreator(String sql, SqlParameterSource paramSource) { ParsedSql parsedSql = getParsedSql(sql); String sqlToUse = NamedParameterUtils.substituteNamedParameters(parsedSql, paramSource); Object[] params = NamedParameterUtils.buildValueArray(parsedSql, paramSource, null); List declaredParameters = NamedParameterUtils.buildSqlParameterList(parsedSql, paramSource); PreparedStatementCreatorFactory pscf = new PreparedStatementCreatorFactory(sqlToUse, declaredParameters); return pscf.newPreparedStatementCreator(params); } /** * Obtain a parsed representation of the given SQL statement. *

The default implementation uses an LRU cache with an upper limit * of 256 entries. * @param sql the original SQL * @return a representation of the parsed SQL statement */ protected ParsedSql getParsedSql(String sql) { if (getCacheLimit() <= 0) { return NamedParameterUtils.parseSqlStatement(sql); } synchronized (this.parsedSqlCache) { ParsedSql parsedSql = this.parsedSqlCache.get(sql); if (parsedSql == null) { parsedSql = NamedParameterUtils.parseSqlStatement(sql); this.parsedSqlCache.put(sql, parsedSql); } return parsedSql; } } } ././@LongLink0000000000000000000000000000021700000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/namedparam/NamedParameterUtils.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000003450011623223530033267 0ustar drazzibdrazzib/* * Copyright 2002-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.namedparam; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.jdbc.core.SqlParameter; import org.springframework.jdbc.core.SqlParameterValue; import org.springframework.util.Assert; /** * Helper methods for named parameter parsing. * Only intended for internal use within Spring's JDBC framework. * * @author Thomas Risberg * @author Juergen Hoeller * @since 2.0 */ public abstract class NamedParameterUtils { /** * Set of characters that qualify as parameter separators, * indicating that a parameter name in a SQL String has ended. */ private static final char[] PARAMETER_SEPARATORS = new char[] {'"', '\'', ':', '&', ',', ';', '(', ')', '|', '=', '+', '-', '*', '%', '/', '\\', '<', '>', '^'}; /** * Set of characters that qualify as comment or quotes starting characters. */ private static final String[] START_SKIP = new String[] {"'", "\"", "--", "/*"}; /** * Set of characters that at are the corresponding comment or quotes ending characters. */ private static final String[] STOP_SKIP = new String[] {"'", "\"", "\n", "*/"}; //------------------------------------------------------------------------- // Core methods used by NamedParameterJdbcTemplate and SqlQuery/SqlUpdate //------------------------------------------------------------------------- /** * Parse the SQL statement and locate any placeholders or named parameters. * Named parameters are substituted for a JDBC placeholder. * @param sql the SQL statement * @return the parsed statement, represented as ParsedSql instance */ public static ParsedSql parseSqlStatement(String sql) { Assert.notNull(sql, "SQL must not be null"); Set namedParameters = new HashSet(); ParsedSql parsedSql = new ParsedSql(sql); char[] statement = sql.toCharArray(); int namedParameterCount = 0; int unnamedParameterCount = 0; int totalParameterCount = 0; int i = 0; while (i < statement.length) { int skipToPosition = skipCommentsAndQuotes(statement, i); if (i != skipToPosition) { if (skipToPosition >= statement.length) { break; } i = skipToPosition; } char c = statement[i]; if (c == ':' || c == '&') { int j = i + 1; if (j < statement.length && statement[j] == ':' && c == ':') { // Postgres-style "::" casting operator - to be skipped. i = i + 2; continue; } while (j < statement.length && !isParameterSeparator(statement[j])) { j++; } if (j - i > 1) { String parameter = sql.substring(i + 1, j); if (!namedParameters.contains(parameter)) { namedParameters.add(parameter); namedParameterCount++; } parsedSql.addNamedParameter(parameter, i, j); totalParameterCount++; } i = j - 1; } else { if (c == '?') { unnamedParameterCount++; totalParameterCount++; } } i++; } parsedSql.setNamedParameterCount(namedParameterCount); parsedSql.setUnnamedParameterCount(unnamedParameterCount); parsedSql.setTotalParameterCount(totalParameterCount); return parsedSql; } /** * Skip over comments and quoted names present in an SQL statement * @param statement character array containing SQL statement * @param position current position of statement * @return next position to process after any comments or quotes are skipped */ private static int skipCommentsAndQuotes(char[] statement, int position) { for (int i = 0; i < START_SKIP.length; i++) { if (statement[position] == START_SKIP[i].charAt(0)) { boolean match = true; for (int j = 1; j < START_SKIP[i].length(); j++) { if (!(statement[position + j] == START_SKIP[i].charAt(j))) { match = false; break; } } if (match) { int offset = START_SKIP[i].length(); for (int m = position + offset; m < statement.length; m++) { if (statement[m] == STOP_SKIP[i].charAt(0)) { boolean endMatch = true; int endPos = m; for (int n = 1; n < STOP_SKIP[i].length(); n++) { if (m + n >= statement.length) { // last comment not closed properly return statement.length; } if (!(statement[m + n] == STOP_SKIP[i].charAt(n))) { endMatch = false; break; } endPos = m + n; } if (endMatch) { // found character sequence ending comment or quote return endPos + 1; } } } // character sequence ending comment or quote not found return statement.length; } } } return position; } /** * Parse the SQL statement and locate any placeholders or named parameters. * Named parameters are substituted for a JDBC placeholder and any select list * is expanded to the required number of placeholders. Select lists may contain * an array of objects and in that case the placeholders will be grouped and * enclosed with parantheses. This allows for the use of "expression lists" in * the SQL statement like:
* select id, name, state from table where (name, age) in (('John', 35), ('Ann', 50)) *

The parameter values passed in are used to determine the number of * placeholder to be used for a select list. Select lists should be limited * to 100 or fewer elements. A larger number of elements is not guaramteed to * be supported by the database and is strictly vendor-dependent. * @param parsedSql the parsed represenation of the SQL statement * @param paramSource the source for named parameters * @return the SQL statement with substituted parameters * @see #parseSqlStatement */ public static String substituteNamedParameters(ParsedSql parsedSql, SqlParameterSource paramSource) { String originalSql = parsedSql.getOriginalSql(); StringBuilder actualSql = new StringBuilder(); List paramNames = parsedSql.getParameterNames(); int lastIndex = 0; for (int i = 0; i < paramNames.size(); i++) { String paramName = (String) paramNames.get(i); int[] indexes = parsedSql.getParameterIndexes(i); int startIndex = indexes[0]; int endIndex = indexes[1]; actualSql.append(originalSql.substring(lastIndex, startIndex)); if (paramSource != null && paramSource.hasValue(paramName)) { Object value = paramSource.getValue(paramName); if (value instanceof Collection) { Iterator entryIter = ((Collection) value).iterator(); int k = 0; while (entryIter.hasNext()) { if (k > 0) { actualSql.append(", "); } k++; Object entryItem = entryIter.next(); if (entryItem instanceof Object[]) { Object[] expressionList = (Object[]) entryItem; actualSql.append("("); for (int m = 0; m < expressionList.length; m++) { if (m > 0) { actualSql.append(", "); } actualSql.append("?"); } actualSql.append(")"); } else { actualSql.append("?"); } } } else { actualSql.append("?"); } } else { actualSql.append("?"); } lastIndex = endIndex; } actualSql.append(originalSql.substring(lastIndex, originalSql.length())); return actualSql.toString(); } /** * Convert a Map of named parameter values to a corresponding array. * @param parsedSql the parsed SQL statement * @param paramSource the source for named parameters * @param declaredParams the List of declared SqlParameter objects * (may be null). If specified, the parameter metadata will * be built into the value array in the form of SqlParameterValue objects. * @return the array of values */ public static Object[] buildValueArray( ParsedSql parsedSql, SqlParameterSource paramSource, List declaredParams) { Object[] paramArray = new Object[parsedSql.getTotalParameterCount()]; if (parsedSql.getNamedParameterCount() > 0 && parsedSql.getUnnamedParameterCount() > 0) { throw new InvalidDataAccessApiUsageException( "You can't mix named and traditional ? placeholders. You have " + parsedSql.getNamedParameterCount() + " named parameter(s) and " + parsedSql.getUnnamedParameterCount() + " traditonal placeholder(s) in [" + parsedSql.getOriginalSql() + "]"); } List paramNames = parsedSql.getParameterNames(); for (int i = 0; i < paramNames.size(); i++) { String paramName = paramNames.get(i); try { Object value = paramSource.getValue(paramName); SqlParameter param = findParameter(declaredParams, paramName, i); paramArray[i] = (param != null ? new SqlParameterValue(param, value) : value); } catch (IllegalArgumentException ex) { throw new InvalidDataAccessApiUsageException( "No value supplied for the SQL parameter '" + paramName + "': " + ex.getMessage()); } } return paramArray; } /** * Find a matching parameter in the given list of declared parameters. * @param declaredParams the declared SqlParameter objects * @param paramName the name of the desired parameter * @param paramIndex the index of the desired parameter * @return the declared SqlParameter, or null if none found */ private static SqlParameter findParameter(List declaredParams, String paramName, int paramIndex) { if (declaredParams != null) { // First pass: Look for named parameter match. for (SqlParameter declaredParam : declaredParams) { if (paramName.equals(declaredParam.getName())) { return declaredParam; } } // Second pass: Look for parameter index match. if (paramIndex < declaredParams.size()) { SqlParameter declaredParam = declaredParams.get(paramIndex); // Only accept unnamed parameters for index matches. if (declaredParam.getName() == null) { return declaredParam; } } } return null; } /** * Determine whether a parameter name ends at the current position, * that is, whether the given character qualifies as a separator. */ private static boolean isParameterSeparator(char c) { if (Character.isWhitespace(c)) { return true; } for (char separator : PARAMETER_SEPARATORS) { if (c == separator) { return true; } } return false; } /** * Convert parameter types from an SqlParameterSource into a corresponding int array. * This is necessary in order to reuse existing methods on JdbcTemplate. * Any named parameter types are placed in the correct position in the * Object array based on the parsed SQL statement info. * @param parsedSql the parsed SQL statement * @param paramSource the source for named parameters */ public static int[] buildSqlTypeArray(ParsedSql parsedSql, SqlParameterSource paramSource) { int[] sqlTypes = new int[parsedSql.getTotalParameterCount()]; List paramNames = parsedSql.getParameterNames(); for (int i = 0; i < paramNames.size(); i++) { String paramName = paramNames.get(i); sqlTypes[i] = paramSource.getSqlType(paramName); } return sqlTypes; } /** * Convert parameter declarations from an SqlParameterSource to a corresponding List of SqlParameters. * This is necessary in order to reuse existing methods on JdbcTemplate. * The SqlParameter for a named parameter is placed in the correct position in the * resulting list based on the parsed SQL statement info. * @param parsedSql the parsed SQL statement * @param paramSource the source for named parameters */ public static List buildSqlParameterList(ParsedSql parsedSql, SqlParameterSource paramSource) { List paramNames = parsedSql.getParameterNames(); List params = new LinkedList(); for (String paramName : paramNames) { SqlParameter param = new SqlParameter( paramName, paramSource.getSqlType(paramName), paramSource.getTypeName(paramName)); params.add(param); } return params; } //------------------------------------------------------------------------- // Convenience methods operating on a plain SQL String //------------------------------------------------------------------------- /** * Parse the SQL statement and locate any placeholders or named parameters. * Named parameters are substituted for a JDBC placeholder. *

This is a shortcut version of * {@link #parseSqlStatement(String)} in combination with * {@link #substituteNamedParameters(ParsedSql, SqlParameterSource)}. * @param sql the SQL statement * @return the actual (parsed) SQL statement */ public static String parseSqlStatementIntoString(String sql) { ParsedSql parsedSql = parseSqlStatement(sql); return substituteNamedParameters(parsedSql, null); } /** * Parse the SQL statement and locate any placeholders or named parameters. * Named parameters are substituted for a JDBC placeholder and any select list * is expanded to the required number of placeholders. *

This is a shortcut version of * {@link #substituteNamedParameters(ParsedSql, SqlParameterSource)}. * @param sql the SQL statement * @param paramSource the source for named parameters * @return the SQL statement with substituted parameters */ public static String substituteNamedParameters(String sql, SqlParameterSource paramSource) { ParsedSql parsedSql = parseSqlStatement(sql); return substituteNamedParameters(parsedSql, paramSource); } /** * Convert a Map of named parameter values to a corresponding array. *

This is a shortcut version of * {@link #buildValueArray(ParsedSql, SqlParameterSource, java.util.List)}. * @param sql the SQL statement * @param paramMap the Map of parameters * @return the array of values */ public static Object[] buildValueArray(String sql, Map paramMap) { ParsedSql parsedSql = parseSqlStatement(sql); return buildValueArray(parsedSql, new MapSqlParameterSource(paramMap), null); } } ././@LongLink0000000000000000000000000000023000000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/namedparam/NamedParameterJdbcDaoSupport.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000273011623223530033267 0ustar drazzibdrazzib/* * Copyright 2002-2006 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.namedparam; import org.springframework.jdbc.core.support.JdbcDaoSupport; /** * Extension of JdbcDaoSupport that exposes a NamedParameterJdbcTemplate as well. * * @author Thomas Risberg * @author Juergen Hoeller * @since 2.0 * @see NamedParameterJdbcTemplate */ public class NamedParameterJdbcDaoSupport extends JdbcDaoSupport { private NamedParameterJdbcTemplate namedParameterJdbcTemplate; /** * Create a NamedParameterJdbcTemplate based on the configured JdbcTemplate. */ @Override protected void initTemplateConfig() { this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(getJdbcTemplate()); } /** * Return a NamedParameterJdbcTemplate wrapping the configured JdbcTemplate. */ public NamedParameterJdbcTemplate getNamedParameterJdbcTemplate() { return namedParameterJdbcTemplate; } } ././@LongLink0000000000000000000000000000023200000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/namedparam/BeanPropertySqlParameterSource.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000644011623223526033276 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.namedparam; import java.beans.PropertyDescriptor; import java.util.ArrayList; import java.util.List; import org.springframework.beans.BeanWrapper; import org.springframework.beans.NotReadablePropertyException; import org.springframework.beans.PropertyAccessor; import org.springframework.beans.PropertyAccessorFactory; import org.springframework.jdbc.core.StatementCreatorUtils; /** * {@link SqlParameterSource} implementation that obtains parameter values * from bean properties of a given JavaBean object. The names of the bean * properties have to match the parameter names. * *

Uses a Spring BeanWrapper for bean property access underneath. * * @author Thomas Risberg * @author Juergen Hoeller * @since 2.0 * @see NamedParameterJdbcTemplate * @see org.springframework.beans.BeanWrapper */ public class BeanPropertySqlParameterSource extends AbstractSqlParameterSource { private final BeanWrapper beanWrapper; private String[] propertyNames; /** * Create a new BeanPropertySqlParameterSource for the given bean. * @param object the bean instance to wrap */ public BeanPropertySqlParameterSource(Object object) { this.beanWrapper = PropertyAccessorFactory.forBeanPropertyAccess(object); } public boolean hasValue(String paramName) { return this.beanWrapper.isReadableProperty(paramName); } public Object getValue(String paramName) throws IllegalArgumentException { try { return this.beanWrapper.getPropertyValue(paramName); } catch (NotReadablePropertyException ex) { throw new IllegalArgumentException(ex.getMessage()); } } /** * Provide access to the property names of the wrapped bean. * Uses support provided in the {@link PropertyAccessor} interface. * @return an array containing all the known property names */ public String[] getReadablePropertyNames() { if (this.propertyNames == null) { List names = new ArrayList(); PropertyDescriptor[] props = this.beanWrapper.getPropertyDescriptors(); for (PropertyDescriptor pd : props) { if (this.beanWrapper.isReadableProperty(pd.getName())) { names.add(pd.getName()); } } this.propertyNames = names.toArray(new String[names.size()]); } return this.propertyNames; } /** * Derives a default SQL type from the corresponding property type. * @see org.springframework.jdbc.core.StatementCreatorUtils#javaTypeToSqlParameterType */ @Override public int getSqlType(String paramName) { int sqlType = super.getSqlType(paramName); if (sqlType != TYPE_UNKNOWN) { return sqlType; } Class propType = this.beanWrapper.getPropertyType(paramName); return StatementCreatorUtils.javaTypeToSqlParameterType(propType); } } ././@LongLink0000000000000000000000000000022100000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/namedparam/MapSqlParameterSource.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001233311623223530033267 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.namedparam; import java.util.Collections; import java.util.HashMap; import java.util.Map; import org.springframework.jdbc.core.SqlParameterValue; import org.springframework.util.Assert; /** * {@link SqlParameterSource} implementation that holds a given Map of parameters. * *

This class is intended for passing in a simple Map of parameter values * to the methods of the {@link NamedParameterJdbcTemplate} class. * *

The addValue methods on this class will make adding several * values easier. The methods return a reference to the {@link MapSqlParameterSource} * itself, so you can chain several method calls together within a single statement. * * @author Thomas Risberg * @author Juergen Hoeller * @since 2.0 * @see #addValue(String, Object) * @see #addValue(String, Object, int) * @see #registerSqlType * @see NamedParameterJdbcTemplate */ public class MapSqlParameterSource extends AbstractSqlParameterSource { private final Map values = new HashMap(); /** * Create an empty MapSqlParameterSource, * with values to be added via addValue. * @see #addValue(String, Object) */ public MapSqlParameterSource() { } /** * Create a new MapSqlParameterSource, with one value * comprised of the supplied arguments. * @param paramName the name of the parameter * @param value the value of the parameter * @see #addValue(String, Object) */ public MapSqlParameterSource(String paramName, Object value) { addValue(paramName, value); } /** * Create a new MapSqlParameterSource based on a Map. * @param values a Map holding existing parameter values (can be null) */ public MapSqlParameterSource(Map values) { addValues(values); } /** * Add a parameter to this parameter source. * @param paramName the name of the parameter * @param value the value of the parameter * @return a reference to this parameter source, * so it's possible to chain several calls together */ public MapSqlParameterSource addValue(String paramName, Object value) { Assert.notNull(paramName, "Parameter name must not be null"); this.values.put(paramName, value); if (value instanceof SqlParameterValue) { registerSqlType(paramName, ((SqlParameterValue) value).getSqlType()); } return this; } /** * Add a parameter to this parameter source. * @param paramName the name of the parameter * @param value the value of the parameter * @param sqlType the SQL type of the parameter * @return a reference to this parameter source, * so it's possible to chain several calls together */ public MapSqlParameterSource addValue(String paramName, Object value, int sqlType) { Assert.notNull(paramName, "Parameter name must not be null"); this.values.put(paramName, value); registerSqlType(paramName, sqlType); return this; } /** * Add a parameter to this parameter source. * @param paramName the name of the parameter * @param value the value of the parameter * @param sqlType the SQL type of the parameter * @param typeName the type name of the parameter * @return a reference to this parameter source, * so it's possible to chain several calls together */ public MapSqlParameterSource addValue(String paramName, Object value, int sqlType, String typeName) { Assert.notNull(paramName, "Parameter name must not be null"); this.values.put(paramName, value); registerSqlType(paramName, sqlType); registerTypeName(paramName, typeName); return this; } /** * Add a Map of parameters to this parameter source. * @param values a Map holding existing parameter values (can be null) * @return a reference to this parameter source, * so it's possible to chain several calls together */ public MapSqlParameterSource addValues(Map values) { if (values != null) { for (Map.Entry entry : values.entrySet()) { this.values.put(entry.getKey(), entry.getValue()); if (entry.getValue() instanceof SqlParameterValue) { SqlParameterValue value = (SqlParameterValue) entry.getValue(); registerSqlType(entry.getKey(), value.getSqlType()); } } } return this; } /** * Expose the current parameter values as read-only Map. */ public Map getValues() { return Collections.unmodifiableMap(this.values); } public boolean hasValue(String paramName) { return this.values.containsKey(paramName); } public Object getValue(String paramName) { if (!hasValue(paramName)) { throw new IllegalArgumentException("No value registered for key '" + paramName + "'"); } return this.values.get(paramName); } } ././@LongLink0000000000000000000000000000023200000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/namedparam/NamedParameterBatchUpdateUtils.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000251211623223530033265 0ustar drazzibdrazzibpackage org.springframework.jdbc.core.namedparam; import java.sql.PreparedStatement; import java.sql.SQLException; import org.springframework.jdbc.core.BatchUpdateUtils; import org.springframework.jdbc.core.JdbcOperations; import org.springframework.jdbc.core.BatchPreparedStatementSetter; /** * Generic utility methods for working with JDBC batch statements using named parameters. Mainly for internal use * within the framework. * * @author Thomas Risberg */ public class NamedParameterBatchUpdateUtils extends BatchUpdateUtils { public static int[] executeBatchUpdateWithNamedParameters(final ParsedSql parsedSql, final SqlParameterSource[] batchArgs, JdbcOperations jdbcOperations) { if (batchArgs.length <= 0) { return new int[] {0}; } String sqlToUse = NamedParameterUtils.substituteNamedParameters(parsedSql, batchArgs[0]); return jdbcOperations.batchUpdate( sqlToUse, new BatchPreparedStatementSetter() { public void setValues(PreparedStatement ps, int i) throws SQLException { Object[] values = NamedParameterUtils.buildValueArray(parsedSql, batchArgs[i], null); int[] columnTypes = NamedParameterUtils.buildSqlTypeArray(parsedSql, batchArgs[i]); setStatementParameters(values, ps, columnTypes); } public int getBatchSize() { return batchArgs.length; } }); } } ././@LongLink0000000000000000000000000000021600000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/namedparam/SqlParameterSource.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000535011623223530033270 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.namedparam; import org.springframework.jdbc.support.JdbcUtils; /** * Interface that defines common functionality for objects that can * offer parameter values for named SQL parameters, serving as argument * for {@link NamedParameterJdbcTemplate} operations. * *

This interface allows for the specification of SQL type in addition * to parameter values. All parameter values and types are identified by * specifying the name of the parameter. * *

Intended to wrap various implementations like a Map or a JavaBean * with a consistent interface. * * @author Thomas Risberg * @author Juergen Hoeller * @since 2.0 * @see NamedParameterJdbcOperations * @see NamedParameterJdbcTemplate * @see MapSqlParameterSource * @see BeanPropertySqlParameterSource */ public interface SqlParameterSource { /** * Constant that indicates an unknown (or unspecified) SQL type. * To be returned from getType when no specific SQL type known. * @see #getSqlType * @see java.sql.Types */ int TYPE_UNKNOWN = JdbcUtils.TYPE_UNKNOWN; /** * Determine whether there is a value for the specified named parameter. * @param paramName the name of the parameter * @return whether there is a value defined */ boolean hasValue(String paramName); /** * Return the parameter value for the requested named parameter. * @param paramName the name of the parameter * @return the value of the specified parameter * @throws IllegalArgumentException if there is no value for the requested parameter */ Object getValue(String paramName) throws IllegalArgumentException; /** * Determine the SQL type for the specified named parameter. * @param paramName the name of the parameter * @return the SQL type of the specified parameter, * or TYPE_UNKNOWN if not known * @see #TYPE_UNKNOWN */ int getSqlType(String paramName); /** * Determine the type name for the specified named parameter. * @param paramName the name of the parameter * @return the type name of the specified parameter, * or null if not known */ String getTypeName(String paramName); } ././@LongLink0000000000000000000000000000022600000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/namedparam/AbstractSqlParameterSource.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000513711623223530033273 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.namedparam; import java.util.HashMap; import java.util.Map; import org.springframework.util.Assert; /** * Abstract base class for {@link SqlParameterSource} implementations. * Provides registration of SQL types per parameter. * * @author Juergen Hoeller * @since 2.0 */ public abstract class AbstractSqlParameterSource implements SqlParameterSource { private final Map sqlTypes = new HashMap(); private final Map typeNames = new HashMap(); /** * Register a SQL type for the given parameter. * @param paramName the name of the parameter * @param sqlType the SQL type of the parameter */ public void registerSqlType(String paramName, int sqlType) { Assert.notNull(paramName, "Parameter name must not be null"); this.sqlTypes.put(paramName, sqlType); } /** * Register a SQL type for the given parameter. * @param paramName the name of the parameter * @param typeName the type name of the parameter */ public void registerTypeName(String paramName, String typeName) { Assert.notNull(paramName, "Parameter name must not be null"); this.typeNames.put(paramName, typeName); } /** * Return the SQL type for the given parameter, if registered. * @param paramName the name of the parameter * @return the SQL type of the parameter, * or TYPE_UNKNOWN if not registered */ public int getSqlType(String paramName) { Assert.notNull(paramName, "Parameter name must not be null"); Integer sqlType = this.sqlTypes.get(paramName); if (sqlType != null) { return sqlType; } return TYPE_UNKNOWN; } /** * Return the type name for the given parameter, if registered. * @param paramName the name of the parameter * @return the type name of the parameter, * or null if not registered */ public String getTypeName(String paramName) { Assert.notNull(paramName, "Parameter name must not be null"); return this.typeNames.get(paramName); } } ././@LongLink0000000000000000000000000000022300000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/namedparam/SqlParameterSourceUtils.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000764111623223530033275 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.namedparam; import java.util.HashMap; import java.util.Map; import java.util.Iterator; import org.springframework.jdbc.core.SqlParameterValue; /** * Class that provides helper methods for the use of {@link SqlParameterSource} * with SimpleJdbc classes. * * @author Thomas Risberg * @since 2.5 * @see org.springframework.jdbc.core.simple.SimpleJdbcTemplate */ public class SqlParameterSourceUtils { /** * Create an array of MapSqlParameterSource objects populated with data from the * values passed in. This will define what is included in a batch operation. * @param valueMaps array of Maps containing the values to be used * @return an array of SqlParameterSource */ public static SqlParameterSource[] createBatch(Map[] valueMaps) { MapSqlParameterSource[] batch = new MapSqlParameterSource[valueMaps.length]; for (int i = 0; i < valueMaps.length; i++) { Map valueMap = valueMaps[i]; batch[i] = new MapSqlParameterSource(valueMap); } return batch; } /** * Create an array of BeanPropertySqlParameterSource objects populated with data * from the values passed in. This will define what is included in a batch operation. * @param beans object array of beans containing the values to be used * @return an array of SqlParameterSource */ public static SqlParameterSource[] createBatch(Object[] beans) { BeanPropertySqlParameterSource[] batch = new BeanPropertySqlParameterSource[beans.length]; for (int i = 0; i < beans.length; i++) { Object bean = beans[i]; batch[i] = new BeanPropertySqlParameterSource(bean); } return batch; } /** * Create a wrapped value if parameter has type information, plain object if not. * @param source the source of paramer values and type information * @param parameterName the name of the parameter * @return the value object */ public static Object getTypedValue(SqlParameterSource source, String parameterName) { int sqlType = source.getSqlType(parameterName); if (sqlType != SqlParameterSource.TYPE_UNKNOWN) { if (source.getTypeName(parameterName) != null) { return new SqlParameterValue(sqlType, source.getTypeName(parameterName), source.getValue(parameterName)); } else { return new SqlParameterValue(sqlType, source.getValue(parameterName)); } } else { return source.getValue(parameterName); } } /** * Create a Map of case insensitive parameter names together with the original name. * @param parameterSource the source of paramer names * @return the Map that can be used for case insensitive matching of parameter names */ public static Map extractCaseInsensitiveParameterNames(SqlParameterSource parameterSource) { Map caseInsensitiveParameterNames = new HashMap(); if (parameterSource instanceof BeanPropertySqlParameterSource) { String[] propertyNames = ((BeanPropertySqlParameterSource)parameterSource).getReadablePropertyNames(); for (int i = 0; i < propertyNames.length; i++) { String name = propertyNames[i]; caseInsensitiveParameterNames.put(name.toLowerCase(), name); } } else if (parameterSource instanceof MapSqlParameterSource) { for (String name : ((MapSqlParameterSource) parameterSource).getValues().keySet()) { caseInsensitiveParameterNames.put(name.toLowerCase(), name); } } return caseInsensitiveParameterNames; } } ././@LongLink0000000000000000000000000000017400000000000011567 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/SqlProvider.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000250311623223526033272 0ustar drazzibdrazzib/* * Copyright 2002-2005 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; /** * Interface to be implemented by objects that can provide SQL strings. * *

Typically implemented by PreparedStatementCreators, CallableStatementCreators * and StatementCallbacks that want to expose the SQL they use to create their * statements, to allow for better contextual information in case of exceptions. * * @author Juergen Hoeller * @since 16.03.2004 * @see PreparedStatementCreator * @see CallableStatementCreator * @see StatementCallback */ public interface SqlProvider { /** * Return the SQL string for this object, i.e. * typically the SQL used for creating statements. * @return the SQL string, or null */ String getSql(); } ././@LongLink0000000000000000000000000000017700000000000011572 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/JdbcOperations.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000014475711623223530033307 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; import java.util.List; import java.util.Map; import org.springframework.dao.DataAccessException; import org.springframework.dao.IncorrectResultSizeDataAccessException; import org.springframework.jdbc.support.KeyHolder; import org.springframework.jdbc.support.rowset.SqlRowSet; /** * Interface specifying a basic set of JDBC operations. * Implemented by {@link JdbcTemplate}. Not often used directly, but a useful * option to enhance testability, as it can easily be mocked or stubbed. * *

Alternatively, the standard JDBC infrastructure can be mocked. * However, mocking this interface constitutes significantly less work. * As an alternative to a mock objects approach to testing data access code, * consider the powerful integration testing support provided in the * org.springframework.test package, shipped in * spring-mock.jar. * * @author Rod Johnson * @author Juergen Hoeller * @see JdbcTemplate */ public interface JdbcOperations { //------------------------------------------------------------------------- // Methods dealing with a plain java.sql.Connection //------------------------------------------------------------------------- /** * Execute a JDBC data access operation, implemented as callback action * working on a JDBC Connection. This allows for implementing arbitrary * data access operations, within Spring's managed JDBC environment: * that is, participating in Spring-managed transactions and converting * JDBC SQLExceptions into Spring's DataAccessException hierarchy. *

The callback action can return a result object, for example a * domain object or a collection of domain objects. * @param action the callback object that specifies the action * @return a result object returned by the action, or null * @throws DataAccessException if there is any problem */ T execute(ConnectionCallback action) throws DataAccessException; //------------------------------------------------------------------------- // Methods dealing with static SQL (java.sql.Statement) //------------------------------------------------------------------------- /** * Execute a JDBC data access operation, implemented as callback action * working on a JDBC Statement. This allows for implementing arbitrary data * access operations on a single Statement, within Spring's managed JDBC * environment: that is, participating in Spring-managed transactions and * converting JDBC SQLExceptions into Spring's DataAccessException hierarchy. *

The callback action can return a result object, for example a * domain object or a collection of domain objects. * @param action callback object that specifies the action * @return a result object returned by the action, or null * @throws DataAccessException if there is any problem */ T execute(StatementCallback action) throws DataAccessException; /** * Issue a single SQL execute, typically a DDL statement. * @param sql static SQL to execute * @throws DataAccessException if there is any problem */ void execute(String sql) throws DataAccessException; /** * Execute a query given static SQL, reading the ResultSet with a * ResultSetExtractor. *

Uses a JDBC Statement, not a PreparedStatement. If you want to * execute a static query with a PreparedStatement, use the overloaded * query method with null as argument array. * @param sql SQL query to execute * @param rse object that will extract all rows of results * @return an arbitrary result object, as returned by the ResultSetExtractor * @throws DataAccessException if there is any problem executing the query * @see #query(String, Object[], ResultSetExtractor) */ T query(String sql, ResultSetExtractor rse) throws DataAccessException; /** * Execute a query given static SQL, reading the ResultSet on a per-row * basis with a RowCallbackHandler. *

Uses a JDBC Statement, not a PreparedStatement. If you want to * execute a static query with a PreparedStatement, use the overloaded * query method with null as argument array. * @param sql SQL query to execute * @param rch object that will extract results, one row at a time * @throws DataAccessException if there is any problem executing the query * @see #query(String, Object[], RowCallbackHandler) */ void query(String sql, RowCallbackHandler rch) throws DataAccessException; /** * Execute a query given static SQL, mapping each row to a Java object * via a RowMapper. *

Uses a JDBC Statement, not a PreparedStatement. If you want to * execute a static query with a PreparedStatement, use the overloaded * query method with null as argument array. * @param sql SQL query to execute * @param rowMapper object that will map one object per row * @return the result List, containing mapped objects * @throws DataAccessException if there is any problem executing the query * @see #query(String, Object[], RowMapper) */ List query(String sql, RowMapper rowMapper) throws DataAccessException; /** * Execute a query given static SQL, mapping a single result row to a Java * object via a RowMapper. *

Uses a JDBC Statement, not a PreparedStatement. If you want to * execute a static query with a PreparedStatement, use the overloaded * queryForObject method with null as argument array. * @param sql SQL query to execute * @param rowMapper object that will map one object per row * @return the single mapped object * @throws IncorrectResultSizeDataAccessException if the query does not * return exactly one row * @throws DataAccessException if there is any problem executing the query * @see #queryForObject(String, Object[], RowMapper) */ T queryForObject(String sql, RowMapper rowMapper) throws DataAccessException; /** * Execute a query for a result object, given static SQL. *

Uses a JDBC Statement, not a PreparedStatement. If you want to * execute a static query with a PreparedStatement, use the overloaded * queryForObject method with null as argument array. *

This method is useful for running static SQL with a known outcome. * The query is expected to be a single row/single column query; the returned * result will be directly mapped to the corresponding object type. * @param sql SQL query to execute * @param requiredType the type that the result object is expected to match * @return the result object of the required type, or null in case of SQL NULL * @throws IncorrectResultSizeDataAccessException if the query does not return * exactly one row, or does not return exactly one column in that row * @throws DataAccessException if there is any problem executing the query * @see #queryForObject(String, Object[], Class) */ T queryForObject(String sql, Class requiredType) throws DataAccessException; /** * Execute a query for a result Map, given static SQL. *

Uses a JDBC Statement, not a PreparedStatement. If you want to * execute a static query with a PreparedStatement, use the overloaded * queryForMap method with null as argument array. *

The query is expected to be a single row query; the result row will be * mapped to a Map (one entry for each column, using the column name as the key). * @param sql SQL query to execute * @return the result Map (one entry for each column, using the * column name as the key) * @throws IncorrectResultSizeDataAccessException if the query does not * return exactly one row * @throws DataAccessException if there is any problem executing the query * @see #queryForMap(String, Object[]) * @see ColumnMapRowMapper */ Map queryForMap(String sql) throws DataAccessException; /** * Execute a query that results in a long value, given static SQL. *

Uses a JDBC Statement, not a PreparedStatement. If you want to * execute a static query with a PreparedStatement, use the overloaded * queryForLong method with null as argument array. *

This method is useful for running static SQL with a known outcome. * The query is expected to be a single row/single column query that results * in a long value. * @param sql SQL query to execute * @return the long value, or 0 in case of SQL NULL * @throws IncorrectResultSizeDataAccessException if the query does not return * exactly one row, or does not return exactly one column in that row * @throws DataAccessException if there is any problem executing the query * @see #queryForLong(String, Object[]) */ long queryForLong(String sql) throws DataAccessException; /** * Execute a query that results in an int value, given static SQL. *

Uses a JDBC Statement, not a PreparedStatement. If you want to * execute a static query with a PreparedStatement, use the overloaded * queryForInt method with null as argument array. *

This method is useful for running static SQL with a known outcome. * The query is expected to be a single row/single column query that results * in an int value. * @param sql SQL query to execute * @return the int value, or 0 in case of SQL NULL * @throws IncorrectResultSizeDataAccessException if the query does not return * exactly one row, or does not return exactly one column in that row * @throws DataAccessException if there is any problem executing the query * @see #queryForInt(String, Object[]) */ int queryForInt(String sql) throws DataAccessException; /** * Execute a query for a result list, given static SQL. *

Uses a JDBC Statement, not a PreparedStatement. If you want to * execute a static query with a PreparedStatement, use the overloaded * queryForList method with null as argument array. *

The results will be mapped to a List (one entry for each row) of * result objects, each of them matching the specified element type. * @param sql SQL query to execute * @param elementType the required type of element in the result list * (for example, Integer.class) * @return a List of objects that match the specified element type * @throws DataAccessException if there is any problem executing the query * @see #queryForList(String, Object[], Class) * @see SingleColumnRowMapper */ List queryForList(String sql, Class elementType) throws DataAccessException; /** * Execute a query for a result list, given static SQL. *

Uses a JDBC Statement, not a PreparedStatement. If you want to * execute a static query with a PreparedStatement, use the overloaded * queryForList method with null as argument array. *

The results will be mapped to a List (one entry for each row) of * Maps (one entry for each column using the column name as the key). * Each element in the list will be of the form returned by this interface's * queryForMap() methods. * @param sql SQL query to execute * @return an List that contains a Map per row * @throws DataAccessException if there is any problem executing the query * @see #queryForList(String, Object[]) */ List> queryForList(String sql) throws DataAccessException; /** * Execute a query for a SqlRowSet, given static SQL. *

Uses a JDBC Statement, not a PreparedStatement. If you want to * execute a static query with a PreparedStatement, use the overloaded * queryForRowSet method with null as argument array. *

The results will be mapped to an SqlRowSet which holds the data in a * disconnected fashion. This wrapper will translate any SQLExceptions thrown. *

Note that that, for the default implementation, JDBC RowSet support needs to * be available at runtime: by default, Sun's com.sun.rowset.CachedRowSetImpl * class is used, which is part of JDK 1.5+ and also available separately as part of * Sun's JDBC RowSet Implementations download (rowset.jar). * @param sql SQL query to execute * @return a SqlRowSet representation (possibly a wrapper around a * javax.sql.rowset.CachedRowSet) * @throws DataAccessException if there is any problem executing the query * @see #queryForRowSet(String, Object[]) * @see SqlRowSetResultSetExtractor * @see javax.sql.rowset.CachedRowSet */ SqlRowSet queryForRowSet(String sql) throws DataAccessException; /** * Issue a single SQL update operation (such as an insert, update or delete statement). * @param sql static SQL to execute * @return the number of rows affected * @throws DataAccessException if there is any problem. */ int update(String sql) throws DataAccessException; /** * Issue multiple SQL updates on a single JDBC Statement using batching. *

Will fall back to separate updates on a single Statement if the JDBC * driver does not support batch updates. * @param sql defining an array of SQL statements that will be executed. * @return an array of the number of rows affected by each statement * @throws DataAccessException if there is any problem executing the batch */ int[] batchUpdate(String[] sql) throws DataAccessException; //------------------------------------------------------------------------- // Methods dealing with prepared statements //------------------------------------------------------------------------- /** * Execute a JDBC data access operation, implemented as callback action * working on a JDBC PreparedStatement. This allows for implementing arbitrary * data access operations on a single Statement, within Spring's managed * JDBC environment: that is, participating in Spring-managed transactions * and converting JDBC SQLExceptions into Spring's DataAccessException hierarchy. *

The callback action can return a result object, for example a * domain object or a collection of domain objects. * @param psc object that can create a PreparedStatement given a Connection * @param action callback object that specifies the action * @return a result object returned by the action, or null * @throws DataAccessException if there is any problem */ T execute(PreparedStatementCreator psc, PreparedStatementCallback action) throws DataAccessException; /** * Execute a JDBC data access operation, implemented as callback action * working on a JDBC PreparedStatement. This allows for implementing arbitrary * data access operations on a single Statement, within Spring's managed * JDBC environment: that is, participating in Spring-managed transactions * and converting JDBC SQLExceptions into Spring's DataAccessException hierarchy. *

The callback action can return a result object, for example a * domain object or a collection of domain objects. * @param sql SQL to execute * @param action callback object that specifies the action * @return a result object returned by the action, or null * @throws DataAccessException if there is any problem */ T execute(String sql, PreparedStatementCallback action) throws DataAccessException; /** * Query using a prepared statement, reading the ResultSet with a * ResultSetExtractor. *

A PreparedStatementCreator can either be implemented directly or * configured through a PreparedStatementCreatorFactory. * @param psc object that can create a PreparedStatement given a Connection * @param rse object that will extract results * @return an arbitrary result object, as returned by the ResultSetExtractor * @throws DataAccessException if there is any problem * @see PreparedStatementCreatorFactory */ T query(PreparedStatementCreator psc, ResultSetExtractor rse) throws DataAccessException; /** * Query using a prepared statement, reading the ResultSet with a * ResultSetExtractor. * @param sql SQL query to execute * @param pss object that knows how to set values on the prepared statement. * If this is null, the SQL will be assumed to contain no bind parameters. * Even if there are no bind parameters, this object may be used to * set fetch size and other performance options. * @param rse object that will extract results * @return an arbitrary result object, as returned by the ResultSetExtractor * @throws DataAccessException if there is any problem */ T query(String sql, PreparedStatementSetter pss, ResultSetExtractor rse) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a list * of arguments to bind to the query, reading the ResultSet with a * ResultSetExtractor. * @param sql SQL query to execute * @param args arguments to bind to the query * @param argTypes SQL types of the arguments * (constants from java.sql.Types) * @param rse object that will extract results * @return an arbitrary result object, as returned by the ResultSetExtractor * @throws DataAccessException if the query fails * @see java.sql.Types */ T query(String sql, Object[] args, int[] argTypes, ResultSetExtractor rse) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a list * of arguments to bind to the query, reading the ResultSet with a * ResultSetExtractor. * @param sql SQL query to execute * @param args arguments to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type); * may also contain {@link SqlParameterValue} objects which indicate not * only the argument value but also the SQL type and optionally the scale * @param rse object that will extract results * @return an arbitrary result object, as returned by the ResultSetExtractor * @throws DataAccessException if the query fails */ T query(String sql, Object[] args, ResultSetExtractor rse) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a list * of arguments to bind to the query, reading the ResultSet with a * ResultSetExtractor. * @param sql SQL query to execute * @param rse object that will extract results * @param args arguments to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type); * may also contain {@link SqlParameterValue} objects which indicate not * only the argument value but also the SQL type and optionally the scale * @return an arbitrary result object, as returned by the ResultSetExtractor * @throws DataAccessException if the query fails */ T query(String sql, ResultSetExtractor rse, Object... args) throws DataAccessException; /** * Query using a prepared statement, reading the ResultSet on a per-row * basis with a RowCallbackHandler. *

A PreparedStatementCreator can either be implemented directly or * configured through a PreparedStatementCreatorFactory. * @param psc object that can create a PreparedStatement given a Connection * @param rch object that will extract results, one row at a time * @throws DataAccessException if there is any problem * @see PreparedStatementCreatorFactory */ void query(PreparedStatementCreator psc, RowCallbackHandler rch) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a * PreparedStatementSetter implementation that knows how to bind values * to the query, reading the ResultSet on a per-row basis with a * RowCallbackHandler. * @param sql SQL query to execute * @param pss object that knows how to set values on the prepared statement. * If this is null, the SQL will be assumed to contain no bind parameters. * Even if there are no bind parameters, this object may be used to * set fetch size and other performance options. * @param rch object that will extract results, one row at a time * @throws DataAccessException if the query fails */ void query(String sql, PreparedStatementSetter pss, RowCallbackHandler rch) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a list of * arguments to bind to the query, reading the ResultSet on a per-row basis * with a RowCallbackHandler. * @param sql SQL query to execute * @param args arguments to bind to the query * @param argTypes SQL types of the arguments * (constants from java.sql.Types) * @param rch object that will extract results, one row at a time * @throws DataAccessException if the query fails * @see java.sql.Types */ void query(String sql, Object[] args, int[] argTypes, RowCallbackHandler rch) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a list of * arguments to bind to the query, reading the ResultSet on a per-row basis * with a RowCallbackHandler. * @param sql SQL query to execute * @param args arguments to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type); * may also contain {@link SqlParameterValue} objects which indicate not * only the argument value but also the SQL type and optionally the scale * @param rch object that will extract results, one row at a time * @throws DataAccessException if the query fails */ void query(String sql, Object[] args, RowCallbackHandler rch) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a list of * arguments to bind to the query, reading the ResultSet on a per-row basis * with a RowCallbackHandler. * @param sql SQL query to execute * @param rch object that will extract results, one row at a time * @param args arguments to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type); * may also contain {@link SqlParameterValue} objects which indicate not * only the argument value but also the SQL type and optionally the scale * @throws DataAccessException if the query fails */ void query(String sql, RowCallbackHandler rch, Object... args) throws DataAccessException; /** * Query using a prepared statement, mapping each row to a Java object * via a RowMapper. *

A PreparedStatementCreator can either be implemented directly or * configured through a PreparedStatementCreatorFactory. * @param psc object that can create a PreparedStatement given a Connection * @param rowMapper object that will map one object per row * @return the result List, containing mapped objects * @throws DataAccessException if there is any problem * @see PreparedStatementCreatorFactory */ List query(PreparedStatementCreator psc, RowMapper rowMapper) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a * PreparedStatementSetter implementation that knows how to bind values * to the query, mapping each row to a Java object via a RowMapper. * @param sql SQL query to execute * @param pss object that knows how to set values on the prepared statement. * If this is null, the SQL will be assumed to contain no bind parameters. * Even if there are no bind parameters, this object may be used to * set fetch size and other performance options. * @param rowMapper object that will map one object per row * @return the result List, containing mapped objects * @throws DataAccessException if the query fails */ List query(String sql, PreparedStatementSetter pss, RowMapper rowMapper) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a list * of arguments to bind to the query, mapping each row to a Java object * via a RowMapper. * @param sql SQL query to execute * @param args arguments to bind to the query * @param argTypes SQL types of the arguments * (constants from java.sql.Types) * @param rowMapper object that will map one object per row * @return the result List, containing mapped objects * @throws DataAccessException if the query fails * @see java.sql.Types */ List query(String sql, Object[] args, int[] argTypes, RowMapper rowMapper) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a list * of arguments to bind to the query, mapping each row to a Java object * via a RowMapper. * @param sql SQL query to execute * @param args arguments to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type); * may also contain {@link SqlParameterValue} objects which indicate not * only the argument value but also the SQL type and optionally the scale * @param rowMapper object that will map one object per row * @return the result List, containing mapped objects * @throws DataAccessException if the query fails */ List query(String sql, Object[] args, RowMapper rowMapper) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a list * of arguments to bind to the query, mapping each row to a Java object * via a RowMapper. * @param sql SQL query to execute * @param rowMapper object that will map one object per row * @param args arguments to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type); * may also contain {@link SqlParameterValue} objects which indicate not * only the argument value but also the SQL type and optionally the scale * @return the result List, containing mapped objects * @throws DataAccessException if the query fails */ List query(String sql, RowMapper rowMapper, Object... args) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a list * of arguments to bind to the query, mapping a single result row to a * Java object via a RowMapper. * @param sql SQL query to execute * @param args arguments to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type) * @param argTypes SQL types of the arguments * (constants from java.sql.Types) * @param rowMapper object that will map one object per row * @return the single mapped object * @throws IncorrectResultSizeDataAccessException if the query does not * return exactly one row * @throws DataAccessException if the query fails */ T queryForObject(String sql, Object[] args, int[] argTypes, RowMapper rowMapper) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a list * of arguments to bind to the query, mapping a single result row to a * Java object via a RowMapper. * @param sql SQL query to execute * @param args arguments to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type); * may also contain {@link SqlParameterValue} objects which indicate not * only the argument value but also the SQL type and optionally the scale * @param rowMapper object that will map one object per row * @return the single mapped object * @throws IncorrectResultSizeDataAccessException if the query does not * return exactly one row * @throws DataAccessException if the query fails */ T queryForObject(String sql, Object[] args, RowMapper rowMapper) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a list * of arguments to bind to the query, mapping a single result row to a * Java object via a RowMapper. * @param sql SQL query to execute * @param rowMapper object that will map one object per row * @param args arguments to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type); * may also contain {@link SqlParameterValue} objects which indicate not * only the argument value but also the SQL type and optionally the scale * @return the single mapped object * @throws IncorrectResultSizeDataAccessException if the query does not * return exactly one row * @throws DataAccessException if the query fails */ T queryForObject(String sql, RowMapper rowMapper, Object... args) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a * list of arguments to bind to the query, expecting a result object. *

The query is expected to be a single row/single column query; the returned * result will be directly mapped to the corresponding object type. * @param sql SQL query to execute * @param args arguments to bind to the query * @param argTypes SQL types of the arguments * (constants from java.sql.Types) * @param requiredType the type that the result object is expected to match * @return the result object of the required type, or null in case of SQL NULL * @throws IncorrectResultSizeDataAccessException if the query does not return * exactly one row, or does not return exactly one column in that row * @throws DataAccessException if the query fails * @see #queryForObject(String, Class) * @see java.sql.Types */ T queryForObject(String sql, Object[] args, int[] argTypes, Class requiredType) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a * list of arguments to bind to the query, expecting a result object. *

The query is expected to be a single row/single column query; the returned * result will be directly mapped to the corresponding object type. * @param sql SQL query to execute * @param args arguments to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type); * may also contain {@link SqlParameterValue} objects which indicate not * only the argument value but also the SQL type and optionally the scale * @param requiredType the type that the result object is expected to match * @return the result object of the required type, or null in case of SQL NULL * @throws IncorrectResultSizeDataAccessException if the query does not return * exactly one row, or does not return exactly one column in that row * @throws DataAccessException if the query fails * @see #queryForObject(String, Class) */ T queryForObject(String sql, Object[] args, Class requiredType) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a * list of arguments to bind to the query, expecting a result object. *

The query is expected to be a single row/single column query; the returned * result will be directly mapped to the corresponding object type. * @param sql SQL query to execute * @param requiredType the type that the result object is expected to match * @param args arguments to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type); * may also contain {@link SqlParameterValue} objects which indicate not * only the argument value but also the SQL type and optionally the scale * @return the result object of the required type, or null in case of SQL NULL * @throws IncorrectResultSizeDataAccessException if the query does not return * exactly one row, or does not return exactly one column in that row * @throws DataAccessException if the query fails * @see #queryForObject(String, Class) */ T queryForObject(String sql, Class requiredType, Object... args) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a * list of arguments to bind to the query, expecting a result Map. *

The query is expected to be a single row query; the result row will be * mapped to a Map (one entry for each column, using the column name as the key). * @param sql SQL query to execute * @param args arguments to bind to the query * @param argTypes SQL types of the arguments * (constants from java.sql.Types) * @return the result Map (one entry for each column, using the * column name as the key) * @throws IncorrectResultSizeDataAccessException if the query does not * return exactly one row * @throws DataAccessException if the query fails * @see #queryForMap(String) * @see ColumnMapRowMapper * @see java.sql.Types */ Map queryForMap(String sql, Object[] args, int[] argTypes) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a * list of arguments to bind to the query, expecting a result Map. * The queryForMap() methods defined by this interface are appropriate * when you don't have a domain model. Otherwise, consider using * one of the queryForObject() methods. *

The query is expected to be a single row query; the result row will be * mapped to a Map (one entry for each column, using the column name as the key). * @param sql SQL query to execute * @param args arguments to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type); * may also contain {@link SqlParameterValue} objects which indicate not * only the argument value but also the SQL type and optionally the scale * @return the result Map (one entry for each column, using the * column name as the key) * @throws IncorrectResultSizeDataAccessException if the query does not * return exactly one row * @throws DataAccessException if the query fails * @see #queryForMap(String) * @see ColumnMapRowMapper */ Map queryForMap(String sql, Object... args) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a * list of arguments to bind to the query, resulting in a long value. *

The query is expected to be a single row/single column query that * results in a long value. * @param sql SQL query to execute * @param args arguments to bind to the query * @param argTypes SQL types of the arguments * (constants from java.sql.Types) * @return the long value, or 0 in case of SQL NULL * @throws IncorrectResultSizeDataAccessException if the query does not return * exactly one row, or does not return exactly one column in that row * @throws DataAccessException if the query fails * @see #queryForLong(String) * @see java.sql.Types */ long queryForLong(String sql, Object[] args, int[] argTypes) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a * list of arguments to bind to the query, resulting in a long value. *

The query is expected to be a single row/single column query that * results in a long value. * @param sql SQL query to execute * @param args arguments to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type); * may also contain {@link SqlParameterValue} objects which indicate not * only the argument value but also the SQL type and optionally the scale * @return the long value, or 0 in case of SQL NULL * @throws IncorrectResultSizeDataAccessException if the query does not return * exactly one row, or does not return exactly one column in that row * @throws DataAccessException if the query fails * @see #queryForLong(String) */ long queryForLong(String sql, Object... args) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a * list of arguments to bind to the query, resulting in an int value. *

The query is expected to be a single row/single column query that * results in an int value. * @param sql SQL query to execute * @param args arguments to bind to the query * @param argTypes SQL types of the arguments * (constants from java.sql.Types) * @return the int value, or 0 in case of SQL NULL * @throws IncorrectResultSizeDataAccessException if the query does not return * exactly one row, or does not return exactly one column in that row * @throws DataAccessException if the query fails * @see #queryForInt(String) * @see java.sql.Types */ int queryForInt(String sql, Object[] args, int[] argTypes) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a * list of arguments to bind to the query, resulting in an int value. *

The query is expected to be a single row/single column query that * results in an int value. * @param sql SQL query to execute * @param args arguments to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type); * may also contain {@link SqlParameterValue} objects which indicate not * only the argument value but also the SQL type and optionally the scale * @return the int value, or 0 in case of SQL NULL * @throws IncorrectResultSizeDataAccessException if the query does not return * exactly one row, or does not return exactly one column in that row * @throws DataAccessException if the query fails * @see #queryForInt(String) */ int queryForInt(String sql, Object... args) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a * list of arguments to bind to the query, expecting a result list. *

The results will be mapped to a List (one entry for each row) of * result objects, each of them matching the specified element type. * @param sql SQL query to execute * @param args arguments to bind to the query * @param argTypes SQL types of the arguments * (constants from java.sql.Types) * @param elementType the required type of element in the result list * (for example, Integer.class) * @return a List of objects that match the specified element type * @throws DataAccessException if the query fails * @see #queryForList(String, Class) * @see SingleColumnRowMapper */ List queryForList(String sql, Object[] args, int[] argTypes, Class elementType) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a * list of arguments to bind to the query, expecting a result list. *

The results will be mapped to a List (one entry for each row) of * result objects, each of them matching the specified element type. * @param sql SQL query to execute * @param args arguments to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type); * may also contain {@link SqlParameterValue} objects which indicate not * only the argument value but also the SQL type and optionally the scale * @param elementType the required type of element in the result list * (for example, Integer.class) * @return a List of objects that match the specified element type * @throws DataAccessException if the query fails * @see #queryForList(String, Class) * @see SingleColumnRowMapper */ List queryForList(String sql, Object[] args, Class elementType) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a * list of arguments to bind to the query, expecting a result list. *

The results will be mapped to a List (one entry for each row) of * result objects, each of them matching the specified element type. * @param sql SQL query to execute * @param elementType the required type of element in the result list * (for example, Integer.class) * @param args arguments to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type); * may also contain {@link SqlParameterValue} objects which indicate not * only the argument value but also the SQL type and optionally the scale * @return a List of objects that match the specified element type * @throws DataAccessException if the query fails * @see #queryForList(String, Class) * @see SingleColumnRowMapper */ List queryForList(String sql, Class elementType, Object... args) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a * list of arguments to bind to the query, expecting a result list. *

The results will be mapped to a List (one entry for each row) of * Maps (one entry for each column, using the column name as the key). * Thus Each element in the list will be of the form returned by this interface's * queryForMap() methods. * @param sql SQL query to execute * @param args arguments to bind to the query * @param argTypes SQL types of the arguments * (constants from java.sql.Types) * @return a List that contains a Map per row * @throws DataAccessException if the query fails * @see #queryForList(String) * @see java.sql.Types */ List> queryForList(String sql, Object[] args, int[] argTypes) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a * list of arguments to bind to the query, expecting a result list. *

The results will be mapped to a List (one entry for each row) of * Maps (one entry for each column, using the column name as the key). * Each element in the list will be of the form returned by this interface's * queryForMap() methods. * @param sql SQL query to execute * @param args arguments to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type); * may also contain {@link SqlParameterValue} objects which indicate not * only the argument value but also the SQL type and optionally the scale * @return a List that contains a Map per row * @throws DataAccessException if the query fails * @see #queryForList(String) */ List> queryForList(String sql, Object... args) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a * list of arguments to bind to the query, expecting a SqlRowSet. *

The results will be mapped to an SqlRowSet which holds the data in a * disconnected fashion. This wrapper will translate any SQLExceptions thrown. *

Note that that, for the default implementation, JDBC RowSet support needs to * be available at runtime: by default, Sun's com.sun.rowset.CachedRowSetImpl * class is used, which is part of JDK 1.5+ and also available separately as part of * Sun's JDBC RowSet Implementations download (rowset.jar). * @param sql SQL query to execute * @param args arguments to bind to the query * @param argTypes SQL types of the arguments * (constants from java.sql.Types) * @return a SqlRowSet representation (possibly a wrapper around a * javax.sql.rowset.CachedRowSet) * @throws DataAccessException if there is any problem executing the query * @see #queryForRowSet(String) * @see SqlRowSetResultSetExtractor * @see javax.sql.rowset.CachedRowSet * @see java.sql.Types */ SqlRowSet queryForRowSet(String sql, Object[] args, int[] argTypes) throws DataAccessException; /** * Query given SQL to create a prepared statement from SQL and a * list of arguments to bind to the query, expecting a SqlRowSet. *

The results will be mapped to an SqlRowSet which holds the data in a * disconnected fashion. This wrapper will translate any SQLExceptions thrown. *

Note that that, for the default implementation, JDBC RowSet support needs to * be available at runtime: by default, Sun's com.sun.rowset.CachedRowSetImpl * class is used, which is part of JDK 1.5+ and also available separately as part of * Sun's JDBC RowSet Implementations download (rowset.jar). * @param sql SQL query to execute * @param args arguments to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type); * may also contain {@link SqlParameterValue} objects which indicate not * only the argument value but also the SQL type and optionally the scale * @return a SqlRowSet representation (possibly a wrapper around a * javax.sql.rowset.CachedRowSet) * @throws DataAccessException if there is any problem executing the query * @see #queryForRowSet(String) * @see SqlRowSetResultSetExtractor * @see javax.sql.rowset.CachedRowSet */ SqlRowSet queryForRowSet(String sql, Object... args) throws DataAccessException; /** * Issue a single SQL update operation (such as an insert, update or delete statement) * using a PreparedStatementCreator to provide SQL and any required parameters. *

A PreparedStatementCreator can either be implemented directly or * configured through a PreparedStatementCreatorFactory. * @param psc object that provides SQL and any necessary parameters * @return the number of rows affected * @throws DataAccessException if there is any problem issuing the update * @see PreparedStatementCreatorFactory */ int update(PreparedStatementCreator psc) throws DataAccessException; /** * Issue an update statement using a PreparedStatementCreator to provide SQL and * any required parameters. Generated keys will be put into the given KeyHolder. *

Note that the given PreparedStatementCreator has to create a statement * with activated extraction of generated keys (a JDBC 3.0 feature). This can * either be done directly or through using a PreparedStatementCreatorFactory. * @param psc object that provides SQL and any necessary parameters * @param generatedKeyHolder KeyHolder that will hold the generated keys * @return the number of rows affected * @throws DataAccessException if there is any problem issuing the update * @see PreparedStatementCreatorFactory * @see org.springframework.jdbc.support.GeneratedKeyHolder */ int update(PreparedStatementCreator psc, KeyHolder generatedKeyHolder) throws DataAccessException; /** * Issue an update statement using a PreparedStatementSetter to set bind parameters, * with given SQL. Simpler than using a PreparedStatementCreator as this method * will create the PreparedStatement: The PreparedStatementSetter just needs to * set parameters. * @param sql SQL containing bind parameters * @param pss helper that sets bind parameters. If this is null * we run an update with static SQL. * @return the number of rows affected * @throws DataAccessException if there is any problem issuing the update */ int update(String sql, PreparedStatementSetter pss) throws DataAccessException; /** * Issue a single SQL update operation (such as an insert, update or delete statement) * via a prepared statement, binding the given arguments. * @param sql SQL containing bind parameters * @param args arguments to bind to the query * @param argTypes SQL types of the arguments * (constants from java.sql.Types) * @return the number of rows affected * @throws DataAccessException if there is any problem issuing the update * @see java.sql.Types */ int update(String sql, Object[] args, int[] argTypes) throws DataAccessException; /** * Issue a single SQL update operation (such as an insert, update or delete statement) * via a prepared statement, binding the given arguments. * @param sql SQL containing bind parameters * @param args arguments to bind to the query * (leaving it to the PreparedStatement to guess the corresponding SQL type); * may also contain {@link SqlParameterValue} objects which indicate not * only the argument value but also the SQL type and optionally the scale * @return the number of rows affected * @throws DataAccessException if there is any problem issuing the update */ int update(String sql, Object... args) throws DataAccessException; /** * Issue multiple update statements on a single PreparedStatement, * using batch updates and a BatchPreparedStatementSetter to set values. *

Will fall back to separate updates on a single PreparedStatement * if the JDBC driver does not support batch updates. * @param sql defining PreparedStatement that will be reused. * All statements in the batch will use the same SQL. * @param pss object to set parameters on the PreparedStatement * created by this method * @return an array of the number of rows affected by each statement * @throws DataAccessException if there is any problem issuing the update */ int[] batchUpdate(String sql, BatchPreparedStatementSetter pss) throws DataAccessException; //------------------------------------------------------------------------- // Methods dealing with callable statements //------------------------------------------------------------------------- /** * Execute a JDBC data access operation, implemented as callback action * working on a JDBC CallableStatement. This allows for implementing arbitrary * data access operations on a single Statement, within Spring's managed * JDBC environment: that is, participating in Spring-managed transactions * and converting JDBC SQLExceptions into Spring's DataAccessException hierarchy. *

The callback action can return a result object, for example a * domain object or a collection of domain objects. * @param csc object that can create a CallableStatement given a Connection * @param action callback object that specifies the action * @return a result object returned by the action, or null * @throws DataAccessException if there is any problem */ T execute(CallableStatementCreator csc, CallableStatementCallback action) throws DataAccessException; /** * Execute a JDBC data access operation, implemented as callback action * working on a JDBC CallableStatement. This allows for implementing arbitrary * data access operations on a single Statement, within Spring's managed * JDBC environment: that is, participating in Spring-managed transactions * and converting JDBC SQLExceptions into Spring's DataAccessException hierarchy. *

The callback action can return a result object, for example a * domain object or a collection of domain objects. * @param callString the SQL call string to execute * @param action callback object that specifies the action * @return a result object returned by the action, or null * @throws DataAccessException if there is any problem */ T execute(String callString, CallableStatementCallback action) throws DataAccessException; /** * Execute a SQL call using a CallableStatementCreator to provide SQL and any * required parameters. * @param csc object that provides SQL and any necessary parameters * @param declaredParameters list of declared SqlParameter objects * @return Map of extracted out parameters * @throws DataAccessException if there is any problem issuing the update */ Map call(CallableStatementCreator csc, List declaredParameters) throws DataAccessException; } ././@LongLink0000000000000000000000000000020200000000000011557 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/SqlParameterValue.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000607211623223526033277 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; /** * Object to represent a SQL parameter value, including parameter metadata * such as the SQL type and the scale for numeric values. * *

Designed for use with {@link JdbcTemplate}'s operations that take an array of * argument values: Each such argument value may be a SqlParameterValue, * indicating the SQL type (and optionally the scale) instead of letting the * template guess a default type. Note that this only applies to the operations with * a 'plain' argument array, not to the overloaded variants with an explicit type array. * * @author Juergen Hoeller * @since 2.0.5 * @see java.sql.Types * @see JdbcTemplate#query(String, Object[], ResultSetExtractor) * @see JdbcTemplate#query(String, Object[], RowCallbackHandler) * @see JdbcTemplate#query(String, Object[], RowMapper) * @see JdbcTemplate#update(String, Object[]) */ public class SqlParameterValue extends SqlParameter { private final Object value; /** * Create a new SqlParameterValue, supplying the SQL type. * @param sqlType SQL type of the parameter according to java.sql.Types * @param value the value object */ public SqlParameterValue(int sqlType, Object value) { super(sqlType); this.value = value; } /** * Create a new SqlParameterValue, supplying the SQL type. * @param sqlType SQL type of the parameter according to java.sql.Types * @param typeName the type name of the parameter (optional) * @param value the value object */ public SqlParameterValue(int sqlType, String typeName, Object value) { super(sqlType, typeName); this.value = value; } /** * Create a new SqlParameterValue, supplying the SQL type. * @param sqlType SQL type of the parameter according to java.sql.Types * @param scale the number of digits after the decimal point * (for DECIMAL and NUMERIC types) * @param value the value object */ public SqlParameterValue(int sqlType, int scale, Object value) { super(sqlType, scale); this.value = value; } /** * Create a new SqlParameterValue based on the given SqlParameter declaration. * @param declaredParam the declared SqlParameter to define a value for * @param value the value object */ public SqlParameterValue(SqlParameter declaredParam, Object value) { super(declaredParam); this.value = value; } /** * Return the value object that this parameter value holds. */ public Object getValue() { return this.value; } } ././@LongLink0000000000000000000000000000017200000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/core/RowMapper.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000467611623223526033307 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; import java.sql.ResultSet; import java.sql.SQLException; /** * An interface used by {@link JdbcTemplate} for mapping rows of a * {@link java.sql.ResultSet} on a per-row basis. Implementations of this * interface perform the actual work of mapping each row to a result object, * but don't need to worry about exception handling. * {@link java.sql.SQLException SQLExceptions} will be caught and handled * by the calling JdbcTemplate. * *

Typically used either for {@link JdbcTemplate}'s query methods * or for out parameters of stored procedures. RowMapper objects are * typically stateless and thus reusable; they are an ideal choice for * implementing row-mapping logic in a single place. * *

Alternatively, consider subclassing * {@link org.springframework.jdbc.object.MappingSqlQuery} from the * jdbc.object package: Instead of working with separate * JdbcTemplate and RowMapper objects, you can build executable query * objects (containing row-mapping logic) in that style. * * @author Thomas Risberg * @author Juergen Hoeller * @see JdbcTemplate * @see RowCallbackHandler * @see ResultSetExtractor * @see org.springframework.jdbc.object.MappingSqlQuery */ public interface RowMapper { /** * Implementations must implement this method to map each row of data * in the ResultSet. This method should not call next() on * the ResultSet; it is only supposed to map values of the current row. * @param rs the ResultSet to map (pre-initialized for the current row) * @param rowNum the number of the current row * @return the result object for the current row * @throws SQLException if a SQLException is encountered getting * column values (that is, there's no need to catch SQLException) */ T mapRow(ResultSet rs, int rowNum) throws SQLException; } ././@LongLink0000000000000000000000000000021000000000000011556 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/LobRetrievalFailureException.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000246411623223530033273 0ustar drazzibdrazzib/* * Copyright 2002-2005 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc; import java.io.IOException; import org.springframework.dao.DataRetrievalFailureException; /** * Exception to be thrown when a LOB could not be retrieved. * * @author Juergen Hoeller * @since 1.0.2 */ public class LobRetrievalFailureException extends DataRetrievalFailureException { /** * Constructor for LobRetrievalFailureException. * @param msg the detail message */ public LobRetrievalFailureException(String msg) { super(msg); } /** * Constructor for LobRetrievalFailureException. * @param msg the detail message * @param ex IOException root cause */ public LobRetrievalFailureException(String msg, IOException ex) { super(msg, ex); } } ././@LongLink0000000000000000000000000000020500000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/UncategorizedSQLException.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000333011623223526033271 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc; import java.sql.SQLException; import org.springframework.dao.UncategorizedDataAccessException; /** * Exception thrown when we can't classify a SQLException into * one of our generic data access exceptions. * * @author Rod Johnson * @author Juergen Hoeller */ public class UncategorizedSQLException extends UncategorizedDataAccessException { /** SQL that led to the problem */ private final String sql; /** * Constructor for UncategorizedSQLException. * @param task name of current task * @param sql the offending SQL statement * @param ex the root cause */ public UncategorizedSQLException(String task, String sql, SQLException ex) { super(task + "; uncategorized SQLException for SQL [" + sql + "]; SQL state [" + ex.getSQLState() + "]; error code [" + ex.getErrorCode() + "]; " + ex.getMessage(), ex); this.sql = sql; } /** * Return the underlying SQLException. */ public SQLException getSQLException() { return (SQLException) getCause(); } /** * Return the SQL that led to the problem. */ public String getSql() { return this.sql; } } ././@LongLink0000000000000000000000000000020200000000000011557 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/BadSqlGrammarException.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000345511623223530033274 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc; import java.sql.SQLException; import org.springframework.dao.InvalidDataAccessResourceUsageException; /** * Exception thrown when SQL specified is invalid. Such exceptions always have * a java.sql.SQLException root cause. * *

It would be possible to have subclasses for no such table, no such column etc. * A custom SQLExceptionTranslator could create such more specific exceptions, * without affecting code using this class. * * @author Rod Johnson * @see InvalidResultSetAccessException */ public class BadSqlGrammarException extends InvalidDataAccessResourceUsageException { private String sql; /** * Constructor for BadSqlGrammarException. * @param task name of current task * @param sql the offending SQL statement * @param ex the root cause */ public BadSqlGrammarException(String task, String sql, SQLException ex) { super(task + "; bad SQL grammar [" + sql + "]", ex); this.sql = sql; } /** * Return the wrapped SQLException. */ public SQLException getSQLException() { return (SQLException) getCause(); } /** * Return the SQL that caused the problem. */ public String getSql() { return this.sql; } } ././@LongLink0000000000000000000000000000015700000000000011570 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000755000175000017500000000000011623223530033263 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000021200000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/SQLExceptionTranslator.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000432211623223530033266 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support; import java.sql.SQLException; import org.springframework.dao.DataAccessException; /** * Strategy interface for translating between {@link SQLException SQLExceptions} * and Spring's data access strategy-agnostic {@link DataAccessException} * hierarchy. * *

Implementations can be generic (for example, using * {@link java.sql.SQLException#getSQLState() SQLState} codes for JDBC) or wholly * proprietary (for example, using Oracle error codes) for greater precision. * * @author Rod Johnson * @author Juergen Hoeller * @see org.springframework.dao.DataAccessException */ public interface SQLExceptionTranslator { /** * Translate the given {@link SQLException} into a generic {@link DataAccessException}. *

The returned DataAccessException is supposed to contain the original * SQLException as root cause. However, client code may not generally * rely on this due to DataAccessExceptions possibly being caused by other resource * APIs as well. That said, a getRootCause() instanceof SQLException * check (and subsequent cast) is considered reliable when expecting JDBC-based * access to have happened. * @param task readable text describing the task being attempted * @param sql SQL query or update that caused the problem (may be null) * @param ex the offending SQLException * @return the DataAccessException, wrapping the SQLException * @see org.springframework.dao.DataAccessException#getRootCause() */ DataAccessException translate(String task, String sql, SQLException ex); } ././@LongLink0000000000000000000000000000020000000000000011555 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/package-info.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000055711623223526033301 0ustar drazzibdrazzib /** * * Support classes for the JDBC framework, used by the classes in the * jdbc.core and jdbc.object packages. Provides a translator from * SQLExceptions Spring's generic DataAccessExceptions. * *

Can be used independently, for example in custom JDBC access code, * or in JDBC-based O/R mapping layers. * */ package org.springframework.jdbc.support; ././@LongLink0000000000000000000000000000021000000000000011556 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/SQLErrorCodesFactory.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000002125611623223526033300 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support; import java.util.Collections; import java.util.Map; import java.util.WeakHashMap; import javax.sql.DataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.BeansException; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.springframework.util.Assert; import org.springframework.util.PatternMatchUtils; /** * Factory for creating {@link SQLErrorCodes} based on the * "databaseProductName" taken from the {@link java.sql.DatabaseMetaData}. * *

Returns SQLErrorCodes populated with vendor codes * defined in a configuration file named "sql-error-codes.xml". * Reads the default file in this package if not overridden by a file in * the root of the class path (for example in the "/WEB-INF/classes" directory). * * @author Thomas Risberg * @author Rod Johnson * @author Juergen Hoeller * @see java.sql.DatabaseMetaData#getDatabaseProductName() */ public class SQLErrorCodesFactory { /** * The name of custom SQL error codes file, loading from the root * of the class path (e.g. from the "/WEB-INF/classes" directory). */ public static final String SQL_ERROR_CODE_OVERRIDE_PATH = "sql-error-codes.xml"; /** * The name of default SQL error code files, loading from the class path. */ public static final String SQL_ERROR_CODE_DEFAULT_PATH = "org/springframework/jdbc/support/sql-error-codes.xml"; private static final Log logger = LogFactory.getLog(SQLErrorCodesFactory.class); /** * Keep track of a single instance so we can return it to classes that request it. */ private static final SQLErrorCodesFactory instance = new SQLErrorCodesFactory(); /** * Return the singleton instance. */ public static SQLErrorCodesFactory getInstance() { return instance; } /** * Map to hold error codes for all databases defined in the config file. * Key is the database product name, value is the SQLErrorCodes instance. */ private final Map errorCodesMap; /** * Map to cache the SQLErrorCodes instance per DataSource. */ private final Map dataSourceCache = new WeakHashMap(16); /** * Create a new instance of the {@link SQLErrorCodesFactory} class. *

Not public to enforce Singleton design pattern. Would be private * except to allow testing via overriding the * {@link #loadResource(String)} method. *

Do not subclass in application code. * @see #loadResource(String) */ protected SQLErrorCodesFactory() { Map errorCodes; try { DefaultListableBeanFactory lbf = new DefaultListableBeanFactory(); lbf.setBeanClassLoader(getClass().getClassLoader()); XmlBeanDefinitionReader bdr = new XmlBeanDefinitionReader(lbf); // Load default SQL error codes. Resource resource = loadResource(SQL_ERROR_CODE_DEFAULT_PATH); if (resource != null && resource.exists()) { bdr.loadBeanDefinitions(resource); } else { logger.warn("Default sql-error-codes.xml not found (should be included in spring.jar)"); } // Load custom SQL error codes, overriding defaults. resource = loadResource(SQL_ERROR_CODE_OVERRIDE_PATH); if (resource != null && resource.exists()) { bdr.loadBeanDefinitions(resource); logger.info("Found custom sql-error-codes.xml file at the root of the classpath"); } // Check all beans of type SQLErrorCodes. errorCodes = lbf.getBeansOfType(SQLErrorCodes.class, true, false); if (logger.isInfoEnabled()) { logger.info("SQLErrorCodes loaded: " + errorCodes.keySet()); } } catch (BeansException ex) { logger.warn("Error loading SQL error codes from config file", ex); errorCodes = Collections.emptyMap(); } this.errorCodesMap = errorCodes; } /** * Load the given resource from the class path. *

Not to be overridden by application developers, who should obtain * instances of this class from the static {@link #getInstance()} method. *

Protected for testability. * @param path resource path; either a custom path or one of either * {@link #SQL_ERROR_CODE_DEFAULT_PATH} or * {@link #SQL_ERROR_CODE_OVERRIDE_PATH}. * @return the resource, or null if the resource wasn't found * @see #getInstance */ protected Resource loadResource(String path) { return new ClassPathResource(path, getClass().getClassLoader()); } /** * Return the {@link SQLErrorCodes} instance for the given database. *

No need for a database metadata lookup. * @param dbName the database name (must not be null) * @return the SQLErrorCodes instance for the given database * @throws IllegalArgumentException if the supplied database name is null */ public SQLErrorCodes getErrorCodes(String dbName) { Assert.notNull(dbName, "Database product name must not be null"); SQLErrorCodes sec = this.errorCodesMap.get(dbName); if (sec == null) { for (SQLErrorCodes candidate : this.errorCodesMap.values()) { if (PatternMatchUtils.simpleMatch(candidate.getDatabaseProductNames(), dbName)) { sec = candidate; break; } } } if (sec != null) { if (logger.isDebugEnabled()) { logger.debug("SQL error codes for '" + dbName + "' found"); } return sec; } // Could not find the database among the defined ones. if (logger.isDebugEnabled()) { logger.debug("SQL error codes for '" + dbName + "' not found"); } return new SQLErrorCodes(); } /** * Return {@link SQLErrorCodes} for the given {@link DataSource}, * evaluating "databaseProductName" from the * {@link java.sql.DatabaseMetaData}, or an empty error codes * instance if no SQLErrorCodes were found. * @param dataSource the DataSource identifying the database * @return the corresponding SQLErrorCodes object * @see java.sql.DatabaseMetaData#getDatabaseProductName() */ public SQLErrorCodes getErrorCodes(DataSource dataSource) { Assert.notNull(dataSource, "DataSource must not be null"); if (logger.isDebugEnabled()) { logger.debug("Looking up default SQLErrorCodes for DataSource [" + dataSource + "]"); } synchronized (this.dataSourceCache) { // Let's avoid looking up database product info if we can. SQLErrorCodes sec = this.dataSourceCache.get(dataSource); if (sec != null) { if (logger.isDebugEnabled()) { logger.debug("SQLErrorCodes found in cache for DataSource [" + dataSource.getClass().getName() + '@' + Integer.toHexString(dataSource.hashCode()) + "]"); } return sec; } // We could not find it - got to look it up. try { String dbName = (String) JdbcUtils.extractDatabaseMetaData(dataSource, "getDatabaseProductName"); if (dbName != null) { if (logger.isDebugEnabled()) { logger.debug("Database product name cached for DataSource [" + dataSource.getClass().getName() + '@' + Integer.toHexString(dataSource.hashCode()) + "]: name is '" + dbName + "'"); } sec = getErrorCodes(dbName); this.dataSourceCache.put(dataSource, sec); return sec; } } catch (MetaDataAccessException ex) { logger.warn("Error while extracting database product name - falling back to empty error codes", ex); } } // Fallback is to return an empty SQLErrorCodes instance. return new SQLErrorCodes(); } /** * Associate the specified database name with the given {@link DataSource}. * @param dataSource the DataSource identifying the database * @param dbName the corresponding database name as stated in the error codes * definition file (must not be null) * @return the corresponding SQLErrorCodes object */ public SQLErrorCodes registerDatabase(DataSource dataSource, String dbName) { synchronized (this.dataSourceCache) { SQLErrorCodes sec = getErrorCodes(dbName); this.dataSourceCache.put(dataSource, sec); return sec; } } } ././@LongLink0000000000000000000000000000017300000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/incrementer/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000755000175000017500000000000011623223530033263 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000021400000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/incrementer/package-info.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000043011623223526033267 0ustar drazzibdrazzib /** * * Provides a support framework for incrementing database table values * via sequences, with implementations for various databases. * *

Can be used independently, for example in custom JDBC access code. * */ package org.springframework.jdbc.support.incrementer; ././@LongLink0000000000000000000000000000023400000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/incrementer/DataFieldMaxValueIncrementer.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000353711623223530033275 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.incrementer; import org.springframework.dao.DataAccessException; /** * Interface that defines contract of incrementing any data store field's * maximum value. Works much like a sequence number generator. * *

Typical implementations may use standard SQL, native RDBMS sequences * or Stored Procedures to do the job. * * @author Dmitriy Kopylenko * @author Jean-Pierre Pawlak * @author Juergen Hoeller */ public interface DataFieldMaxValueIncrementer { /** * Increment the data store field's max value as int. * @return int next data store value such as max + 1 * @throws org.springframework.dao.DataAccessException in case of errors */ int nextIntValue() throws DataAccessException; /** * Increment the data store field's max value as long. * @return int next data store value such as max + 1 * @throws org.springframework.dao.DataAccessException in case of errors */ long nextLongValue() throws DataAccessException; /** * Increment the data store field's max value as String. * @return next data store value such as max + 1 * @throws org.springframework.dao.DataAccessException in case of errors */ String nextStringValue() throws DataAccessException; } ././@LongLink0000000000000000000000000000024500000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/incrementer/PostgreSQLSequenceMaxValueIncrementer.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000303611623223530033267 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.incrementer; import javax.sql.DataSource; /** * {@link DataFieldMaxValueIncrementer} that retrieves the next value of a given PostgreSQL sequence. * Thanks to Tomislav Urban for the suggestion! * * @author Juergen Hoeller */ public class PostgreSQLSequenceMaxValueIncrementer extends AbstractSequenceMaxValueIncrementer { /** * Default constructor for bean property style usage. * @see #setDataSource * @see #setIncrementerName */ public PostgreSQLSequenceMaxValueIncrementer() { } /** * Convenience constructor. * @param dataSource the DataSource to use * @param incrementerName the name of the sequence/table to use */ public PostgreSQLSequenceMaxValueIncrementer(DataSource dataSource, String incrementerName) { super(dataSource, incrementerName); } @Override protected String getSequenceQuery() { return "select nextval('" + getIncrementerName() + "')"; } } ././@LongLink0000000000000000000000000000023100000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/incrementer/SybaseMaxValueIncrementer.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001110411623223526033267 0ustar drazzibdrazzibpackage org.springframework.jdbc.support.incrementer; import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.jdbc.datasource.DataSourceUtils; import org.springframework.jdbc.support.JdbcUtils; import javax.sql.DataSource; import java.sql.Connection; import java.sql.Statement; import java.sql.ResultSet; import java.sql.SQLException; /** * {@link org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer} that increments * the maximum value of a given Sybase SQL Server table * with the equivalent of an auto-increment column. Note: If you use this class, your table key * column should NOT be defined as an IDENTITY column, as the sequence table does the job. * *

This class is intended to be used with Sybase Adaptive Server. * *

The sequence is kept in a table. There should be one sequence table per * table that needs an auto-generated key. * *

Example: * *

 create table tab (id int not null primary key, text varchar(100))
 * create table tab_sequence (id bigint identity)
 * insert into tab_sequence values()
* * If "cacheSize" is set, the intermediate values are served without querying the * database. If the server or your application is stopped or crashes or a transaction * is rolled back, the unused values will never be served. The maximum hole size in * numbering is consequently the value of cacheSize. * * HINT: Since Sybase supports the JDBC 3.0 getGeneratedKeys method, * it is recommended to use IDENTITY columns directly in the tables and then using a * {@link org.springframework.jdbc.core.simple.SimpleJdbcInsert} or utilizing * a {@link org.springframework.jdbc.support.KeyHolder} when calling the with the * update(PreparedStatementCreator psc, KeyHolder generatedKeyHolder) * method of the {@link org.springframework.jdbc.core.JdbcTemplate}. * *

Thanks to Yinwei Liu for the suggestion! * * @author Thomas Risberg * @since 2.5.5 */ public class SybaseMaxValueIncrementer extends AbstractColumnMaxValueIncrementer { /** The current cache of values */ private long[] valueCache; /** The next id to serve from the value cache */ private int nextValueIndex = -1; /** * Default constructor for bean property style usage. * @see #setDataSource * @see #setIncrementerName * @see #setColumnName */ public SybaseMaxValueIncrementer() { } /** * Convenience constructor. * @param dataSource the DataSource to use * @param incrementerName the name of the sequence/table to use * @param columnName the name of the column in the sequence table to use */ public SybaseMaxValueIncrementer(DataSource dataSource, String incrementerName, String columnName) { super(dataSource, incrementerName, columnName); } @Override protected synchronized long getNextKey() throws DataAccessException { if (this.nextValueIndex < 0 || this.nextValueIndex >= getCacheSize()) { /* * Need to use straight JDBC code because we need to make sure that the insert and select * are performed on the same connection (otherwise we can't be sure that @@identity * returnes the correct value) */ Connection con = DataSourceUtils.getConnection(getDataSource()); Statement stmt = null; try { stmt = con.createStatement(); DataSourceUtils.applyTransactionTimeout(stmt, getDataSource()); this.valueCache = new long[getCacheSize()]; this.nextValueIndex = 0; for (int i = 0; i < getCacheSize(); i++) { stmt.executeUpdate(getIncrementStatement()); ResultSet rs = stmt.executeQuery("select @@identity"); try { if (!rs.next()) { throw new DataAccessResourceFailureException("@@identity failed after executing an update"); } this.valueCache[i] = rs.getLong(1); } finally { JdbcUtils.closeResultSet(rs); } } long maxValue = this.valueCache[(this.valueCache.length - 1)]; stmt.executeUpdate("delete from " + getIncrementerName() + " where " + getColumnName() + " < " + maxValue); } catch (SQLException ex) { throw new DataAccessResourceFailureException("Could not increment identity", ex); } finally { JdbcUtils.closeStatement(stmt); DataSourceUtils.releaseConnection(con, getDataSource()); } } return this.valueCache[this.nextValueIndex++]; } /** * Statement to use to increment the "sequence" value. Can be overridden by sub-classes. * @return The SQL statement to use */ protected String getIncrementStatement() { return "insert into " + getIncrementerName() + " values()"; } } ././@LongLink0000000000000000000000000000023000000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/incrementer/MySQLMaxValueIncrementer.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001077311623223530033275 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.incrementer; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import javax.sql.DataSource; import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.jdbc.datasource.DataSourceUtils; import org.springframework.jdbc.support.JdbcUtils; /** * {@link DataFieldMaxValueIncrementer} that increments the maximum value of a given MySQL table * with the equivalent of an auto-increment column. Note: If you use this class, your MySQL * key column should NOT be auto-increment, as the sequence table does the job. * *

The sequence is kept in a table; there should be one sequence table per * table that needs an auto-generated key. The table type of the sequence table * should be MyISAM so the sequences are allocated without regard to any * transactions that might be in progress. * *

Example: * *

create table tab (id int unsigned not null primary key, text varchar(100));
 * create table tab_sequence (value int not null) type=MYISAM;
 * insert into tab_sequence values(0);
* * If "cacheSize" is set, the intermediate values are served without querying the * database. If the server or your application is stopped or crashes or a transaction * is rolled back, the unused values will never be served. The maximum hole size in * numbering is consequently the value of cacheSize. * * @author Jean-Pierre Pawlak * @author Thomas Risberg * @author Juergen Hoeller */ public class MySQLMaxValueIncrementer extends AbstractColumnMaxValueIncrementer { /** The SQL string for retrieving the new sequence value */ private static final String VALUE_SQL = "select last_insert_id()"; /** The next id to serve */ private long nextId = 0; /** The max id to serve */ private long maxId = 0; /** * Default constructor for bean property style usage. * @see #setDataSource * @see #setIncrementerName * @see #setColumnName */ public MySQLMaxValueIncrementer() { } /** * Convenience constructor. * @param dataSource the DataSource to use * @param incrementerName the name of the sequence/table to use * @param columnName the name of the column in the sequence table to use */ public MySQLMaxValueIncrementer(DataSource dataSource, String incrementerName, String columnName) { super(dataSource, incrementerName, columnName); } @Override protected synchronized long getNextKey() throws DataAccessException { if (this.maxId == this.nextId) { /* * Need to use straight JDBC code because we need to make sure that the insert and select * are performed on the same connection (otherwise we can't be sure that last_insert_id() * returned the correct value) */ Connection con = DataSourceUtils.getConnection(getDataSource()); Statement stmt = null; try { stmt = con.createStatement(); DataSourceUtils.applyTransactionTimeout(stmt, getDataSource()); // Increment the sequence column... String columnName = getColumnName(); stmt.executeUpdate("update "+ getIncrementerName() + " set " + columnName + " = last_insert_id(" + columnName + " + " + getCacheSize() + ")"); // Retrieve the new max of the sequence column... ResultSet rs = stmt.executeQuery(VALUE_SQL); try { if (!rs.next()) { throw new DataAccessResourceFailureException("last_insert_id() failed after executing an update"); } this.maxId = rs.getLong(1); } finally { JdbcUtils.closeResultSet(rs); } this.nextId = this.maxId - getCacheSize() + 1; } catch (SQLException ex) { throw new DataAccessResourceFailureException("Could not obtain last_insert_id()", ex); } finally { JdbcUtils.closeStatement(stmt); DataSourceUtils.releaseConnection(con, getDataSource()); } } else { this.nextId++; } return this.nextId; } } ././@LongLink0000000000000000000000000000023400000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/incrementer/SqlServerMaxValueIncrementer.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001052611623223526033276 0ustar drazzibdrazzibpackage org.springframework.jdbc.support.incrementer; import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.jdbc.datasource.DataSourceUtils; import org.springframework.jdbc.support.JdbcUtils; import javax.sql.DataSource; import java.sql.Connection; import java.sql.Statement; import java.sql.ResultSet; import java.sql.SQLException; /** * {@link DataFieldMaxValueIncrementer} that increments the maximum value of a given SQL Server table * with the equivalent of an auto-increment column. Note: If you use this class, your Derby key * column should NOT be defined as an IDENTITY column, as the sequence table does the job. * *

This class is inteded to be used with Microsoft SQL Server. * *

The sequence is kept in a table. There should be one sequence table per * table that needs an auto-generated key. * *

Example: * *

 create table tab (id int not null primary key, text varchar(100))
 * create table tab_sequence (id bigint identity)
 * insert into tab_sequence default values
* * If "cacheSize" is set, the intermediate values are served without querying the * database. If the server or your application is stopped or crashes or a transaction * is rolled back, the unused values will never be served. The maximum hole size in * numbering is consequently the value of cacheSize. * * HINT: Since Microsoft SQL Server supports the JDBC 3.0 getGeneratedKeys method, * it is recommended to use IDENTITY columns directly in the tables and then using a * {@link org.springframework.jdbc.core.simple.SimpleJdbcInsert} or utilizing * a {@link org.springframework.jdbc.support.KeyHolder} when calling the with the * update(PreparedStatementCreator psc, KeyHolder generatedKeyHolder) * method of the {@link org.springframework.jdbc.core.JdbcTemplate}. * *

Thanks to Preben Nilsson for the suggestion! * * @author Thomas Risberg * @since 2.5.5 */ public class SqlServerMaxValueIncrementer extends AbstractColumnMaxValueIncrementer { /** The current cache of values */ private long[] valueCache; /** The next id to serve from the value cache */ private int nextValueIndex = -1; /** * Default constructor for bean property style usage. * @see #setDataSource * @see #setIncrementerName * @see #setColumnName */ public SqlServerMaxValueIncrementer() { } /** * Convenience constructor. * @param dataSource the DataSource to use * @param incrementerName the name of the sequence/table to use * @param columnName the name of the column in the sequence table to use */ public SqlServerMaxValueIncrementer(DataSource dataSource, String incrementerName, String columnName) { super(dataSource, incrementerName, columnName); } @Override protected synchronized long getNextKey() throws DataAccessException { if (this.nextValueIndex < 0 || this.nextValueIndex >= getCacheSize()) { /* * Need to use straight JDBC code because we need to make sure that the insert and select * are performed on the same connection (otherwise we can't be sure that @@identity * returnes the correct value) */ Connection con = DataSourceUtils.getConnection(getDataSource()); Statement stmt = null; try { stmt = con.createStatement(); DataSourceUtils.applyTransactionTimeout(stmt, getDataSource()); this.valueCache = new long[getCacheSize()]; this.nextValueIndex = 0; for (int i = 0; i < getCacheSize(); i++) { stmt.executeUpdate("insert into " + getIncrementerName() + " default values"); ResultSet rs = stmt.executeQuery("select @@identity"); try { if (!rs.next()) { throw new DataAccessResourceFailureException("@@identity failed after executing an update"); } this.valueCache[i] = rs.getLong(1); } finally { JdbcUtils.closeResultSet(rs); } } long maxValue = this.valueCache[(this.valueCache.length - 1)]; stmt.executeUpdate("delete from " + getIncrementerName() + " where " + getColumnName() + " < " + maxValue); } catch (SQLException ex) { throw new DataAccessResourceFailureException("Could not increment identity", ex); } finally { JdbcUtils.closeStatement(stmt); DataSourceUtils.releaseConnection(con, getDataSource()); } } return this.valueCache[this.nextValueIndex++]; } } ././@LongLink0000000000000000000000000000023000000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/incrementer/DerbyMaxValueIncrementer.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001420711623223530033271 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.incrementer; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import javax.sql.DataSource; import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.jdbc.datasource.DataSourceUtils; import org.springframework.jdbc.support.JdbcUtils; /** * {@link DataFieldMaxValueIncrementer} that increments the maximum value of a given Derby table * with the equivalent of an auto-increment column. Note: If you use this class, your Derby key * column should NOT be defined as an IDENTITY column, as the sequence table does the job. * *

The sequence is kept in a table. There should be one sequence table per * table that needs an auto-generated key. * *

Derby requires an additional column to be used for the insert since it is impossible * to insert a null into the identity column and have the value generated. This is solved by * providing the name of a dummy column that also must be created in the sequence table. * *

Example: * *

create table tab (id int not null primary key, text varchar(100));
 * create table tab_sequence (value int generated always as identity, dummy char(1));
 * insert into tab_sequence (dummy) values(null);
* * If "cacheSize" is set, the intermediate values are served without querying the * database. If the server or your application is stopped or crashes or a transaction * is rolled back, the unused values will never be served. The maximum hole size in * numbering is consequently the value of cacheSize. * * HINT: Since Derby supports the JDBC 3.0 getGeneratedKeys method, * it is recommended to use IDENTITY columns directly in the tables and then utilizing * a {@link org.springframework.jdbc.support.KeyHolder} when calling the with the * update(PreparedStatementCreator psc, KeyHolder generatedKeyHolder) * method of the {@link org.springframework.jdbc.core.JdbcTemplate}. * *

Thanks to Endre Stolsvik for the suggestion! * * @author Thomas Risberg * @author Juergen Hoeller * @since 2.5 */ public class DerbyMaxValueIncrementer extends AbstractColumnMaxValueIncrementer { /** The default for dummy name */ private static final String DEFAULT_DUMMY_NAME = "dummy"; /** The name of the dummy column used for inserts */ private String dummyName = DEFAULT_DUMMY_NAME; /** The current cache of values */ private long[] valueCache; /** The next id to serve from the value cache */ private int nextValueIndex = -1; /** * Default constructor for bean property style usage. * @see #setDataSource * @see #setIncrementerName * @see #setColumnName */ public DerbyMaxValueIncrementer() { } /** * Convenience constructor. * @param dataSource the DataSource to use * @param incrementerName the name of the sequence/table to use * @param columnName the name of the column in the sequence table to use */ public DerbyMaxValueIncrementer(DataSource dataSource, String incrementerName, String columnName) { super(dataSource, incrementerName, columnName); this.dummyName = DEFAULT_DUMMY_NAME; } /** * Convenience constructor. * @param dataSource the DataSource to use * @param incrementerName the name of the sequence/table to use * @param columnName the name of the column in the sequence table to use * @param dummyName the name of the dummy column used for inserts */ public DerbyMaxValueIncrementer(DataSource dataSource, String incrementerName, String columnName, String dummyName) { super(dataSource, incrementerName, columnName); this.dummyName = dummyName; } /** * Set the name of the dummy column. */ public void setDummyName(String dummyName) { this.dummyName = dummyName; } /** * Return the name of the dummy column. */ public String getDummyName() { return this.dummyName; } @Override protected synchronized long getNextKey() throws DataAccessException { if (this.nextValueIndex < 0 || this.nextValueIndex >= getCacheSize()) { /* * Need to use straight JDBC code because we need to make sure that the insert and select * are performed on the same connection (otherwise we can't be sure that last_insert_id() * returned the correct value) */ Connection con = DataSourceUtils.getConnection(getDataSource()); Statement stmt = null; try { stmt = con.createStatement(); DataSourceUtils.applyTransactionTimeout(stmt, getDataSource()); this.valueCache = new long[getCacheSize()]; this.nextValueIndex = 0; for (int i = 0; i < getCacheSize(); i++) { stmt.executeUpdate("insert into " + getIncrementerName() + " (" + getDummyName() + ") values(null)"); ResultSet rs = stmt.executeQuery("select IDENTITY_VAL_LOCAL() from " + getIncrementerName()); try { if (!rs.next()) { throw new DataAccessResourceFailureException("IDENTITY_VAL_LOCAL() failed after executing an update"); } this.valueCache[i] = rs.getLong(1); } finally { JdbcUtils.closeResultSet(rs); } } long maxValue = this.valueCache[(this.valueCache.length - 1)]; stmt.executeUpdate("delete from " + getIncrementerName() + " where " + getColumnName() + " < " + maxValue); } catch (SQLException ex) { throw new DataAccessResourceFailureException("Could not obtain IDENTITY value", ex); } finally { JdbcUtils.closeStatement(stmt); DataSourceUtils.releaseConnection(con, getDataSource()); } } return this.valueCache[this.nextValueIndex++]; } } ././@LongLink0000000000000000000000000000024400000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/incrementer/AbstractDataFieldMaxValueIncrementer.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001007211623223526033272 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.incrementer; import javax.sql.DataSource; import org.springframework.beans.factory.InitializingBean; import org.springframework.dao.DataAccessException; import org.springframework.util.Assert; /** * Base implementation of {@link DataFieldMaxValueIncrementer} that delegates * to a single {@link #getNextKey} template method that returns a long. * Uses longs for String values, padding with zeroes if required. * * @author Dmitriy Kopylenko * @author Juergen Hoeller * @author Jean-Pierre Pawlak * @author Juergen Hoeller */ public abstract class AbstractDataFieldMaxValueIncrementer implements DataFieldMaxValueIncrementer, InitializingBean { private DataSource dataSource; /** The name of the sequence/table containing the sequence */ private String incrementerName; /** The length to which a string result should be pre-pended with zeroes */ protected int paddingLength = 0; /** * Default constructor for bean property style usage. * @see #setDataSource * @see #setIncrementerName */ public AbstractDataFieldMaxValueIncrementer() { } /** * Convenience constructor. * @param dataSource the DataSource to use * @param incrementerName the name of the sequence/table to use */ public AbstractDataFieldMaxValueIncrementer(DataSource dataSource, String incrementerName) { Assert.notNull(dataSource, "DataSource must not be null"); Assert.notNull(incrementerName, "Incrementer name must not be null"); this.dataSource = dataSource; this.incrementerName = incrementerName; } /** * Set the data source to retrieve the value from. */ public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } /** * Return the data source to retrieve the value from. */ public DataSource getDataSource() { return this.dataSource; } /** * Set the name of the sequence/table. */ public void setIncrementerName(String incrementerName) { this.incrementerName = incrementerName; } /** * Return the name of the sequence/table. */ public String getIncrementerName() { return this.incrementerName; } /** * Set the padding length, i.e. the length to which a string result * should be pre-pended with zeroes. */ public void setPaddingLength(int paddingLength) { this.paddingLength = paddingLength; } /** * Return the padding length for String values. */ public int getPaddingLength() { return this.paddingLength; } public void afterPropertiesSet() { if (this.dataSource == null) { throw new IllegalArgumentException("Property 'dataSource' is required"); } if (this.incrementerName == null) { throw new IllegalArgumentException("Property 'incrementerName' is required"); } } public int nextIntValue() throws DataAccessException { return (int) getNextKey(); } public long nextLongValue() throws DataAccessException { return getNextKey(); } public String nextStringValue() throws DataAccessException { String s = Long.toString(getNextKey()); int len = s.length(); if (len < this.paddingLength) { StringBuilder sb = new StringBuilder(this.paddingLength); for (int i = 0; i < this.paddingLength - len; i++) { sb.append('0'); } sb.append(s); s = sb.toString(); } return s; } /** * Determine the next key to use, as a long. * @return the key to use as a long. It will eventually be converted later * in another format by the public concrete methods of this class. */ protected abstract long getNextKey(); } ././@LongLink0000000000000000000000000000024100000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/incrementer/AbstractColumnMaxValueIncrementer.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000515711623223530033275 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.incrementer; import javax.sql.DataSource; import org.springframework.util.Assert; /** * Abstract base class for {@link DataFieldMaxValueIncrementer} implementations that use * a column in a custom sequence table. Subclasses need to provide the specific handling * of that table in their {@link #getNextKey()} implementation.. * * @author Juergen Hoeller * @since 2.5.3 */ public abstract class AbstractColumnMaxValueIncrementer extends AbstractDataFieldMaxValueIncrementer { /** The name of the column for this sequence */ private String columnName; /** The number of keys buffered in a cache */ private int cacheSize = 1; /** * Default constructor for bean property style usage. * @see #setDataSource * @see #setIncrementerName * @see #setColumnName */ public AbstractColumnMaxValueIncrementer() { } /** * Convenience constructor. * @param dataSource the DataSource to use * @param incrementerName the name of the sequence/table to use * @param columnName the name of the column in the sequence table to use */ public AbstractColumnMaxValueIncrementer(DataSource dataSource, String incrementerName, String columnName) { super(dataSource, incrementerName); Assert.notNull(columnName, "Column name must not be null"); this.columnName = columnName; } /** * Set the name of the column in the sequence table. */ public void setColumnName(String columnName) { this.columnName = columnName; } /** * Return the name of the column in the sequence table. */ public String getColumnName() { return this.columnName; } /** * Set the number of buffered keys. */ public void setCacheSize(int cacheSize) { this.cacheSize = cacheSize; } /** * Return the number of buffered keys. */ public int getCacheSize() { return this.cacheSize; } @Override public void afterPropertiesSet() { super.afterPropertiesSet(); if (this.columnName == null) { throw new IllegalArgumentException("Property 'columnName' is required"); } } } ././@LongLink0000000000000000000000000000024100000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/incrementer/SybaseAnywhereMaxValueIncrementer.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000476611623223526033307 0ustar drazzibdrazzibpackage org.springframework.jdbc.support.incrementer; import javax.sql.DataSource; /** * {@link org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer} that increments * the maximum value of a given Sybase SQL Anywhere table * with the equivalent of an auto-increment column. Note: If you use this class, your table key * column should NOT be defined as an IDENTITY column, as the sequence table does the job. * *

This class is intended to be used with Sybase Anywhere. * *

The sequence is kept in a table. There should be one sequence table per * table that needs an auto-generated key. * *

Example: * *

 create table tab (id int not null primary key, text varchar(100))
 * create table tab_sequence (id bigint identity)
 * insert into tab_sequence values(DEFAULT)
* * If "cacheSize" is set, the intermediate values are served without querying the * database. If the server or your application is stopped or crashes or a transaction * is rolled back, the unused values will never be served. The maximum hole size in * numbering is consequently the value of cacheSize. * * HINT: Since Sybase Anywhere supports the JDBC 3.0 getGeneratedKeys method, * it is recommended to use IDENTITY columns directly in the tables and then using a * {@link org.springframework.jdbc.core.simple.SimpleJdbcInsert} or utilizing * a {@link org.springframework.jdbc.support.KeyHolder} when calling the with the * update(PreparedStatementCreator psc, KeyHolder generatedKeyHolder) * method of the {@link org.springframework.jdbc.core.JdbcTemplate}. * *

Thanks to Tarald Saxi Stormark for the suggestion! * * @author Thomas Risberg * @since 3.0.5 */ public class SybaseAnywhereMaxValueIncrementer extends SybaseMaxValueIncrementer { /** * Default constructor for bean property style usage. * @see #setDataSource * @see #setIncrementerName * @see #setColumnName */ public SybaseAnywhereMaxValueIncrementer() { } /** * Convenience constructor. * @param dataSource the DataSource to use * @param incrementerName the name of the sequence/table to use * @param columnName the name of the column in the sequence table to use */ public SybaseAnywhereMaxValueIncrementer(DataSource dataSource, String incrementerName, String columnName) { super(dataSource, incrementerName, columnName); } @Override protected String getIncrementStatement() { return "insert into " + getIncrementerName() + " values(DEFAULT)"; } } ././@LongLink0000000000000000000000000000023700000000000011567 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/incrementer/HsqlSequenceMaxValueIncrementer.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000332011623223526033270 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.incrementer; import javax.sql.DataSource; /** * {@link DataFieldMaxValueIncrementer} that retrieves the next value of a given HSQL sequence. * Thanks to Guillaume Bilodeau for the suggestion! * *

NOTE: This is an alternative to using a regular table to support generating * unique keys that was necessary in previous versions of HSQL. * * @author Thomas Risberg * @since 2.5 * @see HsqlMaxValueIncrementer */ public class HsqlSequenceMaxValueIncrementer extends AbstractSequenceMaxValueIncrementer { /** * Default constructor for bean property style usage. * @see #setDataSource * @see #setIncrementerName */ public HsqlSequenceMaxValueIncrementer() { } /** * Convenience constructor. * @param dataSource the DataSource to use * @param incrementerName the name of the sequence/table to use */ public HsqlSequenceMaxValueIncrementer(DataSource dataSource, String incrementerName) { super(dataSource, incrementerName); } @Override protected String getSequenceQuery() { return "call next value for " + getIncrementerName(); } } ././@LongLink0000000000000000000000000000023600000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/incrementer/DB2SequenceMaxValueIncrementer.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000313311623223530033265 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.incrementer; import javax.sql.DataSource; /** * {@link DataFieldMaxValueIncrementer} that retrieves the next value of a given sequence * on DB2 UDB (for Unix and Windows). Thanks to Mark MacMahon for the suggestion! * * @author Juergen Hoeller * @since 1.1.3 * @see DB2MainframeSequenceMaxValueIncrementer */ public class DB2SequenceMaxValueIncrementer extends AbstractSequenceMaxValueIncrementer { /** * Default constructor for bean property style usage. * @see #setDataSource * @see #setIncrementerName */ public DB2SequenceMaxValueIncrementer() { } /** * Convenience constructor. * @param dataSource the DataSource to use * @param incrementerName the name of the sequence/table to use */ public DB2SequenceMaxValueIncrementer(DataSource dataSource, String incrementerName) { super(dataSource, incrementerName); } @Override protected String getSequenceQuery() { return "values nextval for " + getIncrementerName(); } } ././@LongLink0000000000000000000000000000022700000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/incrementer/HsqlMaxValueIncrementer.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001104411623223530033265 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.incrementer; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import javax.sql.DataSource; import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.jdbc.datasource.DataSourceUtils; import org.springframework.jdbc.support.JdbcUtils; /** * {@link DataFieldMaxValueIncrementer} that increments the maximum value of a given HSQL table * with the equivalent of an auto-increment column. Note: If you use this class, your HSQL * key column should NOT be auto-increment, as the sequence table does the job. * *

The sequence is kept in a table. There should be one sequence table per * table that needs an auto-generated key. * *

Example: * *

create table tab (id int not null primary key, text varchar(100));
 * create table tab_sequence (value identity);
 * insert into tab_sequence values(0);
* * If "cacheSize" is set, the intermediate values are served without querying the * database. If the server or your application is stopped or crashes or a transaction * is rolled back, the unused values will never be served. The maximum hole size in * numbering is consequently the value of cacheSize. * *

NOTE: HSQL now supports sequences and you should consider using them instead: * {@link HsqlSequenceMaxValueIncrementer} * * @author Jean-Pierre Pawlak * @author Thomas Risberg * @author Juergen Hoeller * @see HsqlSequenceMaxValueIncrementer */ public class HsqlMaxValueIncrementer extends AbstractColumnMaxValueIncrementer { /** The current cache of values */ private long[] valueCache; /** The next id to serve from the value cache */ private int nextValueIndex = -1; /** * Default constructor for bean property style usage. * @see #setDataSource * @see #setIncrementerName * @see #setColumnName */ public HsqlMaxValueIncrementer() { } /** * Convenience constructor. * @param dataSource the DataSource to use * @param incrementerName the name of the sequence/table to use * @param columnName the name of the column in the sequence table to use */ public HsqlMaxValueIncrementer(DataSource dataSource, String incrementerName, String columnName) { super(dataSource, incrementerName, columnName); } @Override protected synchronized long getNextKey() throws DataAccessException { if (this.nextValueIndex < 0 || this.nextValueIndex >= getCacheSize()) { /* * Need to use straight JDBC code because we need to make sure that the insert and select * are performed on the same Connection. Otherwise we can't be sure that last_insert_id() * returned the correct value. */ Connection con = DataSourceUtils.getConnection(getDataSource()); Statement stmt = null; try { stmt = con.createStatement(); DataSourceUtils.applyTransactionTimeout(stmt, getDataSource()); this.valueCache = new long[getCacheSize()]; this.nextValueIndex = 0; for (int i = 0; i < getCacheSize(); i++) { stmt.executeUpdate("insert into " + getIncrementerName() + " values(null)"); ResultSet rs = stmt.executeQuery("select max(identity()) from " + getIncrementerName()); try { if (!rs.next()) { throw new DataAccessResourceFailureException("identity() failed after executing an update"); } this.valueCache[i] = rs.getLong(1); } finally { JdbcUtils.closeResultSet(rs); } } long maxValue = this.valueCache[(this.valueCache.length - 1)]; stmt.executeUpdate("delete from " + getIncrementerName() + " where " + getColumnName() + " < " + maxValue); } catch (SQLException ex) { throw new DataAccessResourceFailureException("Could not obtain identity()", ex); } finally { JdbcUtils.closeStatement(stmt); DataSourceUtils.releaseConnection(con, getDataSource()); } } return this.valueCache[this.nextValueIndex++]; } } ././@LongLink0000000000000000000000000000024300000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/incrementer/AbstractSequenceMaxValueIncrementer.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000566311623223530033277 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.incrementer; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import javax.sql.DataSource; import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.jdbc.datasource.DataSourceUtils; import org.springframework.jdbc.support.JdbcUtils; /** * Abstract base class for {@link DataFieldMaxValueIncrementer} implementations that use * a database sequence. Subclasses need to provide the database-specific SQL to use. * * @author Juergen Hoeller * @since 26.02.2004 * @see #getSequenceQuery */ public abstract class AbstractSequenceMaxValueIncrementer extends AbstractDataFieldMaxValueIncrementer { /** * Default constructor for bean property style usage. * @see #setDataSource * @see #setIncrementerName */ public AbstractSequenceMaxValueIncrementer() { } /** * Convenience constructor. * @param dataSource the DataSource to use * @param incrementerName the name of the sequence/table to use */ public AbstractSequenceMaxValueIncrementer(DataSource dataSource, String incrementerName) { super(dataSource, incrementerName); } /** * Executes the SQL as specified by {@link #getSequenceQuery()}. */ @Override protected long getNextKey() throws DataAccessException { Connection con = DataSourceUtils.getConnection(getDataSource()); Statement stmt = null; ResultSet rs = null; try { stmt = con.createStatement(); DataSourceUtils.applyTransactionTimeout(stmt, getDataSource()); rs = stmt.executeQuery(getSequenceQuery()); if (rs.next()) { return rs.getLong(1); } else { throw new DataAccessResourceFailureException("Sequence query did not return a result"); } } catch (SQLException ex) { throw new DataAccessResourceFailureException("Could not obtain sequence value", ex); } finally { JdbcUtils.closeResultSet(rs); JdbcUtils.closeStatement(stmt); DataSourceUtils.releaseConnection(con, getDataSource()); } } /** * Return the database-specific query to use for retrieving a sequence value. *

The provided SQL is supposed to result in a single row with a single * column that allows for extracting a long value. */ protected abstract String getSequenceQuery(); } ././@LongLink0000000000000000000000000000024100000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/incrementer/OracleSequenceMaxValueIncrementer.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000303411623223526033272 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.incrementer; import javax.sql.DataSource; /** * {@link DataFieldMaxValueIncrementer} that retrieves the next value of a given Oracle sequence. * * @author Dmitriy Kopylenko * @author Thomas Risberg * @author Juergen Hoeller */ public class OracleSequenceMaxValueIncrementer extends AbstractSequenceMaxValueIncrementer { /** * Default constructor for bean property style usage. * @see #setDataSource * @see #setIncrementerName */ public OracleSequenceMaxValueIncrementer() { } /** * Convenience constructor. * @param dataSource the DataSource to use * @param incrementerName the name of the sequence/table to use */ public OracleSequenceMaxValueIncrementer(DataSource dataSource, String incrementerName) { super(dataSource, incrementerName); } @Override protected String getSequenceQuery() { return "select " + getIncrementerName() + ".nextval from dual"; } } ././@LongLink0000000000000000000000000000024700000000000011570 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/incrementer/DB2MainframeSequenceMaxValueIncrementer.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000320011623223530033260 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.incrementer; import javax.sql.DataSource; /** * {@link DataFieldMaxValueIncrementer} that retrieves the next value of a given sequence * on DB2/390 or DB2/400. Thanks to Jens Eickmeyer for the suggestion! * * @author Juergen Hoeller * @since 2.5.3 * @see DB2SequenceMaxValueIncrementer */ public class DB2MainframeSequenceMaxValueIncrementer extends AbstractSequenceMaxValueIncrementer { /** * Default constructor for bean property style usage. * @see #setDataSource * @see #setIncrementerName */ public DB2MainframeSequenceMaxValueIncrementer() { } /** * Convenience constructor. * @param dataSource the DataSource to use * @param incrementerName the name of the sequence/table to use */ public DB2MainframeSequenceMaxValueIncrementer(DataSource dataSource, String incrementerName) { super(dataSource, incrementerName); } @Override protected String getSequenceQuery() { return "select next value for " + getIncrementerName() + " from sysibm.sysdummy1"; } } ././@LongLink0000000000000000000000000000023500000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/incrementer/H2SequenceMaxValueIncrementer.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000275311623223530033274 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.incrementer; import javax.sql.DataSource; /** * {@link DataFieldMaxValueIncrementer} that retrieves the next value of a given H2 Database sequence. * * @author Thomas Risberg * @since 2.5 */ public class H2SequenceMaxValueIncrementer extends AbstractSequenceMaxValueIncrementer { /** * Default constructor for bean property style usage. * @see #setDataSource * @see #setIncrementerName */ public H2SequenceMaxValueIncrementer() { } /** * Convenience constructor. * @param dataSource the DataSource to use * @param incrementerName the name of the sequence/table to use */ public H2SequenceMaxValueIncrementer(DataSource dataSource, String incrementerName) { super(dataSource, incrementerName); } @Override protected String getSequenceQuery() { return "select " + getIncrementerName() + ".nextval from dual"; } } ././@LongLink0000000000000000000000000000022200000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/SQLStateSQLExceptionTranslator.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001325411623223526033277 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support; import java.sql.SQLException; import java.util.HashSet; import java.util.Set; import org.springframework.dao.ConcurrencyFailureException; import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.dao.TransientDataAccessResourceException; import org.springframework.jdbc.BadSqlGrammarException; /** * {@link SQLExceptionTranslator} implementation that analyzes the SQL state in * the {@link SQLException} based on the first two digits (the SQL state "class"). * Detects standard SQL state values and well-known vendor-specific SQL states. * *

Not able to diagnose all problems, but is portable between databases and * does not require special initialization (no database vendor detection, etc.). * For more precise translation, consider {@link SQLErrorCodeSQLExceptionTranslator}. * * @author Rod Johnson * @author Juergen Hoeller * @author Thomas Risberg * @see java.sql.SQLException#getSQLState() * @see SQLErrorCodeSQLExceptionTranslator */ public class SQLStateSQLExceptionTranslator extends AbstractFallbackSQLExceptionTranslator { private static final Set BAD_SQL_GRAMMAR_CODES = new HashSet(8); private static final Set DATA_INTEGRITY_VIOLATION_CODES = new HashSet(8); private static final Set DATA_ACCESS_RESOURCE_FAILURE_CODES = new HashSet(8); private static final Set TRANSIENT_DATA_ACCESS_RESOURCE_CODES = new HashSet(8); private static final Set CONCURRENCY_FAILURE_CODES = new HashSet(4); static { BAD_SQL_GRAMMAR_CODES.add("07"); // Dynamic SQL error BAD_SQL_GRAMMAR_CODES.add("21"); // Cardinality violation BAD_SQL_GRAMMAR_CODES.add("2A"); // Syntax error direct SQL BAD_SQL_GRAMMAR_CODES.add("37"); // Syntax error dynamic SQL BAD_SQL_GRAMMAR_CODES.add("42"); // General SQL syntax error BAD_SQL_GRAMMAR_CODES.add("65"); // Oracle: unknown identifier BAD_SQL_GRAMMAR_CODES.add("S0"); // MySQL uses this - from ODBC error codes? DATA_INTEGRITY_VIOLATION_CODES.add("01"); // Data truncation DATA_INTEGRITY_VIOLATION_CODES.add("02"); // No data found DATA_INTEGRITY_VIOLATION_CODES.add("22"); // Value out of range DATA_INTEGRITY_VIOLATION_CODES.add("23"); // Integrity constraint violation DATA_INTEGRITY_VIOLATION_CODES.add("27"); // Triggered data change violation DATA_INTEGRITY_VIOLATION_CODES.add("44"); // With check violation DATA_ACCESS_RESOURCE_FAILURE_CODES.add("08"); // Connection exception DATA_ACCESS_RESOURCE_FAILURE_CODES.add("53"); // PostgreSQL: insufficient resources (e.g. disk full) DATA_ACCESS_RESOURCE_FAILURE_CODES.add("54"); // PostgreSQL: program limit exceeded (e.g. statement too complex) DATA_ACCESS_RESOURCE_FAILURE_CODES.add("57"); // DB2: out-of-memory exception / database not started DATA_ACCESS_RESOURCE_FAILURE_CODES.add("58"); // DB2: unexpected system error TRANSIENT_DATA_ACCESS_RESOURCE_CODES.add("JW"); // Sybase: internal I/O error TRANSIENT_DATA_ACCESS_RESOURCE_CODES.add("JZ"); // Sybase: unexpected I/O error TRANSIENT_DATA_ACCESS_RESOURCE_CODES.add("S1"); // DB2: communication failure CONCURRENCY_FAILURE_CODES.add("40"); // Transaction rollback CONCURRENCY_FAILURE_CODES.add("61"); // Oracle: deadlock } @Override protected DataAccessException doTranslate(String task, String sql, SQLException ex) { String sqlState = getSqlState(ex); if (sqlState != null && sqlState.length() >= 2) { String classCode = sqlState.substring(0, 2); if (logger.isDebugEnabled()) { logger.debug("Extracted SQL state class '" + classCode + "' from value '" + sqlState + "'"); } if (BAD_SQL_GRAMMAR_CODES.contains(classCode)) { return new BadSqlGrammarException(task, sql, ex); } else if (DATA_INTEGRITY_VIOLATION_CODES.contains(classCode)) { return new DataIntegrityViolationException(buildMessage(task, sql, ex), ex); } else if (DATA_ACCESS_RESOURCE_FAILURE_CODES.contains(classCode)) { return new DataAccessResourceFailureException(buildMessage(task, sql, ex), ex); } else if (TRANSIENT_DATA_ACCESS_RESOURCE_CODES.contains(classCode)) { return new TransientDataAccessResourceException(buildMessage(task, sql, ex), ex); } else if (CONCURRENCY_FAILURE_CODES.contains(classCode)) { return new ConcurrencyFailureException(buildMessage(task, sql, ex), ex); } } return null; } /** * Gets the SQL state code from the supplied {@link SQLException exception}. *

Some JDBC drivers nest the actual exception from a batched update, so we * might need to dig down into the nested exception. * @param ex the exception from which the {@link SQLException#getSQLState() SQL state} * is to be extracted * @return the SQL state code */ private String getSqlState(SQLException ex) { String sqlState = ex.getSQLState(); if (sqlState == null) { SQLException nestedEx = ex.getNextException(); if (nestedEx != null) { sqlState = nestedEx.getSQLState(); } } return sqlState; } } ././@LongLink0000000000000000000000000000017500000000000011570 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/KeyHolder.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000575311623223530033277 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support; import java.util.List; import java.util.Map; import org.springframework.dao.InvalidDataAccessApiUsageException; /** * Interface for retrieving keys, typically used for auto-generated keys * as potentially returned by JDBC insert statements. * *

Implementations of this interface can hold any number of keys. * In the general case, the keys are returned as a List containing one Map * for each row of keys. * *

Most applications only use on key per row and process only one row at a * time in an insert statement. In these cases, just call getKey * to retrieve the key. The returned value is a Number here, which is the * usual type for auto-generated keys. * * @author Thomas Risberg * @author Juergen Hoeller * @since 1.1 * @see org.springframework.jdbc.core.JdbcTemplate * @see org.springframework.jdbc.object.SqlUpdate */ public interface KeyHolder { /** * Retrieve the first item from the first map, assuming that there is just * one item and just one map, and that the item is a number. * This is the typical case: a single, numeric generated key. *

Keys are held in a List of Maps, where each item in the list represents * the keys for each row. If there are multiple columns, then the Map will have * multiple entries as well. If this method encounters multiple entries in * either the map or the list meaning that multiple keys were returned, * then an InvalidDataAccessApiUsageException is thrown. * @return the generated key * @throws InvalidDataAccessApiUsageException if multiple keys are encountered. */ Number getKey() throws InvalidDataAccessApiUsageException; /** * Retrieve the first map of keys. If there are multiple entries in the list * (meaning that multiple rows had keys returned), then an * InvalidDataAccessApiUsageException is thrown. * @return the Map of generated keys * @throws InvalidDataAccessApiUsageException if keys for multiple rows are encountered */ Map getKeys() throws InvalidDataAccessApiUsageException; /** * Return a reference to the List that contains the keys. * Can be used for extracting keys for multiple rows (an unusual case), * and also for adding new maps of keys. * @return the List for the generated keys, with each entry being a Map * of column names and key values */ List> getKeyList(); } ././@LongLink0000000000000000000000000000016300000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/lob/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000755000175000017500000000000011623223530033263 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000020400000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/lob/package-info.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000042711623223530033270 0ustar drazzibdrazzib /** * * Provides a stategy interface for Large OBject handling, * with implementations for various databases. * *

Can be used independently from jdbc.core and jdbc.object, * for example in custom JDBC access code. * */ package org.springframework.jdbc.support.lob; ././@LongLink0000000000000000000000000000020200000000000011557 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/lob/LobCreator.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001440211623223530033266 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.lob; import java.io.InputStream; import java.io.Reader; import java.sql.PreparedStatement; import java.sql.SQLException; /** * Interface that abstracts potentially database-specific creation of large binary * fields and large text fields. Does not work with java.sql.Blob * and java.sql.Clob instances in the API, as some JDBC drivers * do not support these types as such. * *

The LOB creation part is where {@link LobHandler} implementations usually * differ. Possible strategies include usage of * PreparedStatement.setBinaryStream/setCharacterStream but also * PreparedStatement.setBlob/setClob with either a stream argument * (requires JDBC 4.0) or java.sql.Blob/Clob wrapper objects. * *

A LobCreator represents a session for creating BLOBs: It is not * thread-safe and needs to be instantiated for each statement execution or for * each transaction. Each LobCreator needs to be closed after completion. * *

For convenient working with a PreparedStatement and a LobCreator, * consider using {@link org.springframework.jdbc.core.JdbcTemplate} with an *{@link org.springframework.jdbc.core.support.AbstractLobCreatingPreparedStatementCallback} * implementation. See the latter's javadoc for details. * * @author Juergen Hoeller * @since 04.12.2003 * @see #close() * @see LobHandler#getLobCreator() * @see DefaultLobHandler.DefaultLobCreator * @see OracleLobHandler.OracleLobCreator * @see java.sql.PreparedStatement#setBlob * @see java.sql.PreparedStatement#setClob * @see java.sql.PreparedStatement#setBytes * @see java.sql.PreparedStatement#setBinaryStream * @see java.sql.PreparedStatement#setString * @see java.sql.PreparedStatement#setAsciiStream * @see java.sql.PreparedStatement#setCharacterStream */ public interface LobCreator { /** * Set the given content as bytes on the given statement, using the given * parameter index. Might simply invoke PreparedStatement.setBytes * or create a Blob instance for it, depending on the database and driver. * @param ps the PreparedStatement to the set the content on * @param paramIndex the parameter index to use * @param content the content as byte array, or null for SQL NULL * @throws SQLException if thrown by JDBC methods * @see java.sql.PreparedStatement#setBytes */ void setBlobAsBytes(PreparedStatement ps, int paramIndex, byte[] content) throws SQLException; /** * Set the given content as binary stream on the given statement, using the given * parameter index. Might simply invoke PreparedStatement.setBinaryStream * or create a Blob instance for it, depending on the database and driver. * @param ps the PreparedStatement to the set the content on * @param paramIndex the parameter index to use * @param contentStream the content as binary stream, or null for SQL NULL * @throws SQLException if thrown by JDBC methods * @see java.sql.PreparedStatement#setBinaryStream */ void setBlobAsBinaryStream( PreparedStatement ps, int paramIndex, InputStream contentStream, int contentLength) throws SQLException; /** * Set the given content as String on the given statement, using the given * parameter index. Might simply invoke PreparedStatement.setString * or create a Clob instance for it, depending on the database and driver. * @param ps the PreparedStatement to the set the content on * @param paramIndex the parameter index to use * @param content the content as String, or null for SQL NULL * @throws SQLException if thrown by JDBC methods * @see java.sql.PreparedStatement#setBytes */ void setClobAsString(PreparedStatement ps, int paramIndex, String content) throws SQLException; /** * Set the given content as ASCII stream on the given statement, using the given * parameter index. Might simply invoke PreparedStatement.setAsciiStream * or create a Clob instance for it, depending on the database and driver. * @param ps the PreparedStatement to the set the content on * @param paramIndex the parameter index to use * @param asciiStream the content as ASCII stream, or null for SQL NULL * @throws SQLException if thrown by JDBC methods * @see java.sql.PreparedStatement#setAsciiStream */ void setClobAsAsciiStream( PreparedStatement ps, int paramIndex, InputStream asciiStream, int contentLength) throws SQLException; /** * Set the given content as character stream on the given statement, using the given * parameter index. Might simply invoke PreparedStatement.setCharacterStream * or create a Clob instance for it, depending on the database and driver. * @param ps the PreparedStatement to the set the content on * @param paramIndex the parameter index to use * @param characterStream the content as character stream, or null for SQL NULL * @throws SQLException if thrown by JDBC methods * @see java.sql.PreparedStatement#setCharacterStream */ void setClobAsCharacterStream( PreparedStatement ps, int paramIndex, Reader characterStream, int contentLength) throws SQLException; /** * Close this LobCreator session and free its temporarily created BLOBs and CLOBs. * Will not need to do anything if using PreparedStatement's standard methods, * but might be necessary to free database resources if using proprietary means. *

NOTE: Needs to be invoked after the involved PreparedStatements have * been executed or the affected O/R mapping sessions have been flushed. * Otherwise, the database resources for the temporary BLOBs might stay allocated. */ void close(); } ././@LongLink0000000000000000000000000000020200000000000011557 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/lob/LobHandler.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000002356311623223526033303 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.lob; import java.io.InputStream; import java.io.Reader; import java.sql.ResultSet; import java.sql.SQLException; /** * Abstraction for handling large binary fields and large text fields in * specific databases, no matter if represented as simple types or Large OBjects. * Its main purpose is to isolate Oracle's peculiar handling of LOBs in * {@link OracleLobHandler}; most other databases should be able to work * with the provided {@link DefaultLobHandler}. * *

Provides accessor methods for BLOBs and CLOBs, and acts as factory for * LobCreator instances, to be used as sessions for creating BLOBs or CLOBs. * LobCreators are typically instantiated for each statement execution or for * each transaction; they are not thread-safe because they might track * allocated database resources in order to free them after execution. * *

Most databases/drivers should be able to work with {@link DefaultLobHandler}, * which by default delegates to JDBC's direct accessor methods, avoiding the * java.sql.Blob and java.sql.Clob API completely. * {@link DefaultLobHandler} can also be configured to access LOBs using * PreparedStatement.setBlob/setClob (e.g. for PostgreSQL), through * setting the {@link DefaultLobHandler#setWrapAsLob "wrapAsLob"} property. * *

Unfortunately, Oracle 9i just accepts Blob/Clob instances created via its own * proprietary BLOB/CLOB API, and additionally doesn't accept large streams for * PreparedStatement's corresponding setter methods. Therefore, you need to use * {@link OracleLobHandler} there, which uses Oracle's BLOB/CLOB API for both types * of access. The Oracle 10g JDBC driver should basically work with * {@link DefaultLobHandler} as well, with some limitations in terms of LOB sizes. * *

Of course, you need to declare different field types for each database. * In Oracle, any binary content needs to go into a BLOB, and all character content * beyond 4000 bytes needs to go into a CLOB. In MySQL, there is no notion of a * CLOB type but rather a LONGTEXT type that behaves like a VARCHAR. For complete * portability, use a LobHandler for fields that might typically require LOBs on * some database because of the field size (take Oracle's numbers as a guideline). * *

Summarizing the recommended options (for actual LOB fields): *

    *
  • JDBC 4.0 driver: {@link DefaultLobHandler} with streamAsLob=true. *
  • PostgreSQL: {@link DefaultLobHandler} with wrapAsLob=true. *
  • Oracle 9i/10g: {@link OracleLobHandler} with a connection-pool-specific * {@link OracleLobHandler#setNativeJdbcExtractor NativeJdbcExtractor}. *
  • For all other database drivers (and for non-LOB fields that might potentially * turn into LOBs on some databases): a plain {@link DefaultLobHandler}. *
* * @author Juergen Hoeller * @since 23.12.2003 * @see DefaultLobHandler * @see OracleLobHandler * @see java.sql.ResultSet#getBlob * @see java.sql.ResultSet#getClob * @see java.sql.ResultSet#getBytes * @see java.sql.ResultSet#getBinaryStream * @see java.sql.ResultSet#getString * @see java.sql.ResultSet#getAsciiStream * @see java.sql.ResultSet#getCharacterStream */ public interface LobHandler { /** * Retrieve the given column as bytes from the given ResultSet. * Might simply invoke ResultSet.getBytes or work with * ResultSet.getBlob, depending on the database and driver. * @param rs the ResultSet to retrieve the content from * @param columnName the column name to use * @return the content as byte array, or null in case of SQL NULL * @throws SQLException if thrown by JDBC methods * @see java.sql.ResultSet#getBytes */ byte[] getBlobAsBytes(ResultSet rs, String columnName) throws SQLException; /** * Retrieve the given column as bytes from the given ResultSet. * Might simply invoke ResultSet.getBytes or work with * ResultSet.getBlob, depending on the database and driver. * @param rs the ResultSet to retrieve the content from * @param columnIndex the column index to use * @return the content as byte array, or null in case of SQL NULL * @throws SQLException if thrown by JDBC methods * @see java.sql.ResultSet#getBytes */ byte[] getBlobAsBytes(ResultSet rs, int columnIndex) throws SQLException; /** * Retrieve the given column as binary stream from the given ResultSet. * Might simply invoke ResultSet.getBinaryStream or work with * ResultSet.getBlob, depending on the database and driver. * @param rs the ResultSet to retrieve the content from * @param columnName the column name to use * @return the content as binary stream, or null in case of SQL NULL * @throws SQLException if thrown by JDBC methods * @see java.sql.ResultSet#getBinaryStream */ InputStream getBlobAsBinaryStream(ResultSet rs, String columnName) throws SQLException; /** * Retrieve the given column as binary stream from the given ResultSet. * Might simply invoke ResultSet.getBinaryStream or work with * ResultSet.getBlob, depending on the database and driver. * @param rs the ResultSet to retrieve the content from * @param columnIndex the column index to use * @return the content as binary stream, or null in case of SQL NULL * @throws SQLException if thrown by JDBC methods * @see java.sql.ResultSet#getBinaryStream */ InputStream getBlobAsBinaryStream(ResultSet rs, int columnIndex) throws SQLException; /** * Retrieve the given column as String from the given ResultSet. * Might simply invoke ResultSet.getString or work with * ResultSet.getClob, depending on the database and driver. * @param rs the ResultSet to retrieve the content from * @param columnName the column name to use * @return the content as String, or null in case of SQL NULL * @throws SQLException if thrown by JDBC methods * @see java.sql.ResultSet#getString */ String getClobAsString(ResultSet rs, String columnName) throws SQLException; /** * Retrieve the given column as String from the given ResultSet. * Might simply invoke ResultSet.getString or work with * ResultSet.getClob, depending on the database and driver. * @param rs the ResultSet to retrieve the content from * @param columnIndex the column index to use * @return the content as String, or null in case of SQL NULL * @throws SQLException if thrown by JDBC methods * @see java.sql.ResultSet#getString */ String getClobAsString(ResultSet rs, int columnIndex) throws SQLException; /** * Retrieve the given column as ASCII stream from the given ResultSet. * Might simply invoke ResultSet.getAsciiStream or work with * ResultSet.getClob, depending on the database and driver. * @param rs the ResultSet to retrieve the content from * @param columnName the column name to use * @return the content as ASCII stream, or null in case of SQL NULL * @throws SQLException if thrown by JDBC methods * @see java.sql.ResultSet#getAsciiStream */ InputStream getClobAsAsciiStream(ResultSet rs, String columnName) throws SQLException; /** * Retrieve the given column as ASCII stream from the given ResultSet. * Might simply invoke ResultSet.getAsciiStream or work with * ResultSet.getClob, depending on the database and driver. * @param rs the ResultSet to retrieve the content from * @param columnIndex the column index to use * @return the content as ASCII stream, or null in case of SQL NULL * @throws SQLException if thrown by JDBC methods * @see java.sql.ResultSet#getAsciiStream */ InputStream getClobAsAsciiStream(ResultSet rs, int columnIndex) throws SQLException; /** * Retrieve the given column as character stream from the given ResultSet. * Might simply invoke ResultSet.getCharacterStream or work with * ResultSet.getClob, depending on the database and driver. * @param rs the ResultSet to retrieve the content from * @param columnName the column name to use * @return the content as character stream * @throws SQLException if thrown by JDBC methods * @see java.sql.ResultSet#getCharacterStream */ Reader getClobAsCharacterStream(ResultSet rs, String columnName) throws SQLException; /** * Retrieve the given column as character stream from the given ResultSet. * Might simply invoke ResultSet.getCharacterStream or work with * ResultSet.getClob, depending on the database and driver. * @param rs the ResultSet to retrieve the content from * @param columnIndex the column index to use * @return the content as character stream * @throws SQLException if thrown by JDBC methods * @see java.sql.ResultSet#getCharacterStream */ Reader getClobAsCharacterStream(ResultSet rs, int columnIndex) throws SQLException; /** * Create a new {@link LobCreator} instance, i.e. a session for creating BLOBs * and CLOBs. Needs to be closed after the created LOBs are not needed anymore - * typically after statement execution or transaction completion. * @return the new LobCreator instance * @see LobCreator#close() */ LobCreator getLobCreator(); } ././@LongLink0000000000000000000000000000020700000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/lob/LobCreatorUtils.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000646011623223526033300 0ustar drazzibdrazzib/* * Copyright 2002-2006 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.lob; import javax.transaction.Status; import javax.transaction.TransactionManager; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.transaction.TransactionSystemException; import org.springframework.transaction.support.TransactionSynchronizationManager; /** * Helper class for registering a transaction synchronization for closing * a LobCreator, preferring Spring transaction synchronization and falling * back to plain JTA transaction synchronization. * * @author Juergen Hoeller * @since 2.0 * @see SpringLobCreatorSynchronization * @see org.springframework.transaction.support.TransactionSynchronizationManager * @see JtaLobCreatorSynchronization * @see javax.transaction.Transaction#registerSynchronization */ public abstract class LobCreatorUtils { private static final Log logger = LogFactory.getLog(LobCreatorUtils.class); /** * Register a transaction synchronization for closing the given LobCreator, * preferring Spring transaction synchronization and falling back to * plain JTA transaction synchronization. * @param lobCreator the LobCreator to close after transaction completion * @param jtaTransactionManager the JTA TransactionManager to fall back to * when no Spring transaction synchronization is active (may be null) * @throws IllegalStateException if there is neither active Spring transaction * synchronization nor active JTA transaction synchronization */ public static void registerTransactionSynchronization( LobCreator lobCreator, TransactionManager jtaTransactionManager) throws IllegalStateException { if (TransactionSynchronizationManager.isSynchronizationActive()) { logger.debug("Registering Spring transaction synchronization for LobCreator"); TransactionSynchronizationManager.registerSynchronization( new SpringLobCreatorSynchronization(lobCreator)); } else { if (jtaTransactionManager != null) { try { int jtaStatus = jtaTransactionManager.getStatus(); if (jtaStatus == Status.STATUS_ACTIVE || jtaStatus == Status.STATUS_MARKED_ROLLBACK) { logger.debug("Registering JTA transaction synchronization for LobCreator"); jtaTransactionManager.getTransaction().registerSynchronization( new JtaLobCreatorSynchronization(lobCreator)); return; } } catch (Throwable ex) { throw new TransactionSystemException( "Could not register synchronization with JTA TransactionManager", ex); } } throw new IllegalStateException("Active Spring transaction synchronization or active " + "JTA transaction with specified [javax.transaction.TransactionManager] required"); } } } ././@LongLink0000000000000000000000000000022400000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/lob/JtaLobCreatorSynchronization.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000404611623223526033276 0ustar drazzibdrazzib/* * Copyright 2002-2006 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.lob; import javax.transaction.Synchronization; import org.springframework.util.Assert; /** * Callback for resource cleanup at the end of a JTA transaction. * Invokes LobCreator.close() to clean up temporary LOBs * that might have been created. * * @author Juergen Hoeller * @since 2.0 * @see org.springframework.jdbc.support.lob.LobCreator#close() * @see javax.transaction.Transaction#registerSynchronization */ public class JtaLobCreatorSynchronization implements Synchronization { private final LobCreator lobCreator; private boolean beforeCompletionCalled = false; /** * Create a JtaLobCreatorSynchronization for the given LobCreator. * @param lobCreator the LobCreator to close after transaction completion */ public JtaLobCreatorSynchronization(LobCreator lobCreator) { Assert.notNull(lobCreator, "LobCreator must not be null"); this.lobCreator = lobCreator; } public void beforeCompletion() { // Close the LobCreator early if possible, to avoid issues with strict JTA // implementations that issue warnings when doing JDBC operations after // transaction completion. this.beforeCompletionCalled = true; this.lobCreator.close(); } public void afterCompletion(int status) { if (!this.beforeCompletionCalled) { // beforeCompletion not called before (probably because of JTA rollback). // Close the LobCreator here. this.lobCreator.close(); } } } ././@LongLink0000000000000000000000000000020700000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/lob/PassThroughClob.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001000411623223530033260 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.lob; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.Reader; import java.io.StringReader; import java.io.UnsupportedEncodingException; import java.io.Writer; import java.sql.Clob; import java.sql.SQLException; import org.springframework.util.FileCopyUtils; /** * Simple JDBC {@link Clob} adapter that exposes a given String or character stream. * Optionally used by {@link DefaultLobHandler}. * * @author Juergen Hoeller * @since 2.5.3 */ class PassThroughClob implements Clob { private String content; private Reader characterStream; private InputStream asciiStream; private long contentLength; public PassThroughClob(String content) { this.content = content; this.contentLength = content.length(); } public PassThroughClob(Reader characterStream, long contentLength) { this.characterStream = characterStream; this.contentLength = contentLength; } public PassThroughClob(InputStream asciiStream, long contentLength) { this.asciiStream = asciiStream; this.contentLength = contentLength; } public long length() throws SQLException { return this.contentLength; } public Reader getCharacterStream() throws SQLException { try { if (this.content != null) { return new StringReader(this.content); } else if (this.characterStream != null) { return this.characterStream; } else { return new InputStreamReader(this.asciiStream, "US-ASCII"); } } catch (UnsupportedEncodingException ex) { throw new SQLException("US-ASCII encoding not supported: " + ex); } } public InputStream getAsciiStream() throws SQLException { try { if (this.content != null) { return new ByteArrayInputStream(this.content.getBytes("US-ASCII")); } else if (this.characterStream != null) { String tempContent = FileCopyUtils.copyToString(this.characterStream); return new ByteArrayInputStream(tempContent.getBytes("US-ASCII")); } else { return this.asciiStream; } } catch (UnsupportedEncodingException ex) { throw new SQLException("US-ASCII encoding not supported: " + ex); } catch (IOException ex) { throw new SQLException("Failed to read stream content: " + ex); } } public Reader getCharacterStream(long pos, long length) throws SQLException { throw new UnsupportedOperationException(); } public Writer setCharacterStream(long pos) throws SQLException { throw new UnsupportedOperationException(); } public OutputStream setAsciiStream(long pos) throws SQLException { throw new UnsupportedOperationException(); } public String getSubString(long pos, int length) throws SQLException { throw new UnsupportedOperationException(); } public int setString(long pos, String str) throws SQLException { throw new UnsupportedOperationException(); } public int setString(long pos, String str, int offset, int len) throws SQLException { throw new UnsupportedOperationException(); } public long position(String searchstr, long start) throws SQLException { throw new UnsupportedOperationException(); } public long position(Clob searchstr, long start) throws SQLException { throw new UnsupportedOperationException(); } public void truncate(long len) throws SQLException { throw new UnsupportedOperationException(); } public void free() throws SQLException { // no-op } } ././@LongLink0000000000000000000000000000020700000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/lob/PassThroughBlob.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000514111623223530033266 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.lob; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.OutputStream; import java.sql.Blob; import java.sql.SQLException; /** * Simple JDBC {@link Blob} adapter that exposes a given byte array or binary stream. * Optionally used by {@link DefaultLobHandler}. * * @author Juergen Hoeller * @since 2.5.3 */ class PassThroughBlob implements Blob { private byte[] content; private InputStream binaryStream; private long contentLength; public PassThroughBlob(byte[] content) { this.content = content; this.contentLength = content.length; } public PassThroughBlob(InputStream binaryStream, long contentLength) { this.binaryStream = binaryStream; this.contentLength = contentLength; } public long length() throws SQLException { return this.contentLength; } public InputStream getBinaryStream() throws SQLException { return (this.content != null ? new ByteArrayInputStream(this.content) : this.binaryStream); } public InputStream getBinaryStream(long pos, long length) throws SQLException { throw new UnsupportedOperationException(); } public OutputStream setBinaryStream(long pos) throws SQLException { throw new UnsupportedOperationException(); } public byte[] getBytes(long pos, int length) throws SQLException { throw new UnsupportedOperationException(); } public int setBytes(long pos, byte[] bytes) throws SQLException { throw new UnsupportedOperationException(); } public int setBytes(long pos, byte[] bytes, int offset, int len) throws SQLException { throw new UnsupportedOperationException(); } public long position(byte pattern[], long start) throws SQLException { throw new UnsupportedOperationException(); } public long position(Blob pattern, long start) throws SQLException { throw new UnsupportedOperationException(); } public void truncate(long len) throws SQLException { throw new UnsupportedOperationException(); } public void free() throws SQLException { // no-op } } ././@LongLink0000000000000000000000000000021200000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/lob/AbstractLobHandler.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000361311623223530033270 0ustar drazzibdrazzib/* * Copyright 2002-2005 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.lob; import java.io.InputStream; import java.io.Reader; import java.sql.ResultSet; import java.sql.SQLException; /** * Abstract base class for LobHandler implementations. * *

Implements all accessor methods for column names through a column lookup * and delegating to the corresponding accessor that takes a column index. * * @author Juergen Hoeller * @since 1.2 * @see java.sql.ResultSet#findColumn */ public abstract class AbstractLobHandler implements LobHandler { public byte[] getBlobAsBytes(ResultSet rs, String columnName) throws SQLException { return getBlobAsBytes(rs, rs.findColumn(columnName)); } public InputStream getBlobAsBinaryStream(ResultSet rs, String columnName) throws SQLException { return getBlobAsBinaryStream(rs, rs.findColumn(columnName)); } public String getClobAsString(ResultSet rs, String columnName) throws SQLException { return getClobAsString(rs, rs.findColumn(columnName)); } public InputStream getClobAsAsciiStream(ResultSet rs, String columnName) throws SQLException { return getClobAsAsciiStream(rs, rs.findColumn(columnName)); } public Reader getClobAsCharacterStream(ResultSet rs, String columnName) throws SQLException { return getClobAsCharacterStream(rs, rs.findColumn(columnName)); } } ././@LongLink0000000000000000000000000000022700000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/lob/SpringLobCreatorSynchronization.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000536111623223530033272 0ustar drazzibdrazzib/* * Copyright 2002-2006 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.lob; import org.springframework.jdbc.datasource.DataSourceUtils; import org.springframework.transaction.support.TransactionSynchronizationAdapter; import org.springframework.util.Assert; /** * Callback for resource cleanup at the end of a Spring transaction. * Invokes LobCreator.close() to clean up temporary LOBs * that might have been created. * * @author Juergen Hoeller * @since 2.0 * @see org.springframework.jdbc.support.lob.LobCreator#close() */ public class SpringLobCreatorSynchronization extends TransactionSynchronizationAdapter { /** * Order value for TransactionSynchronization objects that clean up LobCreators. * Return CONNECTION_SYNCHRONIZATION_ORDER - 200 to execute LobCreator cleanup * before Hibernate Session (- 100) and JDBC Connection cleanup, if any. * @see org.springframework.jdbc.datasource.DataSourceUtils#CONNECTION_SYNCHRONIZATION_ORDER */ public static final int LOB_CREATOR_SYNCHRONIZATION_ORDER = DataSourceUtils.CONNECTION_SYNCHRONIZATION_ORDER - 200; private final LobCreator lobCreator; private boolean beforeCompletionCalled = false; /** * Create a SpringLobCreatorSynchronization for the given LobCreator. * @param lobCreator the LobCreator to close after transaction completion */ public SpringLobCreatorSynchronization(LobCreator lobCreator) { Assert.notNull(lobCreator, "LobCreator must not be null"); this.lobCreator = lobCreator; } @Override public int getOrder() { return LOB_CREATOR_SYNCHRONIZATION_ORDER; } @Override public void beforeCompletion() { // Close the LobCreator early if possible, to avoid issues with strict JTA // implementations that issue warnings when doing JDBC operations after // transaction completion. this.beforeCompletionCalled = true; this.lobCreator.close(); } @Override public void afterCompletion(int status) { if (!this.beforeCompletionCalled) { // beforeCompletion not called before (probably because of flushing on commit // in the transaction manager, after the chain of beforeCompletion calls). // Close the LobCreator here. this.lobCreator.close(); } } } ././@LongLink0000000000000000000000000000021000000000000011556 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/lob/OracleLobHandler.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000005242111623223526033276 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.lob; import java.io.InputStream; import java.io.OutputStream; import java.io.Reader; import java.io.Writer; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.sql.Blob; import java.sql.Clob; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor; import org.springframework.util.FileCopyUtils; /** * {@link LobHandler} implementation for Oracle databases. Uses proprietary API * to create oracle.sql.BLOB and oracle.sql.CLOB * instances, as necessary when working with Oracle's JDBC driver. * Note that this LobHandler requires Oracle JDBC driver 9i or higher! * *

While most databases are able to work with {@link DefaultLobHandler}, * Oracle just accepts Blob/Clob instances created via its own proprietary * BLOB/CLOB API, and additionally doesn't accept large streams for * PreparedStatement's corresponding setter methods. Therefore, you need * to use a strategy like this LobHandler implementation. * *

Needs to work on a native JDBC Connection, to be able to cast it to * oracle.jdbc.OracleConnection. If you pass in Connections from a * connection pool (the usual case in a J2EE environment), you need to set an * appropriate {@link org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor} * to allow for automatical retrieval of the underlying native JDBC Connection. * LobHandler and NativeJdbcExtractor are separate concerns, therefore they * are represented by separate strategy interfaces. * *

Coded via reflection to avoid dependencies on Oracle classes. * Even reads in Oracle constants via reflection because of different Oracle * drivers (classes12, ojdbc14, ojdbc5, ojdbc6) having different constant values! * As this LobHandler initializes Oracle classes on instantiation, do not define * this as eager-initializing singleton if you do not want to depend on the Oracle * JAR being in the class path: use "lazy-init=true" to avoid this issue. * * @author Juergen Hoeller * @author Thomas Risberg * @since 04.12.2003 * @see #setNativeJdbcExtractor * @see oracle.sql.BLOB * @see oracle.sql.CLOB */ public class OracleLobHandler extends AbstractLobHandler { private static final String BLOB_CLASS_NAME = "oracle.sql.BLOB"; private static final String CLOB_CLASS_NAME = "oracle.sql.CLOB"; private static final String DURATION_SESSION_FIELD_NAME = "DURATION_SESSION"; private static final String MODE_READWRITE_FIELD_NAME = "MODE_READWRITE"; private static final String MODE_READONLY_FIELD_NAME = "MODE_READONLY"; protected final Log logger = LogFactory.getLog(getClass()); private NativeJdbcExtractor nativeJdbcExtractor; private Boolean cache = Boolean.TRUE; private Boolean releaseResourcesAfterRead = Boolean.FALSE; private Class blobClass; private Class clobClass; private final Map durationSessionConstants = new HashMap(2); private final Map modeReadWriteConstants = new HashMap(2); private final Map modeReadOnlyConstants = new HashMap(2); /** * Set an appropriate NativeJdbcExtractor to be able to retrieve the underlying * native oracle.jdbc.OracleConnection. This is necessary for * DataSource-based connection pools, as those need to return wrapped JDBC * Connection handles that cannot be cast to a native Connection implementation. *

Effectively, this LobHandler just invokes a single NativeJdbcExtractor * method, namely getNativeConnectionFromStatement with a * PreparedStatement argument (falling back to a * PreparedStatement.getConnection() call if no extractor is set). *

A common choice is SimpleNativeJdbcExtractor, whose Connection unwrapping * (which is what OracleLobHandler needs) will work with many connection pools. * See SimpleNativeJdbcExtractor's javadoc for details. * @see org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor#getNativeConnectionFromStatement * @see org.springframework.jdbc.support.nativejdbc.SimpleNativeJdbcExtractor * @see org.springframework.jdbc.support.nativejdbc.OracleJdbc4NativeJdbcExtractor * @see oracle.jdbc.OracleConnection */ public void setNativeJdbcExtractor(NativeJdbcExtractor nativeJdbcExtractor) { this.nativeJdbcExtractor = nativeJdbcExtractor; } /** * Set whether to cache the temporary LOB in the buffer cache. * This value will be passed into BLOB/CLOB.createTemporary. * *

Default is true. * @see oracle.sql.BLOB#createTemporary * @see oracle.sql.CLOB#createTemporary */ public void setCache(boolean cache) { this.cache = cache; } /** * Set whether to agressively release any resources used by the LOB. If set to true * then you can only read the LOB values once. Any subsequent reads will fail since the resources * have been closed. *

Setting this property to true can be useful when your queries generates large * temporary LOBs that occupy space in the TEMPORARY tablespace or when you want to free up any * memory allocated by the driver for the LOB reading. *

Default is false. * @see oracle.sql.BLOB#freeTemporary * @see oracle.sql.CLOB#freeTemporary * @see oracle.sql.BLOB#open * @see oracle.sql.CLOB#open * @see oracle.sql.BLOB#close * @see oracle.sql.CLOB#close */ public void setReleaseResourcesAfterRead(boolean releaseResources) { this.releaseResourcesAfterRead = releaseResources; } /** * Retrieve the oracle.sql.BLOB and oracle.sql.CLOB * classes via reflection, and initialize the values for the * DURATION_SESSION, MODE_READWRITE and MODE_READONLY constants defined there. * @param con the Oracle Connection, for using the exact same class loader * that the Oracle driver was loaded with * @see oracle.sql.BLOB#DURATION_SESSION * @see oracle.sql.BLOB#MODE_READWRITE * @see oracle.sql.BLOB#MODE_READONLY * @see oracle.sql.CLOB#DURATION_SESSION * @see oracle.sql.CLOB#MODE_READWRITE * @see oracle.sql.CLOB#MODE_READONLY */ protected synchronized void initOracleDriverClasses(Connection con) { if (this.blobClass == null) { try { // Initialize oracle.sql.BLOB class this.blobClass = con.getClass().getClassLoader().loadClass(BLOB_CLASS_NAME); this.durationSessionConstants.put( this.blobClass, this.blobClass.getField(DURATION_SESSION_FIELD_NAME).getInt(null)); this.modeReadWriteConstants.put( this.blobClass, this.blobClass.getField(MODE_READWRITE_FIELD_NAME).getInt(null)); this.modeReadOnlyConstants.put( this.blobClass, this.blobClass.getField(MODE_READONLY_FIELD_NAME).getInt(null)); // Initialize oracle.sql.CLOB class this.clobClass = con.getClass().getClassLoader().loadClass(CLOB_CLASS_NAME); this.durationSessionConstants.put( this.clobClass, this.clobClass.getField(DURATION_SESSION_FIELD_NAME).getInt(null)); this.modeReadWriteConstants.put( this.clobClass, this.clobClass.getField(MODE_READWRITE_FIELD_NAME).getInt(null)); this.modeReadOnlyConstants.put( this.clobClass, this.clobClass.getField(MODE_READONLY_FIELD_NAME).getInt(null)); } catch (Exception ex) { throw new InvalidDataAccessApiUsageException( "Couldn't initialize OracleLobHandler because Oracle driver classes are not available. " + "Note that OracleLobHandler requires Oracle JDBC driver 9i or higher!", ex); } } } public byte[] getBlobAsBytes(ResultSet rs, int columnIndex) throws SQLException { logger.debug("Returning Oracle BLOB as bytes"); Blob blob = rs.getBlob(columnIndex); initializeResourcesBeforeRead(rs.getStatement().getConnection(), blob); byte[] retVal = (blob != null ? blob.getBytes(1, (int) blob.length()) : null); releaseResourcesAfterRead(rs.getStatement().getConnection(), blob); return retVal; } public InputStream getBlobAsBinaryStream(ResultSet rs, int columnIndex) throws SQLException { logger.debug("Returning Oracle BLOB as binary stream"); Blob blob = rs.getBlob(columnIndex); initializeResourcesBeforeRead(rs.getStatement().getConnection(), blob); InputStream retVal = (blob != null ? blob.getBinaryStream() : null); releaseResourcesAfterRead(rs.getStatement().getConnection(), blob); return retVal; } public String getClobAsString(ResultSet rs, int columnIndex) throws SQLException { logger.debug("Returning Oracle CLOB as string"); Clob clob = rs.getClob(columnIndex); initializeResourcesBeforeRead(rs.getStatement().getConnection(), clob); String retVal = (clob != null ? clob.getSubString(1, (int) clob.length()) : null); releaseResourcesAfterRead(rs.getStatement().getConnection(), clob); return retVal; } public InputStream getClobAsAsciiStream(ResultSet rs, int columnIndex) throws SQLException { logger.debug("Returning Oracle CLOB as ASCII stream"); Clob clob = rs.getClob(columnIndex); initializeResourcesBeforeRead(rs.getStatement().getConnection(), clob); InputStream retVal = (clob != null ? clob.getAsciiStream() : null); releaseResourcesAfterRead(rs.getStatement().getConnection(), clob); return retVal; } public Reader getClobAsCharacterStream(ResultSet rs, int columnIndex) throws SQLException { logger.debug("Returning Oracle CLOB as character stream"); Clob clob = rs.getClob(columnIndex); initializeResourcesBeforeRead(rs.getStatement().getConnection(), clob); Reader retVal = (clob != null ? clob.getCharacterStream() : null); releaseResourcesAfterRead(rs.getStatement().getConnection(), clob); return retVal; } public LobCreator getLobCreator() { return new OracleLobCreator(); } /** * Initialize any LOB resources before a read is done. *

This implementation calls BLOB.open(BLOB.MODE_READONLY) or * CLOB.open(CLOB.MODE_READONLY) on any non-temporary LOBs if * releaseResourcesAfterRead property is set to true. *

This method can be overridden by sublcasses if different behavior is desired. * @param con the connection to be usde for initilization * @param lob the LOB to initialize */ protected void initializeResourcesBeforeRead(Connection con, Object lob) { if (this.releaseResourcesAfterRead) { initOracleDriverClasses(con); try { /* if (!((BLOB) lob.isTemporary() { */ Method isTemporary = lob.getClass().getMethod("isTemporary"); Boolean temporary = (Boolean) isTemporary.invoke(lob); if (!temporary) { /* ((BLOB) lob).open(BLOB.MODE_READONLY); */ Method open = lob.getClass().getMethod("open", int.class); open.invoke(lob, modeReadOnlyConstants.get(lob.getClass())); } } catch (InvocationTargetException ex) { logger.error("Could not open Oracle LOB", ex.getTargetException()); } catch (Exception ex) { throw new DataAccessResourceFailureException("Could not open Oracle LOB", ex); } } } /** * Release any LOB resources after read is complete. *

If releaseResourcesAfterRead property is set to true * then this implementation calls * BLOB.close() or CLOB.close() * on any non-temporary LOBs that are open or * BLOB.freeTemporary() or CLOB.freeTemporary() * on any temporary LOBs. *

This method can be overridden by sublcasses if different behavior is desired. * @param con the connection to be usde for initilization * @param lob the LOB to initialize */ protected void releaseResourcesAfterRead(Connection con, Object lob) { if (this.releaseResourcesAfterRead) { initOracleDriverClasses(con); Boolean temporary = Boolean.FALSE; try { /* if (((BLOB) lob.isTemporary() { */ Method isTemporary = lob.getClass().getMethod("isTemporary"); temporary = (Boolean) isTemporary.invoke(lob); if (temporary) { /* ((BLOB) lob).freeTemporary(); */ Method freeTemporary = lob.getClass().getMethod("freeTemporary"); freeTemporary.invoke(lob); } else { /* if (((BLOB) lob.isOpen() { */ Method isOpen = lob.getClass().getMethod("isOpen"); Boolean open = (Boolean) isOpen.invoke(lob); if (open) { /* ((BLOB) lob).close(); */ Method close = lob.getClass().getMethod("close"); close.invoke(lob); } } } catch (InvocationTargetException ex) { if (temporary) { logger.error("Could not free Oracle LOB", ex.getTargetException()); } else { logger.error("Could not close Oracle LOB", ex.getTargetException()); } } catch (Exception ex) { if (temporary) { throw new DataAccessResourceFailureException("Could not free Oracle LOB", ex); } else { throw new DataAccessResourceFailureException("Could not close Oracle LOB", ex); } } } } /** * LobCreator implementation for Oracle databases. * Creates Oracle-style temporary BLOBs and CLOBs that it frees on close. * @see #close */ protected class OracleLobCreator implements LobCreator { private final List createdLobs = new LinkedList(); public void setBlobAsBytes(PreparedStatement ps, int paramIndex, final byte[] content) throws SQLException { if (content != null) { Blob blob = (Blob) createLob(ps, false, new LobCallback() { public void populateLob(Object lob) throws Exception { Method methodToInvoke = lob.getClass().getMethod("getBinaryOutputStream"); OutputStream out = (OutputStream) methodToInvoke.invoke(lob); FileCopyUtils.copy(content, out); } }); ps.setBlob(paramIndex, blob); if (logger.isDebugEnabled()) { logger.debug("Set bytes for Oracle BLOB with length " + blob.length()); } } else { ps.setBlob(paramIndex, (Blob) null); logger.debug("Set Oracle BLOB to null"); } } public void setBlobAsBinaryStream( PreparedStatement ps, int paramIndex, final InputStream binaryStream, int contentLength) throws SQLException { if (binaryStream != null) { Blob blob = (Blob) createLob(ps, false, new LobCallback() { public void populateLob(Object lob) throws Exception { Method methodToInvoke = lob.getClass().getMethod("getBinaryOutputStream", (Class[]) null); OutputStream out = (OutputStream) methodToInvoke.invoke(lob, (Object[]) null); FileCopyUtils.copy(binaryStream, out); } }); ps.setBlob(paramIndex, blob); if (logger.isDebugEnabled()) { logger.debug("Set binary stream for Oracle BLOB with length " + blob.length()); } } else { ps.setBlob(paramIndex, (Blob) null); logger.debug("Set Oracle BLOB to null"); } } public void setClobAsString(PreparedStatement ps, int paramIndex, final String content) throws SQLException { if (content != null) { Clob clob = (Clob) createLob(ps, true, new LobCallback() { public void populateLob(Object lob) throws Exception { Method methodToInvoke = lob.getClass().getMethod("getCharacterOutputStream", (Class[]) null); Writer writer = (Writer) methodToInvoke.invoke(lob, (Object[]) null); FileCopyUtils.copy(content, writer); } }); ps.setClob(paramIndex, clob); if (logger.isDebugEnabled()) { logger.debug("Set string for Oracle CLOB with length " + clob.length()); } } else { ps.setClob(paramIndex, (Clob) null); logger.debug("Set Oracle CLOB to null"); } } public void setClobAsAsciiStream( PreparedStatement ps, int paramIndex, final InputStream asciiStream, int contentLength) throws SQLException { if (asciiStream != null) { Clob clob = (Clob) createLob(ps, true, new LobCallback() { public void populateLob(Object lob) throws Exception { Method methodToInvoke = lob.getClass().getMethod("getAsciiOutputStream", (Class[]) null); OutputStream out = (OutputStream) methodToInvoke.invoke(lob, (Object[]) null); FileCopyUtils.copy(asciiStream, out); } }); ps.setClob(paramIndex, clob); if (logger.isDebugEnabled()) { logger.debug("Set ASCII stream for Oracle CLOB with length " + clob.length()); } } else { ps.setClob(paramIndex, (Clob) null); logger.debug("Set Oracle CLOB to null"); } } public void setClobAsCharacterStream( PreparedStatement ps, int paramIndex, final Reader characterStream, int contentLength) throws SQLException { if (characterStream != null) { Clob clob = (Clob) createLob(ps, true, new LobCallback() { public void populateLob(Object lob) throws Exception { Method methodToInvoke = lob.getClass().getMethod("getCharacterOutputStream", (Class[]) null); Writer writer = (Writer) methodToInvoke.invoke(lob, (Object[]) null); FileCopyUtils.copy(characterStream, writer); } }); ps.setClob(paramIndex, clob); if (logger.isDebugEnabled()) { logger.debug("Set character stream for Oracle CLOB with length " + clob.length()); } } else { ps.setClob(paramIndex, (Clob) null); logger.debug("Set Oracle CLOB to null"); } } /** * Create a LOB instance for the given PreparedStatement, * populating it via the given callback. */ protected Object createLob(PreparedStatement ps, boolean clob, LobCallback callback) throws SQLException { Connection con = null; try { con = getOracleConnection(ps); initOracleDriverClasses(con); Object lob = prepareLob(con, clob ? clobClass : blobClass); callback.populateLob(lob); lob.getClass().getMethod("close", (Class[]) null).invoke(lob, (Object[]) null); this.createdLobs.add(lob); if (logger.isDebugEnabled()) { logger.debug("Created new Oracle " + (clob ? "CLOB" : "BLOB")); } return lob; } catch (SQLException ex) { throw ex; } catch (InvocationTargetException ex) { if (ex.getTargetException() instanceof SQLException) { throw (SQLException) ex.getTargetException(); } else if (con != null && ex.getTargetException() instanceof ClassCastException) { throw new InvalidDataAccessApiUsageException( "OracleLobCreator needs to work on [oracle.jdbc.OracleConnection], not on [" + con.getClass().getName() + "]: specify a corresponding NativeJdbcExtractor", ex.getTargetException()); } else { throw new DataAccessResourceFailureException("Could not create Oracle LOB", ex.getTargetException()); } } catch (Exception ex) { throw new DataAccessResourceFailureException("Could not create Oracle LOB", ex); } } /** * Retrieve the underlying OracleConnection, using a NativeJdbcExtractor if set. */ protected Connection getOracleConnection(PreparedStatement ps) throws SQLException, ClassNotFoundException { return (nativeJdbcExtractor != null ? nativeJdbcExtractor.getNativeConnectionFromStatement(ps) : ps.getConnection()); } /** * Create and open an oracle.sql.BLOB/CLOB instance via reflection. */ protected Object prepareLob(Connection con, Class lobClass) throws Exception { /* BLOB blob = BLOB.createTemporary(con, false, BLOB.DURATION_SESSION); blob.open(BLOB.MODE_READWRITE); return blob; */ Method createTemporary = lobClass.getMethod( "createTemporary", Connection.class, boolean.class, int.class); Object lob = createTemporary.invoke(null, con, cache, durationSessionConstants.get(lobClass)); Method open = lobClass.getMethod("open", int.class); open.invoke(lob, modeReadWriteConstants.get(lobClass)); return lob; } /** * Free all temporary BLOBs and CLOBs created by this creator. */ public void close() { try { for (Iterator it = this.createdLobs.iterator(); it.hasNext();) { /* BLOB blob = (BLOB) it.next(); blob.freeTemporary(); */ Object lob = it.next(); Method freeTemporary = lob.getClass().getMethod("freeTemporary"); freeTemporary.invoke(lob); it.remove(); } } catch (InvocationTargetException ex) { logger.error("Could not free Oracle LOB", ex.getTargetException()); } catch (Exception ex) { throw new DataAccessResourceFailureException("Could not free Oracle LOB", ex); } } } /** * Internal callback interface for use with createLob. */ protected static interface LobCallback { /** * Populate the given BLOB or CLOB instance with content. * @throws Exception any exception including InvocationTargetException */ void populateLob(Object lob) throws Exception; } } ././@LongLink0000000000000000000000000000021100000000000011557 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/lob/DefaultLobHandler.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000002477011623223526033304 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.lob; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.io.StringReader; import java.io.UnsupportedEncodingException; import java.sql.Blob; import java.sql.Clob; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Default implementation of the {@link LobHandler} interface. Invokes * the direct accessor methods that java.sql.ResultSet * and java.sql.PreparedStatement offer. * *

This LobHandler should work for any JDBC driver that is JDBC compliant * in terms of the spec's suggestions regarding simple BLOB and CLOB handling. * This does not apply to Oracle 9i, and only to a limited degree to Oracle 10g! * As a consequence, use {@link OracleLobHandler} for accessing Oracle BLOBs/CLOBs. * *

Some JDBC drivers require values with a BLOB/CLOB target column to be * explicitly set through the JDBC setBlob / setClob * API: for example, PostgreSQL's driver. Switch the {@link #setWrapAsLob "wrapAsLob"} * property to "true" when operating against such a driver. * *

On JDBC 4.0, this LobHandler also supports streaming the BLOB/CLOB content * via the setBlob / setClob variants that take a stream * argument directly. Consider switching the {@link #setStreamAsLob "streamAsLob"} * property to "true" when operating against a fully compliant JDBC 4.0 driver. * *

See the {@link LobHandler} javadoc for a summary of recommendations. * * @author Juergen Hoeller * @since 04.12.2003 * @see #setStreamAsLob * @see java.sql.ResultSet#getBytes * @see java.sql.ResultSet#getBinaryStream * @see java.sql.ResultSet#getString * @see java.sql.ResultSet#getAsciiStream * @see java.sql.ResultSet#getCharacterStream * @see java.sql.PreparedStatement#setBytes * @see java.sql.PreparedStatement#setBinaryStream * @see java.sql.PreparedStatement#setString * @see java.sql.PreparedStatement#setAsciiStream * @see java.sql.PreparedStatement#setCharacterStream */ public class DefaultLobHandler extends AbstractLobHandler { protected final Log logger = LogFactory.getLog(getClass()); private boolean wrapAsLob = false; private boolean streamAsLob = false; /** * Specify whether to submit a byte array / String to the JDBC driver * wrapped in a JDBC Blob / Clob object, using the JDBC setBlob / * setClob method with a Blob / Clob argument. *

Default is "false", using the common JDBC 2.0 setBinaryStream * / setCharacterStream method for setting the content. * Switch this to "true" for explicit Blob / Clob wrapping against * JDBC drivers that are known to require such wrapping (e.g. PostgreSQL's). *

This setting affects byte array / String arguments as well as stream * arguments, unless {@link #setStreamAsLob "streamAsLob"} overrides this * handling to use JDBC 4.0's new explicit streaming support (if available). * @see java.sql.PreparedStatement#setBlob(int, java.sql.Blob) * @see java.sql.PreparedStatement#setClob(int, java.sql.Clob) */ public void setWrapAsLob(boolean wrapAsLob) { this.wrapAsLob = wrapAsLob; } /** * Specify whether to submit a binary stream / character stream to the JDBC * driver as explicit LOB content, using the JDBC 4.0 setBlob / * setClob method with a stream argument. *

Default is "false", using the common JDBC 2.0 setBinaryStream * / setCharacterStream method for setting the content. * Switch this to "true" for explicit JDBC 4.0 usage, provided that your * JDBC driver actually supports those JDBC 4.0 operations (e.g. Derby's). *

This setting affects stream arguments as well as byte array / String * arguments, requiring JDBC 4.0 support. For supporting LOB content against * JDBC 3.0, check out the {@link #setWrapAsLob "wrapAsLob"} setting. * @see java.sql.PreparedStatement#setBlob(int, java.io.InputStream, long) * @see java.sql.PreparedStatement#setClob(int, java.io.Reader, long) */ public void setStreamAsLob(boolean streamAsLob) { this.streamAsLob = streamAsLob; } public byte[] getBlobAsBytes(ResultSet rs, int columnIndex) throws SQLException { logger.debug("Returning BLOB as bytes"); if (this.wrapAsLob) { Blob blob = rs.getBlob(columnIndex); return blob.getBytes(1, (int) blob.length()); } else { return rs.getBytes(columnIndex); } } public InputStream getBlobAsBinaryStream(ResultSet rs, int columnIndex) throws SQLException { logger.debug("Returning BLOB as binary stream"); if (this.wrapAsLob) { Blob blob = rs.getBlob(columnIndex); return blob.getBinaryStream(); } else { return rs.getBinaryStream(columnIndex); } } public String getClobAsString(ResultSet rs, int columnIndex) throws SQLException { logger.debug("Returning CLOB as string"); if (this.wrapAsLob) { Clob clob = rs.getClob(columnIndex); return clob.getSubString(1, (int) clob.length()); } else { return rs.getString(columnIndex); } } public InputStream getClobAsAsciiStream(ResultSet rs, int columnIndex) throws SQLException { logger.debug("Returning CLOB as ASCII stream"); if (this.wrapAsLob) { Clob clob = rs.getClob(columnIndex); return clob.getAsciiStream(); } else { return rs.getAsciiStream(columnIndex); } } public Reader getClobAsCharacterStream(ResultSet rs, int columnIndex) throws SQLException { logger.debug("Returning CLOB as character stream"); if (this.wrapAsLob) { Clob clob = rs.getClob(columnIndex); return clob.getCharacterStream(); } else { return rs.getCharacterStream(columnIndex); } } public LobCreator getLobCreator() { return new DefaultLobCreator(); } /** * Default LobCreator implementation as inner class. * Can be subclassed in DefaultLobHandler extensions. */ protected class DefaultLobCreator implements LobCreator { public void setBlobAsBytes(PreparedStatement ps, int paramIndex, byte[] content) throws SQLException { if (streamAsLob) { if (content != null) { ps.setBlob(paramIndex, new ByteArrayInputStream(content), content.length); } else { ps.setBlob(paramIndex, (Blob) null); } } else if (wrapAsLob) { if (content != null) { ps.setBlob(paramIndex, new PassThroughBlob(content)); } else { ps.setBlob(paramIndex, (Blob) null); } } else { ps.setBytes(paramIndex, content); } if (logger.isDebugEnabled()) { logger.debug(content != null ? "Set bytes for BLOB with length " + content.length : "Set BLOB to null"); } } public void setBlobAsBinaryStream( PreparedStatement ps, int paramIndex, InputStream binaryStream, int contentLength) throws SQLException { if (streamAsLob) { if (binaryStream != null) { ps.setBlob(paramIndex, binaryStream, contentLength); } else { ps.setBlob(paramIndex, (Blob) null); } } else if (wrapAsLob) { if (binaryStream != null) { ps.setBlob(paramIndex, new PassThroughBlob(binaryStream, contentLength)); } else { ps.setBlob(paramIndex, (Blob) null); } } else { ps.setBinaryStream(paramIndex, binaryStream, contentLength); } if (logger.isDebugEnabled()) { logger.debug(binaryStream != null ? "Set binary stream for BLOB with length " + contentLength : "Set BLOB to null"); } } public void setClobAsString(PreparedStatement ps, int paramIndex, String content) throws SQLException { if (streamAsLob) { if (content != null) { ps.setClob(paramIndex, new StringReader(content), content.length()); } else { ps.setClob(paramIndex, (Clob) null); } } else if (wrapAsLob) { if (content != null) { ps.setClob(paramIndex, new PassThroughClob(content)); } else { ps.setClob(paramIndex, (Clob) null); } } else { ps.setString(paramIndex, content); } if (logger.isDebugEnabled()) { logger.debug(content != null ? "Set string for CLOB with length " + content.length() : "Set CLOB to null"); } } public void setClobAsAsciiStream( PreparedStatement ps, int paramIndex, InputStream asciiStream, int contentLength) throws SQLException { if (streamAsLob || wrapAsLob) { if (asciiStream != null) { try { if (streamAsLob) { ps.setClob(paramIndex, new InputStreamReader(asciiStream, "US-ASCII"), contentLength); } else { ps.setClob(paramIndex, new PassThroughClob(asciiStream, contentLength)); } } catch (UnsupportedEncodingException ex) { throw new SQLException("US-ASCII encoding not supported: " + ex); } } else { ps.setClob(paramIndex, (Clob) null); } } else { ps.setAsciiStream(paramIndex, asciiStream, contentLength); } if (logger.isDebugEnabled()) { logger.debug(asciiStream != null ? "Set ASCII stream for CLOB with length " + contentLength : "Set CLOB to null"); } } public void setClobAsCharacterStream( PreparedStatement ps, int paramIndex, Reader characterStream, int contentLength) throws SQLException { if (streamAsLob) { if (characterStream != null) { ps.setClob(paramIndex, characterStream, contentLength); } else { ps.setClob(paramIndex, (Clob) null); } } else if (wrapAsLob) { if (characterStream != null) { ps.setClob(paramIndex, new PassThroughClob(characterStream, contentLength)); } else { ps.setClob(paramIndex, (Clob) null); } } else { ps.setCharacterStream(paramIndex, characterStream, contentLength); } if (logger.isDebugEnabled()) { logger.debug(characterStream != null ? "Set character stream for CLOB with length " + contentLength : "Set CLOB to null"); } } public void close() { // nothing to do here } } } ././@LongLink0000000000000000000000000000022600000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/SQLErrorCodeSQLExceptionTranslator.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000004245611623223530033300 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support; import java.lang.reflect.Constructor; import java.sql.BatchUpdateException; import java.sql.SQLException; import java.util.Arrays; import javax.sql.DataSource; import org.springframework.core.JdkVersion; import org.springframework.dao.CannotAcquireLockException; import org.springframework.dao.CannotSerializeTransactionException; import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.dao.DeadlockLoserDataAccessException; import org.springframework.dao.PermissionDeniedDataAccessException; import org.springframework.dao.TransientDataAccessResourceException; import org.springframework.dao.DuplicateKeyException; import org.springframework.jdbc.BadSqlGrammarException; import org.springframework.jdbc.InvalidResultSetAccessException; /** * Implementation of {@link SQLExceptionTranslator} that analyzes vendor-specific error codes. * More precise than an implementation based on SQL state, but heavily vendor-specific. * *

This class applies the following matching rules: *

    *
  • Try custom translation implemented by any subclass. Note that this class is * concrete and is typically used itself, in which case this rule doesn't apply. *
  • Apply error code matching. Error codes are obtained from the SQLErrorCodesFactory * by default. This factory loads a "sql-error-codes.xml" file from the class path, * defining error code mappings for database names from database metadata. *
  • Fallback to a fallback translator. {@link SQLStateSQLExceptionTranslator} is the * default fallback translator, analyzing the exception's SQL state only. On Java 6 * which introduces its own SQLException subclass hierarchy, we will * use {@link SQLExceptionSubclassTranslator} by default, which in turns falls back * to Spring's own SQL state translation when not encountering specific subclasses. *
* *

The configuration file named "sql-error-codes.xml" is by default read from * this package. It can be overridden through a file of the same name in the root * of the class path (e.g. in the "/WEB-INF/classes" directory), as long as the * Spring JDBC package is loaded from the same ClassLoader. * * @author Rod Johnson * @author Thomas Risberg * @author Juergen Hoeller * @see SQLErrorCodesFactory * @see SQLStateSQLExceptionTranslator */ public class SQLErrorCodeSQLExceptionTranslator extends AbstractFallbackSQLExceptionTranslator { private static final int MESSAGE_ONLY_CONSTRUCTOR = 1; private static final int MESSAGE_THROWABLE_CONSTRUCTOR = 2; private static final int MESSAGE_SQLEX_CONSTRUCTOR = 3; private static final int MESSAGE_SQL_THROWABLE_CONSTRUCTOR = 4; private static final int MESSAGE_SQL_SQLEX_CONSTRUCTOR = 5; /** Error codes used by this translator */ private SQLErrorCodes sqlErrorCodes; /** * Constructor for use as a JavaBean. * The SqlErrorCodes or DataSource property must be set. */ public SQLErrorCodeSQLExceptionTranslator() { if (JdkVersion.getMajorJavaVersion() >= JdkVersion.JAVA_16) { setFallbackTranslator(new SQLExceptionSubclassTranslator()); } else { setFallbackTranslator(new SQLStateSQLExceptionTranslator()); } } /** * Create a SQL error code translator for the given DataSource. * Invoking this constructor will cause a Connection to be obtained * from the DataSource to get the metadata. * @param dataSource DataSource to use to find metadata and establish * which error codes are usable * @see SQLErrorCodesFactory */ public SQLErrorCodeSQLExceptionTranslator(DataSource dataSource) { this(); setDataSource(dataSource); } /** * Create a SQL error code translator for the given database product name. * Invoking this constructor will avoid obtaining a Connection from the * DataSource to get the metadata. * @param dbName the database product name that identifies the error codes entry * @see SQLErrorCodesFactory * @see java.sql.DatabaseMetaData#getDatabaseProductName() */ public SQLErrorCodeSQLExceptionTranslator(String dbName) { this(); setDatabaseProductName(dbName); } /** * Create a SQLErrorCode translator given these error codes. * Does not require a database metadata lookup to be performed using a connection. * @param sec error codes */ public SQLErrorCodeSQLExceptionTranslator(SQLErrorCodes sec) { this(); this.sqlErrorCodes = sec; } /** * Set the DataSource for this translator. *

Setting this property will cause a Connection to be obtained from * the DataSource to get the metadata. * @param dataSource DataSource to use to find metadata and establish * which error codes are usable * @see SQLErrorCodesFactory#getErrorCodes(javax.sql.DataSource) * @see java.sql.DatabaseMetaData#getDatabaseProductName() */ public void setDataSource(DataSource dataSource) { this.sqlErrorCodes = SQLErrorCodesFactory.getInstance().getErrorCodes(dataSource); } /** * Set the database product name for this translator. *

Setting this property will avoid obtaining a Connection from the DataSource * to get the metadata. * @param dbName the database product name that identifies the error codes entry * @see SQLErrorCodesFactory#getErrorCodes(String) * @see java.sql.DatabaseMetaData#getDatabaseProductName() */ public void setDatabaseProductName(String dbName) { this.sqlErrorCodes = SQLErrorCodesFactory.getInstance().getErrorCodes(dbName); } /** * Set custom error codes to be used for translation. * @param sec custom error codes to use */ public void setSqlErrorCodes(SQLErrorCodes sec) { this.sqlErrorCodes = sec; } /** * Return the error codes used by this translator. * Usually determined via a DataSource. * @see #setDataSource */ public SQLErrorCodes getSqlErrorCodes() { return this.sqlErrorCodes; } @Override protected DataAccessException doTranslate(String task, String sql, SQLException ex) { SQLException sqlEx = ex; if (sqlEx instanceof BatchUpdateException && sqlEx.getNextException() != null) { SQLException nestedSqlEx = sqlEx.getNextException(); if (nestedSqlEx.getErrorCode() > 0 || nestedSqlEx.getSQLState() != null) { logger.debug("Using nested SQLException from the BatchUpdateException"); sqlEx = nestedSqlEx; } } // First, try custom translation from overridden method. DataAccessException dex = customTranslate(task, sql, sqlEx); if (dex != null) { return dex; } // Next, try the custom SQLException translator, if available. if (this.sqlErrorCodes != null) { SQLExceptionTranslator customTranslator = this.sqlErrorCodes.getCustomSqlExceptionTranslator(); if (customTranslator != null) { DataAccessException customDex = customTranslator.translate(task, sql, sqlEx); if (customDex != null) { return customDex; } } } // Check SQLErrorCodes with corresponding error code, if available. if (this.sqlErrorCodes != null) { String errorCode = null; if (this.sqlErrorCodes.isUseSqlStateForTranslation()) { errorCode = sqlEx.getSQLState(); } else { errorCode = Integer.toString(sqlEx.getErrorCode()); } if (errorCode != null) { // Look for defined custom translations first. CustomSQLErrorCodesTranslation[] customTranslations = this.sqlErrorCodes.getCustomTranslations(); if (customTranslations != null) { for (int i = 0; i < customTranslations.length; i++) { CustomSQLErrorCodesTranslation customTranslation = customTranslations[i]; if (Arrays.binarySearch(customTranslation.getErrorCodes(), errorCode) >= 0) { if (customTranslation.getExceptionClass() != null) { DataAccessException customException = createCustomException( task, sql, sqlEx, customTranslation.getExceptionClass()); if (customException != null) { logTranslation(task, sql, sqlEx, true); return customException; } } } } } // Next, look for grouped error codes. if (Arrays.binarySearch(this.sqlErrorCodes.getBadSqlGrammarCodes(), errorCode) >= 0) { logTranslation(task, sql, sqlEx, false); return new BadSqlGrammarException(task, sql, sqlEx); } else if (Arrays.binarySearch(this.sqlErrorCodes.getInvalidResultSetAccessCodes(), errorCode) >= 0) { logTranslation(task, sql, sqlEx, false); return new InvalidResultSetAccessException(task, sql, sqlEx); } else if (Arrays.binarySearch(this.sqlErrorCodes.getDuplicateKeyCodes(), errorCode) >= 0) { logTranslation(task, sql, sqlEx, false); return new DuplicateKeyException(buildMessage(task, sql, sqlEx), sqlEx); } else if (Arrays.binarySearch(this.sqlErrorCodes.getDataIntegrityViolationCodes(), errorCode) >= 0) { logTranslation(task, sql, sqlEx, false); return new DataIntegrityViolationException(buildMessage(task, sql, sqlEx), sqlEx); } else if (Arrays.binarySearch(this.sqlErrorCodes.getPermissionDeniedCodes(), errorCode) >= 0) { logTranslation(task, sql, sqlEx, false); return new PermissionDeniedDataAccessException(buildMessage(task, sql, sqlEx), sqlEx); } else if (Arrays.binarySearch(this.sqlErrorCodes.getDataAccessResourceFailureCodes(), errorCode) >= 0) { logTranslation(task, sql, sqlEx, false); return new DataAccessResourceFailureException(buildMessage(task, sql, sqlEx), sqlEx); } else if (Arrays.binarySearch(this.sqlErrorCodes.getTransientDataAccessResourceCodes(), errorCode) >= 0) { logTranslation(task, sql, sqlEx, false); return new TransientDataAccessResourceException(buildMessage(task, sql, sqlEx), sqlEx); } else if (Arrays.binarySearch(this.sqlErrorCodes.getCannotAcquireLockCodes(), errorCode) >= 0) { logTranslation(task, sql, sqlEx, false); return new CannotAcquireLockException(buildMessage(task, sql, sqlEx), sqlEx); } else if (Arrays.binarySearch(this.sqlErrorCodes.getDeadlockLoserCodes(), errorCode) >= 0) { logTranslation(task, sql, sqlEx, false); return new DeadlockLoserDataAccessException(buildMessage(task, sql, sqlEx), sqlEx); } else if (Arrays.binarySearch(this.sqlErrorCodes.getCannotSerializeTransactionCodes(), errorCode) >= 0) { logTranslation(task, sql, sqlEx, false); return new CannotSerializeTransactionException(buildMessage(task, sql, sqlEx), sqlEx); } } } // We couldn't identify it more precisely - let's hand it over to the SQLState fallback translator. if (logger.isDebugEnabled()) { String codes = null; if (this.sqlErrorCodes != null && this.sqlErrorCodes.isUseSqlStateForTranslation()) { codes = "SQL state '" + sqlEx.getSQLState() + "', error code '" + sqlEx.getErrorCode(); } else { codes = "Error code '" + sqlEx.getErrorCode() + "'"; } logger.debug("Unable to translate SQLException with " + codes + ", will now try the fallback translator"); } return null; } /** * Subclasses can override this method to attempt a custom mapping from SQLException * to DataAccessException. * @param task readable text describing the task being attempted * @param sql SQL query or update that caused the problem. May be null. * @param sqlEx the offending SQLException * @return null if no custom translation was possible, otherwise a DataAccessException * resulting from custom translation. This exception should include the sqlEx parameter * as a nested root cause. This implementation always returns null, meaning that * the translator always falls back to the default error codes. */ protected DataAccessException customTranslate(String task, String sql, SQLException sqlEx) { return null; } /** * Create a custom DataAccessException, based on a given exception * class from a CustomSQLErrorCodesTranslation definition. * @param task readable text describing the task being attempted * @param sql SQL query or update that caused the problem. May be null. * @param sqlEx the offending SQLException * @param exceptionClass the exception class to use, as defined in the * CustomSQLErrorCodesTranslation definition * @return null if the custom exception could not be created, otherwise * the resulting DataAccessException. This exception should include the * sqlEx parameter as a nested root cause. * @see CustomSQLErrorCodesTranslation#setExceptionClass */ protected DataAccessException createCustomException( String task, String sql, SQLException sqlEx, Class exceptionClass) { // find appropriate constructor try { int constructorType = 0; Constructor[] constructors = exceptionClass.getConstructors(); for (int i = 0; i < constructors.length; i++) { Class[] parameterTypes = constructors[i].getParameterTypes(); if (parameterTypes.length == 1 && parameterTypes[0].equals(String.class)) { if (constructorType < MESSAGE_ONLY_CONSTRUCTOR) constructorType = MESSAGE_ONLY_CONSTRUCTOR; } if (parameterTypes.length == 2 && parameterTypes[0].equals(String.class) && parameterTypes[1].equals(Throwable.class)) { if (constructorType < MESSAGE_THROWABLE_CONSTRUCTOR) constructorType = MESSAGE_THROWABLE_CONSTRUCTOR; } if (parameterTypes.length == 2 && parameterTypes[0].equals(String.class) && parameterTypes[1].equals(SQLException.class)) { if (constructorType < MESSAGE_SQLEX_CONSTRUCTOR) constructorType = MESSAGE_SQLEX_CONSTRUCTOR; } if (parameterTypes.length == 3 && parameterTypes[0].equals(String.class) && parameterTypes[1].equals(String.class) && parameterTypes[2].equals(Throwable.class)) { if (constructorType < MESSAGE_SQL_THROWABLE_CONSTRUCTOR) constructorType = MESSAGE_SQL_THROWABLE_CONSTRUCTOR; } if (parameterTypes.length == 3 && parameterTypes[0].equals(String.class) && parameterTypes[1].equals(String.class) && parameterTypes[2].equals(SQLException.class)) { if (constructorType < MESSAGE_SQL_SQLEX_CONSTRUCTOR) constructorType = MESSAGE_SQL_SQLEX_CONSTRUCTOR; } } // invoke constructor Constructor exceptionConstructor = null; switch (constructorType) { case MESSAGE_SQL_SQLEX_CONSTRUCTOR: Class[] messageAndSqlAndSqlExArgsClass = new Class[] {String.class, String.class, SQLException.class}; Object[] messageAndSqlAndSqlExArgs = new Object[] {task, sql, sqlEx}; exceptionConstructor = exceptionClass.getConstructor(messageAndSqlAndSqlExArgsClass); return (DataAccessException) exceptionConstructor.newInstance(messageAndSqlAndSqlExArgs); case MESSAGE_SQL_THROWABLE_CONSTRUCTOR: Class[] messageAndSqlAndThrowableArgsClass = new Class[] {String.class, String.class, Throwable.class}; Object[] messageAndSqlAndThrowableArgs = new Object[] {task, sql, sqlEx}; exceptionConstructor = exceptionClass.getConstructor(messageAndSqlAndThrowableArgsClass); return (DataAccessException) exceptionConstructor.newInstance(messageAndSqlAndThrowableArgs); case MESSAGE_SQLEX_CONSTRUCTOR: Class[] messageAndSqlExArgsClass = new Class[] {String.class, SQLException.class}; Object[] messageAndSqlExArgs = new Object[] {task + ": " + sqlEx.getMessage(), sqlEx}; exceptionConstructor = exceptionClass.getConstructor(messageAndSqlExArgsClass); return (DataAccessException) exceptionConstructor.newInstance(messageAndSqlExArgs); case MESSAGE_THROWABLE_CONSTRUCTOR: Class[] messageAndThrowableArgsClass = new Class[] {String.class, Throwable.class}; Object[] messageAndThrowableArgs = new Object[] {task + ": " + sqlEx.getMessage(), sqlEx}; exceptionConstructor = exceptionClass.getConstructor(messageAndThrowableArgsClass); return (DataAccessException)exceptionConstructor.newInstance(messageAndThrowableArgs); case MESSAGE_ONLY_CONSTRUCTOR: Class[] messageOnlyArgsClass = new Class[] {String.class}; Object[] messageOnlyArgs = new Object[] {task + ": " + sqlEx.getMessage()}; exceptionConstructor = exceptionClass.getConstructor(messageOnlyArgsClass); return (DataAccessException) exceptionConstructor.newInstance(messageOnlyArgs); default: if (logger.isWarnEnabled()) { logger.warn("Unable to find appropriate constructor of custom exception class [" + exceptionClass.getName() + "]"); } return null; } } catch (Throwable ex) { if (logger.isWarnEnabled()) { logger.warn("Unable to instantiate custom exception class [" + exceptionClass.getName() + "]", ex); } return null; } } private void logTranslation(String task, String sql, SQLException sqlEx, boolean custom) { if (logger.isDebugEnabled()) { String intro = custom ? "Custom translation of" : "Translating"; logger.debug(intro + " SQLException with SQL state '" + sqlEx.getSQLState() + "', error code '" + sqlEx.getErrorCode() + "', message [" + sqlEx.getMessage() + "]; SQL was [" + sql + "] for task [" + task + "]"); } } } ././@LongLink0000000000000000000000000000021400000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/DatabaseMetaDataCallback.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000343611623223530033273 0ustar drazzibdrazzib/* * Copyright 2002-2005 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support; import java.sql.DatabaseMetaData; import java.sql.SQLException; /** * A callback interface used by the JdbcUtils class. Implementations of this * interface perform the actual work of extracting database meta data, but * don't need to worry about exception handling. SQLExceptions will be caught * and handled correctly by the JdbcUtils class. * * @author Thomas Risberg * @see JdbcUtils#extractDatabaseMetaData */ public interface DatabaseMetaDataCallback { /** * Implementations must implement this method to process the meta data * passed in. Exactly what the implementation chooses to do is up to it. * @param dbmd the DatabaseMetaData to process * @return a result object extracted from the meta data * (can be an arbitrary object, as needed by the implementation) * @throws SQLException if a SQLException is encountered getting * column values (that is, there's no need to catch SQLException) * @throws MetaDataAccessException in case of other failures while * extracting meta data (for example, reflection failure) */ Object processMetaData(DatabaseMetaData dbmd) throws SQLException, MetaDataAccessException; } ././@LongLink0000000000000000000000000000022200000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/CustomSQLErrorCodesTranslation.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000377511623223530033301 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support; import org.springframework.dao.DataAccessException; import org.springframework.util.StringUtils; /** * JavaBean for holding custom JDBC error codes translation for a particular * database. The "exceptionClass" property defines which exception will be * thrown for the list of error codes specified in the errorCodes property. * * @author Thomas Risberg * @since 1.1 * @see SQLErrorCodeSQLExceptionTranslator */ public class CustomSQLErrorCodesTranslation { private String[] errorCodes = new String[0]; private Class exceptionClass; /** * Set the SQL error codes to match. */ public void setErrorCodes(String[] errorCodes) { this.errorCodes = StringUtils.sortStringArray(errorCodes); } /** * Return the SQL error codes to match. */ public String[] getErrorCodes() { return this.errorCodes; } /** * Set the exception class for the specified error codes. */ public void setExceptionClass(Class exceptionClass) { if (!DataAccessException.class.isAssignableFrom(exceptionClass)) { throw new IllegalArgumentException("Invalid exception class [" + exceptionClass + "]: needs to be a subclass of [org.springframework.dao.DataAccessException]"); } this.exceptionClass = exceptionClass; } /** * Return the exception class for the specified error codes. */ public Class getExceptionClass() { return this.exceptionClass; } } ././@LongLink0000000000000000000000000000023200000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/AbstractFallbackSQLExceptionTranslator.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000753311623223530033275 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support; import java.sql.SQLException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.dao.DataAccessException; import org.springframework.jdbc.UncategorizedSQLException; import org.springframework.util.Assert; /** * Base class for {@link SQLExceptionTranslator} implementations that allow for * fallback to some other {@link SQLExceptionTranslator}. * * @author Juergen Hoeller * @since 2.5.6 */ public abstract class AbstractFallbackSQLExceptionTranslator implements SQLExceptionTranslator { /** Logger available to subclasses */ protected final Log logger = LogFactory.getLog(getClass()); private SQLExceptionTranslator fallbackTranslator; /** * Override the default SQL state fallback translator * (typically a {@link SQLStateSQLExceptionTranslator}). */ public void setFallbackTranslator(SQLExceptionTranslator fallback) { this.fallbackTranslator = fallback; } /** * Return the fallback exception translator, if any. */ public SQLExceptionTranslator getFallbackTranslator() { return this.fallbackTranslator; } /** * Pre-checks the arguments, calls {@link #doTranslate}, and invokes the * {@link #getFallbackTranslator() fallback translator} if necessary. */ public DataAccessException translate(String task, String sql, SQLException ex) { Assert.notNull(ex, "Cannot translate a null SQLException"); if (task == null) { task = ""; } if (sql == null) { sql = ""; } DataAccessException dex = doTranslate(task, sql, ex); if (dex != null) { // Specific exception match found. return dex; } // Looking for a fallback... SQLExceptionTranslator fallback = getFallbackTranslator(); if (fallback != null) { return fallback.translate(task, sql, ex); } // We couldn't identify it more precisely. return new UncategorizedSQLException(task, sql, ex); } /** * Template method for actually translating the given exception. *

The passed-in arguments will have been pre-checked. Furthermore, this method * is allowed to return null to indicate that no exception match has * been found and that fallback translation should kick in. * @param task readable text describing the task being attempted * @param sql SQL query or update that caused the problem (may be null) * @param ex the offending SQLException * @return the DataAccessException, wrapping the SQLException; * or null if no exception match found */ protected abstract DataAccessException doTranslate(String task, String sql, SQLException ex); /** * Build a message String for the given {@link java.sql.SQLException}. *

To be called by translator subclasses when creating an instance of a generic * {@link org.springframework.dao.DataAccessException} class. * @param task readable text describing the task being attempted * @param sql the SQL statement that caused the problem (may be null) * @param ex the offending SQLException * @return the message String to use */ protected String buildMessage(String task, String sql, SQLException ex) { return task + "; SQL [" + sql + "]; " + ex.getMessage(); } } ././@LongLink0000000000000000000000000000020100000000000011556 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/SQLErrorCodes.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001544011623223530033271 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support; import org.springframework.util.StringUtils; import org.springframework.dao.InvalidDataAccessResourceUsageException; /** * JavaBean for holding JDBC error codes for a particular database. * Instances of this class are normally loaded through a bean factory. * *

Used by Spring's {@link SQLErrorCodeSQLExceptionTranslator}. * The file "sql-error-codes.xml" in this package contains default * SQLErrorCodes instances for various databases. * * @author Thomas Risberg * @author Juergen Hoeller * @see SQLErrorCodesFactory * @see SQLErrorCodeSQLExceptionTranslator */ public class SQLErrorCodes { private String[] databaseProductNames; private boolean useSqlStateForTranslation = false; private SQLExceptionTranslator customSqlExceptionTranslator = null; private String[] badSqlGrammarCodes = new String[0]; private String[] invalidResultSetAccessCodes = new String[0]; private String[] duplicateKeyCodes = new String[0]; private String[] dataIntegrityViolationCodes = new String[0]; private String[] permissionDeniedCodes = new String[0]; private String[] dataAccessResourceFailureCodes = new String[0]; private String[] transientDataAccessResourceCodes = new String[0]; private String[] cannotAcquireLockCodes = new String[0]; private String[] deadlockLoserCodes = new String[0]; private String[] cannotSerializeTransactionCodes = new String[0]; private CustomSQLErrorCodesTranslation[] customTranslations; /** * Set this property if the database name contains spaces, * in which case we can not use the bean name for lookup. */ public void setDatabaseProductName(String databaseProductName) { this.databaseProductNames = new String[] {databaseProductName}; } public String getDatabaseProductName() { return (this.databaseProductNames != null && this.databaseProductNames.length > 0 ? this.databaseProductNames[0] : null); } /** * Set this property to specify multiple database names that contains spaces, * in which case we can not use bean names for lookup. */ public void setDatabaseProductNames(String[] databaseProductNames) { this.databaseProductNames = databaseProductNames; } public String[] getDatabaseProductNames() { return this.databaseProductNames; } /** * Set this property to true for databases that do not provide an error code * but that do provide SQL State (this includes PostgreSQL). */ public void setUseSqlStateForTranslation(boolean useStateCodeForTranslation) { this.useSqlStateForTranslation = useStateCodeForTranslation; } public boolean isUseSqlStateForTranslation() { return this.useSqlStateForTranslation; } public SQLExceptionTranslator getCustomSqlExceptionTranslator() { return customSqlExceptionTranslator; } public void setCustomSqlExceptionTranslatorClass(Class customSqlExceptionTranslatorClass) { if (customSqlExceptionTranslatorClass != null) { try { this.customSqlExceptionTranslator = (SQLExceptionTranslator) customSqlExceptionTranslatorClass.newInstance(); } catch (InstantiationException e) { throw new InvalidDataAccessResourceUsageException( "Unable to instantiate " + customSqlExceptionTranslatorClass.getName(), e); } catch (IllegalAccessException e) { throw new InvalidDataAccessResourceUsageException( "Unable to instantiate " + customSqlExceptionTranslatorClass.getName(), e); } } } public void setBadSqlGrammarCodes(String[] badSqlGrammarCodes) { this.badSqlGrammarCodes = StringUtils.sortStringArray(badSqlGrammarCodes); } public String[] getBadSqlGrammarCodes() { return this.badSqlGrammarCodes; } public void setInvalidResultSetAccessCodes(String[] invalidResultSetAccessCodes) { this.invalidResultSetAccessCodes = StringUtils.sortStringArray(invalidResultSetAccessCodes); } public String[] getInvalidResultSetAccessCodes() { return this.invalidResultSetAccessCodes; } public String[] getDuplicateKeyCodes() { return duplicateKeyCodes; } public void setDuplicateKeyCodes(String[] duplicateKeyCodes) { this.duplicateKeyCodes = duplicateKeyCodes; } public void setDataIntegrityViolationCodes(String[] dataIntegrityViolationCodes) { this.dataIntegrityViolationCodes = StringUtils.sortStringArray(dataIntegrityViolationCodes); } public String[] getDataIntegrityViolationCodes() { return this.dataIntegrityViolationCodes; } public void setPermissionDeniedCodes(String[] permissionDeniedCodes) { this.permissionDeniedCodes = StringUtils.sortStringArray(permissionDeniedCodes); } public String[] getPermissionDeniedCodes() { return this.permissionDeniedCodes; } public void setDataAccessResourceFailureCodes(String[] dataAccessResourceFailureCodes) { this.dataAccessResourceFailureCodes = StringUtils.sortStringArray(dataAccessResourceFailureCodes); } public String[] getDataAccessResourceFailureCodes() { return this.dataAccessResourceFailureCodes; } public void setTransientDataAccessResourceCodes(String[] transientDataAccessResourceCodes) { this.transientDataAccessResourceCodes = StringUtils.sortStringArray(transientDataAccessResourceCodes); } public String[] getTransientDataAccessResourceCodes() { return this.transientDataAccessResourceCodes; } public void setCannotAcquireLockCodes(String[] cannotAcquireLockCodes) { this.cannotAcquireLockCodes = StringUtils.sortStringArray(cannotAcquireLockCodes); } public String[] getCannotAcquireLockCodes() { return this.cannotAcquireLockCodes; } public void setDeadlockLoserCodes(String[] deadlockLoserCodes) { this.deadlockLoserCodes = StringUtils.sortStringArray(deadlockLoserCodes); } public String[] getDeadlockLoserCodes() { return this.deadlockLoserCodes; } public void setCannotSerializeTransactionCodes(String[] cannotSerializeTransactionCodes) { this.cannotSerializeTransactionCodes = StringUtils.sortStringArray(cannotSerializeTransactionCodes); } public String[] getCannotSerializeTransactionCodes() { return this.cannotSerializeTransactionCodes; } public void setCustomTranslations(CustomSQLErrorCodesTranslation[] customTranslations) { this.customTranslations = customTranslations; } public CustomSQLErrorCodesTranslation[] getCustomTranslations() { return this.customTranslations; } } ././@LongLink0000000000000000000000000000022200000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/SQLExceptionSubclassTranslator.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001032211623223526033270 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support; import java.sql.SQLDataException; import java.sql.SQLException; import java.sql.SQLFeatureNotSupportedException; import java.sql.SQLIntegrityConstraintViolationException; import java.sql.SQLInvalidAuthorizationSpecException; import java.sql.SQLNonTransientConnectionException; import java.sql.SQLNonTransientException; import java.sql.SQLRecoverableException; import java.sql.SQLSyntaxErrorException; import java.sql.SQLTimeoutException; import java.sql.SQLTransactionRollbackException; import java.sql.SQLTransientConnectionException; import java.sql.SQLTransientException; import org.springframework.dao.ConcurrencyFailureException; import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.dao.PermissionDeniedDataAccessException; import org.springframework.dao.RecoverableDataAccessException; import org.springframework.dao.TransientDataAccessResourceException; import org.springframework.jdbc.BadSqlGrammarException; /** * {@link SQLExceptionTranslator} implementation which analyzes the specific * {@link java.sql.SQLException} subclass thrown by the JDBC driver. * *

This is only available with JDBC 4.0 and later drivers when using Java 6 or later. * Falls back to a standard {@link SQLStateSQLExceptionTranslator} if the JDBC driver * does not actually expose JDBC 4 compliant SQLException subclasses. * * @author Thomas Risberg * @author Juergen Hoeller * @since 2.5 * @see java.sql.SQLTransientException * @see java.sql.SQLTransientException * @see java.sql.SQLRecoverableException */ public class SQLExceptionSubclassTranslator extends AbstractFallbackSQLExceptionTranslator { public SQLExceptionSubclassTranslator() { setFallbackTranslator(new SQLStateSQLExceptionTranslator()); } @Override protected DataAccessException doTranslate(String task, String sql, SQLException ex) { if (ex instanceof SQLTransientException) { if (ex instanceof SQLTransactionRollbackException) { return new ConcurrencyFailureException(buildMessage(task, sql, ex), ex); } if (ex instanceof SQLTransientConnectionException) { return new TransientDataAccessResourceException(buildMessage(task, sql, ex), ex); } if (ex instanceof SQLTimeoutException) { return new TransientDataAccessResourceException(buildMessage(task, sql, ex), ex); } } else if (ex instanceof SQLNonTransientException) { if (ex instanceof SQLDataException) { return new DataIntegrityViolationException(buildMessage(task, sql, ex), ex); } else if (ex instanceof SQLFeatureNotSupportedException) { return new InvalidDataAccessApiUsageException(buildMessage(task, sql, ex), ex); } else if (ex instanceof SQLIntegrityConstraintViolationException) { return new DataIntegrityViolationException(buildMessage(task, sql, ex), ex); } else if (ex instanceof SQLInvalidAuthorizationSpecException) { return new PermissionDeniedDataAccessException(buildMessage(task, sql, ex), ex); } else if (ex instanceof SQLNonTransientConnectionException) { return new DataAccessResourceFailureException(buildMessage(task, sql, ex), ex); } else if (ex instanceof SQLSyntaxErrorException) { return new BadSqlGrammarException(task, sql, ex); } } else if (ex instanceof SQLRecoverableException) { return new RecoverableDataAccessException(buildMessage(task, sql, ex), ex); } // Fallback to Spring's own SQL state translation... return null; } } ././@LongLink0000000000000000000000000000020000000000000011555 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/JdbcAccessor.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001074311623223526033277 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support; import javax.sql.DataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.InitializingBean; /** * Base class for {@link org.springframework.jdbc.core.JdbcTemplate} and * other JDBC-accessing DAO helpers, defining common properties such as * DataSource and exception translator. * *

Not intended to be used directly. * See {@link org.springframework.jdbc.core.JdbcTemplate}. * * @author Juergen Hoeller * @since 28.11.2003 * @see org.springframework.jdbc.core.JdbcTemplate */ public abstract class JdbcAccessor implements InitializingBean { /** Logger available to subclasses */ protected final Log logger = LogFactory.getLog(getClass()); private DataSource dataSource; private SQLExceptionTranslator exceptionTranslator; private boolean lazyInit = true; /** * Set the JDBC DataSource to obtain connections from. */ public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } /** * Return the DataSource used by this template. */ public DataSource getDataSource() { return this.dataSource; } /** * Specify the database product name for the DataSource that this accessor uses. * This allows to initialize a SQLErrorCodeSQLExceptionTranslator without * obtaining a Connection from the DataSource to get the metadata. * @param dbName the database product name that identifies the error codes entry * @see SQLErrorCodeSQLExceptionTranslator#setDatabaseProductName * @see java.sql.DatabaseMetaData#getDatabaseProductName() */ public void setDatabaseProductName(String dbName) { this.exceptionTranslator = new SQLErrorCodeSQLExceptionTranslator(dbName); } /** * Set the exception translator for this instance. *

If no custom translator is provided, a default * {@link SQLErrorCodeSQLExceptionTranslator} is used * which examines the SQLException's vendor-specific error code. * @see org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator * @see org.springframework.jdbc.support.SQLStateSQLExceptionTranslator */ public void setExceptionTranslator(SQLExceptionTranslator exceptionTranslator) { this.exceptionTranslator = exceptionTranslator; } /** * Return the exception translator for this instance. *

Creates a default {@link SQLErrorCodeSQLExceptionTranslator} * for the specified DataSource if none set, or a * {@link SQLStateSQLExceptionTranslator} in case of no DataSource. * @see #getDataSource() */ public synchronized SQLExceptionTranslator getExceptionTranslator() { if (this.exceptionTranslator == null) { DataSource dataSource = getDataSource(); if (dataSource != null) { this.exceptionTranslator = new SQLErrorCodeSQLExceptionTranslator(dataSource); } else { this.exceptionTranslator = new SQLStateSQLExceptionTranslator(); } } return this.exceptionTranslator; } /** * Set whether to lazily initialize the SQLExceptionTranslator for this accessor, * on first encounter of a SQLException. Default is "true"; can be switched to * "false" for initialization on startup. *

Early initialization just applies if afterPropertiesSet() is called. * @see #getExceptionTranslator() * @see #afterPropertiesSet() */ public void setLazyInit(boolean lazyInit) { this.lazyInit = lazyInit; } /** * Return whether to lazily initialize the SQLExceptionTranslator for this accessor. * @see #getExceptionTranslator() */ public boolean isLazyInit() { return this.lazyInit; } /** * Eagerly initialize the exception translator, if demanded, * creating a default one for the specified DataSource if none set. */ public void afterPropertiesSet() { if (getDataSource() == null) { throw new IllegalArgumentException("Property 'dataSource' is required"); } if (!isLazyInit()) { getExceptionTranslator(); } } } ././@LongLink0000000000000000000000000000020600000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/GeneratedKeyHolder.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000641711623223526033302 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import org.springframework.dao.DataRetrievalFailureException; import org.springframework.dao.InvalidDataAccessApiUsageException; /** * Default implementation of the {@link KeyHolder} interface, to be used for * holding auto-generated keys (as potentially returned by JDBC insert statements). * *

Create an instance of this class for each insert operation, and pass * it to the corresponding {@link org.springframework.jdbc.core.JdbcTemplate} * or {org.springframework.jdbc.object.SqlUpdate} methods. * * @author Thomas Risberg * @author Juergen Hoeller * @since 1.1 */ public class GeneratedKeyHolder implements KeyHolder { private final List> keyList; /** * Create a new GeneratedKeyHolder with a default list. */ public GeneratedKeyHolder() { this.keyList = new LinkedList>(); } /** * Create a new GeneratedKeyHolder with a given list. * @param keyList a list to hold maps of keys */ public GeneratedKeyHolder(List> keyList) { this.keyList = keyList; } public Number getKey() throws InvalidDataAccessApiUsageException, DataRetrievalFailureException { if (this.keyList.size() == 0) { return null; } if (this.keyList.size() > 1 || this.keyList.get(0).size() > 1) { throw new InvalidDataAccessApiUsageException( "The getKey method should only be used when a single key is returned. " + "The current key entry contains multiple keys: " + this.keyList); } Iterator keyIter = this.keyList.get(0).values().iterator(); if (keyIter.hasNext()) { Object key = keyIter.next(); if (!(key instanceof Number)) { throw new DataRetrievalFailureException( "The generated key is not of a supported numeric type. " + "Unable to cast [" + (key != null ? key.getClass().getName() : null) + "] to [" + Number.class.getName() + "]"); } return (Number) key; } else { throw new DataRetrievalFailureException("Unable to retrieve the generated key. " + "Check that the table has an identity column enabled."); } } public Map getKeys() throws InvalidDataAccessApiUsageException { if (this.keyList.size() == 0) { return null; } if (this.keyList.size() > 1) throw new InvalidDataAccessApiUsageException( "The getKeys method should only be used when keys for a single row are returned. " + "The current key list contains keys for multiple rows: " + this.keyList); return this.keyList.get(0); } public List> getKeyList() { return this.keyList; } } ././@LongLink0000000000000000000000000000017400000000000011567 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/SqlValue.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000346011623223526033275 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support; import java.sql.PreparedStatement; import java.sql.SQLException; /** * Simple interface for complex types to be set as statement parameters. * *

Implementations perform the actual work of setting the actual values. They must * implement the callback method setValue which can throw SQLExceptions * that will be caught and translated by the calling code. This callback method has * access to the underlying Connection via the given PreparedStatement object, if that * should be needed to create any database-specific objects. * * @author Juergen Hoeller * @since 2.5.6 * @see org.springframework.jdbc.core.SqlTypeValue * @see org.springframework.jdbc.core.DisposableSqlTypeValue */ public interface SqlValue { /** * Set the value on the given PreparedStatement. * @param ps the PreparedStatement to work on * @param paramIndex the index of the parameter for which we need to set the value * @throws SQLException if a SQLException is encountered while setting parameter values */ void setValue(PreparedStatement ps, int paramIndex) throws SQLException; /** * Clean up resources held by this value object. */ void cleanup(); } ././@LongLink0000000000000000000000000000017500000000000011570 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/JdbcUtils.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000004061211623223530033270 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.math.BigDecimal; import java.sql.Blob; import java.sql.Clob; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; import java.sql.Types; import javax.sql.DataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.jdbc.CannotGetJdbcConnectionException; import org.springframework.jdbc.datasource.DataSourceUtils; /** * Generic utility methods for working with JDBC. Mainly for internal use * within the framework, but also useful for custom JDBC access code. * * @author Thomas Risberg * @author Juergen Hoeller */ public abstract class JdbcUtils { /** * Constant that indicates an unknown (or unspecified) SQL type. * @see java.sql.Types */ public static final int TYPE_UNKNOWN = Integer.MIN_VALUE; private static final Log logger = LogFactory.getLog(JdbcUtils.class); /** * Close the given JDBC Connection and ignore any thrown exception. * This is useful for typical finally blocks in manual JDBC code. * @param con the JDBC Connection to close (may be null) */ public static void closeConnection(Connection con) { if (con != null) { try { con.close(); } catch (SQLException ex) { logger.debug("Could not close JDBC Connection", ex); } catch (Throwable ex) { // We don't trust the JDBC driver: It might throw RuntimeException or Error. logger.debug("Unexpected exception on closing JDBC Connection", ex); } } } /** * Close the given JDBC Statement and ignore any thrown exception. * This is useful for typical finally blocks in manual JDBC code. * @param stmt the JDBC Statement to close (may be null) */ public static void closeStatement(Statement stmt) { if (stmt != null) { try { stmt.close(); } catch (SQLException ex) { logger.trace("Could not close JDBC Statement", ex); } catch (Throwable ex) { // We don't trust the JDBC driver: It might throw RuntimeException or Error. logger.trace("Unexpected exception on closing JDBC Statement", ex); } } } /** * Close the given JDBC ResultSet and ignore any thrown exception. * This is useful for typical finally blocks in manual JDBC code. * @param rs the JDBC ResultSet to close (may be null) */ public static void closeResultSet(ResultSet rs) { if (rs != null) { try { rs.close(); } catch (SQLException ex) { logger.trace("Could not close JDBC ResultSet", ex); } catch (Throwable ex) { // We don't trust the JDBC driver: It might throw RuntimeException or Error. logger.trace("Unexpected exception on closing JDBC ResultSet", ex); } } } /** * Retrieve a JDBC column value from a ResultSet, using the specified value type. *

Uses the specifically typed ResultSet accessor methods, falling back to * {@link #getResultSetValue(java.sql.ResultSet, int)} for unknown types. *

Note that the returned value may not be assignable to the specified * required type, in case of an unknown type. Calling code needs to deal * with this case appropriately, e.g. throwing a corresponding exception. * @param rs is the ResultSet holding the data * @param index is the column index * @param requiredType the required value type (may be null) * @return the value object * @throws SQLException if thrown by the JDBC API */ public static Object getResultSetValue(ResultSet rs, int index, Class requiredType) throws SQLException { if (requiredType == null) { return getResultSetValue(rs, index); } Object value = null; boolean wasNullCheck = false; // Explicitly extract typed value, as far as possible. if (String.class.equals(requiredType)) { value = rs.getString(index); } else if (boolean.class.equals(requiredType) || Boolean.class.equals(requiredType)) { value = rs.getBoolean(index); wasNullCheck = true; } else if (byte.class.equals(requiredType) || Byte.class.equals(requiredType)) { value = rs.getByte(index); wasNullCheck = true; } else if (short.class.equals(requiredType) || Short.class.equals(requiredType)) { value = rs.getShort(index); wasNullCheck = true; } else if (int.class.equals(requiredType) || Integer.class.equals(requiredType)) { value = rs.getInt(index); wasNullCheck = true; } else if (long.class.equals(requiredType) || Long.class.equals(requiredType)) { value = rs.getLong(index); wasNullCheck = true; } else if (float.class.equals(requiredType) || Float.class.equals(requiredType)) { value = rs.getFloat(index); wasNullCheck = true; } else if (double.class.equals(requiredType) || Double.class.equals(requiredType) || Number.class.equals(requiredType)) { value = rs.getDouble(index); wasNullCheck = true; } else if (byte[].class.equals(requiredType)) { value = rs.getBytes(index); } else if (java.sql.Date.class.equals(requiredType)) { value = rs.getDate(index); } else if (java.sql.Time.class.equals(requiredType)) { value = rs.getTime(index); } else if (java.sql.Timestamp.class.equals(requiredType) || java.util.Date.class.equals(requiredType)) { value = rs.getTimestamp(index); } else if (BigDecimal.class.equals(requiredType)) { value = rs.getBigDecimal(index); } else if (Blob.class.equals(requiredType)) { value = rs.getBlob(index); } else if (Clob.class.equals(requiredType)) { value = rs.getClob(index); } else { // Some unknown type desired -> rely on getObject. value = getResultSetValue(rs, index); } // Perform was-null check if demanded (for results that the // JDBC driver returns as primitives). if (wasNullCheck && value != null && rs.wasNull()) { value = null; } return value; } /** * Retrieve a JDBC column value from a ResultSet, using the most appropriate * value type. The returned value should be a detached value object, not having * any ties to the active ResultSet: in particular, it should not be a Blob or * Clob object but rather a byte array respectively String representation. *

Uses the getObject(index) method, but includes additional "hacks" * to get around Oracle 10g returning a non-standard object for its TIMESTAMP * datatype and a java.sql.Date for DATE columns leaving out the * time portion: These columns will explicitly be extracted as standard * java.sql.Timestamp object. * @param rs is the ResultSet holding the data * @param index is the column index * @return the value object * @throws SQLException if thrown by the JDBC API * @see java.sql.Blob * @see java.sql.Clob * @see java.sql.Timestamp */ public static Object getResultSetValue(ResultSet rs, int index) throws SQLException { Object obj = rs.getObject(index); String className = null; if (obj != null) { className = obj.getClass().getName(); } if (obj instanceof Blob) { obj = rs.getBytes(index); } else if (obj instanceof Clob) { obj = rs.getString(index); } else if (className != null && ("oracle.sql.TIMESTAMP".equals(className) || "oracle.sql.TIMESTAMPTZ".equals(className))) { obj = rs.getTimestamp(index); } else if (className != null && className.startsWith("oracle.sql.DATE")) { String metaDataClassName = rs.getMetaData().getColumnClassName(index); if ("java.sql.Timestamp".equals(metaDataClassName) || "oracle.sql.TIMESTAMP".equals(metaDataClassName)) { obj = rs.getTimestamp(index); } else { obj = rs.getDate(index); } } else if (obj != null && obj instanceof java.sql.Date) { if ("java.sql.Timestamp".equals(rs.getMetaData().getColumnClassName(index))) { obj = rs.getTimestamp(index); } } return obj; } /** * Extract database meta data via the given DatabaseMetaDataCallback. *

This method will open a connection to the database and retrieve the database metadata. * Since this method is called before the exception translation feature is configured for * a datasource, this method can not rely on the SQLException translation functionality. *

Any exceptions will be wrapped in a MetaDataAccessException. This is a checked exception * and any calling code should catch and handle this exception. You can just log the * error and hope for the best, but there is probably a more serious error that will * reappear when you try to access the database again. * @param dataSource the DataSource to extract metadata for * @param action callback that will do the actual work * @return object containing the extracted information, as returned by * the DatabaseMetaDataCallback's processMetaData method * @throws MetaDataAccessException if meta data access failed */ public static Object extractDatabaseMetaData(DataSource dataSource, DatabaseMetaDataCallback action) throws MetaDataAccessException { Connection con = null; try { con = DataSourceUtils.getConnection(dataSource); if (con == null) { // should only happen in test environments throw new MetaDataAccessException("Connection returned by DataSource [" + dataSource + "] was null"); } DatabaseMetaData metaData = con.getMetaData(); if (metaData == null) { // should only happen in test environments throw new MetaDataAccessException("DatabaseMetaData returned by Connection [" + con + "] was null"); } return action.processMetaData(metaData); } catch (CannotGetJdbcConnectionException ex) { throw new MetaDataAccessException("Could not get Connection for extracting meta data", ex); } catch (SQLException ex) { throw new MetaDataAccessException("Error while extracting DatabaseMetaData", ex); } catch (AbstractMethodError err) { throw new MetaDataAccessException( "JDBC DatabaseMetaData method not implemented by JDBC driver - upgrade your driver", err); } finally { DataSourceUtils.releaseConnection(con, dataSource); } } /** * Call the specified method on DatabaseMetaData for the given DataSource, * and extract the invocation result. * @param dataSource the DataSource to extract meta data for * @param metaDataMethodName the name of the DatabaseMetaData method to call * @return the object returned by the specified DatabaseMetaData method * @throws MetaDataAccessException if we couldn't access the DatabaseMetaData * or failed to invoke the specified method * @see java.sql.DatabaseMetaData */ public static Object extractDatabaseMetaData(DataSource dataSource, final String metaDataMethodName) throws MetaDataAccessException { return extractDatabaseMetaData(dataSource, new DatabaseMetaDataCallback() { public Object processMetaData(DatabaseMetaData dbmd) throws SQLException, MetaDataAccessException { try { Method method = DatabaseMetaData.class.getMethod(metaDataMethodName, (Class[]) null); return method.invoke(dbmd, (Object[]) null); } catch (NoSuchMethodException ex) { throw new MetaDataAccessException("No method named '" + metaDataMethodName + "' found on DatabaseMetaData instance [" + dbmd + "]", ex); } catch (IllegalAccessException ex) { throw new MetaDataAccessException( "Could not access DatabaseMetaData method '" + metaDataMethodName + "'", ex); } catch (InvocationTargetException ex) { if (ex.getTargetException() instanceof SQLException) { throw (SQLException) ex.getTargetException(); } throw new MetaDataAccessException( "Invocation of DatabaseMetaData method '" + metaDataMethodName + "' failed", ex); } } }); } /** * Return whether the given JDBC driver supports JDBC 2.0 batch updates. *

Typically invoked right before execution of a given set of statements: * to decide whether the set of SQL statements should be executed through * the JDBC 2.0 batch mechanism or simply in a traditional one-by-one fashion. *

Logs a warning if the "supportsBatchUpdates" methods throws an exception * and simply returns false in that case. * @param con the Connection to check * @return whether JDBC 2.0 batch updates are supported * @see java.sql.DatabaseMetaData#supportsBatchUpdates() */ public static boolean supportsBatchUpdates(Connection con) { try { DatabaseMetaData dbmd = con.getMetaData(); if (dbmd != null) { if (dbmd.supportsBatchUpdates()) { logger.debug("JDBC driver supports batch updates"); return true; } else { logger.debug("JDBC driver does not support batch updates"); } } } catch (SQLException ex) { logger.debug("JDBC driver 'supportsBatchUpdates' method threw exception", ex); } catch (AbstractMethodError err) { logger.debug("JDBC driver does not support JDBC 2.0 'supportsBatchUpdates' method", err); } return false; } /** * Extract a common name for the database in use even if various drivers/platforms provide varying names. * @param source the name as provided in database metedata * @return the common name to be used */ public static String commonDatabaseName(String source) { String name = source; if (source != null && source.startsWith("DB2")) { name = "DB2"; } else if ("Sybase SQL Server".equals(source) || "Adaptive Server Enterprise".equals(source) || "ASE".equals(source) || "sql server".equalsIgnoreCase(source) ) { name = "Sybase"; } return name; } /** * Check whether the given SQL type is numeric. * @param sqlType the SQL type to be checked * @return whether the type is numeric */ public static boolean isNumeric(int sqlType) { return Types.BIT == sqlType || Types.BIGINT == sqlType || Types.DECIMAL == sqlType || Types.DOUBLE == sqlType || Types.FLOAT == sqlType || Types.INTEGER == sqlType || Types.NUMERIC == sqlType || Types.REAL == sqlType || Types.SMALLINT == sqlType || Types.TINYINT == sqlType; } /** * Determine the column name to use. The column name is determined based on a * lookup using ResultSetMetaData. *

This method implementation takes into account recent clarifications * expressed in the JDBC 4.0 specification: *

columnLabel - the label for the column specified with the SQL AS clause. * If the SQL AS clause was not specified, then the label is the name of the column. * @return the column name to use * @param resultSetMetaData the current meta data to use * @param columnIndex the index of the column for the look up * @throws SQLException in case of lookup failure */ public static String lookupColumnName(ResultSetMetaData resultSetMetaData, int columnIndex) throws SQLException { String name = resultSetMetaData.getColumnLabel(columnIndex); if (name == null || name.length() < 1) { name = resultSetMetaData.getColumnName(columnIndex); } return name; } /** * Convert a column name with underscores to the corresponding property name using "camel case". A name * like "customer_number" would match a "customerNumber" property name. * @param name the column name to be converted * @return the name using "camel case" */ public static String convertUnderscoreNameToPropertyName(String name) { StringBuilder result = new StringBuilder(); boolean nextIsUpper = false; if (name != null && name.length() > 0) { if (name.length() > 1 && name.substring(1,2).equals("_")) { result.append(name.substring(0, 1).toUpperCase()); } else { result.append(name.substring(0, 1).toLowerCase()); } for (int i = 1; i < name.length(); i++) { String s = name.substring(i, i + 1); if (s.equals("_")) { nextIsUpper = true; } else { if (nextIsUpper) { result.append(s.toUpperCase()); nextIsUpper = false; } else { result.append(s.toLowerCase()); } } } } return result.toString(); } } ././@LongLink0000000000000000000000000000021300000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/MetaDataAccessException.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000275711623223530033300 0ustar drazzibdrazzib/* * Copyright 2002-2006 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support; import org.springframework.core.NestedCheckedException; /** * Exception indicating that something went wrong during JDBC metadata lookup. * *

This is a checked exception since we want it to be caught, logged and * handled rather than cause the application to fail. Failure to read JDBC * metadata is usually not a fatal problem. * * @author Thomas Risberg * @since 1.0.1 */ public class MetaDataAccessException extends NestedCheckedException { /** * Constructor for MetaDataAccessException. * @param msg the detail message */ public MetaDataAccessException(String msg) { super(msg); } /** * Constructor for MetaDataAccessException. * @param msg the detail message * @param cause the root cause from the data access API in use */ public MetaDataAccessException(String msg, Throwable cause) { super(msg, cause); } } ././@LongLink0000000000000000000000000000016600000000000011570 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/rowset/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000755000175000017500000000000011623223530033263 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000020700000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/rowset/package-info.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000030011623223526033263 0ustar drazzibdrazzib /** * * Provides a convenient holder for disconnected result sets. * Supported by JdbcTemplate, but can be used independently too. * */ package org.springframework.jdbc.support.rowset; ././@LongLink0000000000000000000000000000020400000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/rowset/SqlRowSet.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000004214711623223530033275 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.rowset; import java.io.Serializable; import java.math.BigDecimal; import java.sql.Date; import java.sql.Time; import java.sql.Timestamp; import java.util.Calendar; import java.util.Map; import org.springframework.jdbc.InvalidResultSetAccessException; /** * Mirror interface for javax.sql.RowSet, representing * disconnected java.sql.ResultSet data. * *

The main difference to the standard JDBC RowSet is that an SQLException * is never thrown here. This allows a SqlRowSet to be used without having * to deal with checked exceptions. A SqlRowSet will throw Spring's * org.springframework.jdbc.InvalidResultSetAccessException * instead (when appropriate). * *

Note: This interface extends the java.io.Serializable * marker interface. Implementations, which typically hold disconnected data, * are encouraged to be actually serializable (as far as possible). * * @author Thomas Risberg * @author Juergen Hoeller * @since 1.2 * @see javax.sql.RowSet * @see java.sql.ResultSet * @see org.springframework.jdbc.InvalidResultSetAccessException * @see org.springframework.jdbc.core.JdbcTemplate#queryForRowSet */ public interface SqlRowSet extends Serializable { /** * Retrieves the meta data (number, types and properties for the columns) * of this row set. * @return a corresponding SqlRowSetMetaData instance * @see java.sql.ResultSet#getMetaData() */ SqlRowSetMetaData getMetaData(); /** * Maps the given column label to its column index. * @param columnLabel the name of the column * @return the column index for the given column label * @see java.sql.ResultSet#findColumn(String) */ int findColumn(String columnLabel) throws InvalidResultSetAccessException; // RowSet methods for extracting data values /** * Retrieves the value of the indicated column in the current row as * an BigDecimal object. * @param columnIndex the column index * @return an BigDecimal object representing the column value * @see java.sql.ResultSet#getBigDecimal(int) */ BigDecimal getBigDecimal(int columnIndex) throws InvalidResultSetAccessException; /** * Retrieves the value of the indicated column in the current row as * an BigDecimal object. * @param columnLabel the column label * @return an BigDecimal object representing the column value * @see java.sql.ResultSet#getBigDecimal(java.lang.String) */ BigDecimal getBigDecimal(String columnLabel) throws InvalidResultSetAccessException; /** * Retrieves the value of the indicated column in the current row as * a boolean. * @param columnIndex the column index * @return a boolean representing the column value * @see java.sql.ResultSet#getBoolean(int) */ boolean getBoolean(int columnIndex) throws InvalidResultSetAccessException; /** * Retrieves the value of the indicated column in the current row as * a boolean. * @param columnLabel the column label * @return a boolean representing the column value * @see java.sql.ResultSet#getBoolean(java.lang.String) */ boolean getBoolean(String columnLabel) throws InvalidResultSetAccessException; /** * Retrieves the value of the indicated column in the current row as * a byte. * @param columnIndex the column index * @return a byte representing the column value * @see java.sql.ResultSet#getByte(int) */ byte getByte(int columnIndex) throws InvalidResultSetAccessException; /** * Retrieves the value of the indicated column in the current row as * a byte. * @param columnLabel the column label * @return a byte representing the column value * @see java.sql.ResultSet#getByte(java.lang.String) */ byte getByte(String columnLabel) throws InvalidResultSetAccessException; /** * Retrieves the value of the indicated column in the current row as * a Date object. * @param columnIndex the column index * @param cal the Calendar to use in constructing the Date * @return a Date object representing the column value * @see java.sql.ResultSet#getDate(int, java.util.Calendar) */ Date getDate(int columnIndex, Calendar cal) throws InvalidResultSetAccessException; /** * Retrieves the value of the indicated column in the current row as * a Date object. * @param columnIndex the column index * @return a Date object representing the column value * @see java.sql.ResultSet#getDate(int) */ Date getDate(int columnIndex) throws InvalidResultSetAccessException; /** * Retrieves the value of the indicated column in the current row as * a Date object. * @param columnLabel the column label * @param cal the Calendar to use in constructing the Date * @return a Date object representing the column value * @see java.sql.ResultSet#getDate(java.lang.String, java.util.Calendar) */ Date getDate(String columnLabel, Calendar cal) throws InvalidResultSetAccessException; /** * Retrieves the value of the indicated column in the current row as * a Date object. * @param columnLabel the column label * @return a Date object representing the column value * @see java.sql.ResultSet#getDate(java.lang.String) */ Date getDate(String columnLabel) throws InvalidResultSetAccessException; /** * Retrieves the value of the indicated column in the current row as * a Double object. * @param columnIndex the column index * @return a Double object representing the column value * @see java.sql.ResultSet#getDouble(int) */ double getDouble(int columnIndex) throws InvalidResultSetAccessException; /** * Retrieves the value of the indicated column in the current row as * a Double object. * @param columnLabel the column label * @return a Double object representing the column value * @see java.sql.ResultSet#getDouble(java.lang.String) */ double getDouble(String columnLabel) throws InvalidResultSetAccessException; /** * Retrieves the value of the indicated column in the current row as * a float. * @param columnIndex the column index * @return a float representing the column value * @see java.sql.ResultSet#getFloat(int) */ float getFloat(int columnIndex) throws InvalidResultSetAccessException; /** * Retrieves the value of the indicated column in the current row as * a float. * @param columnLabel the column label * @return a float representing the column value * @see java.sql.ResultSet#getFloat(java.lang.String) */ float getFloat(String columnLabel) throws InvalidResultSetAccessException; /** * Retrieves the value of the indicated column in the current row as * an int. * @param columnIndex the column index * @return an int representing the column value * @see java.sql.ResultSet#getInt(int) */ int getInt(int columnIndex) throws InvalidResultSetAccessException; /** * Retrieves the value of the indicated column in the current row as * an int. * @param columnLabel the column label * @return an int representing the column value * @see java.sql.ResultSet#getInt(java.lang.String) */ int getInt(String columnLabel) throws InvalidResultSetAccessException; /** * Retrieves the value of the indicated column in the current row as * a long. * @param columnIndex the column index * @return a long representing the column value * @see java.sql.ResultSet#getLong(int) */ long getLong(int columnIndex) throws InvalidResultSetAccessException; /** * Retrieves the value of the indicated column in the current row as * a long. * @param columnLabel the column label * @return a long representing the column value * @see java.sql.ResultSet#getLong(java.lang.String) */ long getLong(String columnLabel) throws InvalidResultSetAccessException; /** * Retrieves the value of the indicated column in the current row as * an Object. * @param columnIndex the column index * @param map a Map object containing the mapping from SQL types to Java types * @return a Object representing the column value * @see java.sql.ResultSet#getObject(int, java.util.Map) */ Object getObject(int columnIndex, Map> map) throws InvalidResultSetAccessException; /** * Retrieves the value of the indicated column in the current row as * an Object. * @param columnIndex the column index * @return a Object representing the column value * @see java.sql.ResultSet#getObject(int) */ Object getObject(int columnIndex) throws InvalidResultSetAccessException; /** * Retrieves the value of the indicated column in the current row as * an Object. * @param columnLabel the column label * @param map a Map object containing the mapping from SQL types to Java types * @return a Object representing the column value * @see java.sql.ResultSet#getObject(java.lang.String, java.util.Map) */ Object getObject(String columnLabel, Map> map) throws InvalidResultSetAccessException; /** * Retrieves the value of the indicated column in the current row as * an Object. * @param columnLabel the column label * @return a Object representing the column value * @see java.sql.ResultSet#getObject(java.lang.String) */ Object getObject(String columnLabel) throws InvalidResultSetAccessException; /** * Retrieves the value of the indicated column in the current row as * a short. * @param columnIndex the column index * @return a short representing the column value * @see java.sql.ResultSet#getShort(int) */ short getShort(int columnIndex) throws InvalidResultSetAccessException; /** * Retrieves the value of the indicated column in the current row as * a short. * @param columnLabel the column label * @return a short representing the column value * @see java.sql.ResultSet#getShort(java.lang.String) */ short getShort(String columnLabel) throws InvalidResultSetAccessException; /** * Retrieves the value of the indicated column in the current row as * a String. * @param columnIndex the column index * @return a String representing the column value * @see java.sql.ResultSet#getString(int) */ String getString(int columnIndex) throws InvalidResultSetAccessException; /** * Retrieves the value of the indicated column in the current row as * a String. * @param columnLabel the column label * @return a String representing the column value * @see java.sql.ResultSet#getString(java.lang.String) */ String getString(String columnLabel) throws InvalidResultSetAccessException; /** * Retrieves the value of the indicated column in the current row as * a Time object. * @param columnIndex the column index * @param cal the Calendar to use in constructing the Date * @return a Time object representing the column value * @see java.sql.ResultSet#getTime(int, java.util.Calendar) */ Time getTime(int columnIndex, Calendar cal) throws InvalidResultSetAccessException; /** * Retrieves the value of the indicated column in the current row as * a Time object. * @param columnIndex the column index * @return a Time object representing the column value * @see java.sql.ResultSet#getTime(int) */ Time getTime(int columnIndex) throws InvalidResultSetAccessException; /** * Retrieves the value of the indicated column in the current row as * a Time object. * @param columnLabel the column label * @param cal the Calendar to use in constructing the Date * @return a Time object representing the column value * @see java.sql.ResultSet#getTime(java.lang.String, java.util.Calendar) */ Time getTime(String columnLabel, Calendar cal) throws InvalidResultSetAccessException; /** * Retrieves the value of the indicated column in the current row as * a Time object. * @param columnLabel the column label * @return a Time object representing the column value * @see java.sql.ResultSet#getTime(java.lang.String) */ Time getTime(String columnLabel) throws InvalidResultSetAccessException; /** * Retrieves the value of the indicated column in the current row as * a Timestamp object. * @param columnIndex the column index * @param cal the Calendar to use in constructing the Date * @return a Timestamp object representing the column value * @see java.sql.ResultSet#getTimestamp(int, java.util.Calendar) */ Timestamp getTimestamp(int columnIndex, Calendar cal) throws InvalidResultSetAccessException; /** * Retrieves the value of the indicated column in the current row as * a Timestamp object. * @param columnIndex the column index * @return a Timestamp object representing the column value * @see java.sql.ResultSet#getTimestamp(int) */ Timestamp getTimestamp(int columnIndex) throws InvalidResultSetAccessException; /** * Retrieves the value of the indicated column in the current row as * a Timestamp object. * @param columnLabel the column label * @param cal the Calendar to use in constructing the Date * @return a Timestamp object representing the column value * @see java.sql.ResultSet#getTimestamp(java.lang.String, java.util.Calendar) */ Timestamp getTimestamp(String columnLabel, Calendar cal) throws InvalidResultSetAccessException; /** * Retrieves the value of the indicated column in the current row as * a Timestamp object. * @param columnLabel the column label * @return a Timestamp object representing the column value * @see java.sql.ResultSet#getTimestamp(java.lang.String) */ Timestamp getTimestamp(String columnLabel) throws InvalidResultSetAccessException; // RowSet navigation methods /** * Moves the cursor to the given row number in the RowSet, just after the last row. * @param row the number of the row where the cursor should move * @return true if the cursor is on the RowSet, false otherwise * @see java.sql.ResultSet#absolute(int) */ boolean absolute(int row) throws InvalidResultSetAccessException; /** * Moves the cursor to the end of this RowSet. * @see java.sql.ResultSet#afterLast() */ void afterLast() throws InvalidResultSetAccessException; /** * Moves the cursor to the front of this RowSet, just before the first row. * @see java.sql.ResultSet#beforeFirst() */ void beforeFirst() throws InvalidResultSetAccessException; /** * Moves the cursor to the first row of this RowSet. * @return true if the cursor is on a valid row, false otherwise * @see java.sql.ResultSet#first() */ boolean first() throws InvalidResultSetAccessException; /** * Retrieves the current row number. * @return the current row number * @see java.sql.ResultSet#getRow() */ int getRow() throws InvalidResultSetAccessException; /** * Retrieves whether the cursor is after the last row of this RowSet. * @return true if the cursor is after the last row, false otherwise * @see java.sql.ResultSet#isAfterLast() */ boolean isAfterLast() throws InvalidResultSetAccessException; /** * Retrieves whether the cursor is after the first row of this RowSet. * @return true if the cursor is after the first row, false otherwise * @see java.sql.ResultSet#isBeforeFirst() */ boolean isBeforeFirst() throws InvalidResultSetAccessException; /** * Retrieves whether the cursor is on the first row of this RowSet. * @return true if the cursor is after the first row, false otherwise * @see java.sql.ResultSet#isFirst() */ boolean isFirst() throws InvalidResultSetAccessException; /** * Retrieves whether the cursor is on the last row of this RowSet. * @return true if the cursor is after the last row, false otherwise * @see java.sql.ResultSet#isLast() */ boolean isLast() throws InvalidResultSetAccessException; /** * Moves the cursor to the last row of this RowSet. * @return true if the cursor is on a valid row, false otherwise * @see java.sql.ResultSet#last() */ boolean last() throws InvalidResultSetAccessException; /** * Moves the cursor to the next row. * @return true if the new row is valid, false if there are no more rows * @see java.sql.ResultSet#next() */ boolean next() throws InvalidResultSetAccessException; /** * Moves the cursor to the previous row. * @return true if the new row is valid, false if it is off the RowSet * @see java.sql.ResultSet#previous() */ boolean previous() throws InvalidResultSetAccessException; /** * Moves the cursor a relative number f rows, either positive or negative. * @return true if the cursor is on a row, false otherwise * @see java.sql.ResultSet#relative(int) */ boolean relative(int rows) throws InvalidResultSetAccessException; /** * Reports whether the last column read had a value of SQL NULL. * Note that you must first call one of the getter methods and then call * the wasNull method. * @return true if the most recent coumn retrieved was SQL NULL, * false otherwise * @see java.sql.ResultSet#wasNull() */ boolean wasNull() throws InvalidResultSetAccessException; } ././@LongLink0000000000000000000000000000021400000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/rowset/SqlRowSetMetaData.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001361111623223530033267 0ustar drazzibdrazzib/* * Copyright 2002-2005 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.rowset; import org.springframework.jdbc.InvalidResultSetAccessException; /** * Meta data interface for Spring's SqlRowSet, * analogous to javax.sql.ResultSetMetaData * *

The main difference to the standard JDBC RowSetMetaData is that an SQLException * is never thrown here. This allows a SqlRowSetMetaData to be used without having * to deal with checked exceptions. A SqlRowSetMetaData will throw Spring's * org.springframework.jdbc.InvalidResultSetAccessException * instead (when appropriate). * * @author Thomas Risberg * @since 1.2 * @see SqlRowSet#getMetaData * @see java.sql.ResultSetMetaData * @see org.springframework.jdbc.InvalidResultSetAccessException */ public interface SqlRowSetMetaData { /** * Retrieves the catalog name of the table that served as the source for the specified column. * @param columnIndex the index of the column * @return the catalog name * @see java.sql.ResultSetMetaData#getCatalogName(int) */ String getCatalogName(int columnIndex) throws InvalidResultSetAccessException; /** * Retrieves the fully qualified class that the specified column will be mapped to. * @param columnIndex the index of the column * @return the class name as a String * @see java.sql.ResultSetMetaData#getColumnClassName(int) */ String getColumnClassName(int columnIndex) throws InvalidResultSetAccessException; /** * Retrives the number of columns in the RowSet. * @return the number of columns * @see java.sql.ResultSetMetaData#getColumnCount() */ int getColumnCount() throws InvalidResultSetAccessException; /** * Return the column names of the table that the result set represents. * @return the column names */ String[] getColumnNames() throws InvalidResultSetAccessException; /** * Retrieves the maximum width of the designated column. * @param columnIndex the index of the column * @return the width of the column * @see java.sql.ResultSetMetaData#getColumnDisplaySize(int) */ int getColumnDisplaySize(int columnIndex) throws InvalidResultSetAccessException; /** * Retrieve the suggested column title for the column specified. * @param columnIndex the index of the column * @return the column title * @see java.sql.ResultSetMetaData#getColumnLabel(int) */ String getColumnLabel(int columnIndex) throws InvalidResultSetAccessException; /** * Retrieve the column name for the indicated column. * @param columnIndex the index of the column * @return the column name * @see java.sql.ResultSetMetaData#getColumnName(int) */ String getColumnName(int columnIndex) throws InvalidResultSetAccessException; /** * Retrieve the SQL type code for the indicated column. * @param columnIndex the index of the column * @return the SQL type code * @see java.sql.ResultSetMetaData#getColumnType(int) * @see java.sql.Types */ int getColumnType(int columnIndex) throws InvalidResultSetAccessException; /** * Retrieves the DBMS-specific type name for the indicated column. * @param columnIndex the index of the column * @return the type name * @see java.sql.ResultSetMetaData#getColumnTypeName(int) */ String getColumnTypeName(int columnIndex) throws InvalidResultSetAccessException; /** * Retrieves the precision for the indicated column. * @param columnIndex the index of the column * @return the precision * @see java.sql.ResultSetMetaData#getPrecision(int) */ int getPrecision(int columnIndex) throws InvalidResultSetAccessException; /** * Retrieves the scale of the indicated column. * @param columnIndex the index of the column * @return the scale * @see java.sql.ResultSetMetaData#getScale(int) */ int getScale(int columnIndex) throws InvalidResultSetAccessException; /** * Retrieves the schema name of the table that served as the source for the specified column. * @param columnIndex the index of the column * @return the schema name * @see java.sql.ResultSetMetaData#getSchemaName(int) */ String getSchemaName(int columnIndex) throws InvalidResultSetAccessException; /** * Retrieves the name of the table that served as the source for the specified column. * @param columnIndex the index of the column * @return the name of the table * @see java.sql.ResultSetMetaData#getTableName(int) */ String getTableName(int columnIndex) throws InvalidResultSetAccessException; /** * Indicates whether the case of the designated column is significant. * @param columnIndex the index of the column * @return true if the case sensitive, false otherwise * @see java.sql.ResultSetMetaData#isCaseSensitive(int) */ boolean isCaseSensitive(int columnIndex) throws InvalidResultSetAccessException; /** * Indicates whether the designated column contains a currency value. * @param columnIndex the index of the column * @return true if the value is a currency value, false otherwise * @see java.sql.ResultSetMetaData#isCurrency(int) */ boolean isCurrency(int columnIndex) throws InvalidResultSetAccessException; /** * Indicates whether the designated column contains a signed number. * @param columnIndex the index of the column * @return true if the column contains a signed number, false otherwise * @see java.sql.ResultSetMetaData#isSigned(int) */ boolean isSigned(int columnIndex) throws InvalidResultSetAccessException; } ././@LongLink0000000000000000000000000000022500000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/rowset/ResultSetWrappingSqlRowSet.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000004146611623223530033300 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.rowset; import java.math.BigDecimal; import java.sql.Date; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Time; import java.sql.Timestamp; import java.util.Calendar; import java.util.Collections; import java.util.HashMap; import java.util.Map; import org.springframework.jdbc.InvalidResultSetAccessException; /** * Default implementation of Spring's {@link SqlRowSet} interface. * *

This implementation wraps a javax.sql.ResultSet, catching any SQLExceptions * and translating them to the appropriate Spring {@link InvalidResultSetAccessException}. * *

The passed-in ResultSets should already be disconnected if the SqlRowSet is supposed * to be usable in a disconnected fashion. This means that you will usually pass in a * javax.sql.rowset.CachedRowSet, which implements the ResultSet interface. * *

Note: Since JDBC 4.0, it has been clarified that any methods using a String to identify * the column should be using the column label. The column label is assigned using the ALIAS * keyword in the SQL query string. When the query doesn't use an ALIAS, the default label is * the column name. Most JDBC ResultSet implementations follow this new pattern but there are * exceptions such as the com.sun.rowset.CachedRowSetImpl class which only uses * the column name, ignoring any column labels. As of Spring 3.0.5, ResultSetWrappingSqlRowSet * will translate column labels to the correct column index to provide better support for the * com.sun.rowset.CachedRowSetImpl which is the default implementation used by * {@link org.springframework.jdbc.core.JdbcTemplate} when working with RowSets. * *

Note: This class implements the java.io.Serializable marker interface * through the SqlRowSet interface, but is only actually serializable if the disconnected * ResultSet/RowSet contained in it is serializable. Most CachedRowSet implementations * are actually serializable, so this should usually work out. * * @author Thomas Risberg * @author Juergen Hoeller * @since 1.2 * @see java.sql.ResultSet * @see javax.sql.rowset.CachedRowSet * @see org.springframework.jdbc.core.JdbcTemplate#queryForRowSet */ public class ResultSetWrappingSqlRowSet implements SqlRowSet { /** use serialVersionUID from Spring 1.2 for interoperability */ private static final long serialVersionUID = -4688694393146734764L; private final ResultSet resultSet; private final SqlRowSetMetaData rowSetMetaData; private final Map columnLabelMap; /** * Create a new ResultSetWrappingSqlRowSet for the given ResultSet. * @param resultSet a disconnected ResultSet to wrap * (usually a javax.sql.rowset.CachedRowSet) * @throws InvalidResultSetAccessException if extracting * the ResultSetMetaData failed * @see javax.sql.rowset.CachedRowSet * @see java.sql.ResultSet#getMetaData * @see ResultSetWrappingSqlRowSetMetaData */ public ResultSetWrappingSqlRowSet(ResultSet resultSet) throws InvalidResultSetAccessException { this.resultSet = resultSet; try { this.rowSetMetaData = new ResultSetWrappingSqlRowSetMetaData(resultSet.getMetaData()); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } try { ResultSetMetaData rsmd = resultSet.getMetaData(); if (rsmd != null) { int columnCount = rsmd.getColumnCount(); this.columnLabelMap = new HashMap(columnCount); for (int i = 1; i <= columnCount; i++) { this.columnLabelMap.put(rsmd.getColumnLabel(i), i); } } else { this.columnLabelMap = Collections.emptyMap(); } } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } /** * Return the underlying ResultSet * (usually a javax.sql.rowset.CachedRowSet). * @see javax.sql.rowset.CachedRowSet */ public final ResultSet getResultSet() { return this.resultSet; } /** * @see java.sql.ResultSetMetaData#getCatalogName(int) */ public final SqlRowSetMetaData getMetaData() { return this.rowSetMetaData; } /** * @see java.sql.ResultSet#findColumn(String) */ public int findColumn(String columnLabel) throws InvalidResultSetAccessException { Integer columnIndex = this.columnLabelMap.get(columnLabel); if (columnIndex != null) { return columnIndex; } else { try { return this.resultSet.findColumn(columnLabel); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } } // RowSet methods for extracting data values /** * @see java.sql.ResultSet#getBigDecimal(int) */ public BigDecimal getBigDecimal(int columnIndex) throws InvalidResultSetAccessException { try { return this.resultSet.getBigDecimal(columnIndex); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } /** * @see java.sql.ResultSet#getBigDecimal(String) */ public BigDecimal getBigDecimal(String columnLabel) throws InvalidResultSetAccessException { return getBigDecimal(findColumn(columnLabel)); } /** * @see java.sql.ResultSet#getBoolean(int) */ public boolean getBoolean(int columnIndex) throws InvalidResultSetAccessException { try { return this.resultSet.getBoolean(columnIndex); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } /** * @see java.sql.ResultSet#getBoolean(String) */ public boolean getBoolean(String columnLabel) throws InvalidResultSetAccessException { return getBoolean(findColumn(columnLabel)); } /** * @see java.sql.ResultSet#getByte(int) */ public byte getByte(int columnIndex) throws InvalidResultSetAccessException { try { return this.resultSet.getByte(columnIndex); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } /** * @see java.sql.ResultSet#getByte(String) */ public byte getByte(String columnLabel) throws InvalidResultSetAccessException { return getByte(findColumn(columnLabel)); } /** * @see java.sql.ResultSet#getDate(int, java.util.Calendar) */ public Date getDate(int columnIndex, Calendar cal) throws InvalidResultSetAccessException { try { return this.resultSet.getDate(columnIndex, cal); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } /** * @see java.sql.ResultSet#getDate(int) */ public Date getDate(int columnIndex) throws InvalidResultSetAccessException { try { return this.resultSet.getDate(columnIndex); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } /** * @see java.sql.ResultSet#getDate(String, java.util.Calendar) */ public Date getDate(String columnLabel, Calendar cal) throws InvalidResultSetAccessException { return getDate(findColumn(columnLabel), cal); } /** * @see java.sql.ResultSet#getDate(String) */ public Date getDate(String columnLabel) throws InvalidResultSetAccessException { return getDate(findColumn(columnLabel)); } /** * @see java.sql.ResultSet#getDouble(int) */ public double getDouble(int columnIndex) throws InvalidResultSetAccessException { try { return this.resultSet.getDouble(columnIndex); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } /** * @see java.sql.ResultSet#getDouble(String) */ public double getDouble(String columnLabel) throws InvalidResultSetAccessException { return getDouble(findColumn(columnLabel)); } /** * @see java.sql.ResultSet#getFloat(int) */ public float getFloat(int columnIndex) throws InvalidResultSetAccessException { try { return this.resultSet.getFloat(columnIndex); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } /** * @see java.sql.ResultSet#getFloat(String) */ public float getFloat(String columnLabel) throws InvalidResultSetAccessException { return getFloat(findColumn(columnLabel)); } /** * @see java.sql.ResultSet#getInt(int) */ public int getInt(int columnIndex) throws InvalidResultSetAccessException { try { return this.resultSet.getInt(columnIndex); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } /** * @see java.sql.ResultSet#getInt(String) */ public int getInt(String columnLabel) throws InvalidResultSetAccessException { return getInt(findColumn(columnLabel)); } /** * @see java.sql.ResultSet#getLong(int) */ public long getLong(int columnIndex) throws InvalidResultSetAccessException { try { return this.resultSet.getLong(columnIndex); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } /** * @see java.sql.ResultSet#getLong(String) */ public long getLong(String columnLabel) throws InvalidResultSetAccessException { return getLong(findColumn(columnLabel)); } /** * @see java.sql.ResultSet#getObject(int, java.util.Map) */ public Object getObject(int i, Map> map) throws InvalidResultSetAccessException { try { return this.resultSet.getObject(i, map); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } /** * @see java.sql.ResultSet#getObject(int) */ public Object getObject(int columnIndex) throws InvalidResultSetAccessException { try { return this.resultSet.getObject(columnIndex); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } /** * @see java.sql.ResultSet#getObject(String, java.util.Map) */ public Object getObject(String columnLabel, Map> map) throws InvalidResultSetAccessException { return getObject(findColumn(columnLabel), map); } /** * @see java.sql.ResultSet#getObject(String) */ public Object getObject(String columnLabel) throws InvalidResultSetAccessException { return getObject(findColumn(columnLabel)); } /** * @see java.sql.ResultSet#getShort(int) */ public short getShort(int columnIndex) throws InvalidResultSetAccessException { try { return this.resultSet.getShort(columnIndex); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } /** * @see java.sql.ResultSet#getShort(String) */ public short getShort(String columnLabel) throws InvalidResultSetAccessException { return getShort(findColumn(columnLabel)); } /** * @see java.sql.ResultSet#getString(int) */ public String getString(int columnIndex) throws InvalidResultSetAccessException { try { return this.resultSet.getString(columnIndex); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } /** * @see java.sql.ResultSet#getString(String) */ public String getString(String columnLabel) throws InvalidResultSetAccessException { return getString(findColumn(columnLabel)); } /** * @see java.sql.ResultSet#getTime(int, java.util.Calendar) */ public Time getTime(int columnIndex, Calendar cal) throws InvalidResultSetAccessException { try { return this.resultSet.getTime(columnIndex, cal); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } /** * @see java.sql.ResultSet#getTime(int) */ public Time getTime(int columnIndex) throws InvalidResultSetAccessException { try { return this.resultSet.getTime(columnIndex); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } /** * @see java.sql.ResultSet#getTime(String, java.util.Calendar) */ public Time getTime(String columnLabel, Calendar cal) throws InvalidResultSetAccessException { return getTime(findColumn(columnLabel), cal); } /** * @see java.sql.ResultSet#getTime(String) */ public Time getTime(String columnLabel) throws InvalidResultSetAccessException { return getTime(findColumn(columnLabel)); } /** * @see java.sql.ResultSet#getTimestamp(int, java.util.Calendar) */ public Timestamp getTimestamp(int columnIndex, Calendar cal) throws InvalidResultSetAccessException { try { return this.resultSet.getTimestamp(columnIndex, cal); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } /** * @see java.sql.ResultSet#getTimestamp(int) */ public Timestamp getTimestamp(int columnIndex) throws InvalidResultSetAccessException { try { return this.resultSet.getTimestamp(columnIndex); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } /** * @see java.sql.ResultSet#getTimestamp(String, java.util.Calendar) */ public Timestamp getTimestamp(String columnLabel, Calendar cal) throws InvalidResultSetAccessException { return getTimestamp(findColumn(columnLabel), cal); } /** * @see java.sql.ResultSet#getTimestamp(String) */ public Timestamp getTimestamp(String columnLabel) throws InvalidResultSetAccessException { return getTimestamp(findColumn(columnLabel)); } // RowSet navigation methods /** * @see java.sql.ResultSet#absolute(int) */ public boolean absolute(int row) throws InvalidResultSetAccessException { try { return this.resultSet.absolute(row); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } /** * @see java.sql.ResultSet#afterLast() */ public void afterLast() throws InvalidResultSetAccessException { try { this.resultSet.afterLast(); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } /** * @see java.sql.ResultSet#beforeFirst() */ public void beforeFirst() throws InvalidResultSetAccessException { try { this.resultSet.beforeFirst(); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } /** * @see java.sql.ResultSet#first() */ public boolean first() throws InvalidResultSetAccessException { try { return this.resultSet.first(); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } /** * @see java.sql.ResultSet#getRow() */ public int getRow() throws InvalidResultSetAccessException { try { return this.resultSet.getRow(); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } /** * @see java.sql.ResultSet#isAfterLast() */ public boolean isAfterLast() throws InvalidResultSetAccessException { try { return this.resultSet.isAfterLast(); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } /** * @see java.sql.ResultSet#isBeforeFirst() */ public boolean isBeforeFirst() throws InvalidResultSetAccessException { try { return this.resultSet.isBeforeFirst(); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } /** * @see java.sql.ResultSet#isFirst() */ public boolean isFirst() throws InvalidResultSetAccessException { try { return this.resultSet.isFirst(); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } /** * @see java.sql.ResultSet#isLast() */ public boolean isLast() throws InvalidResultSetAccessException { try { return this.resultSet.isLast(); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } /** * @see java.sql.ResultSet#last() */ public boolean last() throws InvalidResultSetAccessException { try { return this.resultSet.last(); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } /** * @see java.sql.ResultSet#next() */ public boolean next() throws InvalidResultSetAccessException { try { return this.resultSet.next(); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } /** * @see java.sql.ResultSet#previous() */ public boolean previous() throws InvalidResultSetAccessException { try { return this.resultSet.previous(); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } /** * @see java.sql.ResultSet#relative(int) */ public boolean relative(int rows) throws InvalidResultSetAccessException { try { return this.resultSet.relative(rows); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } /** * @see java.sql.ResultSet#wasNull() */ public boolean wasNull() throws InvalidResultSetAccessException { try { return this.resultSet.wasNull(); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } } ././@LongLink0000000000000000000000000000023500000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/rowset/ResultSetWrappingSqlRowSetMetaData.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001313711623223530033272 0ustar drazzibdrazzib/* * Copyright 2002-2005 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.rowset; import java.sql.ResultSetMetaData; import java.sql.SQLException; import org.springframework.jdbc.InvalidResultSetAccessException; /** * Default implementation of Spring's SqlRowSetMetaData interface. * Used by ResultSetWrappingSqlRowSet. * *

This implementation wraps a javax.sql.ResultSetMetaData * instance, catching any SQLExceptions and translating them to the * appropriate Spring DataAccessException. * * @author Thomas Risberg * @author Juergen Hoeller * @since 1.2 * @see ResultSetWrappingSqlRowSet#getMetaData */ public class ResultSetWrappingSqlRowSetMetaData implements SqlRowSetMetaData { private final ResultSetMetaData resultSetMetaData; private String[] columnNames; /** * Create a new ResultSetWrappingSqlRowSetMetaData object * for the given ResultSetMetaData instance. * @param resultSetMetaData a disconnected ResultSetMetaData instance * to wrap (usually a javax.sql.RowSetMetaData instance) * @see java.sql.ResultSet#getMetaData * @see javax.sql.RowSetMetaData * @see ResultSetWrappingSqlRowSet#getMetaData */ public ResultSetWrappingSqlRowSetMetaData(ResultSetMetaData resultSetMetaData) { this.resultSetMetaData = resultSetMetaData; } public String getCatalogName(int column) throws InvalidResultSetAccessException { try { return this.resultSetMetaData.getCatalogName(column); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } public String getColumnClassName(int column) throws InvalidResultSetAccessException { try { return this.resultSetMetaData.getColumnClassName(column); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } public int getColumnCount() throws InvalidResultSetAccessException { try { return this.resultSetMetaData.getColumnCount(); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } public String[] getColumnNames() throws InvalidResultSetAccessException { if (this.columnNames == null) { this.columnNames = new String[getColumnCount()]; for (int i = 0; i < getColumnCount(); i++) { this.columnNames[i] = getColumnName(i + 1); } } return this.columnNames; } public int getColumnDisplaySize(int column) throws InvalidResultSetAccessException { try { return this.resultSetMetaData.getColumnDisplaySize(column); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } public String getColumnLabel(int column) throws InvalidResultSetAccessException { try { return this.resultSetMetaData.getColumnLabel(column); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } public String getColumnName(int column) throws InvalidResultSetAccessException { try { return this.resultSetMetaData.getColumnName(column); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } public int getColumnType(int column) throws InvalidResultSetAccessException { try { return this.resultSetMetaData.getColumnType(column); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } public String getColumnTypeName(int column) throws InvalidResultSetAccessException { try { return this.resultSetMetaData.getColumnTypeName(column); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } public int getPrecision(int column) throws InvalidResultSetAccessException { try { return this.resultSetMetaData.getPrecision(column); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } public int getScale(int column) throws InvalidResultSetAccessException { try { return this.resultSetMetaData.getScale(column); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } public String getSchemaName(int column) throws InvalidResultSetAccessException { try { return this.resultSetMetaData.getSchemaName(column); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } public String getTableName(int column) throws InvalidResultSetAccessException { try { return this.resultSetMetaData.getTableName(column); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } public boolean isCaseSensitive(int column) throws InvalidResultSetAccessException { try { return this.resultSetMetaData.isCaseSensitive(column); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } public boolean isCurrency(int column) throws InvalidResultSetAccessException { try { return this.resultSetMetaData.isCurrency(column); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } public boolean isSigned(int column) throws InvalidResultSetAccessException { try { return this.resultSetMetaData.isSigned(column); } catch (SQLException se) { throw new InvalidResultSetAccessException(se); } } } ././@LongLink0000000000000000000000000000016300000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/xml/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000755000175000017500000000000011623223530033263 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000021100000000000011557 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/xml/XmlResultProvider.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000235011623223530033265 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.xml; import javax.xml.transform.Result; /** * Interface defining handling involved with providing Result * data for XML input. * * @author Thomas Risberg * @since 2.5.5 * @see javax.xml.transform.Result */ public interface XmlResultProvider { /** * Implementations must implement this method to provide the XML content * for the Result. Implementations will vary depending on * the Result implementation used. * @param result the Result object being used to provide the XML input */ void provideXml(Result result); } ././@LongLink0000000000000000000000000000023400000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/xml/SqlXmlFeatureNotImplementedException.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000264211623223530033271 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.xml; import org.springframework.dao.InvalidDataAccessApiUsageException; /** * Exception thrown when the underlying implementation does not support the * requested feature of the API. * * @author Thomas Risberg * @since 2.5.5 */ public class SqlXmlFeatureNotImplementedException extends InvalidDataAccessApiUsageException { /** * Constructor for SqlXmlFeatureNotImplementedException. * @param msg the detail message */ public SqlXmlFeatureNotImplementedException(String msg) { super(msg); } /** * Constructor for SqlXmlFeatureNotImplementedException. * @param msg the detail message * @param cause the root cause from the data access API in use */ public SqlXmlFeatureNotImplementedException(String msg, Throwable cause) { super(msg, cause); } } ././@LongLink0000000000000000000000000000020400000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/xml/package-info.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000016611623223526033275 0ustar drazzibdrazzib /** * * Abstraction for handling fields of SQLXML data type. * */ package org.springframework.jdbc.support.xml; ././@LongLink0000000000000000000000000000020500000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/xml/SqlXmlHandler.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000002140211623223526033271 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.xml; import java.io.InputStream; import java.io.Reader; import java.sql.ResultSet; import java.sql.SQLException; import javax.xml.transform.Source; import org.w3c.dom.Document; /** * Abstraction for handling XML fields in specific databases. Its main purpose * is to isolate database-specific handling of XML stored in the database. * *

JDBC 4.0 introduces the new data type java.sql.SQLXML * but most databases and their drivers currently rely on database-specific * data types and features. * *

Provides accessor methods for XML fields and acts as factory for * {@link SqlXmlValue} instances. * * @author Thomas Risberg * @since 2.5.5 * @see Jdbc4SqlXmlHandler * @see java.sql.SQLXML * @see java.sql.ResultSet#getSQLXML * @see java.sql.PreparedStatement#setSQLXML */ public interface SqlXmlHandler { //------------------------------------------------------------------------- // Convenience methods for accessing XML content //------------------------------------------------------------------------- /** * Retrieve the given column as String from the given ResultSet. *

Might simply invoke ResultSet.getString or work with * SQLXML or database-specific classes depending on the * database and driver. * @param rs the ResultSet to retrieve the content from * @param columnName the column name to use * @return the content as String, or null in case of SQL NULL * @throws SQLException if thrown by JDBC methods * @see java.sql.ResultSet#getString * @see java.sql.ResultSet#getSQLXML */ String getXmlAsString(ResultSet rs, String columnName) throws SQLException; /** * Retrieve the given column as String from the given ResultSet. *

Might simply invoke ResultSet.getString or work with * SQLXML or database-specific classes depending on the * database and driver. * @param rs the ResultSet to retrieve the content from * @param columnIndex the column index to use * @return the content as String, or null in case of SQL NULL * @throws SQLException if thrown by JDBC methods * @see java.sql.ResultSet#getString * @see java.sql.ResultSet#getSQLXML */ String getXmlAsString(ResultSet rs, int columnIndex) throws SQLException; /** * Retrieve the given column as binary stream from the given ResultSet. *

Might simply invoke ResultSet.getAsciiStream or work with * SQLXML or database-specific classes depending on the * database and driver. * @param rs the ResultSet to retrieve the content from * @param columnName the column name to use * @return the content as a binary stream, or null in case of SQL NULL * @throws SQLException if thrown by JDBC methods * @see java.sql.ResultSet#getSQLXML * @see java.sql.SQLXML#getBinaryStream */ InputStream getXmlAsBinaryStream(ResultSet rs, String columnName) throws SQLException; /** * Retrieve the given column as binary stream from the given ResultSet. *

Might simply invoke ResultSet.getAsciiStream or work with * SQLXML or database-specific classes depending on the * database and driver. * @param rs the ResultSet to retrieve the content from * @param columnIndex the column index to use * @return the content as binary stream, or null in case of SQL NULL * @throws SQLException if thrown by JDBC methods * @see java.sql.ResultSet#getSQLXML * @see java.sql.SQLXML#getBinaryStream */ InputStream getXmlAsBinaryStream(ResultSet rs, int columnIndex) throws SQLException; /** * Retrieve the given column as character stream from the given ResultSet. *

Might simply invoke ResultSet.getCharacterStream or work with * SQLXML or database-specific classes depending on the * database and driver. * @param rs the ResultSet to retrieve the content from * @param columnName the column name to use * @return the content as character stream * @throws SQLException if thrown by JDBC methods * @see java.sql.ResultSet#getSQLXML * @see java.sql.SQLXML#getCharacterStream */ Reader getXmlAsCharacterStream(ResultSet rs, String columnName) throws SQLException; /** * Retrieve the given column as character stream from the given ResultSet. *

Might simply invoke ResultSet.getCharacterStream or work with * SQLXML or database-specific classes depending on the * database and driver. * @param rs the ResultSet to retrieve the content from * @param columnIndex the column index to use * @return the content as character stream * @throws SQLException if thrown by JDBC methods * @see java.sql.ResultSet#getSQLXML * @see java.sql.SQLXML#getCharacterStream */ Reader getXmlAsCharacterStream(ResultSet rs, int columnIndex) throws SQLException; /** * Retrieve the given column as Source implemented using the specified source class * from the given ResultSet. *

Might work with SQLXML or database-specific classes depending * on the database and driver. * @param rs the ResultSet to retrieve the content from * @param columnName the column name to use * @param sourceClass the implementation class to be used * @return the content as character stream * @throws SQLException if thrown by JDBC methods * @see java.sql.ResultSet#getSQLXML * @see java.sql.SQLXML#getSource */ Source getXmlAsSource(ResultSet rs, String columnName, Class sourceClass) throws SQLException; /** * Retrieve the given column as Source implemented using the specified source class * from the given ResultSet. *

Might work with SQLXML or database-specific classes depending * on the database and driver. * @param rs the ResultSet to retrieve the content from * @param columnIndex the column index to use * @param sourceClass the implementation class to be used * @return the content as character stream * @throws SQLException if thrown by JDBC methods * @see java.sql.ResultSet#getSQLXML * @see java.sql.SQLXML#getSource */ Source getXmlAsSource(ResultSet rs, int columnIndex, Class sourceClass) throws SQLException; //------------------------------------------------------------------------- // Convenience methods for building XML content //------------------------------------------------------------------------- /** * Create a SqlXmlValue instance for the given XML data, * as supported by the underlying JDBC driver. * @param value the XML String value providing XML data * @return the implementation specific instance * @see SqlXmlValue * @see java.sql.SQLXML#setString(String) */ SqlXmlValue newSqlXmlValue(String value); /** * Create a SqlXmlValue instance for the given XML data, * as supported by the underlying JDBC driver. * @param provider the XmlBinaryStreamProvider providing XML data * @return the implementation specific instance * @see SqlXmlValue * @see java.sql.SQLXML#setBinaryStream() */ SqlXmlValue newSqlXmlValue(XmlBinaryStreamProvider provider); /** * Create a SqlXmlValue instance for the given XML data, * as supported by the underlying JDBC driver. * @param provider the XmlCharacterStreamProvider providing XML data * @return the implementation specific instance * @see SqlXmlValue * @see java.sql.SQLXML#setCharacterStream() */ SqlXmlValue newSqlXmlValue(XmlCharacterStreamProvider provider); /** * Create a SqlXmlValue instance for the given XML data, * as supported by the underlying JDBC driver. * @param resultClass the Result implementation class to be used * @param provider the XmlResultProvider that will provide the XML data * @return the implementation specific instance * @see SqlXmlValue * @see java.sql.SQLXML#setResult(Class) */ SqlXmlValue newSqlXmlValue(Class resultClass, XmlResultProvider provider); /** * Create a SqlXmlValue instance for the given XML data, * as supported by the underlying JDBC driver. * @param doc the XML Document to be used * @return the implementation specific instance * @see SqlXmlValue */ SqlXmlValue newSqlXmlValue(Document doc); } ././@LongLink0000000000000000000000000000021200000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/xml/Jdbc4SqlXmlHandler.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001275511623223526033304 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.xml; import java.io.IOException; import java.io.InputStream; import java.io.Reader; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.SQLXML; import javax.xml.transform.Source; import javax.xml.transform.dom.DOMResult; import javax.xml.transform.dom.DOMSource; import org.w3c.dom.Document; import org.springframework.dao.DataAccessResourceFailureException; /** * Default implementation of the {@link SqlXmlHandler} interface. * Provides database-specific implementations for storing and * retrieving XML documents to and from fields in a database, * relying on the JDBC 4.0 java.sql.SQLXML facility. * * @author Thomas Risberg * @author Juergen Hoeller * @since 2.5.6 * @see java.sql.SQLXML * @see java.sql.ResultSet#getSQLXML * @see java.sql.PreparedStatement#setSQLXML */ public class Jdbc4SqlXmlHandler implements SqlXmlHandler { //------------------------------------------------------------------------- // Convenience methods for accessing XML content //------------------------------------------------------------------------- public String getXmlAsString(ResultSet rs, String columnName) throws SQLException { return rs.getSQLXML(columnName).getString(); } public String getXmlAsString(ResultSet rs, int columnIndex) throws SQLException { return rs.getSQLXML(columnIndex).getString(); } public InputStream getXmlAsBinaryStream(ResultSet rs, String columnName) throws SQLException { return rs.getSQLXML(columnName).getBinaryStream(); } public InputStream getXmlAsBinaryStream(ResultSet rs, int columnIndex) throws SQLException { return rs.getSQLXML(columnIndex).getBinaryStream(); } public Reader getXmlAsCharacterStream(ResultSet rs, String columnName) throws SQLException { return rs.getSQLXML(columnName).getCharacterStream(); } public Reader getXmlAsCharacterStream(ResultSet rs, int columnIndex) throws SQLException { return rs.getSQLXML(columnIndex).getCharacterStream(); } @SuppressWarnings("unchecked") public Source getXmlAsSource(ResultSet rs, String columnName, Class sourceClass) throws SQLException { return rs.getSQLXML(columnName).getSource(sourceClass != null ? sourceClass : DOMSource.class); } @SuppressWarnings("unchecked") public Source getXmlAsSource(ResultSet rs, int columnIndex, Class sourceClass) throws SQLException { return rs.getSQLXML(columnIndex).getSource(sourceClass != null ? sourceClass : DOMSource.class); } //------------------------------------------------------------------------- // Convenience methods for building XML content //------------------------------------------------------------------------- public SqlXmlValue newSqlXmlValue(final String value) { return new AbstractJdbc4SqlXmlValue() { @Override protected void provideXml(SQLXML xmlObject) throws SQLException, IOException { xmlObject.setString(value); } }; } public SqlXmlValue newSqlXmlValue(final XmlBinaryStreamProvider provider) { return new AbstractJdbc4SqlXmlValue() { @Override protected void provideXml(SQLXML xmlObject) throws SQLException, IOException { provider.provideXml(xmlObject.setBinaryStream()); } }; } public SqlXmlValue newSqlXmlValue(final XmlCharacterStreamProvider provider) { return new AbstractJdbc4SqlXmlValue() { @Override protected void provideXml(SQLXML xmlObject) throws SQLException, IOException { provider.provideXml(xmlObject.setCharacterStream()); } }; } public SqlXmlValue newSqlXmlValue(final Class resultClass, final XmlResultProvider provider) { return new AbstractJdbc4SqlXmlValue() { @Override @SuppressWarnings("unchecked") protected void provideXml(SQLXML xmlObject) throws SQLException, IOException { provider.provideXml(xmlObject.setResult(resultClass)); } }; } public SqlXmlValue newSqlXmlValue(final Document document) { return new AbstractJdbc4SqlXmlValue() { @Override protected void provideXml(SQLXML xmlObject) throws SQLException, IOException { xmlObject.setResult(DOMResult.class).setNode(document); } }; } /** * Internal base class for {@link SqlXmlValue} implementations. */ private static abstract class AbstractJdbc4SqlXmlValue implements SqlXmlValue { private SQLXML xmlObject; public void setValue(PreparedStatement ps, int paramIndex) throws SQLException { this.xmlObject = ps.getConnection().createSQLXML(); try { provideXml(this.xmlObject); } catch (IOException ex) { throw new DataAccessResourceFailureException("Failure encountered while providing XML", ex); } ps.setSQLXML(paramIndex, this.xmlObject); } public void cleanup() { try { this.xmlObject.free(); } catch (SQLException ex) { throw new DataAccessResourceFailureException("Could not free SQLXML object", ex); } } protected abstract void provideXml(SQLXML xmlObject) throws SQLException, IOException; } } ././@LongLink0000000000000000000000000000022200000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/xml/SqlXmlObjectMappingHandler.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000506111623223530033267 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.xml; import java.sql.ResultSet; import java.sql.SQLException; /** * Abstraction for handling XML object mapping to fields in a database. * *

Provides accessor methods for XML fields unmarshalled to an Object, * and acts as factory for {@link SqlXmlValue} instances for marshalling * purposes. * * @author Thomas Risberg * @since 2.5.5 * @see java.sql.ResultSet#getSQLXML * @see java.sql.SQLXML */ public interface SqlXmlObjectMappingHandler extends SqlXmlHandler { /** * Retrieve the given column as an object marshalled from the XML data retrieved * from the given ResultSet. *

Works with an internal Object to XML Mapping implementation. * @param rs the ResultSet to retrieve the content from * @param columnName the column name to use * @return the content as an Object, or null in case of SQL NULL * @throws java.sql.SQLException if thrown by JDBC methods * @see java.sql.ResultSet#getSQLXML */ Object getXmlAsObject(ResultSet rs, String columnName) throws SQLException; /** * Retrieve the given column as an object marshalled from the XML data retrieved * from the given ResultSet. *

Works with an internal Object to XML Mapping implementation. * @param rs the ResultSet to retrieve the content from * @param columnIndex the column index to use * @return the content as an Object, or null in case of SQL NULL * @throws java.sql.SQLException if thrown by JDBC methods * @see java.sql.ResultSet#getSQLXML */ Object getXmlAsObject(ResultSet rs, int columnIndex) throws SQLException; /** * Get an instance of an SqlXmlValue implementation to be used together * with the database specific implementation of this SqlXmlObjectMappingHandler. * @param value the Object to be marshalled to XML * @return the implementation specific instance * @see SqlXmlValue */ SqlXmlValue newMarshallingSqlXmlValue(Object value); } ././@LongLink0000000000000000000000000000020300000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/xml/SqlXmlValue.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000215111623223526033271 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.xml; import org.springframework.jdbc.support.SqlValue; /** * Subinterface of {@link org.springframework.jdbc.support.SqlValue} * that supports passing in XML data to specified column and adds a * cleanup callback, to be invoked after the value has been set and * the corresponding statement has been executed. * * @author Thomas Risberg * @since 2.5.5 * @see org.springframework.jdbc.support.SqlValue */ public interface SqlXmlValue extends SqlValue { } ././@LongLink0000000000000000000000000000021700000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/xml/XmlBinaryStreamProvider.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000244311623223530033270 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.xml; import java.io.OutputStream; import java.io.IOException; /** * Interface defining handling involved with providing OutputStream * data for XML input. * * @author Thomas Risberg * @since 2.5.5 * @see java.io.OutputStream */ public interface XmlBinaryStreamProvider { /** * Implementations must implement this method to provide the XML content * for the OutputStream. * @param outputStream the OutputStream object being used to provide the XML input * @throws IOException if an I/O error occurs while providing the XML */ void provideXml(OutputStream outputStream) throws IOException; } ././@LongLink0000000000000000000000000000022200000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/xml/XmlCharacterStreamProvider.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000236611623223526033301 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.xml; import java.io.Writer; import java.io.IOException; /** * Interface defining handling involved with providing Writer * data for XML input. * * @author Thomas Risberg * @since 2.5.5 * @see java.io.Writer */ public interface XmlCharacterStreamProvider { /** * Implementations must implement this method to provide the XML content * for the Writer. * @param writer the Writer object being used to provide the XML input * @throws IOException if an I/O error occurs while providing the XML */ void provideXml(Writer writer) throws IOException; } ././@LongLink0000000000000000000000000000021400000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/DatabaseStartupValidator.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001052611623223526033276 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support; import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; import javax.sql.DataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.InitializingBean; import org.springframework.jdbc.CannotGetJdbcConnectionException; /** * Bean that checks if a database has already started up. To be referenced * via "depends-on" from beans that depend on database startup, like a Hibernate * SessionFactory or custom data access objects that access a DataSource directly. * *

Useful to defer application initialization until a database has started up. * Particularly appropriate for waiting on a slowly starting Oracle database. * * @author Juergen Hoeller * @since 18.12.2003 */ public class DatabaseStartupValidator implements InitializingBean { public static final int DEFAULT_INTERVAL = 1; public static final int DEFAULT_TIMEOUT = 60; protected final Log logger = LogFactory.getLog(getClass()); private DataSource dataSource; private String validationQuery; private int interval = DEFAULT_INTERVAL; private int timeout = DEFAULT_TIMEOUT; /** * Set the DataSource to validate. */ public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } /** * Set the SQL query string to use for validation. */ public void setValidationQuery(String validationQuery) { this.validationQuery = validationQuery; } /** * Set the interval between validation runs (in seconds). * Default is 1. */ public void setInterval(int interval) { this.interval = interval; } /** * Set the timeout (in seconds) after which a fatal exception * will be thrown. Default is 60. */ public void setTimeout(int timeout) { this.timeout = timeout; } /** * Check whether the validation query can be executed on a Connection * from the specified DataSource, with the specified interval between * checks, until the specified timeout. */ public void afterPropertiesSet() { if (this.dataSource == null) { throw new IllegalArgumentException("dataSource is required"); } if (this.validationQuery == null) { throw new IllegalArgumentException("validationQuery is required"); } try { boolean validated = false; long beginTime = System.currentTimeMillis(); long deadLine = beginTime + this.timeout * 1000; SQLException latestEx = null; while (!validated && System.currentTimeMillis() < deadLine) { Connection con = null; Statement stmt = null; try { con = this.dataSource.getConnection(); stmt = con.createStatement(); stmt.execute(this.validationQuery); validated = true; } catch (SQLException ex) { latestEx = ex; logger.debug("Validation query [" + this.validationQuery + "] threw exception", ex); float rest = ((float) (deadLine - System.currentTimeMillis())) / 1000; if (rest > this.interval) { logger.warn("Database has not started up yet - retrying in " + this.interval + " seconds (timeout in " + rest + " seconds)"); } } finally { JdbcUtils.closeStatement(stmt); JdbcUtils.closeConnection(con); } if (!validated) { Thread.sleep(this.interval * 1000); } } if (!validated) { throw new CannotGetJdbcConnectionException( "Database has not started up within " + this.timeout + " seconds", latestEx); } float duration = (System.currentTimeMillis() - beginTime) / 1000; if (logger.isInfoEnabled()) { logger.info("Database startup detected after " + duration + " seconds"); } } catch (InterruptedException ex) { // Re-interrupt current thread, to allow other threads to react. Thread.currentThread().interrupt(); } } } ././@LongLink0000000000000000000000000000017200000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000755000175000017500000000000011623223530033263 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000023100000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/NativeJdbcExtractorAdapter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001350011623223530033264 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.nativejdbc; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import org.springframework.jdbc.datasource.DataSourceUtils; /** * Abstract adapter class for the {@link NativeJdbcExtractor} interface, * for simplified implementation of basic extractors. * Basically returns the passed-in JDBC objects on all methods. * *

getNativeConnection checks for a ConnectionProxy chain, * for example from a TransactionAwareDataSourceProxy, before delegating to * doGetNativeConnection for actual unwrapping. You can override * either of the two for a specific connection pool, but the latter is * recommended to participate in ConnectionProxy unwrapping. * *

getNativeConnection also applies a fallback if the first * native extraction process failed, that is, returned the same Connection as * passed in. It assumes that some additional proxying is going in this case: * Hence, it retrieves the underlying native Connection from the DatabaseMetaData * via conHandle.getMetaData().getConnection() and retries the native * extraction process based on that Connection handle. This works, for example, * for the Connection proxies exposed by Hibernate 3.1's Session.connection(). * *

The getNativeConnectionFromStatement method is implemented * to simply delegate to getNativeConnection with the Statement's * Connection. This is what most extractor implementations will stick to, * unless there's a more efficient version for a specific pool. * * @author Juergen Hoeller * @since 1.1 * @see #getNativeConnection * @see #getNativeConnectionFromStatement * @see org.springframework.jdbc.datasource.ConnectionProxy */ public abstract class NativeJdbcExtractorAdapter implements NativeJdbcExtractor { /** * Return false by default. */ public boolean isNativeConnectionNecessaryForNativeStatements() { return false; } /** * Return false by default. */ public boolean isNativeConnectionNecessaryForNativePreparedStatements() { return false; } /** * Return false by default. */ public boolean isNativeConnectionNecessaryForNativeCallableStatements() { return false; } /** * Check for a ConnectionProxy chain, then delegate to doGetNativeConnection. *

ConnectionProxy is used by Spring's TransactionAwareDataSourceProxy * and LazyConnectionDataSourceProxy. The target connection behind it is * typically one from a local connection pool, to be unwrapped by the * doGetNativeConnection implementation of a concrete subclass. * @see #doGetNativeConnection * @see org.springframework.jdbc.datasource.ConnectionProxy * @see org.springframework.jdbc.datasource.DataSourceUtils#getTargetConnection * @see org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy * @see org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy */ public Connection getNativeConnection(Connection con) throws SQLException { if (con == null) { return null; } Connection targetCon = DataSourceUtils.getTargetConnection(con); Connection nativeCon = doGetNativeConnection(targetCon); if (nativeCon == targetCon) { // We haven't received a different Connection, so we'll assume that there's // some additional proxying going on. Let's check whether we get something // different back from the DatabaseMetaData.getConnection() call. DatabaseMetaData metaData = targetCon.getMetaData(); // The following check is only really there for mock Connections // which might not carry a DatabaseMetaData instance. if (metaData != null) { Connection metaCon = metaData.getConnection(); if (metaCon != null && metaCon != targetCon) { // We've received a different Connection there: // Let's retry the native extraction process with it. nativeCon = doGetNativeConnection(metaCon); } } } return nativeCon; } /** * Not able to unwrap: return passed-in Connection. */ protected Connection doGetNativeConnection(Connection con) throws SQLException { return con; } /** * Retrieve the Connection via the Statement's Connection. * @see #getNativeConnection * @see Statement#getConnection */ public Connection getNativeConnectionFromStatement(Statement stmt) throws SQLException { if (stmt == null) { return null; } return getNativeConnection(stmt.getConnection()); } /** * Not able to unwrap: return passed-in Statement. */ public Statement getNativeStatement(Statement stmt) throws SQLException { return stmt; } /** * Not able to unwrap: return passed-in PreparedStatement. */ public PreparedStatement getNativePreparedStatement(PreparedStatement ps) throws SQLException { return ps; } /** * Not able to unwrap: return passed-in CallableStatement. */ public CallableStatement getNativeCallableStatement(CallableStatement cs) throws SQLException { return cs; } /** * Not able to unwrap: return passed-in ResultSet. */ public ResultSet getNativeResultSet(ResultSet rs) throws SQLException { return rs; } } ././@LongLink0000000000000000000000000000021300000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/package-info.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000044411623223530033267 0ustar drazzibdrazzib /** * * Provides a mechanism for extracting native implementations of JDBC * interfaces from wrapper objects that got returned from connection pools. * *

Can be used independently, for example in custom JDBC access code. * */ package org.springframework.jdbc.support.nativejdbc; ././@LongLink0000000000000000000000000000022200000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/NativeJdbcExtractor.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001755711623223526033311 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.nativejdbc; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; /** * Interface for extracting native JDBC objects from wrapped objects coming from * connection pools. This is necessary to allow for casting to native implementations * like OracleConnection or OracleResultSet in application * code, for example to create Blobs or to access vendor-specific features. * *

Note: Setting a custom NativeJdbcExtractor is just necessary * if you intend to cast to database-specific implementations like * OracleConnection or OracleResultSet. * Otherwise, any wrapped JDBC object will be fine, with no need for unwrapping. * *

Note: To be able to support any pool's strategy of native ResultSet wrapping, * it is advisable to get both the native Statement and the native ResultSet * via this extractor. Some pools just allow to unwrap the Statement, some just to * unwrap the ResultSet - the above strategy will cover both. It is typically * not necessary to unwrap the Connection to retrieve a native ResultSet. * *

When working with a simple connection pool that wraps Connections but not * Statements, a {@link SimpleNativeJdbcExtractor} is often sufficient. However, * some pools (like Jakarta's Commons DBCP) wrap all JDBC objects that they * return: Therefore, you need to use a specific NativeJdbcExtractor * (like {@link CommonsDbcpNativeJdbcExtractor}) with them. * *

{@link org.springframework.jdbc.core.JdbcTemplate} can properly apply a * NativeJdbcExtractor if specified, unwrapping all JDBC objects * that it creates. Note that this is just necessary if you intend to cast to * native implementations in your data access code. * *

{@link org.springframework.jdbc.support.lob.OracleLobHandler}, * the Oracle-specific implementation of Spring's * {@link org.springframework.jdbc.support.lob.LobHandler} interface, requires a * NativeJdbcExtractor for obtaining the native OracleConnection. * This is also necessary for other Oracle-specific features that you may want * to leverage in your applications, such as Oracle InterMedia. * * @author Juergen Hoeller * @since 25.08.2003 * @see SimpleNativeJdbcExtractor * @see CommonsDbcpNativeJdbcExtractor * @see org.springframework.jdbc.core.JdbcTemplate#setNativeJdbcExtractor * @see org.springframework.jdbc.support.lob.OracleLobHandler#setNativeJdbcExtractor */ public interface NativeJdbcExtractor { /** * Return whether it is necessary to work on the native Connection to * receive native Statements. *

This should be true if the connection pool does not allow to extract * the native JDBC objects from its Statement wrapper but supports a way * to retrieve the native JDBC Connection. This way, applications can * still receive native Statements and ResultSet via working on the * native JDBC Connection. */ boolean isNativeConnectionNecessaryForNativeStatements(); /** * Return whether it is necessary to work on the native Connection to * receive native PreparedStatements. *

This should be true if the connection pool does not allow to extract * the native JDBC objects from its PreparedStatement wrappers but * supports a way to retrieve the native JDBC Connection. This way, * applications can still receive native Statements and ResultSet via * working on the native JDBC Connection. */ boolean isNativeConnectionNecessaryForNativePreparedStatements(); /** * Return whether it is necessary to work on the native Connection to * receive native CallableStatements. *

This should be true if the connection pool does not allow to extract * the native JDBC objects from its CallableStatement wrappers but * supports a way to retrieve the native JDBC Connection. This way, * applications can still receive native Statements and ResultSet via * working on the native JDBC Connection. */ boolean isNativeConnectionNecessaryForNativeCallableStatements(); /** * Retrieve the underlying native JDBC Connection for the given Connection. * Supposed to return the given Connection if not capable of unwrapping. * @param con the Connection handle, potentially wrapped by a connection pool * @return the underlying native JDBC Connection, if possible; * else, the original Connection * @throws SQLException if thrown by JDBC methods */ Connection getNativeConnection(Connection con) throws SQLException; /** * Retrieve the underlying native JDBC Connection for the given Statement. * Supposed to return the Statement.getConnection() if not * capable of unwrapping. *

Having this extra method allows for more efficient unwrapping if data * access code already has a Statement. Statement.getConnection() * often returns the native JDBC Connection even if the Statement itself * is wrapped by a pool. * @param stmt the Statement handle, potentially wrapped by a connection pool * @return the underlying native JDBC Connection, if possible; * else, the original Connection * @throws SQLException if thrown by JDBC methods * @see java.sql.Statement#getConnection() */ Connection getNativeConnectionFromStatement(Statement stmt) throws SQLException; /** * Retrieve the underlying native JDBC Statement for the given Statement. * Supposed to return the given Statement if not capable of unwrapping. * @param stmt the Statement handle, potentially wrapped by a connection pool * @return the underlying native JDBC Statement, if possible; * else, the original Statement * @throws SQLException if thrown by JDBC methods */ Statement getNativeStatement(Statement stmt) throws SQLException; /** * Retrieve the underlying native JDBC PreparedStatement for the given statement. * Supposed to return the given PreparedStatement if not capable of unwrapping. * @param ps the PreparedStatement handle, potentially wrapped by a connection pool * @return the underlying native JDBC PreparedStatement, if possible; * else, the original PreparedStatement * @throws SQLException if thrown by JDBC methods */ PreparedStatement getNativePreparedStatement(PreparedStatement ps) throws SQLException; /** * Retrieve the underlying native JDBC CallableStatement for the given statement. * Supposed to return the given CallableStatement if not capable of unwrapping. * @param cs the CallableStatement handle, potentially wrapped by a connection pool * @return the underlying native JDBC CallableStatement, if possible; * else, the original CallableStatement * @throws SQLException if thrown by JDBC methods */ CallableStatement getNativeCallableStatement(CallableStatement cs) throws SQLException; /** * Retrieve the underlying native JDBC ResultSet for the given statement. * Supposed to return the given ResultSet if not capable of unwrapping. * @param rs the ResultSet handle, potentially wrapped by a connection pool * @return the underlying native JDBC ResultSet, if possible; * else, the original ResultSet * @throws SQLException if thrown by JDBC methods */ ResultSet getNativeResultSet(ResultSet rs) throws SQLException; } ././@LongLink0000000000000000000000000000023300000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/WebSphereNativeJdbcExtractor.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000714311623223530033272 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.nativejdbc; import java.lang.reflect.Method; import java.sql.Connection; import java.sql.SQLException; import org.springframework.util.ReflectionUtils; /** * Implementation of the {@link NativeJdbcExtractor} interface for WebSphere, * supporting WebSphere Application Server 5.1 and higher. * *

Returns the underlying native Connection to application code instead * of WebSphere's wrapper implementation; unwraps the Connection for * native statements. The returned JDBC classes can then safely be cast, * e.g. to oracle.jdbc.OracleConnection. * *

This NativeJdbcExtractor can be set just to allow working * with a WebSphere DataSource: If a given object is not a WebSphere * Connection wrapper, it will be returned as-is. * * @author Juergen Hoeller * @since 1.1 * @see com.ibm.ws.rsadapter.jdbc.WSJdbcConnection * @see com.ibm.ws.rsadapter.jdbc.WSJdbcUtil#getNativeConnection */ public class WebSphereNativeJdbcExtractor extends NativeJdbcExtractorAdapter { private static final String JDBC_ADAPTER_CONNECTION_NAME_5 = "com.ibm.ws.rsadapter.jdbc.WSJdbcConnection"; private static final String JDBC_ADAPTER_UTIL_NAME_5 = "com.ibm.ws.rsadapter.jdbc.WSJdbcUtil"; private Class webSphere5ConnectionClass; private Method webSphere5NativeConnectionMethod; /** * This constructor retrieves WebSphere JDBC adapter classes, * so we can get the underlying vendor connection using reflection. */ public WebSphereNativeJdbcExtractor() { try { this.webSphere5ConnectionClass = getClass().getClassLoader().loadClass(JDBC_ADAPTER_CONNECTION_NAME_5); Class jdbcAdapterUtilClass = getClass().getClassLoader().loadClass(JDBC_ADAPTER_UTIL_NAME_5); this.webSphere5NativeConnectionMethod = jdbcAdapterUtilClass.getMethod("getNativeConnection", new Class[] {this.webSphere5ConnectionClass}); } catch (Exception ex) { throw new IllegalStateException( "Could not initialize WebSphereNativeJdbcExtractor because WebSphere API classes are not available: " + ex); } } /** * Return true, as WebSphere returns wrapped Statements. */ @Override public boolean isNativeConnectionNecessaryForNativeStatements() { return true; } /** * Return true, as WebSphere returns wrapped PreparedStatements. */ @Override public boolean isNativeConnectionNecessaryForNativePreparedStatements() { return true; } /** * Return true, as WebSphere returns wrapped CallableStatements. */ @Override public boolean isNativeConnectionNecessaryForNativeCallableStatements() { return true; } /** * Retrieve the Connection via WebSphere's getNativeConnection method. */ @Override protected Connection doGetNativeConnection(Connection con) throws SQLException { if (this.webSphere5ConnectionClass.isAssignableFrom(con.getClass())) { return (Connection) ReflectionUtils.invokeJdbcMethod( this.webSphere5NativeConnectionMethod, null, new Object[] {con}); } return con; } } ././@LongLink0000000000000000000000000000023000000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/SimpleNativeJdbcExtractor.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001545011623223530033272 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.nativejdbc; /** * Simple implementation of the {@link NativeJdbcExtractor} interface. * Assumes a pool that wraps Connection handles but not DatabaseMetaData: * In this case, the underlying native Connection can be retrieved by simply * calling conHandle.getMetaData().getConnection(). * All other JDBC objects will be returned as passed in. * *

This extractor should work with any pool that does not wrap DatabaseMetaData, * and will also work with any plain JDBC driver. Note that a pool can still wrap * Statements, PreparedStatements, etc: The only requirement of this extractor is * that java.sql.DatabaseMetaData does not get wrapped, returning the * native Connection of the JDBC driver on metaData.getConnection(). * *

Customize this extractor by setting the "nativeConnectionNecessaryForXxx" * flags accordingly: If Statements, PreparedStatements, and/or CallableStatements * are wrapped by your pool, set the corresponding "nativeConnectionNecessaryForXxx" * flags to "true". If none of the statement types is wrapped - or you solely need * Connection unwrapping in the first place -, the defaults are fine. * *

SimpleNativeJdbcExtractor is a common choice for use with OracleLobHandler, * which just needs Connection unwrapping via the * {@link #getNativeConnectionFromStatement} method. This usage will work * with almost any connection pool. Known to work are, for example: *

    *
  • Caucho Resin 2.1.x, 3.0.x *
  • Sun Java System Application Server 8 *
  • Oracle OC4J 9.0.3, 9.0.4 *
  • C3P0 0.8.x *
  • Jakarta Commons DBCP 1.0, 1.1, 1.2 (used in Tomcat 4.1.x, 5.0.x) *
  • JBoss 3.2.x *
* *

For full usage with JdbcTemplate, i.e. to also provide Statement unwrapping: *

    *
  • Use a default SimpleNativeJdbcExtractor for Resin and SJSAS (no JDBC * Statement objects are wrapped, therefore no special unwrapping is necessary). *
  • Use a SimpleNativeJdbcExtractor with all "nativeConnectionNecessaryForXxx" * flags set to "true" for OC4J and C3P0 (all JDBC Statement objects are wrapped, * but none of the wrappers allow for unwrapping). *
  • Use a CommonsDbcpNativeJdbcExtractor for Jakarta Commons DBCP respectively * a JBossNativeJdbcExtractor for JBoss (all JDBC Statement objects are wrapped, * but all of them can be extracted by casting to implementation classes). *
* * @author Juergen Hoeller * @since 05.12.2003 * @see #setNativeConnectionNecessaryForNativeStatements * @see #setNativeConnectionNecessaryForNativePreparedStatements * @see #setNativeConnectionNecessaryForNativeCallableStatements * @see Jdbc4NativeJdbcExtractor * @see org.springframework.jdbc.core.JdbcTemplate#setNativeJdbcExtractor * @see org.springframework.jdbc.support.lob.OracleLobHandler#setNativeJdbcExtractor */ public class SimpleNativeJdbcExtractor extends NativeJdbcExtractorAdapter { private boolean nativeConnectionNecessaryForNativeStatements = false; private boolean nativeConnectionNecessaryForNativePreparedStatements = false; private boolean nativeConnectionNecessaryForNativeCallableStatements = false; /** * Set whether it is necessary to work on the native Connection to * receive native Statements. Default is "false". If true, the Connection * will be unwrapped first to create a Statement. *

This makes sense if you need to work with native Statements from * a pool that does not allow to extract the native JDBC objects from its * wrappers but returns the native Connection on DatabaseMetaData.getConnection. *

The standard SimpleNativeJdbcExtractor is unable to unwrap statements, * so set this to true if your connection pool wraps Statements. * @see java.sql.Connection#createStatement * @see java.sql.DatabaseMetaData#getConnection */ public void setNativeConnectionNecessaryForNativeStatements(boolean nativeConnectionNecessaryForNativeStatements) { this.nativeConnectionNecessaryForNativeStatements = nativeConnectionNecessaryForNativeStatements; } @Override public boolean isNativeConnectionNecessaryForNativeStatements() { return this.nativeConnectionNecessaryForNativeStatements; } /** * Set whether it is necessary to work on the native Connection to * receive native PreparedStatements. Default is "false". If true, * the Connection will be unwrapped first to create a PreparedStatement. *

This makes sense if you need to work with native PreparedStatements from * a pool that does not allow to extract the native JDBC objects from its * wrappers but returns the native Connection on Statement.getConnection. *

The standard SimpleNativeJdbcExtractor is unable to unwrap statements, * so set this to true if your connection pool wraps PreparedStatements. * @see java.sql.Connection#prepareStatement * @see java.sql.DatabaseMetaData#getConnection */ public void setNativeConnectionNecessaryForNativePreparedStatements(boolean nativeConnectionNecessary) { this.nativeConnectionNecessaryForNativePreparedStatements = nativeConnectionNecessary; } @Override public boolean isNativeConnectionNecessaryForNativePreparedStatements() { return this.nativeConnectionNecessaryForNativePreparedStatements; } /** * Set whether it is necessary to work on the native Connection to * receive native CallableStatements. Default is "false". If true, * the Connection will be unwrapped first to create a CallableStatement. *

This makes sense if you need to work with native CallableStatements from * a pool that does not allow to extract the native JDBC objects from its * wrappers but returns the native Connection on Statement.getConnection. *

The standard SimpleNativeJdbcExtractor is unable to unwrap statements, * so set this to true if your connection pool wraps CallableStatements. * @see java.sql.Connection#prepareCall * @see java.sql.DatabaseMetaData#getConnection */ public void setNativeConnectionNecessaryForNativeCallableStatements(boolean nativeConnectionNecessary) { this.nativeConnectionNecessaryForNativeCallableStatements = nativeConnectionNecessary; } @Override public boolean isNativeConnectionNecessaryForNativeCallableStatements() { return this.nativeConnectionNecessaryForNativeCallableStatements; } } ././@LongLink0000000000000000000000000000022700000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/Jdbc4NativeJdbcExtractor.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001043511623223526033275 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.nativejdbc; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; /** * {@link NativeJdbcExtractor} implementation that delegates to JDBC 4.0's * unwrap method, as defined by {@link java.sql.Wrapper}. * You will typically need to specify a vendor {@link #setConnectionType Connection type} * / {@link #setStatementType Statement type} / {@link #setResultSetType ResultSet type} * to extract, since JDBC 4.0 only actually unwraps to a given target type. * *

Note: Only use this when actually running against a JDBC 4.0 driver, with a * connection pool that supports the JDBC 4.0 API (i.e. at least accepts JDBC 4.0 * API calls and passes them through to the underlying driver)! Other than that, * there is no need for connection pool specific setup. As of JDBC 4.0, * NativeJdbcExtractors will typically be implemented for specific drivers * instead of for specific pools (e.g. {@link OracleJdbc4NativeJdbcExtractor}). * * @author Juergen Hoeller * @since 2.5 * @see java.sql.Wrapper#unwrap * @see SimpleNativeJdbcExtractor * @see org.springframework.jdbc.core.JdbcTemplate#setNativeJdbcExtractor * @see org.springframework.jdbc.support.lob.OracleLobHandler#setNativeJdbcExtractor */ public class Jdbc4NativeJdbcExtractor extends NativeJdbcExtractorAdapter { private Class connectionType = Connection.class; private Class statementType = Statement.class; private Class preparedStatementType = PreparedStatement.class; private Class callableStatementType = CallableStatement.class; private Class resultSetType = ResultSet.class; /** * Set the vendor's Connection type, e.g. oracle.jdbc.OracleConnection. */ public void setConnectionType(Class connectionType) { this.connectionType = connectionType; } /** * Set the vendor's Statement type, e.g. oracle.jdbc.OracleStatement. */ public void setStatementType(Class statementType) { this.statementType = statementType; } /** * Set the vendor's PreparedStatement type, e.g. oracle.jdbc.OraclePreparedStatement. */ public void setPreparedStatementType(Class preparedStatementType) { this.preparedStatementType = preparedStatementType; } /** * Set the vendor's CallableStatement type, e.g. oracle.jdbc.OracleCallableStatement. */ public void setCallableStatementType(Class callableStatementType) { this.callableStatementType = callableStatementType; } /** * Set the vendor's ResultSet type, e.g. oracle.jdbc.OracleResultSet. */ public void setResultSetType(Class resultSetType) { this.resultSetType = resultSetType; } @Override protected Connection doGetNativeConnection(Connection con) throws SQLException { return con.unwrap(this.connectionType); } @Override public Statement getNativeStatement(Statement stmt) throws SQLException { return stmt.unwrap(this.statementType); } @Override public PreparedStatement getNativePreparedStatement(PreparedStatement ps) throws SQLException { return ps.unwrap(this.preparedStatementType); } @Override public CallableStatement getNativeCallableStatement(CallableStatement cs) throws SQLException { return cs.unwrap(this.callableStatementType); } @Override public ResultSet getNativeResultSet(ResultSet rs) throws SQLException { return rs.unwrap(this.resultSetType); } } ././@LongLink0000000000000000000000000000023200000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/WebLogicNativeJdbcExtractor.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000644211623223526033300 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.nativejdbc; import java.lang.reflect.Method; import java.sql.Connection; import java.sql.SQLException; import org.springframework.util.ReflectionUtils; /** * Implementation of the {@link NativeJdbcExtractor} interface for WebLogic, * supporting WebLogic Server 8.1 and higher. * *

Returns the underlying native Connection to application code instead * of WebLogic's wrapper implementation; unwraps the Connection for native * statements. The returned JDBC classes can then safely be cast, e.g. to * oracle.jdbc.OracleConnection. * *

This NativeJdbcExtractor can be set just to allow working * with a WebLogic DataSource: If a given object is not a WebLogic * Connection wrapper, it will be returned as-is. * * @author Thomas Risberg * @author Juergen Hoeller * @since 1.0.2 * @see #getNativeConnection * @see weblogic.jdbc.extensions.WLConnection#getVendorConnection */ public class WebLogicNativeJdbcExtractor extends NativeJdbcExtractorAdapter { private static final String JDBC_EXTENSION_NAME = "weblogic.jdbc.extensions.WLConnection"; private final Class jdbcExtensionClass; private final Method getVendorConnectionMethod; /** * This constructor retrieves the WebLogic JDBC extension interface, * so we can get the underlying vendor connection using reflection. */ public WebLogicNativeJdbcExtractor() { try { this.jdbcExtensionClass = getClass().getClassLoader().loadClass(JDBC_EXTENSION_NAME); this.getVendorConnectionMethod = this.jdbcExtensionClass.getMethod("getVendorConnection", (Class[]) null); } catch (Exception ex) { throw new IllegalStateException( "Could not initialize WebLogicNativeJdbcExtractor because WebLogic API classes are not available: " + ex); } } /** * Return true, as WebLogic returns wrapped Statements. */ @Override public boolean isNativeConnectionNecessaryForNativeStatements() { return true; } /** * Return true, as WebLogic returns wrapped PreparedStatements. */ @Override public boolean isNativeConnectionNecessaryForNativePreparedStatements() { return true; } /** * Return true, as WebLogic returns wrapped CallableStatements. */ @Override public boolean isNativeConnectionNecessaryForNativeCallableStatements() { return true; } /** * Retrieve the Connection via WebLogic's getVendorConnection method. */ @Override protected Connection doGetNativeConnection(Connection con) throws SQLException { if (this.jdbcExtensionClass.isAssignableFrom(con.getClass())) { return (Connection) ReflectionUtils.invokeJdbcMethod(this.getVendorConnectionMethod, con); } return con; } } ././@LongLink0000000000000000000000000000022600000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/C3P0NativeJdbcExtractor.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000673011623223530033273 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.nativejdbc; import java.lang.reflect.Method; import java.sql.Connection; import java.sql.SQLException; import com.mchange.v2.c3p0.C3P0ProxyConnection; import org.springframework.util.ReflectionUtils; /** * Implementation of the {@link NativeJdbcExtractor} interface for the * C3P0 connection pool. * *

Returns underlying native Connections to application code instead of C3P0's * wrapper implementations; unwraps the Connection for native Statements. * The returned JDBC classes can then safely be cast, e.g. to * oracle.jdbc.OracleConnection. * *

This NativeJdbcExtractor can be set just to allow working with * a C3P0 DataSource: If a given object is not a C3P0 wrapper, it will be * returned as-is. * *

Note that this class requires C3P0 0.8.5 or later; for earlier C3P0 versions, * use SimpleNativeJdbcExtractor (which won't work for C3P0 0.8.5 or later). * * @author Juergen Hoeller * @since 1.1.5 * @see com.mchange.v2.c3p0.C3P0ProxyConnection#rawConnectionOperation * @see SimpleNativeJdbcExtractor */ public class C3P0NativeJdbcExtractor extends NativeJdbcExtractorAdapter { private final Method getRawConnectionMethod; /** * This method is not meant to be used directly; it rather serves * as callback method for C3P0's "rawConnectionOperation" API. * @param con a native Connection handle * @return the native Connection handle, as-is */ public static Connection getRawConnection(Connection con) { return con; } public C3P0NativeJdbcExtractor() { try { this.getRawConnectionMethod = getClass().getMethod("getRawConnection", new Class[] {Connection.class}); } catch (NoSuchMethodException ex) { throw new IllegalStateException("Internal error in C3P0NativeJdbcExtractor: " + ex.getMessage()); } } @Override public boolean isNativeConnectionNecessaryForNativeStatements() { return true; } @Override public boolean isNativeConnectionNecessaryForNativePreparedStatements() { return true; } @Override public boolean isNativeConnectionNecessaryForNativeCallableStatements() { return true; } /** * Retrieve the Connection via C3P0's rawConnectionOperation API, * using the getRawConnection as callback to get access to the * raw Connection (which is otherwise not directly supported by C3P0). * @see #getRawConnection */ @Override protected Connection doGetNativeConnection(Connection con) throws SQLException { if (con instanceof C3P0ProxyConnection) { C3P0ProxyConnection cpCon = (C3P0ProxyConnection) con; try { return (Connection) cpCon.rawConnectionOperation( this.getRawConnectionMethod, null, new Object[] {C3P0ProxyConnection.RAW_CONNECTION}); } catch (SQLException ex) { throw ex; } catch (Exception ex) { ReflectionUtils.handleReflectionException(ex); } } return con; } } ././@LongLink0000000000000000000000000000023500000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/OracleJdbc4NativeJdbcExtractor.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000504511623223526033276 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.nativejdbc; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.Statement; /** * A {@link Jdbc4NativeJdbcExtractor} which comes pre-configured for Oracle's JDBC driver, * specifying the following vendor-specific API types for unwrapping: *

    *
  • oracle.jdbc.OracleConnection *
  • oracle.jdbc.OracleStatement *
  • oracle.jdbc.OraclePreparedStatement *
  • oracle.jdbc.OracleCallableStatement *
  • oracle.jdbc.OracleResultSet *
* *

Note: This will work with any JDBC 4.0 compliant connection pool, without a need for * connection pool specific setup. In other words, as of JDBC 4.0, NativeJdbcExtractors * will typically be implemented for specific drivers instead of for specific pools. * * @author Juergen Hoeller * @since 3.0.5 */ public class OracleJdbc4NativeJdbcExtractor extends Jdbc4NativeJdbcExtractor { @SuppressWarnings("unchecked") public OracleJdbc4NativeJdbcExtractor() { try { setConnectionType((Class) getClass().getClassLoader().loadClass("oracle.jdbc.OracleConnection")); setStatementType((Class) getClass().getClassLoader().loadClass("oracle.jdbc.OracleStatement")); setPreparedStatementType((Class) getClass().getClassLoader().loadClass("oracle.jdbc.OraclePreparedStatement")); setCallableStatementType((Class) getClass().getClassLoader().loadClass("oracle.jdbc.OracleCallableStatement")); setResultSetType((Class) getClass().getClassLoader().loadClass("oracle.jdbc.OracleResultSet")); } catch (Exception ex) { throw new IllegalStateException( "Could not initialize OracleJdbc4NativeJdbcExtractor because Oracle API classes are not available: " + ex); } } } ././@LongLink0000000000000000000000000000023500000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/CommonsDbcpNativeJdbcExtractor.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000754411623223530033277 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.nativejdbc; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import org.springframework.util.ReflectionUtils; /** * Implementation of the {@link NativeJdbcExtractor} interface for the * Jakarta Commons DBCP connection pool, version 1.1 or higher. * *

Returns the underlying native Connection, Statement, etc to application * code instead of DBCP's wrapper implementations. The returned JDBC classes * can then safely be cast, e.g. to oracle.jdbc.OracleConnection. * *

This NativeJdbcExtractor can be set just to allow working with a * Commons DBCP DataSource: If a given object is not a Commons DBCP wrapper, * it will be returned as-is. * *

Note that this version of CommonsDbcpNativeJdbcExtractor will work * against the original Commons DBCP in org.apache.commons.dbcp * as well as against Tomcat 5.5's relocated Commons DBCP version in the * org.apache.tomcat.dbcp.dbcp package. * * @author Juergen Hoeller * @since 25.08.2003 */ public class CommonsDbcpNativeJdbcExtractor extends NativeJdbcExtractorAdapter { private static final String GET_INNERMOST_DELEGATE_METHOD_NAME = "getInnermostDelegate"; /** * Extracts the innermost delegate from the given Commons DBCP object. * Falls back to the given object if no underlying object found. * @param obj the Commons DBCP Connection/Statement/ResultSet * @return the underlying native Connection/Statement/ResultSet */ private static Object getInnermostDelegate(Object obj) throws SQLException { if (obj == null) { return null; } try { Class classToAnalyze = obj.getClass(); while (!Modifier.isPublic(classToAnalyze.getModifiers())) { classToAnalyze = classToAnalyze.getSuperclass(); if (classToAnalyze == null) { // No public provider class found -> fall back to given object. return obj; } } Method getInnermostDelegate = classToAnalyze.getMethod(GET_INNERMOST_DELEGATE_METHOD_NAME, (Class[]) null); Object delegate = ReflectionUtils.invokeJdbcMethod(getInnermostDelegate, obj); return (delegate != null ? delegate : obj); } catch (NoSuchMethodException ex) { return obj; } catch (SecurityException ex) { throw new IllegalStateException("Commons DBCP getInnermostDelegate method is not accessible: " + ex); } } @Override protected Connection doGetNativeConnection(Connection con) throws SQLException { return (Connection) getInnermostDelegate(con); } @Override public Statement getNativeStatement(Statement stmt) throws SQLException { return (Statement) getInnermostDelegate(stmt); } @Override public PreparedStatement getNativePreparedStatement(PreparedStatement ps) throws SQLException { return (PreparedStatement) getNativeStatement(ps); } @Override public CallableStatement getNativeCallableStatement(CallableStatement cs) throws SQLException { return (CallableStatement) getNativeStatement(cs); } @Override public ResultSet getNativeResultSet(ResultSet rs) throws SQLException { return (ResultSet) getInnermostDelegate(rs); } } ././@LongLink0000000000000000000000000000022700000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/nativejdbc/JBossNativeJdbcExtractor.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000001175711623223530033300 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.nativejdbc; import java.lang.reflect.Method; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import org.springframework.util.ReflectionUtils; /** * Implementation of the {@link NativeJdbcExtractor} interface for JBoss, * supporting JBoss Application Server 3.2.4+. * *

Returns the underlying native Connection, Statement, etc to * application code instead of JBoss' wrapper implementations. * The returned JDBC classes can then safely be cast, e.g. to * oracle.jdbc.OracleConnection. * *

This NativeJdbcExtractor can be set just to allow working with * a JBoss connection pool: If a given object is not a JBoss wrapper, * it will be returned as-is. * * @author Juergen Hoeller * @since 03.01.2004 * @see org.jboss.resource.adapter.jdbc.WrappedConnection#getUnderlyingConnection * @see org.jboss.resource.adapter.jdbc.WrappedStatement#getUnderlyingStatement * @see org.jboss.resource.adapter.jdbc.WrappedResultSet#getUnderlyingResultSet */ public class JBossNativeJdbcExtractor extends NativeJdbcExtractorAdapter { private static final String WRAPPED_CONNECTION_NAME = "org.jboss.resource.adapter.jdbc.WrappedConnection"; private static final String WRAPPED_STATEMENT_NAME = "org.jboss.resource.adapter.jdbc.WrappedStatement"; private static final String WRAPPED_RESULT_SET_NAME = "org.jboss.resource.adapter.jdbc.WrappedResultSet"; private Class wrappedConnectionClass; private Class wrappedStatementClass; private Class wrappedResultSetClass; private Method getUnderlyingConnectionMethod; private Method getUnderlyingStatementMethod; private Method getUnderlyingResultSetMethod; /** * This constructor retrieves JBoss JDBC wrapper classes, * so we can get the underlying vendor connection using reflection. */ public JBossNativeJdbcExtractor() { try { this.wrappedConnectionClass = getClass().getClassLoader().loadClass(WRAPPED_CONNECTION_NAME); this.wrappedStatementClass = getClass().getClassLoader().loadClass(WRAPPED_STATEMENT_NAME); this.wrappedResultSetClass = getClass().getClassLoader().loadClass(WRAPPED_RESULT_SET_NAME); this.getUnderlyingConnectionMethod = this.wrappedConnectionClass.getMethod("getUnderlyingConnection", (Class[]) null); this.getUnderlyingStatementMethod = this.wrappedStatementClass.getMethod("getUnderlyingStatement", (Class[]) null); this.getUnderlyingResultSetMethod = this.wrappedResultSetClass.getMethod("getUnderlyingResultSet", (Class[]) null); } catch (Exception ex) { throw new IllegalStateException( "Could not initialize JBossNativeJdbcExtractor because JBoss API classes are not available: " + ex); } } /** * Retrieve the Connection via JBoss' getUnderlyingConnection method. */ @Override protected Connection doGetNativeConnection(Connection con) throws SQLException { if (this.wrappedConnectionClass.isAssignableFrom(con.getClass())) { return (Connection) ReflectionUtils.invokeJdbcMethod(this.getUnderlyingConnectionMethod, con); } return con; } /** * Retrieve the Connection via JBoss' getUnderlyingStatement method. */ @Override public Statement getNativeStatement(Statement stmt) throws SQLException { if (this.wrappedStatementClass.isAssignableFrom(stmt.getClass())) { return (Statement) ReflectionUtils.invokeJdbcMethod(this.getUnderlyingStatementMethod, stmt); } return stmt; } /** * Retrieve the Connection via JBoss' getUnderlyingStatement method. */ @Override public PreparedStatement getNativePreparedStatement(PreparedStatement ps) throws SQLException { return (PreparedStatement) getNativeStatement(ps); } /** * Retrieve the Connection via JBoss' getUnderlyingStatement method. */ @Override public CallableStatement getNativeCallableStatement(CallableStatement cs) throws SQLException { return (CallableStatement) getNativeStatement(cs); } /** * Retrieve the Connection via JBoss' getUnderlyingResultSet method. */ @Override public ResultSet getNativeResultSet(ResultSet rs) throws SQLException { if (this.wrappedResultSetClass.isAssignableFrom(rs.getClass())) { return (ResultSet) ReflectionUtils.invokeJdbcMethod(this.getUnderlyingResultSetMethod, rs); } return rs; } } ././@LongLink0000000000000000000000000000023400000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/JdbcUpdateAffectedIncorrectNumberOfRowsException.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000407611623223526033301 0ustar drazzibdrazzib/* * Copyright 2002-2006 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc; import org.springframework.dao.IncorrectUpdateSemanticsDataAccessException; /** * Exception thrown when a JDBC update affects an unexpected number of rows. * Typically we expect an update to affect a single row, meaning it's an * error if it affects multiple rows. * * @author Rod Johnson * @author Juergen Hoeller */ public class JdbcUpdateAffectedIncorrectNumberOfRowsException extends IncorrectUpdateSemanticsDataAccessException { /** Number of rows that should have been affected */ private int expected; /** Number of rows that actually were affected */ private int actual; /** * Constructor for JdbcUpdateAffectedIncorrectNumberOfRowsException. * @param sql SQL we were tring to execute * @param expected the expected number of rows affected * @param actual the actual number of rows affected */ public JdbcUpdateAffectedIncorrectNumberOfRowsException(String sql, int expected, int actual) { super("SQL update '" + sql + "' affected " + actual + " rows, not " + expected + " as expected"); this.expected = expected; this.actual = actual; } /** * Return the number of rows that should have been affected. */ public int getExpectedRowsAffected() { return this.expected; } /** * Return the number of rows that have actually been affected. */ public int getActualRowsAffected() { return this.actual; } @Override public boolean wasDataUpdated() { return (getActualRowsAffected() > 0); } } ././@LongLink0000000000000000000000000000021300000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/InvalidResultSetAccessException.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000412211623223530033264 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc; import java.sql.SQLException; import org.springframework.dao.InvalidDataAccessResourceUsageException; /** * Exception thrown when a ResultSet has been accessed in an invalid fashion. * Such exceptions always have a java.sql.SQLException root cause. * *

This typically happens when an invalid ResultSet column index or name * has been specified. Also thrown by disconnected SqlRowSets. * * @author Juergen Hoeller * @since 1.2 * @see BadSqlGrammarException * @see org.springframework.jdbc.support.rowset.SqlRowSet */ public class InvalidResultSetAccessException extends InvalidDataAccessResourceUsageException { private String sql; /** * Constructor for InvalidResultSetAccessException. * @param task name of current task * @param sql the offending SQL statement * @param ex the root cause */ public InvalidResultSetAccessException(String task, String sql, SQLException ex) { super(task + "; invalid ResultSet access for SQL [" + sql + "]", ex); this.sql = sql; } /** * Constructor for InvalidResultSetAccessException. * @param ex the root cause */ public InvalidResultSetAccessException(SQLException ex) { super(ex.getMessage(), ex); } /** * Return the wrapped SQLException. */ public SQLException getSQLException() { return (SQLException) getCause(); } /** * Return the SQL that caused the problem. * @return the offending SQL, if known */ public String getSql() { return this.sql; } } ././@LongLink0000000000000000000000000000021400000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdbc/CannotGetJdbcConnectionException.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/main/java/org/springframework/jdb0000644000175000017500000000304311623223530033265 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc; import java.sql.SQLException; import org.springframework.dao.DataAccessResourceFailureException; /** * Fatal exception thrown when we can't connect to an RDBMS using JDBC. * * @author Rod Johnson */ public class CannotGetJdbcConnectionException extends DataAccessResourceFailureException { /** * Constructor for CannotGetJdbcConnectionException. * @param msg the detail message * @param ex SQLException root cause */ public CannotGetJdbcConnectionException(String msg, SQLException ex) { super(msg, ex); } /** * Constructor for CannotGetJdbcConnectionException. * @param msg the detail message * @param ex ClassNotFoundException root cause * @deprecated since Spring 2.5, in favor of throwing an * IllegalStateException in case of the driver not being found */ @Deprecated public CannotGetJdbcConnectionException(String msg, ClassNotFoundException ex) { super(msg, ex); } } libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/0000755000175000017500000000000011623223526025713 5ustar drazzibdrazziblibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/0000755000175000017500000000000011623223530027720 5ustar drazzibdrazziblibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/schema.sql0000644000175000017500000000011611623223530031677 0ustar drazzibdrazzibdrop table T_TEST if exists; create table T_TEST (NAME varchar(50) not null);libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/data.sql0000644000175000017500000000005311623223530031350 0ustar drazzibdrazzibinsert into T_TEST (NAME) values ('Keith');libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/0000755000175000017500000000000011623223526030514 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframework/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframewor0000755000175000017500000000000011623223526033502 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000015400000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframewor0000755000175000017500000000000011623223526033502 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000016700000000000011571 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/datasource/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframewor0000755000175000017500000000000011623223526033502 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000020000000000000011555 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/datasource/embedded/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframewor0000755000175000017500000000000011623223530033475 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000022600000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/datasource/embedded/db-schema-comments.sqllibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframewor0000644000175000017500000000022311623223526033501 0ustar drazzibdrazzib-- Failed DROP can be ignored if necessary drop table T_TEST if exists; -- Create the test table create table T_TEST (NAME varchar(50) not null);././@LongLink0000000000000000000000000000024200000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/datasource/embedded/db-schema-failed-drop-comments.sqllibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframewor0000644000175000017500000000021111623223526033476 0ustar drazzibdrazzib-- Failed DROP can be ignored if necessary drop table T_TEST; -- Create the test table create table T_TEST (NAME varchar(50) not null);././@LongLink0000000000000000000000000000021500000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/datasource/embedded/db-schema.sqllibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframewor0000644000175000017500000000011611623223526033502 0ustar drazzibdrazzibdrop table T_TEST if exists; create table T_TEST (NAME varchar(50) not null);././@LongLink0000000000000000000000000000022000000000000011557 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/datasource/embedded/db-test-data.sqllibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframewor0000644000175000017500000000005311623223530033475 0ustar drazzibdrazzibinsert into T_TEST (NAME) values ('Keith');././@LongLink0000000000000000000000000000022300000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/datasource/embedded/db-schema-derby.sqllibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframewor0000644000175000017500000000006011623223526033500 0ustar drazzibdrazzibcreate table T_TEST (NAME varchar(50) not null);././@LongLink0000000000000000000000000000017400000000000011567 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/datasource/init/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframewor0000755000175000017500000000000011623223530033475 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000021400000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/datasource/init/users-schema.sqllibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframewor0000644000175000017500000000024211623223530033475 0ustar drazzibdrazzibDROP TABLE users IF EXISTS; CREATE TABLE users ( id INTEGER NOT NULL IDENTITY PRIMARY KEY, first_name VARCHAR(50) NOT NULL, last_name VARCHAR(50) NOT NULL ); ././@LongLink0000000000000000000000000000023600000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/datasource/init/db-schema-failed-drop-comments.sqllibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframewor0000644000175000017500000000021111623223530033471 0ustar drazzibdrazzib-- Failed DROP can be ignored if necessary drop table T_TEST; -- Create the test table create table T_TEST (NAME varchar(50) not null);././@LongLink0000000000000000000000000000021400000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/datasource/init/db-test-data.sqllibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframewor0000644000175000017500000000005311623223526033502 0ustar drazzibdrazzibinsert into T_TEST (NAME) values ('Keith');././@LongLink0000000000000000000000000000021200000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/datasource/init/users-data.sqllibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframewor0000644000175000017500000000010311623223530033471 0ustar drazzibdrazzibINSERT INTO users(first_name, last_name) values('Sam', 'Brannen'); ././@LongLink0000000000000000000000000000016300000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/object/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframewor0000755000175000017500000000000011623223526033502 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000023200000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/object/GenericStoredProcedureTests-context.xmllibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframewor0000644000175000017500000000300211623223526033477 0ustar drazzibdrazzib ././@LongLink0000000000000000000000000000022300000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/object/GenericSqlQueryTests-context.xmllibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframewor0000644000175000017500000000443111623223526033506 0ustar drazzibdrazzib ././@LongLink0000000000000000000000000000016300000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/config/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframewor0000755000175000017500000000000011623223530033475 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000023100000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/config/jdbc-initialize-placeholder-config.xmllibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframewor0000644000175000017500000000204411623223530033477 0ustar drazzibdrazzib schema.scripts=classpath:org/springframework/jdbc/config/db-schema.sql insert.scripts=classpath*:org/springframework/jdbc/config/*-data.sql data.source.init=true ././@LongLink0000000000000000000000000000021200000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/config/jdbc-config-pattern.xmllibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframewor0000644000175000017500000000130511623223530033476 0ustar drazzibdrazzib ././@LongLink0000000000000000000000000000022700000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/config/jdbc-config-multiple-datasources.xmllibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframewor0000644000175000017500000000106011623223530033474 0ustar drazzibdrazzib ././@LongLink0000000000000000000000000000022300000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/config/jdbc-initialize-cache-config.xmllibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframewor0000644000175000017500000000213011623223526033500 0ustar drazzibdrazzib ././@LongLink0000000000000000000000000000022500000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/config/jdbc-initialize-pattern-config.xmllibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframewor0000644000175000017500000000137511623223526033512 0ustar drazzibdrazzib ././@LongLink0000000000000000000000000000020200000000000011557 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/config/jdbc-config.xmllibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframewor0000644000175000017500000000232111623223526033502 0ustar drazzibdrazzib ././@LongLink0000000000000000000000000000020500000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/config/db-update-data.sqllibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframewor0000644000175000017500000000006111623223530033474 0ustar drazzibdrazzibupdate T_TEST set NAME='Dave' where name='Keith';././@LongLink0000000000000000000000000000020000000000000011555 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/config/db-schema.sqllibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframewor0000644000175000017500000000011611623223526033502 0ustar drazzibdrazzibdrop table T_TEST if exists; create table T_TEST (NAME varchar(50) not null);././@LongLink0000000000000000000000000000020300000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/config/db-test-data.sqllibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframewor0000644000175000017500000000005311623223526033502 0ustar drazzibdrazzibinsert into T_TEST (NAME) values ('Keith');././@LongLink0000000000000000000000000000017700000000000011572 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/config/db-drops.sqllibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframewor0000644000175000017500000000002311623223526033477 0ustar drazzibdrazzibdrop table T_TEST; ././@LongLink0000000000000000000000000000020600000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/config/db-schema-derby.sqllibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframewor0000644000175000017500000000006011623223526033500 0ustar drazzibdrazzibcreate table T_TEST (NAME varchar(50) not null);././@LongLink0000000000000000000000000000022200000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/config/jdbc-initialize-fail-config.xmllibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframewor0000644000175000017500000000155511623223526033512 0ustar drazzibdrazzib ././@LongLink0000000000000000000000000000021500000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/config/jdbc-initialize-config.xmllibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframewor0000644000175000017500000000145311623223526033507 0ustar drazzibdrazzib ././@LongLink0000000000000000000000000000016400000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/support/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframewor0000755000175000017500000000000011623223530033475 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000021200000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/support/custom-error-codes.xmllibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframewor0000644000175000017500000000154111623223530033500 0ustar drazzibdrazzib 1,2 1,1400,1722 999 org.springframework.jdbc.support.CustomErrorCodeException ././@LongLink0000000000000000000000000000021400000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/support/wildcard-error-codes.xmllibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframewor0000644000175000017500000000325011623223526033504 0ustar drazzibdrazzib 1,2,942 1,1400,1722 *DB0 -204,1,2 3,4 DB1* -204,1,2 3,4 *DB2* -204,1,2 3,4 *DB3* -204,1,2 3,4 ././@LongLink0000000000000000000000000000021000000000000011556 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframework/jdbc/support/test-error-codes.xmllibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/org/springframewor0000644000175000017500000000071411623223530033501 0ustar drazzibdrazzib 1,2 1,1400,1722 libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/resources/log4j.xml0000644000175000017500000000131611623223530031462 0ustar drazzibdrazzib libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/0000755000175000017500000000000011623223526026634 5ustar drazzibdrazziblibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/0000755000175000017500000000000011623223526027423 5ustar drazzibdrazziblibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/0000755000175000017500000000000011623223526032643 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000755000175000017500000000000011623223530033316 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000016200000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/datasource/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000755000175000017500000000000011623223530033316 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000017300000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/datasource/embedded/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000755000175000017500000000000011623223530033316 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000024000000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseFactoryBeanTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000000205111623223530033316 0ustar drazzibdrazzibpackage org.springframework.jdbc.datasource.embedded; import static org.junit.Assert.assertEquals; import javax.sql.DataSource; import org.junit.Test; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; public class EmbeddedDatabaseFactoryBeanTests { @Test public void testFactoryBeanLifecycle() throws Exception { EmbeddedDatabaseFactoryBean bean = new EmbeddedDatabaseFactoryBean(); ResourceDatabasePopulator populator = new ResourceDatabasePopulator(); populator.setScripts(new Resource[] { new ClassPathResource("db-schema.sql", getClass()), new ClassPathResource("db-test-data.sql", getClass()) }); bean.setDatabasePopulator(populator); bean.afterPropertiesSet(); DataSource ds = bean.getObject(); JdbcTemplate template = new JdbcTemplate(ds); assertEquals("Keith", template.queryForObject("select NAME from T_TEST", String.class)); bean.destroy(); } } ././@LongLink0000000000000000000000000000023400000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseFactoryTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000000144411623223530033323 0ustar drazzibdrazzibpackage org.springframework.jdbc.datasource.embedded; import static org.junit.Assert.assertTrue; import java.sql.Connection; import org.junit.Test; import org.springframework.jdbc.datasource.init.DatabasePopulator; public class EmbeddedDatabaseFactoryTests { private EmbeddedDatabaseFactory factory = new EmbeddedDatabaseFactory(); @Test public void testGetDataSource() { StubDatabasePopulator populator = new StubDatabasePopulator(); factory.setDatabasePopulator(populator); EmbeddedDatabase db = factory.getDatabase(); assertTrue(populator.populateCalled); db.shutdown(); } private static class StubDatabasePopulator implements DatabasePopulator { private boolean populateCalled; public void populate(Connection connection) { this.populateCalled = true; } } } ././@LongLink0000000000000000000000000000023400000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseBuilderTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000000574711623223526033342 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource.embedded; import static org.junit.Assert.*; import org.junit.Test; import org.springframework.core.io.ClassRelativeResourceLoader; import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.init.CannotReadScriptException; /** * @author Keith Donald */ public class EmbeddedDatabaseBuilderTests { @Test public void testBuildDefaultScripts() { EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder(); EmbeddedDatabase db = builder.addDefaultScripts().build(); assertDatabaseCreatedAndShutdown(db); } @Test public void testBuild() { EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder(new ClassRelativeResourceLoader(getClass())); EmbeddedDatabase db = builder.addScript("db-schema.sql").addScript("db-test-data.sql").build(); assertDatabaseCreatedAndShutdown(db); } @Test public void testBuildWithComments() { EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder(new ClassRelativeResourceLoader(getClass())); EmbeddedDatabase db = builder.addScript("db-schema-comments.sql").addScript("db-test-data.sql").build(); assertDatabaseCreatedAndShutdown(db); } @Test public void testBuildH2() { EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder(new ClassRelativeResourceLoader(getClass())); EmbeddedDatabase db = builder.setType(EmbeddedDatabaseType.H2).addScript("db-schema.sql").addScript("db-test-data.sql").build(); assertDatabaseCreatedAndShutdown(db); } @Test public void testBuildDerby() { EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder(new ClassRelativeResourceLoader(getClass())); EmbeddedDatabase db = builder.setType(EmbeddedDatabaseType.DERBY).addScript("db-schema-derby.sql").addScript("db-test-data.sql").build(); assertDatabaseCreatedAndShutdown(db); } @Test public void testBuildNoSuchScript() { try { new EmbeddedDatabaseBuilder().addScript("bogus.sql").build(); fail("Should have failed"); } catch (DataAccessResourceFailureException ex) { assertTrue(ex.getCause() instanceof CannotReadScriptException); } } private void assertDatabaseCreatedAndShutdown(EmbeddedDatabase db) { JdbcTemplate template = new JdbcTemplate(db); assertEquals("Keith", template.queryForObject("select NAME from T_TEST", String.class)); db.shutdown(); } }././@LongLink0000000000000000000000000000023400000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/datasource/UserCredentialsDataSourceAdapterTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000000553611623223530033331 0ustar drazzibdrazzib/* * Copyright 2002-2005 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource; import java.sql.Connection; import java.sql.SQLException; import javax.sql.DataSource; import junit.framework.TestCase; import org.easymock.MockControl; /** * @author Juergen Hoeller * @since 28.05.2004 */ public class UserCredentialsDataSourceAdapterTests extends TestCase { public void testStaticCredentials() throws SQLException { MockControl dsControl = MockControl.createControl(DataSource.class); DataSource ds = (DataSource) dsControl.getMock(); MockControl conControl = MockControl.createControl(Connection.class); Connection con = (Connection) conControl.getMock(); ds.getConnection("user", "pw"); dsControl.setReturnValue(con); dsControl.replay(); conControl.replay(); UserCredentialsDataSourceAdapter adapter = new UserCredentialsDataSourceAdapter(); adapter.setTargetDataSource(ds); adapter.setUsername("user"); adapter.setPassword("pw"); assertEquals(con, adapter.getConnection()); } public void testNoCredentials() throws SQLException { MockControl dsControl = MockControl.createControl(DataSource.class); DataSource ds = (DataSource) dsControl.getMock(); MockControl conControl = MockControl.createControl(Connection.class); Connection con = (Connection) conControl.getMock(); ds.getConnection(); dsControl.setReturnValue(con); dsControl.replay(); conControl.replay(); UserCredentialsDataSourceAdapter adapter = new UserCredentialsDataSourceAdapter(); adapter.setTargetDataSource(ds); assertEquals(con, adapter.getConnection()); } public void testThreadBoundCredentials() throws SQLException { MockControl dsControl = MockControl.createControl(DataSource.class); DataSource ds = (DataSource) dsControl.getMock(); MockControl conControl = MockControl.createControl(Connection.class); Connection con = (Connection) conControl.getMock(); ds.getConnection("user", "pw"); dsControl.setReturnValue(con); dsControl.replay(); conControl.replay(); UserCredentialsDataSourceAdapter adapter = new UserCredentialsDataSourceAdapter(); adapter.setTargetDataSource(ds); adapter.setCredentialsForCurrentThread("user", "pw"); try { assertEquals(con, adapter.getConnection()); } finally { adapter.removeCredentialsFromCurrentThread(); } } } ././@LongLink0000000000000000000000000000017100000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/datasource/lookup/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000755000175000017500000000000011623223530033316 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000021400000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/datasource/lookup/StubDataSource.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000000233311623223530033321 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource.lookup; import java.sql.Connection; import java.sql.SQLException; import org.springframework.jdbc.datasource.AbstractDataSource; /** * Stub, do-nothing DataSource implementation. * *

All methods throw {@link UnsupportedOperationException}. * * @author Rick Evans */ class StubDataSource extends AbstractDataSource { public Connection getConnection() throws SQLException { throw new UnsupportedOperationException(); } public Connection getConnection(String username, String password) throws SQLException { throw new UnsupportedOperationException(); } } ././@LongLink0000000000000000000000000000022700000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/datasource/lookup/JndiDataSourceLookupTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000000403311623223526033325 0ustar drazzibdrazzib/* * Copyright 2002-2006 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource.lookup; import static org.junit.Assert.*; import javax.naming.NamingException; import javax.sql.DataSource; import org.junit.Test; /** * @author Rick Evans * @author Chris Beams */ public final class JndiDataSourceLookupTests { private static final String DATA_SOURCE_NAME = "Love is like a stove, burns you when it's hot"; @Test public void testSunnyDay() throws Exception { final DataSource expectedDataSource = new StubDataSource(); JndiDataSourceLookup lookup = new JndiDataSourceLookup() { @SuppressWarnings("unchecked") protected Object lookup(String jndiName, Class requiredType) { assertEquals(DATA_SOURCE_NAME, jndiName); return expectedDataSource; } }; DataSource dataSource = lookup.getDataSource(DATA_SOURCE_NAME); assertNotNull("A DataSourceLookup implementation must *never* return null from getDataSource(): this one obviously (and incorrectly) is", dataSource); assertSame(expectedDataSource, dataSource); } @Test(expected=DataSourceLookupFailureException.class) public void testNoDataSourceAtJndiLocation() throws Exception { JndiDataSourceLookup lookup = new JndiDataSourceLookup() { @SuppressWarnings("unchecked") protected Object lookup(String jndiName, Class requiredType) throws NamingException { assertEquals(DATA_SOURCE_NAME, jndiName); throw new NamingException(); } }; lookup.getDataSource(DATA_SOURCE_NAME); } } ././@LongLink0000000000000000000000000000022600000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/datasource/lookup/MapDataSourceLookupTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000001000711623223526033323 0ustar drazzibdrazzib/* * Copyright 2002-2006 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource.lookup; import static org.junit.Assert.*; import java.util.HashMap; import java.util.Map; import javax.sql.DataSource; import org.junit.Test; /** * @author Rick Evans * @author Chris Beams */ public final class MapDataSourceLookupTests { private static final String DATA_SOURCE_NAME = "dataSource"; @SuppressWarnings("unchecked") @Test(expected=UnsupportedOperationException.class) public void testGetDataSourcesReturnsUnmodifiableMap() throws Exception { MapDataSourceLookup lookup = new MapDataSourceLookup(new HashMap()); Map dataSources = lookup.getDataSources(); dataSources.put("", ""); } @Test public void testLookupSunnyDay() throws Exception { Map dataSources = new HashMap(); StubDataSource expectedDataSource = new StubDataSource(); dataSources.put(DATA_SOURCE_NAME, expectedDataSource); MapDataSourceLookup lookup = new MapDataSourceLookup(); lookup.setDataSources(dataSources); DataSource dataSource = lookup.getDataSource(DATA_SOURCE_NAME); assertNotNull("A DataSourceLookup implementation must *never* return null from getDataSource(): this one obviously (and incorrectly) is", dataSource); assertSame(expectedDataSource, dataSource); } @Test public void testSettingDataSourceMapToNullIsAnIdempotentOperation() throws Exception { Map dataSources = new HashMap(); StubDataSource expectedDataSource = new StubDataSource(); dataSources.put(DATA_SOURCE_NAME, expectedDataSource); MapDataSourceLookup lookup = new MapDataSourceLookup(); lookup.setDataSources(dataSources); lookup.setDataSources(null); // must be idempotent (i.e. the following lookup must still work); DataSource dataSource = lookup.getDataSource(DATA_SOURCE_NAME); assertNotNull("A DataSourceLookup implementation must *never* return null from getDataSource(): this one obviously (and incorrectly) is", dataSource); assertSame(expectedDataSource, dataSource); } @Test public void testAddingDataSourcePermitsOverride() throws Exception { Map dataSources = new HashMap(); StubDataSource overridenDataSource = new StubDataSource(); StubDataSource expectedDataSource = new StubDataSource(); dataSources.put(DATA_SOURCE_NAME, overridenDataSource); MapDataSourceLookup lookup = new MapDataSourceLookup(); lookup.setDataSources(dataSources); lookup.addDataSource(DATA_SOURCE_NAME, expectedDataSource); // must override existing entry DataSource dataSource = lookup.getDataSource(DATA_SOURCE_NAME); assertNotNull("A DataSourceLookup implementation must *never* return null from getDataSource(): this one obviously (and incorrectly) is", dataSource); assertSame(expectedDataSource, dataSource); } @SuppressWarnings("unchecked") @Test(expected=ClassCastException.class) public void testGetDataSourceWhereSuppliedMapHasNonDataSourceTypeUnderSpecifiedKey() throws Exception { Map dataSources = new HashMap(); dataSources.put(DATA_SOURCE_NAME, new Object()); MapDataSourceLookup lookup = new MapDataSourceLookup(); lookup.setDataSources(dataSources); lookup.getDataSource(DATA_SOURCE_NAME); } @Test(expected=DataSourceLookupFailureException.class) public void testGetDataSourceWhereSuppliedMapHasNoEntryForSpecifiedKey() throws Exception { MapDataSourceLookup lookup = new MapDataSourceLookup(); lookup.getDataSource(DATA_SOURCE_NAME); } } ././@LongLink0000000000000000000000000000023600000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/datasource/lookup/BeanFactoryDataSourceLookupTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000000527611623223530033332 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource.lookup; import static org.easymock.EasyMock.*; import static org.junit.Assert.*; import javax.sql.DataSource; import org.junit.Test; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanNotOfRequiredTypeException; /** * @author Rick Evans * @author Juergen Hoeller * @author Chris Beams */ public class BeanFactoryDataSourceLookupTests { private static final String DATASOURCE_BEAN_NAME = "dataSource"; @Test public void testLookupSunnyDay() { BeanFactory beanFactory = createMock(BeanFactory.class); StubDataSource expectedDataSource = new StubDataSource(); expect(beanFactory.getBean(DATASOURCE_BEAN_NAME, DataSource.class)).andReturn(expectedDataSource); replay(beanFactory); BeanFactoryDataSourceLookup lookup = new BeanFactoryDataSourceLookup(); lookup.setBeanFactory(beanFactory); DataSource dataSource = lookup.getDataSource(DATASOURCE_BEAN_NAME); assertNotNull("A DataSourceLookup implementation must *never* return null from " + "getDataSource(): this one obviously (and incorrectly) is", dataSource); assertSame(expectedDataSource, dataSource); verify(beanFactory); } @Test public void testLookupWhereBeanFactoryYieldsNonDataSourceType() throws Exception { final BeanFactory beanFactory = createMock(BeanFactory.class); expect( beanFactory.getBean(DATASOURCE_BEAN_NAME, DataSource.class) ).andThrow(new BeanNotOfRequiredTypeException(DATASOURCE_BEAN_NAME, DataSource.class, String.class)); replay(beanFactory); try { BeanFactoryDataSourceLookup lookup = new BeanFactoryDataSourceLookup(beanFactory); lookup.getDataSource(DATASOURCE_BEAN_NAME); fail("should have thrown DataSourceLookupFailureException"); } catch (DataSourceLookupFailureException ex) { /* expected */ } verify(beanFactory); } @Test(expected=IllegalStateException.class) public void testLookupWhereBeanFactoryHasNotBeenSupplied() throws Exception { BeanFactoryDataSourceLookup lookup = new BeanFactoryDataSourceLookup(); lookup.getDataSource(DATASOURCE_BEAN_NAME); } } ././@LongLink0000000000000000000000000000023000000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/datasource/DataSourceTransactionManagerTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000023204311623223530033324 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Savepoint; import javax.sql.DataSource; import junit.framework.TestCase; import org.easymock.MockControl; import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.jdbc.UncategorizedSQLException; import org.springframework.jdbc.support.nativejdbc.SimpleNativeJdbcExtractor; import org.springframework.transaction.CannotCreateTransactionException; import org.springframework.transaction.IllegalTransactionStateException; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.TransactionSystemException; import org.springframework.transaction.TransactionTimedOutException; import org.springframework.transaction.UnexpectedRollbackException; import org.springframework.transaction.support.DefaultTransactionDefinition; import org.springframework.transaction.support.TransactionCallbackWithoutResult; import org.springframework.transaction.support.TransactionSynchronization; import org.springframework.transaction.support.TransactionSynchronizationManager; import org.springframework.transaction.support.TransactionTemplate; /** * @author Juergen Hoeller * @since 04.07.2003 */ public class DataSourceTransactionManagerTests extends TestCase { public void testTransactionCommitWithAutoCommitTrue() throws Exception { doTestTransactionCommitRestoringAutoCommit(true, false, false); } public void testTransactionCommitWithAutoCommitFalse() throws Exception { doTestTransactionCommitRestoringAutoCommit(false, false, false); } public void testTransactionCommitWithAutoCommitTrueAndLazyConnection() throws Exception { doTestTransactionCommitRestoringAutoCommit(true, true, false); } public void testTransactionCommitWithAutoCommitFalseAndLazyConnection() throws Exception { doTestTransactionCommitRestoringAutoCommit(false, true, false); } public void testTransactionCommitWithAutoCommitTrueAndLazyConnectionAndStatementCreated() throws Exception { doTestTransactionCommitRestoringAutoCommit(true, true, true); } public void testTransactionCommitWithAutoCommitFalseAndLazyConnectionAndStatementCreated() throws Exception { doTestTransactionCommitRestoringAutoCommit(false, true, true); } private void doTestTransactionCommitRestoringAutoCommit( boolean autoCommit, boolean lazyConnection, final boolean createStatement) throws Exception { MockControl dsControl = MockControl.createControl(DataSource.class); DataSource ds = (DataSource) dsControl.getMock(); MockControl conControl = MockControl.createControl(Connection.class); final Connection con = (Connection) conControl.getMock(); if (lazyConnection) { ds.getConnection(); dsControl.setReturnValue(con, 1); if (createStatement) { con.getMetaData(); conControl.setReturnValue(null, 1); } con.getAutoCommit(); conControl.setReturnValue(autoCommit, 1); con.getTransactionIsolation(); conControl.setReturnValue(Connection.TRANSACTION_READ_COMMITTED, 1); con.close(); conControl.setVoidCallable(1); } if (!lazyConnection || createStatement) { ds.getConnection(); dsControl.setReturnValue(con, 1); con.getAutoCommit(); conControl.setReturnValue(autoCommit, 1); if (autoCommit) { // Must disable autocommit con.setAutoCommit(false); conControl.setVoidCallable(1); } if (createStatement) { con.createStatement(); conControl.setReturnValue(null, 1); } con.commit(); conControl.setVoidCallable(1); con.isReadOnly(); conControl.setReturnValue(false, 1); if (autoCommit) { // must restore autoCommit con.setAutoCommit(true); conControl.setVoidCallable(1); } con.close(); conControl.setVoidCallable(1); } conControl.replay(); dsControl.replay(); final DataSource dsToUse = (lazyConnection ? new LazyConnectionDataSourceProxy(ds) : ds); PlatformTransactionManager tm = new DataSourceTransactionManager(dsToUse); TransactionTemplate tt = new TransactionTemplate(tm); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(dsToUse)); assertTrue("Synchronization not active", !TransactionSynchronizationManager.isSynchronizationActive()); tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(dsToUse)); assertTrue("Synchronization active", TransactionSynchronizationManager.isSynchronizationActive()); assertTrue("Is new transaction", status.isNewTransaction()); assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); assertTrue(TransactionSynchronizationManager.isActualTransactionActive()); Connection tCon = DataSourceUtils.getConnection(dsToUse); try { if (createStatement) { tCon.createStatement(); assertEquals(con, new SimpleNativeJdbcExtractor().getNativeConnection(tCon)); } } catch (SQLException ex) { throw new UncategorizedSQLException("", "", ex); } } }); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(dsToUse)); assertTrue("Synchronization not active", !TransactionSynchronizationManager.isSynchronizationActive()); conControl.verify(); dsControl.verify(); } public void testTransactionRollbackWithAutoCommitTrue() throws Exception { doTestTransactionRollbackRestoringAutoCommit(true, false, false); } public void testTransactionRollbackWithAutoCommitFalse() throws Exception { doTestTransactionRollbackRestoringAutoCommit(false, false, false); } public void testTransactionRollbackWithAutoCommitTrueAndLazyConnection() throws Exception { doTestTransactionRollbackRestoringAutoCommit(true, true, false); } public void testTransactionRollbackWithAutoCommitFalseAndLazyConnection() throws Exception { doTestTransactionRollbackRestoringAutoCommit(false, true, false); } public void testTransactionRollbackWithAutoCommitTrueAndLazyConnectionAndCreateStatement() throws Exception { doTestTransactionRollbackRestoringAutoCommit(true, true, true); } public void testTransactionRollbackWithAutoCommitFalseAndLazyConnectionAndCreateStatement() throws Exception { doTestTransactionRollbackRestoringAutoCommit(false, true, true); } private void doTestTransactionRollbackRestoringAutoCommit( boolean autoCommit, boolean lazyConnection, final boolean createStatement) throws Exception { MockControl dsControl = MockControl.createControl(DataSource.class); DataSource ds = (DataSource) dsControl.getMock(); MockControl conControl = MockControl.createControl(Connection.class); Connection con = (Connection) conControl.getMock(); if (lazyConnection) { ds.getConnection(); dsControl.setReturnValue(con, 1); con.getAutoCommit(); conControl.setReturnValue(autoCommit, 1); con.getTransactionIsolation(); conControl.setReturnValue(Connection.TRANSACTION_READ_COMMITTED, 1); con.close(); conControl.setVoidCallable(1); } if (!lazyConnection || createStatement) { ds.getConnection(); dsControl.setReturnValue(con, 1); con.getAutoCommit(); conControl.setReturnValue(autoCommit, 1); if (autoCommit) { // Must disable autocommit con.setAutoCommit(false); conControl.setVoidCallable(1); } if (createStatement) { con.createStatement(); conControl.setReturnValue(null, 1); } con.rollback(); conControl.setVoidCallable(1); con.isReadOnly(); conControl.setReturnValue(false, 1); if (autoCommit) { // Must restore autocommit con.setAutoCommit(true); conControl.setVoidCallable(1); } con.close(); conControl.setVoidCallable(1); } conControl.replay(); dsControl.replay(); final DataSource dsToUse = (lazyConnection ? new LazyConnectionDataSourceProxy(ds) : ds); PlatformTransactionManager tm = new DataSourceTransactionManager(dsToUse); TransactionTemplate tt = new TransactionTemplate(tm); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(dsToUse)); assertTrue("Synchronization not active", !TransactionSynchronizationManager.isSynchronizationActive()); final RuntimeException ex = new RuntimeException("Application exception"); try { tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(dsToUse)); assertTrue("Synchronization active", TransactionSynchronizationManager.isSynchronizationActive()); assertTrue("Is new transaction", status.isNewTransaction()); Connection con = DataSourceUtils.getConnection(dsToUse); if (createStatement) { try { con.createStatement(); } catch (SQLException ex) { throw new UncategorizedSQLException("", "", ex); } } throw ex; } }); fail("Should have thrown RuntimeException"); } catch (RuntimeException ex2) { // expected assertTrue("Correct exception thrown", ex2.equals(ex)); } assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); assertTrue("Synchronization not active", !TransactionSynchronizationManager.isSynchronizationActive()); conControl.verify(); dsControl.verify(); } public void testTransactionRollbackOnly() throws Exception { MockControl conControl = MockControl.createControl(Connection.class); Connection con = (Connection) conControl.getMock(); MockControl dsControl = MockControl.createControl(DataSource.class); final DataSource ds = (DataSource) dsControl.getMock(); conControl.replay(); dsControl.replay(); DataSourceTransactionManager tm = new DataSourceTransactionManager(ds); tm.setTransactionSynchronization(DataSourceTransactionManager.SYNCHRONIZATION_NEVER); TransactionTemplate tt = new TransactionTemplate(tm); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); assertTrue("Synchronization not active", !TransactionSynchronizationManager.isSynchronizationActive()); ConnectionHolder conHolder = new ConnectionHolder(con); conHolder.setTransactionActive(true); TransactionSynchronizationManager.bindResource(ds, conHolder); final RuntimeException ex = new RuntimeException("Application exception"); try { tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds)); assertTrue("Synchronization not active", !TransactionSynchronizationManager.isSynchronizationActive()); assertTrue("Is existing transaction", !status.isNewTransaction()); throw ex; } }); fail("Should have thrown RuntimeException"); } catch (RuntimeException ex2) { // expected assertTrue("Synchronization not active", !TransactionSynchronizationManager.isSynchronizationActive()); assertEquals("Correct exception thrown", ex, ex2); } finally { TransactionSynchronizationManager.unbindResource(ds); } assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); conControl.verify(); dsControl.verify(); } public void testParticipatingTransactionWithRollbackOnly() throws Exception { doTestParticipatingTransactionWithRollbackOnly(false); } public void testParticipatingTransactionWithRollbackOnlyAndFailEarly() throws Exception { doTestParticipatingTransactionWithRollbackOnly(true); } private void doTestParticipatingTransactionWithRollbackOnly(boolean failEarly) throws Exception { MockControl conControl = MockControl.createControl(Connection.class); Connection con = (Connection) conControl.getMock(); con.getAutoCommit(); conControl.setReturnValue(false, 1); con.rollback(); conControl.setVoidCallable(1); con.isReadOnly(); conControl.setReturnValue(false, 1); con.close(); conControl.setVoidCallable(1); MockControl dsControl = MockControl.createControl(DataSource.class); final DataSource ds = (DataSource) dsControl.getMock(); ds.getConnection(); dsControl.setReturnValue(con, 1); conControl.replay(); dsControl.replay(); DataSourceTransactionManager tm = new DataSourceTransactionManager(ds); if (failEarly) { tm.setFailEarlyOnGlobalRollbackOnly(true); } assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); assertTrue("Synchronization not active", !TransactionSynchronizationManager.isSynchronizationActive()); TransactionStatus ts = tm.getTransaction(new DefaultTransactionDefinition()); TestTransactionSynchronization synch = new TestTransactionSynchronization(ds, TransactionSynchronization.STATUS_ROLLED_BACK); TransactionSynchronizationManager.registerSynchronization(synch); boolean outerTransactionBoundaryReached = false; try { assertTrue("Is new transaction", ts.isNewTransaction()); final TransactionTemplate tt = new TransactionTemplate(tm); tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { assertTrue("Is existing transaction", !status.isNewTransaction()); assertFalse("Is not rollback-only", status.isRollbackOnly()); tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds)); assertTrue("Synchronization active", TransactionSynchronizationManager.isSynchronizationActive()); assertTrue("Is existing transaction", !status.isNewTransaction()); status.setRollbackOnly(); } }); assertTrue("Is existing transaction", !status.isNewTransaction()); assertTrue("Is rollback-only", status.isRollbackOnly()); } }); outerTransactionBoundaryReached = true; tm.commit(ts); fail("Should have thrown UnexpectedRollbackException"); } catch (UnexpectedRollbackException ex) { // expected if (!outerTransactionBoundaryReached) { tm.rollback(ts); } if (failEarly) { assertFalse(outerTransactionBoundaryReached); } else { assertTrue(outerTransactionBoundaryReached); } } assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); assertFalse(synch.beforeCommitCalled); assertTrue(synch.beforeCompletionCalled); assertFalse(synch.afterCommitCalled); assertTrue(synch.afterCompletionCalled); conControl.verify(); dsControl.verify(); } public void testParticipatingTransactionWithIncompatibleIsolationLevel() throws Exception { MockControl conControl = MockControl.createControl(Connection.class); Connection con = (Connection) conControl.getMock(); con.getAutoCommit(); conControl.setReturnValue(false, 1); con.rollback(); conControl.setVoidCallable(1); con.isReadOnly(); conControl.setReturnValue(false, 1); con.close(); conControl.setVoidCallable(1); MockControl dsControl = MockControl.createControl(DataSource.class); final DataSource ds = (DataSource) dsControl.getMock(); ds.getConnection(); dsControl.setReturnValue(con, 1); conControl.replay(); dsControl.replay(); DataSourceTransactionManager tm = new DataSourceTransactionManager(ds); tm.setValidateExistingTransaction(true); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); assertTrue("Synchronization not active", !TransactionSynchronizationManager.isSynchronizationActive()); try { final TransactionTemplate tt = new TransactionTemplate(tm); final TransactionTemplate tt2 = new TransactionTemplate(tm); tt2.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE); tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { assertFalse("Is not rollback-only", status.isRollbackOnly()); tt2.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { status.setRollbackOnly(); } }); assertTrue("Is rollback-only", status.isRollbackOnly()); } }); fail("Should have thrown IllegalTransactionStateException"); } catch (IllegalTransactionStateException ex) { // expected } assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); conControl.verify(); dsControl.verify(); } public void testParticipatingTransactionWithIncompatibleReadOnly() throws Exception { MockControl conControl = MockControl.createControl(Connection.class); Connection con = (Connection) conControl.getMock(); con.getAutoCommit(); conControl.setReturnValue(false, 1); con.rollback(); conControl.setVoidCallable(1); con.setReadOnly(true); conControl.setThrowable(new SQLException("read-only not supported"), 1); con.isReadOnly(); conControl.setReturnValue(false, 1); con.close(); conControl.setVoidCallable(1); MockControl dsControl = MockControl.createControl(DataSource.class); final DataSource ds = (DataSource) dsControl.getMock(); ds.getConnection(); dsControl.setReturnValue(con, 1); conControl.replay(); dsControl.replay(); DataSourceTransactionManager tm = new DataSourceTransactionManager(ds); tm.setValidateExistingTransaction(true); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); assertTrue("Synchronization not active", !TransactionSynchronizationManager.isSynchronizationActive()); try { final TransactionTemplate tt = new TransactionTemplate(tm); tt.setReadOnly(true); final TransactionTemplate tt2 = new TransactionTemplate(tm); tt2.setReadOnly(false); tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { assertFalse("Is not rollback-only", status.isRollbackOnly()); tt2.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { status.setRollbackOnly(); } }); assertTrue("Is rollback-only", status.isRollbackOnly()); } }); fail("Should have thrown IllegalTransactionStateException"); } catch (IllegalTransactionStateException ex) { // expected } assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); conControl.verify(); dsControl.verify(); } public void testParticipatingTransactionWithTransactionStartedFromSynch() throws Exception { MockControl conControl = MockControl.createControl(Connection.class); Connection con = (Connection) conControl.getMock(); con.getAutoCommit(); conControl.setReturnValue(false, 2); con.commit(); conControl.setVoidCallable(2); con.isReadOnly(); conControl.setReturnValue(false, 2); con.close(); conControl.setVoidCallable(2); MockControl dsControl = MockControl.createControl(DataSource.class); final DataSource ds = (DataSource) dsControl.getMock(); ds.getConnection(); dsControl.setReturnValue(con, 2); conControl.replay(); dsControl.replay(); DataSourceTransactionManager tm = new DataSourceTransactionManager(ds); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); assertTrue("Synchronization not active", !TransactionSynchronizationManager.isSynchronizationActive()); final TransactionTemplate tt = new TransactionTemplate(tm); tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); final TestTransactionSynchronization synch = new TestTransactionSynchronization(ds, TransactionSynchronization.STATUS_COMMITTED) { public void afterCompletion(int status) { super.afterCompletion(status); tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { } }); } }; tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { TransactionSynchronizationManager.registerSynchronization(synch); } }); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); assertTrue(synch.beforeCommitCalled); assertTrue(synch.beforeCompletionCalled); assertTrue(synch.afterCommitCalled); assertTrue(synch.afterCompletionCalled); conControl.verify(); dsControl.verify(); } public void testParticipatingTransactionWithRollbackOnlyAndInnerSynch() throws Exception { MockControl conControl = MockControl.createControl(Connection.class); Connection con = (Connection) conControl.getMock(); con.getAutoCommit(); conControl.setReturnValue(false, 1); con.rollback(); conControl.setVoidCallable(1); con.isReadOnly(); conControl.setReturnValue(false, 1); con.close(); conControl.setVoidCallable(1); MockControl dsControl = MockControl.createControl(DataSource.class); final DataSource ds = (DataSource) dsControl.getMock(); ds.getConnection(); dsControl.setReturnValue(con, 1); conControl.replay(); dsControl.replay(); DataSourceTransactionManager tm = new DataSourceTransactionManager(ds); tm.setTransactionSynchronization(DataSourceTransactionManager.SYNCHRONIZATION_NEVER); DataSourceTransactionManager tm2 = new DataSourceTransactionManager(ds); // tm has no synch enabled (used at outer level), tm2 has synch enabled (inner level) assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); assertTrue("Synchronization not active", !TransactionSynchronizationManager.isSynchronizationActive()); TransactionStatus ts = tm.getTransaction(new DefaultTransactionDefinition()); final TestTransactionSynchronization synch = new TestTransactionSynchronization(ds, TransactionSynchronization.STATUS_UNKNOWN); try { assertTrue("Is new transaction", ts.isNewTransaction()); final TransactionTemplate tt = new TransactionTemplate(tm2); tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { assertTrue("Is existing transaction", !status.isNewTransaction()); assertFalse("Is not rollback-only", status.isRollbackOnly()); tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds)); assertTrue("Synchronization active", TransactionSynchronizationManager.isSynchronizationActive()); assertTrue("Is existing transaction", !status.isNewTransaction()); status.setRollbackOnly(); } }); assertTrue("Is existing transaction", !status.isNewTransaction()); assertTrue("Is rollback-only", status.isRollbackOnly()); TransactionSynchronizationManager.registerSynchronization(synch); } }); tm.commit(ts); fail("Should have thrown UnexpectedRollbackException"); } catch (UnexpectedRollbackException ex) { // expected } assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); assertFalse(synch.beforeCommitCalled); assertTrue(synch.beforeCompletionCalled); assertFalse(synch.afterCommitCalled); assertTrue(synch.afterCompletionCalled); conControl.verify(); dsControl.verify(); } public void testPropagationRequiresNewWithExistingTransaction() throws Exception { MockControl conControl = MockControl.createControl(Connection.class); Connection con = (Connection) conControl.getMock(); con.getAutoCommit(); conControl.setReturnValue(false, 2); con.rollback(); conControl.setVoidCallable(1); con.commit(); conControl.setVoidCallable(1); con.isReadOnly(); conControl.setReturnValue(false, 2); con.close(); conControl.setVoidCallable(2); MockControl dsControl = MockControl.createControl(DataSource.class); final DataSource ds = (DataSource) dsControl.getMock(); ds.getConnection(); dsControl.setReturnValue(con, 2); conControl.replay(); dsControl.replay(); PlatformTransactionManager tm = new DataSourceTransactionManager(ds); final TransactionTemplate tt = new TransactionTemplate(tm); tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); assertTrue("Synchronization not active", !TransactionSynchronizationManager.isSynchronizationActive()); tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { assertTrue("Is new transaction", status.isNewTransaction()); assertTrue("Synchronization active", TransactionSynchronizationManager.isSynchronizationActive()); assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); assertTrue(TransactionSynchronizationManager.isActualTransactionActive()); tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds)); assertTrue("Synchronization active", TransactionSynchronizationManager.isSynchronizationActive()); assertTrue("Is new transaction", status.isNewTransaction()); assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); assertTrue(TransactionSynchronizationManager.isActualTransactionActive()); status.setRollbackOnly(); } }); assertTrue("Is new transaction", status.isNewTransaction()); assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); assertTrue(TransactionSynchronizationManager.isActualTransactionActive()); } }); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); conControl.verify(); dsControl.verify(); } public void testPropagationRequiresNewWithExistingTransactionAndUnrelatedDataSource() throws Exception { MockControl conControl = MockControl.createControl(Connection.class); Connection con = (Connection) conControl.getMock(); con.getAutoCommit(); conControl.setReturnValue(false, 1); con.commit(); conControl.setVoidCallable(1); con.isReadOnly(); conControl.setReturnValue(false, 1); con.close(); conControl.setVoidCallable(1); MockControl dsControl = MockControl.createControl(DataSource.class); final DataSource ds = (DataSource) dsControl.getMock(); ds.getConnection(); dsControl.setReturnValue(con, 1); conControl.replay(); dsControl.replay(); MockControl con2Control = MockControl.createControl(Connection.class); Connection con2 = (Connection) con2Control.getMock(); con2.getAutoCommit(); con2Control.setReturnValue(false, 1); con2.rollback(); con2Control.setVoidCallable(1); con2.isReadOnly(); con2Control.setReturnValue(false, 1); con2.close(); con2Control.setVoidCallable(1); MockControl ds2Control = MockControl.createControl(DataSource.class); final DataSource ds2 = (DataSource) ds2Control.getMock(); ds2.getConnection(); ds2Control.setReturnValue(con2, 1); con2Control.replay(); ds2Control.replay(); PlatformTransactionManager tm = new DataSourceTransactionManager(ds); final TransactionTemplate tt = new TransactionTemplate(tm); tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); PlatformTransactionManager tm2 = new DataSourceTransactionManager(ds2); final TransactionTemplate tt2 = new TransactionTemplate(tm2); tt2.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds2)); assertTrue("Synchronization not active", !TransactionSynchronizationManager.isSynchronizationActive()); tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { assertTrue("Is new transaction", status.isNewTransaction()); assertTrue("Synchronization active", TransactionSynchronizationManager.isSynchronizationActive()); assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); assertTrue(TransactionSynchronizationManager.isActualTransactionActive()); tt2.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds)); assertTrue("Synchronization active", TransactionSynchronizationManager.isSynchronizationActive()); assertTrue("Is new transaction", status.isNewTransaction()); assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); assertTrue(TransactionSynchronizationManager.isActualTransactionActive()); status.setRollbackOnly(); } }); assertTrue("Is new transaction", status.isNewTransaction()); assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); assertTrue(TransactionSynchronizationManager.isActualTransactionActive()); } }); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds2)); conControl.verify(); dsControl.verify(); con2Control.verify(); ds2Control.verify(); } public void testPropagationRequiresNewWithExistingTransactionAndUnrelatedFailingDataSource() throws Exception { MockControl conControl = MockControl.createControl(Connection.class); Connection con = (Connection) conControl.getMock(); con.getAutoCommit(); conControl.setReturnValue(false, 1); con.rollback(); conControl.setVoidCallable(1); con.isReadOnly(); conControl.setReturnValue(false, 1); con.close(); conControl.setVoidCallable(1); MockControl dsControl = MockControl.createControl(DataSource.class); final DataSource ds = (DataSource) dsControl.getMock(); ds.getConnection(); dsControl.setReturnValue(con, 1); conControl.replay(); dsControl.replay(); MockControl ds2Control = MockControl.createControl(DataSource.class); final DataSource ds2 = (DataSource) ds2Control.getMock(); SQLException failure = new SQLException(); ds2.getConnection(); ds2Control.setThrowable(failure); ds2Control.replay(); DataSourceTransactionManager tm = new DataSourceTransactionManager(ds); final TransactionTemplate tt = new TransactionTemplate(tm); tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); DataSourceTransactionManager tm2 = new DataSourceTransactionManager(ds2); tm2.setTransactionSynchronization(DataSourceTransactionManager.SYNCHRONIZATION_NEVER); final TransactionTemplate tt2 = new TransactionTemplate(tm2); tt2.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds2)); assertTrue("Synchronization not active", !TransactionSynchronizationManager.isSynchronizationActive()); try { tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { assertTrue("Is new transaction", status.isNewTransaction()); assertTrue("Synchronization active", TransactionSynchronizationManager.isSynchronizationActive()); assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); assertTrue(TransactionSynchronizationManager.isActualTransactionActive()); tt2.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { status.setRollbackOnly(); } }); } }); fail("Should have thrown CannotCreateTransactionException"); } catch (CannotCreateTransactionException ex) { assertSame(failure, ex.getCause()); } assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds2)); conControl.verify(); dsControl.verify(); ds2Control.verify(); } public void testPropagationNotSupportedWithExistingTransaction() throws Exception { MockControl conControl = MockControl.createControl(Connection.class); Connection con = (Connection) conControl.getMock(); con.getAutoCommit(); conControl.setReturnValue(false, 1); con.commit(); conControl.setVoidCallable(1); con.isReadOnly(); conControl.setReturnValue(false, 1); con.close(); conControl.setVoidCallable(1); MockControl dsControl = MockControl.createControl(DataSource.class); final DataSource ds = (DataSource) dsControl.getMock(); ds.getConnection(); dsControl.setReturnValue(con, 1); conControl.replay(); dsControl.replay(); PlatformTransactionManager tm = new DataSourceTransactionManager(ds); final TransactionTemplate tt = new TransactionTemplate(tm); tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); assertTrue("Synchronization not active", !TransactionSynchronizationManager.isSynchronizationActive()); tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { assertTrue("Is new transaction", status.isNewTransaction()); assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); assertTrue(TransactionSynchronizationManager.isActualTransactionActive()); tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_NOT_SUPPORTED); tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); assertTrue("Synchronization active", TransactionSynchronizationManager.isSynchronizationActive()); assertTrue("Isn't new transaction", !status.isNewTransaction()); assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); assertFalse(TransactionSynchronizationManager.isActualTransactionActive()); status.setRollbackOnly(); } }); assertTrue("Is new transaction", status.isNewTransaction()); assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); assertTrue(TransactionSynchronizationManager.isActualTransactionActive()); } }); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); conControl.verify(); dsControl.verify(); } public void testPropagationNeverWithExistingTransaction() throws Exception { MockControl conControl = MockControl.createControl(Connection.class); Connection con = (Connection) conControl.getMock(); con.getAutoCommit(); conControl.setReturnValue(false, 1); con.rollback(); conControl.setVoidCallable(1); con.isReadOnly(); conControl.setReturnValue(false, 1); con.close(); conControl.setVoidCallable(1); MockControl dsControl = MockControl.createControl(DataSource.class); final DataSource ds = (DataSource) dsControl.getMock(); ds.getConnection(); dsControl.setReturnValue(con, 1); conControl.replay(); dsControl.replay(); PlatformTransactionManager tm = new DataSourceTransactionManager(ds); final TransactionTemplate tt = new TransactionTemplate(tm); tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); assertTrue("Synchronization not active", !TransactionSynchronizationManager.isSynchronizationActive()); try { tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { assertTrue("Is new transaction", status.isNewTransaction()); tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_NEVER); tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { fail("Should have thrown IllegalTransactionStateException"); } }); fail("Should have thrown IllegalTransactionStateException"); } }); } catch (IllegalTransactionStateException ex) { // expected } assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); conControl.verify(); dsControl.verify(); } public void testPropagationSupportsAndRequiresNew() throws Exception { MockControl conControl = MockControl.createControl(Connection.class); final Connection con = (Connection) conControl.getMock(); con.getAutoCommit(); conControl.setReturnValue(false, 1); con.commit(); conControl.setVoidCallable(1); con.isReadOnly(); conControl.setReturnValue(false, 1); con.close(); conControl.setVoidCallable(1); MockControl dsControl = MockControl.createControl(DataSource.class); final DataSource ds = (DataSource) dsControl.getMock(); ds.getConnection(); dsControl.setReturnValue(con, 1); dsControl.replay(); conControl.replay(); final PlatformTransactionManager tm = new DataSourceTransactionManager(ds); TransactionTemplate tt = new TransactionTemplate(tm); tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); assertTrue("Synchronization not active", !TransactionSynchronizationManager.isSynchronizationActive()); tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { assertTrue("Synchronization active", TransactionSynchronizationManager.isSynchronizationActive()); TransactionTemplate tt2 = new TransactionTemplate(tm); tt2.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); tt2.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds)); assertTrue("Synchronization active", TransactionSynchronizationManager.isSynchronizationActive()); assertTrue("Is new transaction", status.isNewTransaction()); assertSame(con, DataSourceUtils.getConnection(ds)); assertSame(con, DataSourceUtils.getConnection(ds)); } }); } }); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); dsControl.verify(); conControl.verify(); } public void testPropagationSupportsAndRequiresNewWithEarlyAccess() throws Exception { MockControl con1Control = MockControl.createControl(Connection.class); final Connection con1 = (Connection) con1Control.getMock(); con1.close(); con1Control.setVoidCallable(1); MockControl con2Control = MockControl.createControl(Connection.class); final Connection con2 = (Connection) con2Control.getMock(); con2.getAutoCommit(); con2Control.setReturnValue(false, 1); con2.commit(); con2Control.setVoidCallable(1); con2.isReadOnly(); con2Control.setReturnValue(false, 1); con2.close(); con2Control.setVoidCallable(1); MockControl dsControl = MockControl.createControl(DataSource.class); final DataSource ds = (DataSource) dsControl.getMock(); ds.getConnection(); dsControl.setReturnValue(con1, 1); ds.getConnection(); dsControl.setReturnValue(con2, 1); dsControl.replay(); con1Control.replay(); con2Control.replay(); final PlatformTransactionManager tm = new DataSourceTransactionManager(ds); TransactionTemplate tt = new TransactionTemplate(tm); tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); assertTrue("Synchronization not active", !TransactionSynchronizationManager.isSynchronizationActive()); tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { assertTrue("Synchronization active", TransactionSynchronizationManager.isSynchronizationActive()); assertSame(con1, DataSourceUtils.getConnection(ds)); assertSame(con1, DataSourceUtils.getConnection(ds)); TransactionTemplate tt2 = new TransactionTemplate(tm); tt2.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); tt2.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds)); assertTrue("Synchronization active", TransactionSynchronizationManager.isSynchronizationActive()); assertTrue("Is new transaction", status.isNewTransaction()); assertSame(con2, DataSourceUtils.getConnection(ds)); assertSame(con2, DataSourceUtils.getConnection(ds)); } }); assertSame(con1, DataSourceUtils.getConnection(ds)); } }); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); dsControl.verify(); con1Control.verify(); con2Control.verify(); } public void testTransactionWithIsolationAndReadOnly() throws Exception { MockControl dsControl = MockControl.createControl(DataSource.class); DataSource ds = (DataSource) dsControl.getMock(); MockControl conControl = MockControl.createControl(Connection.class); final Connection con = (Connection) conControl.getMock(); ds.getConnection(); dsControl.setReturnValue(con, 1); con.getTransactionIsolation(); conControl.setReturnValue(Connection.TRANSACTION_READ_COMMITTED, 1); con.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE); conControl.setVoidCallable(1); con.setReadOnly(true); conControl.setVoidCallable(1); con.getAutoCommit(); conControl.setReturnValue(true, 1); con.setAutoCommit(false); conControl.setVoidCallable(1); con.commit(); conControl.setVoidCallable(1); con.setAutoCommit(true); conControl.setVoidCallable(1); con.isReadOnly(); conControl.setReturnValue(false, 1); con.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); conControl.setVoidCallable(1); con.close(); conControl.setVoidCallable(1); conControl.replay(); dsControl.replay(); PlatformTransactionManager tm = new DataSourceTransactionManager(ds); TransactionTemplate tt = new TransactionTemplate(tm); tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); tt.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE); tt.setReadOnly(true); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) { assertTrue(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); assertTrue(TransactionSynchronizationManager.isActualTransactionActive()); // something transactional } }); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); conControl.verify(); dsControl.verify(); } public void testTransactionWithLongTimeout() throws Exception { doTestTransactionWithTimeout(10); } public void testTransactionWithShortTimeout() throws Exception { doTestTransactionWithTimeout(1); } private void doTestTransactionWithTimeout(int timeout) throws Exception { MockControl dsControl = MockControl.createControl(DataSource.class); final DataSource ds = (DataSource) dsControl.getMock(); MockControl conControl = MockControl.createControl(Connection.class); final Connection con = (Connection) conControl.getMock(); MockControl psControl = MockControl.createControl(PreparedStatement.class); PreparedStatement ps = (PreparedStatement) psControl.getMock(); ds.getConnection(); dsControl.setReturnValue(con, 1); con.getAutoCommit(); conControl.setReturnValue(true, 1); con.setAutoCommit(false); conControl.setVoidCallable(1); con.prepareStatement("some SQL statement"); conControl.setReturnValue(ps, 1); if (timeout > 1) { ps.setQueryTimeout(timeout - 1); psControl.setVoidCallable(1); con.commit(); } else { con.rollback(); } conControl.setVoidCallable(1); con.setAutoCommit(true); conControl.setVoidCallable(1); con.isReadOnly(); conControl.setReturnValue(false, 1); con.close(); conControl.setVoidCallable(1); psControl.replay(); conControl.replay(); dsControl.replay(); PlatformTransactionManager tm = new DataSourceTransactionManager(ds); TransactionTemplate tt = new TransactionTemplate(tm); tt.setTimeout(timeout); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); try { tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) { try { Thread.sleep(1500); } catch (InterruptedException ex) { } try { Connection con = DataSourceUtils.getConnection(ds); PreparedStatement ps = con.prepareStatement("some SQL statement"); DataSourceUtils.applyTransactionTimeout(ps, ds); } catch (SQLException ex) { throw new DataAccessResourceFailureException("", ex); } } }); if (timeout <= 1) { fail("Should have thrown TransactionTimedOutException"); } } catch (TransactionTimedOutException ex) { if (timeout <= 1) { // expected } else { throw ex; } } assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); conControl.verify(); dsControl.verify(); psControl.verify(); } public void testTransactionAwareDataSourceProxy() throws Exception { MockControl dsControl = MockControl.createControl(DataSource.class); final DataSource ds = (DataSource) dsControl.getMock(); MockControl conControl = MockControl.createControl(Connection.class); final Connection con = (Connection) conControl.getMock(); ds.getConnection(); dsControl.setReturnValue(con, 1); con.getMetaData(); conControl.setReturnValue(null, 1); con.getAutoCommit(); conControl.setReturnValue(true, 1); con.setAutoCommit(false); conControl.setVoidCallable(1); con.commit(); conControl.setVoidCallable(1); con.setAutoCommit(true); conControl.setVoidCallable(1); con.isReadOnly(); conControl.setReturnValue(false, 1); con.close(); conControl.setVoidCallable(1); conControl.replay(); dsControl.replay(); PlatformTransactionManager tm = new DataSourceTransactionManager(ds); TransactionTemplate tt = new TransactionTemplate(tm); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) { // something transactional assertEquals(con, DataSourceUtils.getConnection(ds)); TransactionAwareDataSourceProxy dsProxy = new TransactionAwareDataSourceProxy(ds); try { assertEquals(con, ((ConnectionProxy) dsProxy.getConnection()).getTargetConnection()); assertEquals(con, new SimpleNativeJdbcExtractor().getNativeConnection(dsProxy.getConnection())); // should be ignored dsProxy.getConnection().close(); } catch (SQLException ex) { throw new UncategorizedSQLException("", "", ex); } } }); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); conControl.verify(); dsControl.verify(); } public void testTransactionAwareDataSourceProxyWithSuspension() throws Exception { MockControl dsControl = MockControl.createControl(DataSource.class); final DataSource ds = (DataSource) dsControl.getMock(); MockControl conControl = MockControl.createControl(Connection.class); final Connection con = (Connection) conControl.getMock(); ds.getConnection(); dsControl.setReturnValue(con, 2); con.getMetaData(); conControl.setReturnValue(null, 2); con.getAutoCommit(); conControl.setReturnValue(true, 2); con.setAutoCommit(false); conControl.setVoidCallable(2); con.commit(); conControl.setVoidCallable(2); con.setAutoCommit(true); conControl.setVoidCallable(2); con.isReadOnly(); conControl.setReturnValue(false, 2); con.close(); conControl.setVoidCallable(2); conControl.replay(); dsControl.replay(); PlatformTransactionManager tm = new DataSourceTransactionManager(ds); final TransactionTemplate tt = new TransactionTemplate(tm); tt.setPropagationBehavior(TransactionTemplate.PROPAGATION_REQUIRES_NEW); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) { // something transactional assertEquals(con, DataSourceUtils.getConnection(ds)); final TransactionAwareDataSourceProxy dsProxy = new TransactionAwareDataSourceProxy(ds); try { assertEquals(con, ((ConnectionProxy) dsProxy.getConnection()).getTargetConnection()); assertEquals(con, new SimpleNativeJdbcExtractor().getNativeConnection(dsProxy.getConnection())); // should be ignored dsProxy.getConnection().close(); } catch (SQLException ex) { throw new UncategorizedSQLException("", "", ex); } tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) { // something transactional assertEquals(con, DataSourceUtils.getConnection(ds)); try { assertEquals(con, ((ConnectionProxy) dsProxy.getConnection()).getTargetConnection()); assertEquals(con, new SimpleNativeJdbcExtractor().getNativeConnection(dsProxy.getConnection())); // should be ignored dsProxy.getConnection().close(); } catch (SQLException ex) { throw new UncategorizedSQLException("", "", ex); } } }); try { assertEquals(con, ((ConnectionProxy) dsProxy.getConnection()).getTargetConnection()); // should be ignored dsProxy.getConnection().close(); } catch (SQLException ex) { throw new UncategorizedSQLException("", "", ex); } } }); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); conControl.verify(); dsControl.verify(); } public void testTransactionAwareDataSourceProxyWithSuspensionAndReobtaining() throws Exception { MockControl dsControl = MockControl.createControl(DataSource.class); final DataSource ds = (DataSource) dsControl.getMock(); MockControl conControl = MockControl.createControl(Connection.class); final Connection con = (Connection) conControl.getMock(); ds.getConnection(); dsControl.setReturnValue(con, 2); con.getMetaData(); conControl.setReturnValue(null, 2); con.getAutoCommit(); conControl.setReturnValue(true, 2); con.setAutoCommit(false); conControl.setVoidCallable(2); con.commit(); conControl.setVoidCallable(2); con.setAutoCommit(true); conControl.setVoidCallable(2); con.isReadOnly(); conControl.setReturnValue(false, 2); con.close(); conControl.setVoidCallable(2); conControl.replay(); dsControl.replay(); PlatformTransactionManager tm = new DataSourceTransactionManager(ds); final TransactionTemplate tt = new TransactionTemplate(tm); tt.setPropagationBehavior(TransactionTemplate.PROPAGATION_REQUIRES_NEW); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) { // something transactional assertEquals(con, DataSourceUtils.getConnection(ds)); final TransactionAwareDataSourceProxy dsProxy = new TransactionAwareDataSourceProxy(ds); dsProxy.setReobtainTransactionalConnections(true); try { assertEquals(con, ((ConnectionProxy) dsProxy.getConnection()).getTargetConnection()); assertEquals(con, new SimpleNativeJdbcExtractor().getNativeConnection(dsProxy.getConnection())); // should be ignored dsProxy.getConnection().close(); } catch (SQLException ex) { throw new UncategorizedSQLException("", "", ex); } tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) { // something transactional assertEquals(con, DataSourceUtils.getConnection(ds)); try { assertEquals(con, ((ConnectionProxy) dsProxy.getConnection()).getTargetConnection()); assertEquals(con, new SimpleNativeJdbcExtractor().getNativeConnection(dsProxy.getConnection())); // should be ignored dsProxy.getConnection().close(); } catch (SQLException ex) { throw new UncategorizedSQLException("", "", ex); } } }); try { assertEquals(con, ((ConnectionProxy) dsProxy.getConnection()).getTargetConnection()); // should be ignored dsProxy.getConnection().close(); } catch (SQLException ex) { throw new UncategorizedSQLException("", "", ex); } } }); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); conControl.verify(); dsControl.verify(); } /** * Test behavior if the first operation on a connection (getAutoCommit) throws SQLException. */ public void testTransactionWithExceptionOnBegin() throws Exception { MockControl conControl = MockControl.createControl(Connection.class); final Connection con = (Connection) conControl.getMock(); MockControl dsControl = MockControl.createControl(DataSource.class); DataSource ds = (DataSource) dsControl.getMock(); ds.getConnection(); dsControl.setReturnValue(con, 1); con.getAutoCommit(); conControl.setThrowable(new SQLException("Cannot begin")); con.close(); conControl.setVoidCallable(); conControl.replay(); dsControl.replay(); PlatformTransactionManager tm = new DataSourceTransactionManager(ds); TransactionTemplate tt = new TransactionTemplate(tm); try { tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) { // something transactional } }); fail("Should have thrown CannotCreateTransactionException"); } catch (CannotCreateTransactionException ex) { // expected } assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); conControl.verify(); } public void testTransactionWithExceptionOnCommit() throws Exception { MockControl conControl = MockControl.createControl(Connection.class); final Connection con = (Connection) conControl.getMock(); MockControl dsControl = MockControl.createControl(DataSource.class); DataSource ds = (DataSource) dsControl.getMock(); ds.getConnection(); dsControl.setReturnValue(con, 1); con.getAutoCommit(); // No need to restore it conControl.setReturnValue(false, 1); con.commit(); conControl.setThrowable(new SQLException("Cannot commit"), 1); con.isReadOnly(); conControl.setReturnValue(false, 1); con.close(); conControl.setVoidCallable(1); conControl.replay(); dsControl.replay(); PlatformTransactionManager tm = new DataSourceTransactionManager(ds); TransactionTemplate tt = new TransactionTemplate(tm); try { tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) { // something transactional } }); fail("Should have thrown TransactionSystemException"); } catch (TransactionSystemException ex) { // expected } assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); conControl.verify(); } public void testTransactionWithExceptionOnCommitAndRollbackOnCommitFailure() throws Exception { MockControl conControl = MockControl.createControl(Connection.class); final Connection con = (Connection) conControl.getMock(); MockControl dsControl = MockControl.createControl(DataSource.class); DataSource ds = (DataSource) dsControl.getMock(); ds.getConnection(); dsControl.setReturnValue(con, 1); con.getAutoCommit(); // No need to change or restore conControl.setReturnValue(false); con.commit(); conControl.setThrowable(new SQLException("Cannot commit"), 1); con.rollback(); conControl.setVoidCallable(1); con.isReadOnly(); conControl.setReturnValue(false, 1); con.close(); conControl.setVoidCallable(1); conControl.replay(); dsControl.replay(); DataSourceTransactionManager tm = new DataSourceTransactionManager(ds); tm.setRollbackOnCommitFailure(true); TransactionTemplate tt = new TransactionTemplate(tm); try { tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) { // something transactional } }); fail("Should have thrown TransactionSystemException"); } catch (TransactionSystemException ex) { // expected } assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); conControl.verify(); } public void testTransactionWithExceptionOnRollback() throws Exception { MockControl conControl = MockControl.createControl(Connection.class); final Connection con = (Connection) conControl.getMock(); MockControl dsControl = MockControl.createControl(DataSource.class); DataSource ds = (DataSource) dsControl.getMock(); ds.getConnection(); dsControl.setReturnValue(con, 1); con.getAutoCommit(); conControl.setReturnValue(true, 1); // Must restore con.setAutoCommit(false); conControl.setVoidCallable(1); con.rollback(); conControl.setThrowable(new SQLException("Cannot rollback"), 1); con.setAutoCommit(true); conControl.setVoidCallable(1); con.isReadOnly(); conControl.setReturnValue(false, 1); con.close(); conControl.setVoidCallable(1); conControl.replay(); dsControl.replay(); PlatformTransactionManager tm = new DataSourceTransactionManager(ds); TransactionTemplate tt = new TransactionTemplate(tm); try { tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { status.setRollbackOnly(); } }); fail("Should have thrown TransactionSystemException"); } catch (TransactionSystemException ex) { // expected } assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); conControl.verify(); } public void testTransactionWithPropagationSupports() throws Exception { MockControl dsControl = MockControl.createControl(DataSource.class); final DataSource ds = (DataSource) dsControl.getMock(); dsControl.replay(); PlatformTransactionManager tm = new DataSourceTransactionManager(ds); TransactionTemplate tt = new TransactionTemplate(tm); tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_SUPPORTS); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); assertTrue("Is not new transaction", !status.isNewTransaction()); assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); assertFalse(TransactionSynchronizationManager.isActualTransactionActive()); } }); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); dsControl.verify(); } public void testTransactionWithPropagationNotSupported() throws Exception { MockControl dsControl = MockControl.createControl(DataSource.class); final DataSource ds = (DataSource) dsControl.getMock(); dsControl.replay(); PlatformTransactionManager tm = new DataSourceTransactionManager(ds); TransactionTemplate tt = new TransactionTemplate(tm); tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_NOT_SUPPORTED); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); assertTrue("Is not new transaction", !status.isNewTransaction()); } }); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); dsControl.verify(); } public void testTransactionWithPropagationNever() throws Exception { MockControl dsControl = MockControl.createControl(DataSource.class); final DataSource ds = (DataSource) dsControl.getMock(); dsControl.replay(); PlatformTransactionManager tm = new DataSourceTransactionManager(ds); TransactionTemplate tt = new TransactionTemplate(tm); tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_NEVER); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); assertTrue("Is not new transaction", !status.isNewTransaction()); } }); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); dsControl.verify(); } public void testExistingTransactionWithPropagationNested() throws Exception { doTestExistingTransactionWithPropagationNested(1); } public void testExistingTransactionWithPropagationNestedTwice() throws Exception { doTestExistingTransactionWithPropagationNested(2); } private void doTestExistingTransactionWithPropagationNested(final int count) throws Exception { MockControl dsControl = MockControl.createControl(DataSource.class); final DataSource ds = (DataSource) dsControl.getMock(); MockControl conControl = MockControl.createControl(Connection.class); Connection con = (Connection) conControl.getMock(); MockControl mdControl = MockControl.createControl(DatabaseMetaData.class); DatabaseMetaData md = (DatabaseMetaData) mdControl.getMock(); MockControl spControl = MockControl.createControl(Savepoint.class); Savepoint sp = (Savepoint) spControl.getMock(); con.getAutoCommit(); conControl.setReturnValue(false, 1); md.supportsSavepoints(); mdControl.setReturnValue(true, 1); con.getMetaData(); conControl.setReturnValue(md, 1); for (int i = 1; i <= count; i++) { con.setSavepoint(ConnectionHolder.SAVEPOINT_NAME_PREFIX + i); conControl.setReturnValue(sp, 1); con.releaseSavepoint(sp); conControl.setVoidCallable(1); } con.commit(); conControl.setVoidCallable(1); con.isReadOnly(); conControl.setReturnValue(false, 1); con.close(); conControl.setVoidCallable(1); ds.getConnection(); dsControl.setReturnValue(con, 1); spControl.replay(); mdControl.replay(); conControl.replay(); dsControl.replay(); PlatformTransactionManager tm = new DataSourceTransactionManager(ds); final TransactionTemplate tt = new TransactionTemplate(tm); tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_NESTED); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); assertTrue("Synchronization not active", !TransactionSynchronizationManager.isSynchronizationActive()); tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { assertTrue("Is new transaction", status.isNewTransaction()); assertTrue("Isn't nested transaction", !status.hasSavepoint()); for (int i = 0; i < count; i++) { tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds)); assertTrue("Synchronization active", TransactionSynchronizationManager.isSynchronizationActive()); assertTrue("Isn't new transaction", !status.isNewTransaction()); assertTrue("Is nested transaction", status.hasSavepoint()); } }); } assertTrue("Is new transaction", status.isNewTransaction()); assertTrue("Isn't nested transaction", !status.hasSavepoint()); } }); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); spControl.verify(); mdControl.verify(); conControl.verify(); dsControl.verify(); } public void testExistingTransactionWithPropagationNestedAndRollback() throws Exception { MockControl dsControl = MockControl.createControl(DataSource.class); final DataSource ds = (DataSource) dsControl.getMock(); MockControl conControl = MockControl.createControl(Connection.class); Connection con = (Connection) conControl.getMock(); MockControl mdControl = MockControl.createControl(DatabaseMetaData.class); DatabaseMetaData md = (DatabaseMetaData) mdControl.getMock(); MockControl spControl = MockControl.createControl(Savepoint.class); Savepoint sp = (Savepoint) spControl.getMock(); ds.getConnection(); dsControl.setReturnValue(con, 1); con.getAutoCommit(); conControl.setReturnValue(false, 1); md.supportsSavepoints(); mdControl.setReturnValue(true, 1); con.getMetaData(); conControl.setReturnValue(md, 1); con.setSavepoint("SAVEPOINT_1"); conControl.setReturnValue(sp, 1); con.rollback(sp); conControl.setVoidCallable(1); con.commit(); conControl.setVoidCallable(1); con.isReadOnly(); conControl.setReturnValue(false, 1); con.close(); conControl.setVoidCallable(1); spControl.replay(); mdControl.replay(); conControl.replay(); dsControl.replay(); PlatformTransactionManager tm = new DataSourceTransactionManager(ds); final TransactionTemplate tt = new TransactionTemplate(tm); tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_NESTED); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); assertTrue("Synchronization not active", !TransactionSynchronizationManager.isSynchronizationActive()); tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { assertTrue("Is new transaction", status.isNewTransaction()); assertTrue("Isn't nested transaction", !status.hasSavepoint()); tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds)); assertTrue("Synchronization active", TransactionSynchronizationManager.isSynchronizationActive()); assertTrue("Isn't new transaction", !status.isNewTransaction()); assertTrue("Is nested transaction", status.hasSavepoint()); status.setRollbackOnly(); } }); assertTrue("Is new transaction", status.isNewTransaction()); assertTrue("Isn't nested transaction", !status.hasSavepoint()); } }); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); spControl.verify(); mdControl.verify(); conControl.verify(); dsControl.verify(); } public void testExistingTransactionWithManualSavepoint() throws Exception { MockControl dsControl = MockControl.createControl(DataSource.class); final DataSource ds = (DataSource) dsControl.getMock(); MockControl conControl = MockControl.createControl(Connection.class); Connection con = (Connection) conControl.getMock(); MockControl mdControl = MockControl.createControl(DatabaseMetaData.class); DatabaseMetaData md = (DatabaseMetaData) mdControl.getMock(); MockControl spControl = MockControl.createControl(Savepoint.class); Savepoint sp = (Savepoint) spControl.getMock(); con.getAutoCommit(); conControl.setReturnValue(false, 1); md.supportsSavepoints(); mdControl.setReturnValue(true, 1); con.getMetaData(); conControl.setReturnValue(md, 1); con.setSavepoint("SAVEPOINT_1"); conControl.setReturnValue(sp, 1); con.releaseSavepoint(sp); conControl.setVoidCallable(1); con.commit(); conControl.setVoidCallable(1); con.isReadOnly(); conControl.setReturnValue(false, 1); con.close(); conControl.setVoidCallable(1); ds.getConnection(); dsControl.setReturnValue(con, 1); spControl.replay(); mdControl.replay(); conControl.replay(); dsControl.replay(); PlatformTransactionManager tm = new DataSourceTransactionManager(ds); final TransactionTemplate tt = new TransactionTemplate(tm); tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_NESTED); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); assertTrue("Synchronization not active", !TransactionSynchronizationManager.isSynchronizationActive()); tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { assertTrue("Is new transaction", status.isNewTransaction()); Object savepoint = status.createSavepoint(); status.releaseSavepoint(savepoint); assertTrue("Is new transaction", status.isNewTransaction()); } }); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); spControl.verify(); mdControl.verify(); conControl.verify(); dsControl.verify(); } public void testExistingTransactionWithManualSavepointAndRollback() throws Exception { MockControl dsControl = MockControl.createControl(DataSource.class); final DataSource ds = (DataSource) dsControl.getMock(); MockControl conControl = MockControl.createControl(Connection.class); Connection con = (Connection) conControl.getMock(); MockControl mdControl = MockControl.createControl(DatabaseMetaData.class); DatabaseMetaData md = (DatabaseMetaData) mdControl.getMock(); MockControl spControl = MockControl.createControl(Savepoint.class); Savepoint sp = (Savepoint) spControl.getMock(); ds.getConnection(); dsControl.setReturnValue(con, 1); con.getAutoCommit(); conControl.setReturnValue(false, 1); md.supportsSavepoints(); mdControl.setReturnValue(true, 1); con.getMetaData(); conControl.setReturnValue(md, 1); con.setSavepoint("SAVEPOINT_1"); conControl.setReturnValue(sp, 1); con.rollback(sp); conControl.setVoidCallable(1); con.commit(); conControl.setVoidCallable(1); con.isReadOnly(); conControl.setReturnValue(false, 1); con.close(); conControl.setVoidCallable(1); spControl.replay(); mdControl.replay(); conControl.replay(); dsControl.replay(); PlatformTransactionManager tm = new DataSourceTransactionManager(ds); final TransactionTemplate tt = new TransactionTemplate(tm); tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_NESTED); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); assertTrue("Synchronization not active", !TransactionSynchronizationManager.isSynchronizationActive()); tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { assertTrue("Is new transaction", status.isNewTransaction()); Object savepoint = status.createSavepoint(); status.rollbackToSavepoint(savepoint); assertTrue("Is new transaction", status.isNewTransaction()); } }); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); spControl.verify(); mdControl.verify(); conControl.verify(); dsControl.verify(); } public void testTransactionWithPropagationNested() throws Exception { MockControl conControl = MockControl.createControl(Connection.class); Connection con = (Connection) conControl.getMock(); con.getAutoCommit(); conControl.setReturnValue(false, 1); con.commit(); conControl.setVoidCallable(1); con.isReadOnly(); conControl.setReturnValue(false, 1); con.close(); conControl.setVoidCallable(1); MockControl dsControl = MockControl.createControl(DataSource.class); final DataSource ds = (DataSource) dsControl.getMock(); ds.getConnection(); dsControl.setReturnValue(con, 1); conControl.replay(); dsControl.replay(); PlatformTransactionManager tm = new DataSourceTransactionManager(ds); final TransactionTemplate tt = new TransactionTemplate(tm); tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_NESTED); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); assertTrue("Synchronization not active", !TransactionSynchronizationManager.isSynchronizationActive()); tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { assertTrue("Is new transaction", status.isNewTransaction()); } }); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); conControl.verify(); dsControl.verify(); } public void testTransactionWithPropagationNestedAndRollback() throws Exception { MockControl conControl = MockControl.createControl(Connection.class); Connection con = (Connection) conControl.getMock(); con.getAutoCommit(); conControl.setReturnValue(false, 1); con.rollback(); conControl.setVoidCallable(1); con.isReadOnly(); conControl.setReturnValue(false, 1); con.close(); conControl.setVoidCallable(1); MockControl dsControl = MockControl.createControl(DataSource.class); final DataSource ds = (DataSource) dsControl.getMock(); ds.getConnection(); dsControl.setReturnValue(con, 1); conControl.replay(); dsControl.replay(); PlatformTransactionManager tm = new DataSourceTransactionManager(ds); final TransactionTemplate tt = new TransactionTemplate(tm); tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_NESTED); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); assertTrue("Synchronization not active", !TransactionSynchronizationManager.isSynchronizationActive()); tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { assertTrue("Is new transaction", status.isNewTransaction()); status.setRollbackOnly(); } }); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); conControl.verify(); dsControl.verify(); } protected void tearDown() { assertTrue(TransactionSynchronizationManager.getResourceMap().isEmpty()); assertFalse(TransactionSynchronizationManager.isSynchronizationActive()); assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); assertFalse(TransactionSynchronizationManager.isActualTransactionActive()); } private static class TestTransactionSynchronization implements TransactionSynchronization { private DataSource dataSource; private int status; public boolean beforeCommitCalled; public boolean beforeCompletionCalled; public boolean afterCommitCalled; public boolean afterCompletionCalled; public TestTransactionSynchronization(DataSource dataSource, int status) { this.dataSource = dataSource; this.status = status; } public void suspend() { } public void resume() { } public void flush() { } public void beforeCommit(boolean readOnly) { if (this.status != TransactionSynchronization.STATUS_COMMITTED) { fail("Should never be called"); } assertFalse(this.beforeCommitCalled); this.beforeCommitCalled = true; } public void beforeCompletion() { assertFalse(this.beforeCompletionCalled); this.beforeCompletionCalled = true; } public void afterCommit() { if (this.status != TransactionSynchronization.STATUS_COMMITTED) { fail("Should never be called"); } assertFalse(this.afterCommitCalled); this.afterCommitCalled = true; } public void afterCompletion(int status) { assertFalse(this.afterCompletionCalled); this.afterCompletionCalled = true; assertTrue(status == this.status); assertTrue(TransactionSynchronizationManager.hasResource(this.dataSource)); } } } ././@LongLink0000000000000000000000000000022300000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/datasource/DriverManagerDataSourceTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000001206311623223530033322 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource; import java.sql.Connection; import java.util.Properties; import junit.framework.TestCase; import org.easymock.MockControl; /** * @author Rod Johnson */ public class DriverManagerDataSourceTests extends TestCase { public void testStandardUsage() throws Exception { final String jdbcUrl = "url"; final String uname = "uname"; final String pwd = "pwd"; MockControl ctrlConnection = MockControl.createControl(Connection.class); final Connection mockConnection = (Connection) ctrlConnection.getMock(); ctrlConnection.replay(); class TestDriverManagerDataSource extends DriverManagerDataSource { protected Connection getConnectionFromDriverManager(String url, Properties props) { assertEquals(jdbcUrl, url); assertEquals(uname, props.getProperty("user")); assertEquals(pwd, props.getProperty("password")); return mockConnection; } } DriverManagerDataSource ds = new TestDriverManagerDataSource(); //ds.setDriverClassName("foobar"); ds.setUrl(jdbcUrl); ds.setUsername(uname); ds.setPassword(pwd); Connection actualCon = ds.getConnection(); assertTrue(actualCon == mockConnection); assertTrue(ds.getUrl().equals(jdbcUrl)); assertTrue(ds.getPassword().equals(pwd)); assertTrue(ds.getUsername().equals(uname)); ctrlConnection.verify(); } public void testUsageWithConnectionProperties() throws Exception { final String jdbcUrl = "url"; final Properties connProps = new Properties(); connProps.setProperty("myProp", "myValue"); connProps.setProperty("yourProp", "yourValue"); connProps.setProperty("user", "uname"); connProps.setProperty("password", "pwd"); MockControl ctrlConnection = MockControl.createControl(Connection.class); final Connection mockConnection = (Connection) ctrlConnection.getMock(); ctrlConnection.replay(); class TestDriverManagerDataSource extends DriverManagerDataSource { protected Connection getConnectionFromDriverManager(String url, Properties props) { assertEquals(jdbcUrl, url); assertEquals("uname", props.getProperty("user")); assertEquals("pwd", props.getProperty("password")); assertEquals("myValue", props.getProperty("myProp")); assertEquals("yourValue", props.getProperty("yourProp")); return mockConnection; } } DriverManagerDataSource ds = new TestDriverManagerDataSource(); //ds.setDriverClassName("foobar"); ds.setUrl(jdbcUrl); ds.setConnectionProperties(connProps); Connection actualCon = ds.getConnection(); assertTrue(actualCon == mockConnection); assertTrue(ds.getUrl().equals(jdbcUrl)); ctrlConnection.verify(); } public void testUsageWithConnectionPropertiesAndUserCredentials() throws Exception { final String jdbcUrl = "url"; final String uname = "uname"; final String pwd = "pwd"; final Properties connProps = new Properties(); connProps.setProperty("myProp", "myValue"); connProps.setProperty("yourProp", "yourValue"); connProps.setProperty("user", "uname2"); connProps.setProperty("password", "pwd2"); MockControl ctrlConnection = MockControl.createControl(Connection.class); final Connection mockConnection = (Connection) ctrlConnection.getMock(); ctrlConnection.replay(); class TestDriverManagerDataSource extends DriverManagerDataSource { protected Connection getConnectionFromDriverManager(String url, Properties props) { assertEquals(jdbcUrl, url); assertEquals(uname, props.getProperty("user")); assertEquals(pwd, props.getProperty("password")); assertEquals("myValue", props.getProperty("myProp")); assertEquals("yourValue", props.getProperty("yourProp")); return mockConnection; } } DriverManagerDataSource ds = new TestDriverManagerDataSource(); //ds.setDriverClassName("foobar"); ds.setUrl(jdbcUrl); ds.setUsername(uname); ds.setPassword(pwd); ds.setConnectionProperties(connProps); Connection actualCon = ds.getConnection(); assertTrue(actualCon == mockConnection); assertTrue(ds.getUrl().equals(jdbcUrl)); assertTrue(ds.getPassword().equals(pwd)); assertTrue(ds.getUsername().equals(uname)); ctrlConnection.verify(); } public void testInvalidClassName() throws Exception { String bogusClassName = "foobar"; DriverManagerDataSource ds = new DriverManagerDataSource(); try { ds.setDriverClassName(bogusClassName); fail("Should have thrown IllegalStateException"); } catch (IllegalStateException ex) { // OK assertTrue(ex.getCause() instanceof ClassNotFoundException); } } } ././@LongLink0000000000000000000000000000016700000000000011571 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/datasource/init/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000755000175000017500000000000011623223526033323 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000022200000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/datasource/init/DatabasePopulatorTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000000546611623223526033340 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource.init; import static org.junit.Assert.assertEquals; import java.sql.Connection; import javax.sql.DataSource; import org.junit.After; import org.junit.Ignore; import org.junit.Test; import org.springframework.core.io.ClassRelativeResourceLoader; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; /** * @author Dave Syer * @author Sam Brannen */ public class DatabasePopulatorTests { private final EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder(); private final EmbeddedDatabase db = builder.build(); private final ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator(); private final ClassRelativeResourceLoader resourceLoader = new ClassRelativeResourceLoader(getClass()); private final JdbcTemplate jdbcTemplate = new JdbcTemplate(db); private void assertTestDatabaseCreated() { assertEquals("Keith", jdbcTemplate.queryForObject("select NAME from T_TEST", String.class)); } private void assertUsersDatabaseCreated(DataSource db) { assertEquals("Sam", jdbcTemplate.queryForObject("select first_name from users where last_name = 'Brannen'", String.class)); } @After public void shutDown() { db.shutdown(); } @Test public void testBuildWithCommentsAndFailedDrop() throws Exception { databasePopulator.addScript(resourceLoader.getResource("db-schema-failed-drop-comments.sql")); databasePopulator.addScript(resourceLoader.getResource("db-test-data.sql")); databasePopulator.setIgnoreFailedDrops(true); Connection connection = db.getConnection(); try { databasePopulator.populate(connection); } finally { connection.close(); } assertTestDatabaseCreated(); } @Test public void scriptWithEolBetweenTokens() throws Exception { databasePopulator.addScript(resourceLoader.getResource("users-schema.sql")); databasePopulator.addScript(resourceLoader.getResource("users-data.sql")); Connection connection = db.getConnection(); try { databasePopulator.populate(connection); } finally { connection.close(); } assertUsersDatabaseCreated(db); } } ././@LongLink0000000000000000000000000000022400000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/datasource/DataSourceJtaTransactionTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000010413011623223530033317 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.datasource; import java.sql.Connection; import java.sql.SQLException; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.sql.DataSource; import javax.transaction.Status; import javax.transaction.SystemException; import javax.transaction.Transaction; import javax.transaction.TransactionManager; import javax.transaction.UserTransaction; import junit.framework.TestCase; import org.easymock.MockControl; import org.springframework.beans.factory.support.StaticListableBeanFactory; import org.springframework.jdbc.datasource.lookup.BeanFactoryDataSourceLookup; import org.springframework.jdbc.datasource.lookup.IsolationLevelDataSourceRouter; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionException; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.jta.JtaTransactionManager; import org.springframework.transaction.jta.JtaTransactionObject; import org.springframework.transaction.support.TransactionCallbackWithoutResult; import org.springframework.transaction.support.TransactionSynchronization; import org.springframework.transaction.support.TransactionSynchronizationManager; import org.springframework.transaction.support.TransactionTemplate; /** * @author Juergen Hoeller * @since 17.10.2005 */ public class DataSourceJtaTransactionTests extends TestCase { public void testJtaTransactionCommit() throws Exception { doTestJtaTransaction(false); } public void testJtaTransactionRollback() throws Exception { doTestJtaTransaction(true); } private void doTestJtaTransaction(final boolean rollback) throws Exception { MockControl utControl = MockControl.createControl(UserTransaction.class); UserTransaction ut = (UserTransaction) utControl.getMock(); ut.getStatus(); utControl.setReturnValue(Status.STATUS_NO_TRANSACTION, 1); ut.getStatus(); utControl.setReturnValue(Status.STATUS_ACTIVE, 1); ut.begin(); utControl.setVoidCallable(1); if (rollback) { ut.rollback(); } else { ut.getStatus(); utControl.setReturnValue(Status.STATUS_ACTIVE, 1); ut.commit(); } utControl.setVoidCallable(1); utControl.replay(); MockControl dsControl = MockControl.createControl(DataSource.class); final DataSource ds = (DataSource) dsControl.getMock(); MockControl conControl = MockControl.createControl(Connection.class); Connection con = (Connection) conControl.getMock(); ds.getConnection(); dsControl.setReturnValue(con, 1); con.close(); conControl.setVoidCallable(1); conControl.replay(); dsControl.replay(); JtaTransactionManager ptm = new JtaTransactionManager(ut); TransactionTemplate tt = new TransactionTemplate(ptm); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); assertTrue("JTA synchronizations active", TransactionSynchronizationManager.isSynchronizationActive()); assertTrue("Is new transaction", status.isNewTransaction()); Connection c = DataSourceUtils.getConnection(ds); assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds)); DataSourceUtils.releaseConnection(c, ds); c = DataSourceUtils.getConnection(ds); assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds)); DataSourceUtils.releaseConnection(c, ds); if (rollback) { status.setRollbackOnly(); } } }); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); dsControl.verify(); conControl.verify(); utControl.verify(); } public void testJtaTransactionCommitWithPropagationRequiresNew() throws Exception { doTestJtaTransactionWithPropagationRequiresNew(false, false, false, false); } public void testJtaTransactionCommitWithPropagationRequiresNewWithAccessAfterResume() throws Exception { doTestJtaTransactionWithPropagationRequiresNew(false, false, true, false); } public void testJtaTransactionCommitWithPropagationRequiresNewWithOpenOuterConnection() throws Exception { doTestJtaTransactionWithPropagationRequiresNew(false, true, false, false); } public void testJtaTransactionCommitWithPropagationRequiresNewWithOpenOuterConnectionAccessed() throws Exception { doTestJtaTransactionWithPropagationRequiresNew(false, true, true, false); } public void testJtaTransactionCommitWithPropagationRequiresNewWithTransactionAwareDataSource() throws Exception { doTestJtaTransactionWithPropagationRequiresNew(false, false, true, true); } public void testJtaTransactionRollbackWithPropagationRequiresNew() throws Exception { doTestJtaTransactionWithPropagationRequiresNew(true, false, false, false); } public void testJtaTransactionRollbackWithPropagationRequiresNewWithAccessAfterResume() throws Exception { doTestJtaTransactionWithPropagationRequiresNew(true, false, true, false); } public void testJtaTransactionRollbackWithPropagationRequiresNewWithOpenOuterConnection() throws Exception { doTestJtaTransactionWithPropagationRequiresNew(true, true, false, false); } public void testJtaTransactionRollbackWithPropagationRequiresNewWithOpenOuterConnectionAccessed() throws Exception { doTestJtaTransactionWithPropagationRequiresNew(true, true, true, false); } public void testJtaTransactionRollbackWithPropagationRequiresNewWithTransactionAwareDataSource() throws Exception { doTestJtaTransactionWithPropagationRequiresNew(true, false, true, true); } private void doTestJtaTransactionWithPropagationRequiresNew( final boolean rollback, final boolean openOuterConnection, final boolean accessAfterResume, final boolean useTransactionAwareDataSource) throws Exception { MockControl utControl = MockControl.createControl(UserTransaction.class); UserTransaction ut = (UserTransaction) utControl.getMock(); MockControl tmControl = MockControl.createControl(TransactionManager.class); TransactionManager tm = (TransactionManager) tmControl.getMock(); MockControl txControl = MockControl.createControl(Transaction.class); Transaction tx = (Transaction) txControl.getMock(); ut.getStatus(); utControl.setReturnValue(Status.STATUS_NO_TRANSACTION, 1); ut.begin(); utControl.setVoidCallable(1); ut.getStatus(); utControl.setReturnValue(Status.STATUS_ACTIVE, 16); tm.suspend(); tmControl.setReturnValue(tx, 5); ut.begin(); utControl.setVoidCallable(5); ut.commit(); utControl.setVoidCallable(5); tm.resume(tx); tmControl.setVoidCallable(5); if (rollback) { ut.rollback(); } else { ut.getStatus(); utControl.setReturnValue(Status.STATUS_ACTIVE, 1); ut.commit(); } utControl.setVoidCallable(1); utControl.replay(); tmControl.replay(); final MockControl dsControl = MockControl.createControl(DataSource.class); final DataSource ds = (DataSource) dsControl.getMock(); final MockControl conControl = MockControl.createControl(Connection.class); final Connection con = (Connection) conControl.getMock(); ds.getConnection(); dsControl.setReturnValue(con, 1); con.isReadOnly(); conControl.setReturnValue(true, 1); if (!openOuterConnection) { con.close(); conControl.setVoidCallable(1); } conControl.replay(); dsControl.replay(); final DataSource dsToUse = useTransactionAwareDataSource ? new TransactionAwareDataSourceProxy(ds) : ds; JtaTransactionManager ptm = new JtaTransactionManager(ut, tm); final TransactionTemplate tt = new TransactionTemplate(ptm); tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(dsToUse)); assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(dsToUse)); assertTrue("JTA synchronizations active", TransactionSynchronizationManager.isSynchronizationActive()); assertTrue("Is new transaction", status.isNewTransaction()); Connection c = DataSourceUtils.getConnection(dsToUse); try { assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(dsToUse)); c.isReadOnly(); DataSourceUtils.releaseConnection(c, dsToUse); c = DataSourceUtils.getConnection(dsToUse); assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(dsToUse)); if (!openOuterConnection) { DataSourceUtils.releaseConnection(c, dsToUse); } } catch (SQLException ex) { } for (int i = 0; i < 5; i++) { tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(dsToUse)); assertTrue("JTA synchronizations active", TransactionSynchronizationManager.isSynchronizationActive()); assertTrue("Is new transaction", status.isNewTransaction()); try { dsControl.verify(); conControl.verify(); dsControl.reset(); conControl.reset(); ds.getConnection(); dsControl.setReturnValue(con, 1); con.isReadOnly(); conControl.setReturnValue(true, 1); con.close(); conControl.setVoidCallable(1); dsControl.replay(); conControl.replay(); Connection c = DataSourceUtils.getConnection(dsToUse); c.isReadOnly(); assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(dsToUse)); DataSourceUtils.releaseConnection(c, dsToUse); c = DataSourceUtils.getConnection(dsToUse); assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(dsToUse)); DataSourceUtils.releaseConnection(c, dsToUse); } catch (SQLException ex) { } } }); } if (rollback) { status.setRollbackOnly(); } if (accessAfterResume) { try { if (!openOuterConnection) { dsControl.verify(); dsControl.reset(); ds.getConnection(); dsControl.setReturnValue(con, 1); dsControl.replay(); } conControl.verify(); conControl.reset(); con.isReadOnly(); conControl.setReturnValue(true, 1); con.close(); conControl.setVoidCallable(1); conControl.replay(); if (!openOuterConnection) { c = DataSourceUtils.getConnection(dsToUse); } assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(dsToUse)); c.isReadOnly(); DataSourceUtils.releaseConnection(c, dsToUse); c = DataSourceUtils.getConnection(dsToUse); assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(dsToUse)); DataSourceUtils.releaseConnection(c, dsToUse); } catch (SQLException ex) { } } else { if (openOuterConnection) { try { conControl.verify(); conControl.reset(); con.close(); conControl.setVoidCallable(1); conControl.replay(); } catch (SQLException ex) { } DataSourceUtils.releaseConnection(c, dsToUse); } } } }); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(dsToUse)); assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); dsControl.verify(); conControl.verify(); utControl.verify(); tmControl.verify(); } public void testJtaTransactionCommitWithPropagationRequiredWithinSupports() throws Exception { doTestJtaTransactionCommitWithNewTransactionWithinEmptyTransaction(false, false); } public void testJtaTransactionCommitWithPropagationRequiredWithinNotSupported() throws Exception { doTestJtaTransactionCommitWithNewTransactionWithinEmptyTransaction(false, true); } public void testJtaTransactionCommitWithPropagationRequiresNewWithinSupports() throws Exception { doTestJtaTransactionCommitWithNewTransactionWithinEmptyTransaction(true, false); } public void testJtaTransactionCommitWithPropagationRequiresNewWithinNotSupported() throws Exception { doTestJtaTransactionCommitWithNewTransactionWithinEmptyTransaction(true, true); } private void doTestJtaTransactionCommitWithNewTransactionWithinEmptyTransaction( final boolean requiresNew, boolean notSupported) throws Exception { MockControl utControl = MockControl.createControl(UserTransaction.class); UserTransaction ut = (UserTransaction) utControl.getMock(); MockControl tmControl = MockControl.createControl(TransactionManager.class); TransactionManager tm = (TransactionManager) tmControl.getMock(); MockControl txControl = MockControl.createControl(Transaction.class); Transaction tx = (Transaction) txControl.getMock(); if (notSupported) { ut.getStatus(); utControl.setReturnValue(Status.STATUS_ACTIVE, 1); tm.suspend(); tmControl.setReturnValue(tx, 1); } else { ut.getStatus(); utControl.setReturnValue(Status.STATUS_NO_TRANSACTION, 1); } ut.getStatus(); utControl.setReturnValue(Status.STATUS_NO_TRANSACTION, 1); ut.begin(); utControl.setVoidCallable(1); ut.getStatus(); utControl.setReturnValue(Status.STATUS_ACTIVE, 2); ut.commit(); utControl.setVoidCallable(1); if (notSupported) { tm.resume(tx); tmControl.setVoidCallable(1); } utControl.replay(); tmControl.replay(); txControl.replay(); final MockControl dsControl = MockControl.createControl(DataSource.class); final DataSource ds = (DataSource) dsControl.getMock(); final MockControl con1Control = MockControl.createControl(Connection.class); final Connection con1 = (Connection) con1Control.getMock(); final MockControl con2Control = MockControl.createControl(Connection.class); final Connection con2 = (Connection) con2Control.getMock(); ds.getConnection(); dsControl.setReturnValue(con1, 1); ds.getConnection(); dsControl.setReturnValue(con2, 1); con2.close(); con2Control.setVoidCallable(1); con1.close(); con1Control.setVoidCallable(1); dsControl.replay(); con1Control.replay(); con2Control.replay(); final JtaTransactionManager ptm = new JtaTransactionManager(ut, tm); TransactionTemplate tt = new TransactionTemplate(ptm); tt.setPropagationBehavior(notSupported ? TransactionDefinition.PROPAGATION_NOT_SUPPORTED : TransactionDefinition.PROPAGATION_SUPPORTS); assertFalse(TransactionSynchronizationManager.isSynchronizationActive()); tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) { assertTrue(TransactionSynchronizationManager.isSynchronizationActive()); assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); assertFalse(TransactionSynchronizationManager.isActualTransactionActive()); assertSame(con1, DataSourceUtils.getConnection(ds)); assertSame(con1, DataSourceUtils.getConnection(ds)); TransactionTemplate tt2 = new TransactionTemplate(ptm); tt2.setPropagationBehavior(requiresNew ? TransactionDefinition.PROPAGATION_REQUIRES_NEW : TransactionDefinition.PROPAGATION_REQUIRED); tt2.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) { assertTrue(TransactionSynchronizationManager.isSynchronizationActive()); assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); assertTrue(TransactionSynchronizationManager.isActualTransactionActive()); assertSame(con2, DataSourceUtils.getConnection(ds)); assertSame(con2, DataSourceUtils.getConnection(ds)); } }); assertTrue(TransactionSynchronizationManager.isSynchronizationActive()); assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); assertFalse(TransactionSynchronizationManager.isActualTransactionActive()); assertSame(con1, DataSourceUtils.getConnection(ds)); } }); assertFalse(TransactionSynchronizationManager.isSynchronizationActive()); utControl.verify(); tmControl.verify(); txControl.verify(); dsControl.verify(); con1Control.verify(); con2Control.verify(); } public void testJtaTransactionCommitWithPropagationRequiresNewAndSuspendException() throws Exception { doTestJtaTransactionWithPropagationRequiresNewAndBeginException(true, false, false); } public void testJtaTransactionCommitWithPropagationRequiresNewWithOpenOuterConnectionAndSuspendException() throws Exception { doTestJtaTransactionWithPropagationRequiresNewAndBeginException(true, true, false); } public void testJtaTransactionCommitWithPropagationRequiresNewWithTransactionAwareDataSourceAndSuspendException() throws Exception { doTestJtaTransactionWithPropagationRequiresNewAndBeginException(true, false, true); } public void testJtaTransactionCommitWithPropagationRequiresNewWithOpenOuterConnectionAndTransactionAwareDataSourceAndSuspendException() throws Exception { doTestJtaTransactionWithPropagationRequiresNewAndBeginException(true, true, true); } public void testJtaTransactionCommitWithPropagationRequiresNewAndBeginException() throws Exception { doTestJtaTransactionWithPropagationRequiresNewAndBeginException(false, false, false); } public void testJtaTransactionCommitWithPropagationRequiresNewWithOpenOuterConnectionAndBeginException() throws Exception { doTestJtaTransactionWithPropagationRequiresNewAndBeginException(false, true, false); } public void testJtaTransactionCommitWithPropagationRequiresNewWithOpenOuterConnectionAndTransactionAwareDataSourceAndBeginException() throws Exception { doTestJtaTransactionWithPropagationRequiresNewAndBeginException(false, true, true); } public void testJtaTransactionCommitWithPropagationRequiresNewWithTransactionAwareDataSourceAndBeginException() throws Exception { doTestJtaTransactionWithPropagationRequiresNewAndBeginException(false, false, true); } private void doTestJtaTransactionWithPropagationRequiresNewAndBeginException(boolean suspendException, final boolean openOuterConnection, final boolean useTransactionAwareDataSource) throws Exception { MockControl utControl = MockControl.createControl(UserTransaction.class); UserTransaction ut = (UserTransaction) utControl.getMock(); MockControl tmControl = MockControl.createControl(TransactionManager.class); TransactionManager tm = (TransactionManager) tmControl.getMock(); MockControl txControl = MockControl.createControl(Transaction.class); Transaction tx = (Transaction) txControl.getMock(); ut.getStatus(); utControl.setReturnValue(Status.STATUS_NO_TRANSACTION, 1); ut.begin(); utControl.setVoidCallable(1); ut.getStatus(); utControl.setReturnValue(Status.STATUS_ACTIVE, 2); if (suspendException) { tm.suspend(); tmControl.setThrowable(new SystemException(), 1); } else { tm.suspend(); tmControl.setReturnValue(tx, 1); ut.begin(); utControl.setThrowable(new SystemException(), 1); tm.resume(tx); tmControl.setVoidCallable(1); } ut.rollback(); utControl.setVoidCallable(1); utControl.replay(); tmControl.replay(); final MockControl dsControl = MockControl.createControl(DataSource.class); final DataSource ds = (DataSource) dsControl.getMock(); final MockControl conControl = MockControl.createControl(Connection.class); final Connection con = (Connection) conControl.getMock(); ds.getConnection(); dsControl.setReturnValue(con, 1); con.isReadOnly(); conControl.setReturnValue(true, 1); if (!openOuterConnection || useTransactionAwareDataSource) { con.close(); conControl.setVoidCallable(1); } conControl.replay(); dsControl.replay(); final DataSource dsToUse = useTransactionAwareDataSource ? new TransactionAwareDataSourceProxy(ds) : ds; if (dsToUse instanceof TransactionAwareDataSourceProxy) { ((TransactionAwareDataSourceProxy) dsToUse).setReobtainTransactionalConnections(true); } JtaTransactionManager ptm = new JtaTransactionManager(ut, tm); final TransactionTemplate tt = new TransactionTemplate(ptm); tt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(dsToUse)); assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); try { tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(dsToUse)); assertTrue("JTA synchronizations active", TransactionSynchronizationManager.isSynchronizationActive()); assertTrue("Is new transaction", status.isNewTransaction()); Connection c = DataSourceUtils.getConnection(dsToUse); try { assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(dsToUse)); c.isReadOnly(); DataSourceUtils.releaseConnection(c, dsToUse); c = DataSourceUtils.getConnection(dsToUse); assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(dsToUse)); if (!openOuterConnection) { DataSourceUtils.releaseConnection(c, dsToUse); } } catch (SQLException ex) { } try { tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(dsToUse)); assertTrue("JTA synchronizations active", TransactionSynchronizationManager.isSynchronizationActive()); assertTrue("Is new transaction", status.isNewTransaction()); try { dsControl.verify(); conControl.verify(); dsControl.reset(); conControl.reset(); ds.getConnection(); dsControl.setReturnValue(con, 1); con.close(); conControl.setVoidCallable(1); dsControl.replay(); conControl.replay(); Connection c = DataSourceUtils.getConnection(dsToUse); assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(dsToUse)); DataSourceUtils.releaseConnection(c, dsToUse); c = DataSourceUtils.getConnection(dsToUse); assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(dsToUse)); DataSourceUtils.releaseConnection(c, dsToUse); } catch (SQLException ex) { } } }); } finally { if (openOuterConnection) { try { dsControl.verify(); dsControl.reset(); conControl.verify(); conControl.reset(); if (useTransactionAwareDataSource) { ds.getConnection(); dsControl.setReturnValue(con, 1); } con.isReadOnly(); conControl.setReturnValue(true, 1); con.close(); conControl.setVoidCallable(1); dsControl.replay(); conControl.replay(); c.isReadOnly(); DataSourceUtils.releaseConnection(c, dsToUse); } catch (SQLException ex) { } } } } }); fail("Should have thrown TransactionException"); } catch (TransactionException ex) { // expected } assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(dsToUse)); assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); dsControl.verify(); conControl.verify(); utControl.verify(); tmControl.verify(); } public void testJtaTransactionWithConnectionHolderStillBound() throws Exception { MockControl utControl = MockControl.createControl(UserTransaction.class); UserTransaction ut = (UserTransaction) utControl.getMock(); MockControl dsControl = MockControl.createControl(DataSource.class); final DataSource ds = (DataSource) dsControl.getMock(); MockControl conControl = MockControl.createControl(Connection.class); Connection con = (Connection) conControl.getMock(); JtaTransactionManager ptm = new JtaTransactionManager(ut) { protected void doRegisterAfterCompletionWithJtaTransaction( JtaTransactionObject txObject, final List synchronizations) { Thread async = new Thread() { public void run() { invokeAfterCompletion(synchronizations, TransactionSynchronization.STATUS_COMMITTED); } }; async.start(); try { async.join(); } catch (InterruptedException ex) { ex.printStackTrace(); } } }; TransactionTemplate tt = new TransactionTemplate(ptm); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); for (int i = 0; i < 3; i++) { utControl.reset(); ut.getStatus(); utControl.setReturnValue(Status.STATUS_ACTIVE, 1); utControl.replay(); dsControl.reset(); conControl.reset(); ds.getConnection(); dsControl.setReturnValue(con, 1); con.close(); conControl.setVoidCallable(1); dsControl.replay(); conControl.replay(); final boolean releaseCon = (i != 1); tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { assertTrue("JTA synchronizations active", TransactionSynchronizationManager.isSynchronizationActive()); assertTrue("Is existing transaction", !status.isNewTransaction()); Connection c = DataSourceUtils.getConnection(ds); assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds)); DataSourceUtils.releaseConnection(c, ds); c = DataSourceUtils.getConnection(ds); assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds)); if (releaseCon) { DataSourceUtils.releaseConnection(c, ds); } } }); if (!releaseCon) { assertTrue("Still has connection holder", TransactionSynchronizationManager.hasResource(ds)); } else { assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds)); } assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); conControl.verify(); dsControl.verify(); utControl.verify(); } } public void testJtaTransactionWithIsolationLevelDataSourceAdapter() throws Exception { MockControl utControl = MockControl.createControl(UserTransaction.class); UserTransaction ut = (UserTransaction) utControl.getMock(); ut.getStatus(); utControl.setReturnValue(Status.STATUS_NO_TRANSACTION, 1); ut.getStatus(); utControl.setReturnValue(Status.STATUS_ACTIVE, 2); ut.begin(); utControl.setVoidCallable(1); ut.commit(); ut.getStatus(); utControl.setReturnValue(Status.STATUS_NO_TRANSACTION, 1); ut.getStatus(); utControl.setReturnValue(Status.STATUS_ACTIVE, 2); ut.begin(); utControl.setVoidCallable(1); ut.commit(); utControl.setVoidCallable(1); utControl.replay(); MockControl ds1Control = MockControl.createControl(DataSource.class); final DataSource ds1 = (DataSource) ds1Control.getMock(); MockControl con1Control = MockControl.createControl(Connection.class); final Connection con1 = (Connection) con1Control.getMock(); ds1.getConnection(); ds1Control.setReturnValue(con1, 1); con1.close(); con1Control.setVoidCallable(1); ds1.getConnection(); ds1Control.setReturnValue(con1, 1); con1.setReadOnly(true); con1Control.setVoidCallable(1); con1.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ); con1Control.setVoidCallable(1); con1.close(); con1Control.setVoidCallable(1); con1Control.replay(); ds1Control.replay(); final IsolationLevelDataSourceAdapter dsToUse = new IsolationLevelDataSourceAdapter(); dsToUse.setTargetDataSource(ds1); dsToUse.afterPropertiesSet(); JtaTransactionManager ptm = new JtaTransactionManager(ut); ptm.setAllowCustomIsolationLevels(true); TransactionTemplate tt = new TransactionTemplate(ptm); tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { Connection c = DataSourceUtils.getConnection(dsToUse); assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(dsToUse)); assertSame(con1, c); DataSourceUtils.releaseConnection(c, dsToUse); } }); tt.setIsolationLevel(TransactionDefinition.ISOLATION_REPEATABLE_READ); tt.setReadOnly(true); tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { Connection c = DataSourceUtils.getConnection(dsToUse); assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(dsToUse)); assertSame(con1, c); DataSourceUtils.releaseConnection(c, dsToUse); } }); ds1Control.verify(); con1Control.verify(); utControl.verify(); } public void testJtaTransactionWithIsolationLevelDataSourceRouter() throws Exception { doTestJtaTransactionWithIsolationLevelDataSourceRouter(false); } public void testJtaTransactionWithIsolationLevelDataSourceRouterWithDataSourceLookup() throws Exception { doTestJtaTransactionWithIsolationLevelDataSourceRouter(true); } private void doTestJtaTransactionWithIsolationLevelDataSourceRouter(boolean dataSourceLookup) throws Exception { MockControl utControl = MockControl.createControl(UserTransaction.class); UserTransaction ut = (UserTransaction) utControl.getMock(); ut.getStatus(); utControl.setReturnValue(Status.STATUS_NO_TRANSACTION, 1); ut.getStatus(); utControl.setReturnValue(Status.STATUS_ACTIVE, 2); ut.begin(); utControl.setVoidCallable(1); ut.commit(); ut.getStatus(); utControl.setReturnValue(Status.STATUS_NO_TRANSACTION, 1); ut.getStatus(); utControl.setReturnValue(Status.STATUS_ACTIVE, 2); ut.begin(); utControl.setVoidCallable(1); ut.commit(); utControl.setVoidCallable(1); utControl.replay(); MockControl ds1Control = MockControl.createControl(DataSource.class); final DataSource ds1 = (DataSource) ds1Control.getMock(); MockControl con1Control = MockControl.createControl(Connection.class); final Connection con1 = (Connection) con1Control.getMock(); ds1.getConnection(); ds1Control.setReturnValue(con1, 1); con1.close(); con1Control.setVoidCallable(1); con1Control.replay(); ds1Control.replay(); MockControl ds2Control = MockControl.createControl(DataSource.class); final DataSource ds2 = (DataSource) ds2Control.getMock(); MockControl con2Control = MockControl.createControl(Connection.class); final Connection con2 = (Connection) con2Control.getMock(); ds2.getConnection(); ds2Control.setReturnValue(con2, 1); con2.close(); con2Control.setVoidCallable(1); con2Control.replay(); ds2Control.replay(); final IsolationLevelDataSourceRouter dsToUse = new IsolationLevelDataSourceRouter(); Map targetDataSources = new HashMap(); if (dataSourceLookup) { targetDataSources.put("ISOLATION_REPEATABLE_READ", "ds2"); dsToUse.setDefaultTargetDataSource("ds1"); StaticListableBeanFactory beanFactory = new StaticListableBeanFactory(); beanFactory.addBean("ds1", ds1); beanFactory.addBean("ds2", ds2); dsToUse.setDataSourceLookup(new BeanFactoryDataSourceLookup(beanFactory)); } else { targetDataSources.put("ISOLATION_REPEATABLE_READ", ds2); dsToUse.setDefaultTargetDataSource(ds1); } dsToUse.setTargetDataSources(targetDataSources); dsToUse.afterPropertiesSet(); JtaTransactionManager ptm = new JtaTransactionManager(ut); ptm.setAllowCustomIsolationLevels(true); TransactionTemplate tt = new TransactionTemplate(ptm); tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { Connection c = DataSourceUtils.getConnection(dsToUse); assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(dsToUse)); assertSame(con1, c); DataSourceUtils.releaseConnection(c, dsToUse); } }); tt.setIsolationLevel(TransactionDefinition.ISOLATION_REPEATABLE_READ); tt.execute(new TransactionCallbackWithoutResult() { protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { Connection c = DataSourceUtils.getConnection(dsToUse); assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(dsToUse)); assertSame(con2, c); DataSourceUtils.releaseConnection(c, dsToUse); } }); ds1Control.verify(); con1Control.verify(); ds2Control.verify(); con2Control.verify(); utControl.verify(); } protected void tearDown() { assertTrue(TransactionSynchronizationManager.getResourceMap().isEmpty()); assertFalse(TransactionSynchronizationManager.isSynchronizationActive()); assertNull(TransactionSynchronizationManager.getCurrentTransactionName()); assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); assertNull(TransactionSynchronizationManager.getCurrentTransactionIsolationLevel()); assertFalse(TransactionSynchronizationManager.isActualTransactionActive()); } } ././@LongLink0000000000000000000000000000021400000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/datasource/TestDataSourceWrapper.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000000103411623223530033316 0ustar drazzibdrazzibpackage org.springframework.jdbc.datasource; import java.sql.Connection; import java.sql.SQLException; import javax.sql.DataSource; public class TestDataSourceWrapper extends AbstractDataSource { private DataSource target; public void setTarget(DataSource target) { this.target = target; } public Connection getConnection() throws SQLException { return target.getConnection(); } public Connection getConnection(String username, String password) throws SQLException { return target.getConnection(username, password); } } ././@LongLink0000000000000000000000000000015600000000000011567 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/object/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000755000175000017500000000000011623223530033316 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000020700000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/object/GenericSqlQueryTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000001102711623223530033321 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.object; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.expectLastCall; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; import java.util.HashMap; import java.util.List; import java.util.Map; import org.easymock.EasyMock; import org.apache.commons.logging.LogFactory; import org.junit.Test; import org.junit.After; import org.junit.Before; import org.junit.runners.JUnit4; import org.junit.runner.RunWith; import org.springframework.jdbc.AbstractJdbcTests; import org.springframework.jdbc.Customer; import org.springframework.jdbc.datasource.TestDataSourceWrapper; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.xml.XmlBeanFactory; import org.springframework.core.io.ClassPathResource; /** * @author Thomas Risberg */ @RunWith(JUnit4.class) public class GenericSqlQueryTests extends AbstractJdbcTests { private static final String SELECT_ID_FORENAME_NAMED_PARAMETERS_PARSED = "select id, forename from custmr where id = ? and country = ?"; private final boolean debugEnabled = LogFactory.getLog(JdbcTemplate.class).isDebugEnabled(); private PreparedStatement mockPreparedStatement; private ResultSet mockResultSet; private BeanFactory bf; @Before public void setUp() throws Exception { super.setUp(); mockPreparedStatement = createMock(PreparedStatement.class); mockResultSet = createMock(ResultSet.class); this.bf = new XmlBeanFactory( new ClassPathResource("org/springframework/jdbc/object/GenericSqlQueryTests-context.xml")); TestDataSourceWrapper testDataSource = (TestDataSourceWrapper) bf.getBean("dataSource"); testDataSource.setTarget(mockDataSource); } @After public void tearDown() throws Exception { super.tearDown(); if (shouldVerify()) { EasyMock.verify(mockPreparedStatement); EasyMock.verify(mockResultSet); } } protected void replay() { super.replay(); EasyMock.replay(mockPreparedStatement); EasyMock.replay(mockResultSet); } @Test public void testPlaceHoldersCustomerQuery() throws SQLException { SqlQuery query = (SqlQuery) bf.getBean("queryWithPlaceHolders"); testCustomerQuery(query, false); } @Test public void testNamedParameterCustomerQuery() throws SQLException { SqlQuery query = (SqlQuery) bf.getBean("queryWithNamedParameters"); testCustomerQuery(query, true); } private void testCustomerQuery(SqlQuery query, boolean namedParameters) throws SQLException { expect(mockResultSet.next()).andReturn(true); expect(mockResultSet.getInt("id")).andReturn(1); expect(mockResultSet.getString("forename")).andReturn("rod"); expect(mockResultSet.next()).andReturn(false); mockResultSet.close(); expectLastCall(); mockPreparedStatement.setObject(1, new Integer(1), Types.INTEGER); expectLastCall(); mockPreparedStatement.setString(2, "UK"); expectLastCall(); expect(mockPreparedStatement.executeQuery()).andReturn(mockResultSet); if (debugEnabled) { expect(mockPreparedStatement.getWarnings()).andReturn(null); } mockPreparedStatement.close(); expectLastCall(); mockConnection.prepareStatement(SELECT_ID_FORENAME_NAMED_PARAMETERS_PARSED); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); List l; if (namedParameters) { Map params = new HashMap(2); params.put("id", new Integer(1)); params.put("country", "UK"); l = query.executeByNamedParam(params); } else { Object[] params = new Object[] {new Integer(1), "UK"}; l = query.execute(params); } assertTrue("Customer was returned correctly", l.size() == 1); Customer cust = (Customer) l.get(0); assertTrue("Customer id was assigned correctly", cust.getId() == 1); assertTrue("Customer forename was assigned correctly", cust.getForename().equals("rod")); } }././@LongLink0000000000000000000000000000020600000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/object/BatchSqlUpdateTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000001052011623223530033316 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package org.springframework.jdbc.object; import java.sql.DatabaseMetaData; import java.sql.PreparedStatement; import java.sql.Types; import org.easymock.MockControl; import org.apache.commons.logging.LogFactory; import org.springframework.jdbc.AbstractJdbcTests; import org.springframework.jdbc.core.SqlParameter; import org.springframework.jdbc.core.JdbcTemplate; /** * @author Juergen Hoeller * @since 22.02.2005 */ public class BatchSqlUpdateTests extends AbstractJdbcTests { private final boolean debugEnabled = LogFactory.getLog(JdbcTemplate.class).isDebugEnabled(); public void testBatchUpdateWithExplicitFlush() throws Exception { doTestBatchUpdate(false); } public void testBatchUpdateWithFlushThroughBatchSize() throws Exception { doTestBatchUpdate(true); } private void doTestBatchUpdate(boolean flushThroughBatchSize) throws Exception { final String sql = "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = ?"; final int[] ids = new int[] { 100, 200 }; final int[] rowsAffected = new int[] { 1, 2 }; MockControl ctrlPreparedStatement = MockControl.createControl(PreparedStatement.class); PreparedStatement mockPreparedStatement = (PreparedStatement) ctrlPreparedStatement.getMock(); mockPreparedStatement.getConnection(); ctrlPreparedStatement.setReturnValue(mockConnection); mockPreparedStatement.setObject(1, new Integer(ids[0]), Types.INTEGER); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.addBatch(); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.setObject(1, new Integer(ids[1]), Types.INTEGER); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.addBatch(); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeBatch(); ctrlPreparedStatement.setReturnValue(rowsAffected); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); MockControl ctrlDatabaseMetaData = MockControl.createControl(DatabaseMetaData.class); DatabaseMetaData mockDatabaseMetaData = (DatabaseMetaData) ctrlDatabaseMetaData.getMock(); mockDatabaseMetaData.supportsBatchUpdates(); ctrlDatabaseMetaData.setReturnValue(true); mockConnection.prepareStatement(sql); ctrlConnection.setReturnValue(mockPreparedStatement); mockConnection.getMetaData(); ctrlConnection.setReturnValue(mockDatabaseMetaData, 1); ctrlPreparedStatement.replay(); ctrlDatabaseMetaData.replay(); replay(); BatchSqlUpdate update = new BatchSqlUpdate(mockDataSource, sql); update.declareParameter(new SqlParameter(Types.INTEGER)); if (flushThroughBatchSize) { update.setBatchSize(2); } update.update(ids[0]); update.update(ids[1]); if (flushThroughBatchSize) { assertEquals(0, update.getQueueCount()); assertEquals(2, update.getRowsAffected().length); } else { assertEquals(2, update.getQueueCount()); assertEquals(0, update.getRowsAffected().length); } int[] actualRowsAffected = update.flush(); assertEquals(0, update.getQueueCount()); if (flushThroughBatchSize) { assertTrue("flush did not execute updates", actualRowsAffected.length == 0); } else { assertTrue("executed 2 updates", actualRowsAffected.length == 2); assertEquals(rowsAffected[0], actualRowsAffected[0]); assertEquals(rowsAffected[1], actualRowsAffected[1]); } actualRowsAffected = update.getRowsAffected(); assertTrue("executed 2 updates", actualRowsAffected.length == 2); assertEquals(rowsAffected[0], actualRowsAffected[0]); assertEquals(rowsAffected[1], actualRowsAffected[1]); update.reset(); assertEquals(0, update.getRowsAffected().length); ctrlPreparedStatement.verify(); ctrlDatabaseMetaData.verify(); } } ././@LongLink0000000000000000000000000000021600000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/object/GenericStoredProcedureTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000000667011623223526033336 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.object; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.expectLastCall; import java.sql.CallableStatement; import java.sql.Types; import java.util.HashMap; import java.util.Map; import org.easymock.EasyMock; import org.apache.commons.logging.LogFactory; import org.junit.Test; import org.junit.After; import org.junit.Before; import org.junit.runners.JUnit4; import org.junit.runner.RunWith; import org.springframework.jdbc.AbstractJdbcTests; import org.springframework.jdbc.datasource.TestDataSourceWrapper; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.xml.XmlBeanFactory; import org.springframework.core.io.ClassPathResource; /** * @author Thomas Risberg */ @RunWith(JUnit4.class) public class GenericStoredProcedureTests extends AbstractJdbcTests { private final boolean debugEnabled = LogFactory.getLog(JdbcTemplate.class).isDebugEnabled(); private CallableStatement mockCallable; private BeanFactory bf; @Before public void setUp() throws Exception { super.setUp(); mockCallable = createMock(CallableStatement.class); bf = new XmlBeanFactory( new ClassPathResource("org/springframework/jdbc/object/GenericStoredProcedureTests-context.xml")); TestDataSourceWrapper testDataSource = (TestDataSourceWrapper) bf.getBean("dataSource"); testDataSource.setTarget(mockDataSource); } @After public void tearDown() throws Exception { super.tearDown(); if (shouldVerify()) { EasyMock.verify(mockCallable); } } protected void replay() { super.replay(); EasyMock.replay(mockCallable); } @Test public void testAddInvoices() throws Exception { mockCallable.setObject(1, new Integer(1106), Types.INTEGER); expectLastCall(); mockCallable.setObject(2, new Integer(3), Types.INTEGER); expectLastCall(); mockCallable.registerOutParameter(3, Types.INTEGER); expectLastCall(); expect(mockCallable.execute()).andReturn(false); expect(mockCallable.getUpdateCount()).andReturn(-1); expect(mockCallable.getObject(3)).andReturn(new Integer(4)); if (debugEnabled) { expect(mockCallable.getWarnings()).andReturn(null); } mockCallable.close(); expectLastCall(); mockConnection.prepareCall("{call " + "add_invoice" + "(?, ?, ?)}"); ctrlConnection.setReturnValue(mockCallable); replay(); testAddInvoice(1106, 3); } private void testAddInvoice(final int amount, final int custid) throws Exception { StoredProcedure adder = (StoredProcedure) bf.getBean("genericProcedure"); Map in = new HashMap(2); in.put("amount", amount); in.put("custid", custid); Map out = adder.execute(in); Integer id = (Integer) out.get("newid"); assertEquals(4, id.intValue()); } }././@LongLink0000000000000000000000000000020100000000000011556 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/object/SqlUpdateTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000004150411623223530033324 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.object; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Types; import java.util.HashMap; import java.util.Map; import org.easymock.MockControl; import org.apache.commons.logging.LogFactory; import org.springframework.core.JdkVersion; import org.springframework.jdbc.AbstractJdbcTests; import org.springframework.jdbc.JdbcUpdateAffectedIncorrectNumberOfRowsException; import org.springframework.jdbc.core.SqlParameter; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.support.GeneratedKeyHolder; import org.springframework.jdbc.support.KeyHolder; /** * @author Trevor Cook * @author Thomas Risberg * @author Juergen Hoeller */ public class SqlUpdateTests extends AbstractJdbcTests { private static final String UPDATE = "update seat_status set booking_id = null"; private static final String UPDATE_INT = "update seat_status set booking_id = null where performance_id = ?"; private static final String UPDATE_INT_INT = "update seat_status set booking_id = null where performance_id = ? and price_band_id = ?"; private static final String UPDATE_NAMED_PARAMETERS = "update seat_status set booking_id = null where performance_id = :perfId and price_band_id = :priceId"; private static final String UPDATE_STRING = "update seat_status set booking_id = null where name = ?"; private static final String UPDATE_OBJECTS = "update seat_status set booking_id = null where performance_id = ? and price_band_id = ? and name = ? and confirmed = ?"; private static final String INSERT_GENERATE_KEYS = "insert into show (name) values(?)"; private final boolean debugEnabled = LogFactory.getLog(JdbcTemplate.class).isDebugEnabled(); private MockControl ctrlPreparedStatement; private PreparedStatement mockPreparedStatement; private MockControl ctrlResultSet; private ResultSet mockResultSet; private MockControl ctrlResultSetMetaData; private ResultSetMetaData mockResultSetMetaData; protected void setUp() throws Exception { super.setUp(); ctrlPreparedStatement = MockControl.createControl(PreparedStatement.class); mockPreparedStatement = (PreparedStatement) ctrlPreparedStatement.getMock(); } protected void tearDown() throws Exception { super.tearDown(); if (shouldVerify()) { ctrlPreparedStatement.verify(); } } protected void replay() { super.replay(); ctrlPreparedStatement.replay(); } public void testUpdate() throws SQLException { mockPreparedStatement.executeUpdate(); ctrlPreparedStatement.setReturnValue(1); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(UPDATE); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); Updater pc = new Updater(); int rowsAffected = pc.run(); assertEquals(1, rowsAffected); } public void testUpdateInt() throws SQLException { mockPreparedStatement.setObject(1, new Integer(1), Types.NUMERIC); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeUpdate(); ctrlPreparedStatement.setReturnValue(1); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(UPDATE_INT); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); IntUpdater pc = new IntUpdater(); int rowsAffected = pc.run(1); assertEquals(1, rowsAffected); } public void testUpdateIntInt() throws SQLException { mockPreparedStatement.setObject(1, new Integer(1), Types.NUMERIC); mockPreparedStatement.setObject(2, new Integer(1), Types.NUMERIC); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeUpdate(); ctrlPreparedStatement.setReturnValue(1); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(UPDATE_INT_INT); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); IntIntUpdater pc = new IntIntUpdater(); int rowsAffected = pc.run(1, 1); assertEquals(1, rowsAffected); } public void testNamedParameterUpdateWithUnnamedDeclarations() throws SQLException { doTestNamedParameterUpdate(false); } public void testNamedParameterUpdateWithNamedDeclarations() throws SQLException { doTestNamedParameterUpdate(true); } private void doTestNamedParameterUpdate(final boolean namedDeclarations) throws SQLException { mockPreparedStatement.setObject(1, new Integer(1), Types.NUMERIC); mockPreparedStatement.setObject(2, new Integer(1), Types.DECIMAL); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeUpdate(); ctrlPreparedStatement.setReturnValue(1); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(UPDATE_INT_INT); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); class NamedParameterUpdater extends SqlUpdate { public NamedParameterUpdater() { setSql(UPDATE_NAMED_PARAMETERS); setDataSource(mockDataSource); if (namedDeclarations) { declareParameter(new SqlParameter("priceId", Types.DECIMAL)); declareParameter(new SqlParameter("perfId", Types.NUMERIC)); } else { declareParameter(new SqlParameter(Types.NUMERIC)); declareParameter(new SqlParameter(Types.DECIMAL)); } compile(); } public int run(int performanceId, int type) { Map params = new HashMap(); params.put("perfId", new Integer(performanceId)); params.put("priceId", new Integer(type)); return updateByNamedParam(params); } } NamedParameterUpdater pc = new NamedParameterUpdater(); int rowsAffected = pc.run(1, 1); assertEquals(1, rowsAffected); } public void testUpdateString() throws SQLException { mockPreparedStatement.setString(1, "rod"); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeUpdate(); ctrlPreparedStatement.setReturnValue(1); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(UPDATE_STRING); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); StringUpdater pc = new StringUpdater(); int rowsAffected = pc.run("rod"); assertEquals(1, rowsAffected); } public void testUpdateMixed() throws SQLException { mockPreparedStatement.setObject(1, new Integer(1), Types.NUMERIC); mockPreparedStatement.setObject(2, new Integer(1), Types.NUMERIC, 2); mockPreparedStatement.setString(3, "rod"); mockPreparedStatement.setObject(4, Boolean.TRUE, Types.BOOLEAN); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeUpdate(); ctrlPreparedStatement.setReturnValue(1); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(UPDATE_OBJECTS); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); MixedUpdater pc = new MixedUpdater(); int rowsAffected = pc.run(1, 1, "rod", true); assertEquals(1, rowsAffected); } public void testUpdateAndGeneratedKeys() throws SQLException { ctrlResultSetMetaData = MockControl.createControl(ResultSetMetaData.class); mockResultSetMetaData = (ResultSetMetaData) ctrlResultSetMetaData.getMock(); mockResultSetMetaData.getColumnCount(); ctrlResultSetMetaData.setReturnValue(1); mockResultSetMetaData.getColumnLabel(1); ctrlResultSetMetaData.setReturnValue("1", 2); ctrlResultSet = MockControl.createControl(ResultSet.class); mockResultSet = (ResultSet) ctrlResultSet.getMock(); mockResultSet.getMetaData(); ctrlResultSet.setReturnValue(mockResultSetMetaData); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getObject(1); ctrlResultSet.setReturnValue(new Integer(11)); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockPreparedStatement.setString(1, "rod"); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeUpdate(); ctrlPreparedStatement.setReturnValue(1); mockPreparedStatement.getGeneratedKeys(); ctrlPreparedStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(INSERT_GENERATE_KEYS, PreparedStatement.RETURN_GENERATED_KEYS); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); ctrlResultSet.replay(); ctrlResultSetMetaData.replay(); GeneratedKeysUpdater pc = new GeneratedKeysUpdater(); KeyHolder generatedKeyHolder = new GeneratedKeyHolder(); int rowsAffected = pc.run("rod", generatedKeyHolder); assertEquals(1, rowsAffected); assertEquals(1, generatedKeyHolder.getKeyList().size()); assertEquals(11, generatedKeyHolder.getKey().intValue()); } public void testUpdateConstructor() throws SQLException { mockPreparedStatement.setObject(1, new Integer(1), Types.NUMERIC); mockPreparedStatement.setObject(2, new Integer(1), Types.NUMERIC); mockPreparedStatement.setString(3, "rod"); mockPreparedStatement.setObject(4, Boolean.TRUE, Types.BOOLEAN); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeUpdate(); ctrlPreparedStatement.setReturnValue(1); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(UPDATE_OBJECTS); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); ConstructorUpdater pc = new ConstructorUpdater(); int rowsAffected = pc.run(1, 1, "rod", true); assertEquals(1, rowsAffected); } public void testUnderMaxRows() throws SQLException { mockPreparedStatement.executeUpdate(); ctrlPreparedStatement.setReturnValue(3); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(UPDATE); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); MaxRowsUpdater pc = new MaxRowsUpdater(); int rowsAffected = pc.run(); assertEquals(3, rowsAffected); } public void testMaxRows() throws SQLException { mockPreparedStatement.executeUpdate(); ctrlPreparedStatement.setReturnValue(5); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(UPDATE); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); MaxRowsUpdater pc = new MaxRowsUpdater(); int rowsAffected = pc.run(); assertEquals(5, rowsAffected); } public void testOverMaxRows() throws SQLException { mockPreparedStatement.executeUpdate(); ctrlPreparedStatement.setReturnValue(8); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(UPDATE); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); MaxRowsUpdater pc = new MaxRowsUpdater(); try { int rowsAffected = pc.run(); fail("Shouldn't continue when too many rows affected"); } catch (JdbcUpdateAffectedIncorrectNumberOfRowsException juaicrex) { // OK } } public void testRequiredRows() throws SQLException { mockPreparedStatement.executeUpdate(); ctrlPreparedStatement.setReturnValue(3); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(UPDATE); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); RequiredRowsUpdater pc = new RequiredRowsUpdater(); int rowsAffected = pc.run(); assertEquals(3, rowsAffected); } public void testNotRequiredRows() throws SQLException { mockPreparedStatement.executeUpdate(); ctrlPreparedStatement.setReturnValue(2); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(UPDATE); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); RequiredRowsUpdater pc = new RequiredRowsUpdater(); try { int rowsAffected = pc.run(); fail("Shouldn't continue when too many rows affected"); } catch (JdbcUpdateAffectedIncorrectNumberOfRowsException juaicrex) { // OK } } private class Updater extends SqlUpdate { public Updater() { setSql(UPDATE); setDataSource(mockDataSource); compile(); } public int run() { return update(); } } private class IntUpdater extends SqlUpdate { public IntUpdater() { setSql(UPDATE_INT); setDataSource(mockDataSource); declareParameter(new SqlParameter(Types.NUMERIC)); compile(); } public int run(int performanceId) { return update(performanceId); } } private class IntIntUpdater extends SqlUpdate { public IntIntUpdater() { setSql(UPDATE_INT_INT); setDataSource(mockDataSource); declareParameter(new SqlParameter(Types.NUMERIC)); declareParameter(new SqlParameter(Types.NUMERIC)); compile(); } public int run(int performanceId, int type) { return update(performanceId, type); } } private class StringUpdater extends SqlUpdate { public StringUpdater() { setSql(UPDATE_STRING); setDataSource(mockDataSource); declareParameter(new SqlParameter(Types.VARCHAR)); compile(); } public int run(String name) { return update(name); } } private class MixedUpdater extends SqlUpdate { public MixedUpdater() { setSql(UPDATE_OBJECTS); setDataSource(mockDataSource); declareParameter(new SqlParameter(Types.NUMERIC)); declareParameter(new SqlParameter(Types.NUMERIC, 2)); declareParameter(new SqlParameter(Types.VARCHAR)); declareParameter(new SqlParameter(Types.BOOLEAN)); compile(); } public int run(int performanceId, int type, String name, boolean confirmed) { Object[] params = new Object[] {new Integer(performanceId), new Integer(type), name, new Boolean(confirmed)}; return update(params); } } private class GeneratedKeysUpdater extends SqlUpdate { public GeneratedKeysUpdater() { setSql(INSERT_GENERATE_KEYS); setDataSource(mockDataSource); declareParameter(new SqlParameter(Types.VARCHAR)); setReturnGeneratedKeys(true); compile(); } public int run(String name, KeyHolder generatedKeyHolder) { Object[] params = new Object[] {name}; return update(params, generatedKeyHolder); } } private class ConstructorUpdater extends SqlUpdate { public ConstructorUpdater() { super(mockDataSource, UPDATE_OBJECTS, new int[] {Types.NUMERIC, Types.NUMERIC, Types.VARCHAR, Types.BOOLEAN }); compile(); } public int run(int performanceId, int type, String name, boolean confirmed) { Object[] params = new Object[] { new Integer(performanceId), new Integer(type), name, new Boolean(confirmed)}; return update(params); } } private class MaxRowsUpdater extends SqlUpdate { public MaxRowsUpdater() { setSql(UPDATE); setDataSource(mockDataSource); setMaxRowsAffected(5); compile(); } public int run() { return update(); } } private class RequiredRowsUpdater extends SqlUpdate { public RequiredRowsUpdater() { setSql(UPDATE); setDataSource(mockDataSource); setRequiredRowsAffected(3); compile(); } public int run() { return update(); } } } ././@LongLink0000000000000000000000000000020600000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/object/RdbmsOperationTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000001535511623223530033331 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.object; import java.sql.Types; import java.util.HashMap; import java.util.Map; import java.util.List; import java.util.ArrayList; import javax.sql.DataSource; import junit.framework.TestCase; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.SqlInOutParameter; import org.springframework.jdbc.core.SqlOutParameter; import org.springframework.jdbc.core.SqlParameter; import org.springframework.jdbc.datasource.DriverManagerDataSource; /** * @author Trevor Cook * @author Juergen Hoeller */ public class RdbmsOperationTests extends TestCase { public void testEmptySql() { TestRdbmsOperation operation = new TestRdbmsOperation(); try { operation.compile(); fail("Shouldn't allow compiling without sql statement"); } catch (InvalidDataAccessApiUsageException idaauex) { // OK } } public void testSetTypeAfterCompile() { TestRdbmsOperation operation = new TestRdbmsOperation(); operation.setDataSource(new DriverManagerDataSource()); operation.setSql("select * from mytable"); operation.compile(); try { operation.setTypes(new int[] {Types.INTEGER }); fail("Shouldn't allow setting parameters after compile"); } catch (InvalidDataAccessApiUsageException idaauex) { // OK } } public void testDeclareParameterAfterCompile() { TestRdbmsOperation operation = new TestRdbmsOperation(); operation.setDataSource(new DriverManagerDataSource()); operation.setSql("select * from mytable"); operation.compile(); try { operation.declareParameter(new SqlParameter(Types.INTEGER)); fail("Shouldn't allow setting parameters after compile"); } catch (InvalidDataAccessApiUsageException idaauex) { // OK } } public void testTooFewParameters() { TestRdbmsOperation operation = new TestRdbmsOperation(); operation.setSql("select * from mytable"); operation.setTypes(new int[] { Types.INTEGER }); try { operation.validateParameters((Object[]) null); fail("Shouldn't validate without enough parameters"); } catch (InvalidDataAccessApiUsageException idaauex) { // OK } } public void testTooFewMapParameters() { TestRdbmsOperation operation = new TestRdbmsOperation(); operation.setSql("select * from mytable"); operation.setTypes(new int[] { Types.INTEGER }); try { operation.validateNamedParameters((Map) null); fail("Shouldn't validate without enough parameters"); } catch (InvalidDataAccessApiUsageException idaauex) { // OK } } public void testOperationConfiguredViaJdbcTemplateMustGetDataSource() throws Exception { try { TestRdbmsOperation operation = new TestRdbmsOperation(); operation.setSql("foo"); operation.compile(); fail("Can't compile without providing a DataSource for the JdbcTemplate"); } catch (InvalidDataAccessApiUsageException ex) { // Check for helpful error message. Omit leading character // so as not to be fussy about case assertTrue(ex.getMessage().indexOf("ataSource") != -1); } } public void testTooManyParameters() { TestRdbmsOperation operation = new TestRdbmsOperation(); operation.setSql("select * from mytable"); try { operation.validateParameters(new Object[] {new Integer(1), new Integer(2)}); fail("Shouldn't validate with too many parameters"); } catch (InvalidDataAccessApiUsageException idaauex) { // OK } } public void testUnspecifiedMapParameters() { TestRdbmsOperation operation = new TestRdbmsOperation(); operation.setSql("select * from mytable"); try { Map params = new HashMap(); params.put("col1", "value"); operation.validateNamedParameters(params); fail("Shouldn't validate with unspecified parameters"); } catch (InvalidDataAccessApiUsageException idaauex) { // OK } } public void testCompileTwice() { TestRdbmsOperation operation = new TestRdbmsOperation(); operation.setDataSource(new DriverManagerDataSource()); operation.setSql("select * from mytable"); operation.setTypes(null); operation.compile(); operation.compile(); } public void testEmptyDataSource() { SqlOperation operation = new SqlOperation() { }; operation.setSql("select * from mytable"); try { operation.compile(); fail("Shouldn't allow compiling without data source"); } catch (InvalidDataAccessApiUsageException idaauex) { // OK } } public void testParameterPropagation() { SqlOperation operation = new SqlOperation() { }; DataSource ds = new DriverManagerDataSource(); operation.setDataSource(ds); operation.setFetchSize(10); operation.setMaxRows(20); JdbcTemplate jt = operation.getJdbcTemplate(); assertEquals(ds, jt.getDataSource()); assertEquals(10, jt.getFetchSize()); assertEquals(20, jt.getMaxRows()); } public void testValidateInOutParameter() { TestRdbmsOperation operation = new TestRdbmsOperation(); operation.setDataSource(new DriverManagerDataSource()); operation.setSql("DUMMY_PROC"); operation.declareParameter(new SqlOutParameter("DUMMY_OUT_PARAM", Types.VARCHAR)); operation.declareParameter(new SqlInOutParameter("DUMMY_IN_OUT_PARAM", Types.VARCHAR)); operation.validateParameters(new Object[] {"DUMMY_VALUE1", "DUMMY_VALUE2"}); } public void testParametersSetWithList() { TestRdbmsOperation operation = new TestRdbmsOperation(); DataSource ds = new DriverManagerDataSource(); operation.setDataSource(ds); operation.setSql("select * from mytable where one = ? and two = ?"); List l = new ArrayList(); l.add(new SqlParameter("one", Types.NUMERIC)); l.add(new SqlParameter("two", Types.VARCHAR)); operation.setParameters(new SqlParameter[] { new SqlParameter("one", Types.NUMERIC), new SqlParameter("two", Types.NUMERIC)}); operation.afterPropertiesSet(); try { operation.validateParameters(new Object[] {new Integer(1), new String("2")}); assertEquals(2, operation.getDeclaredParameters().size()); // OK } catch (InvalidDataAccessApiUsageException idaauex) { fail("Should have validated with parameters set using List: " + idaauex.getMessage()); } } private static class TestRdbmsOperation extends RdbmsOperation { protected void compileInternal() { } } } ././@LongLink0000000000000000000000000000020700000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/object/StoredProcedureTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000007570411623223526033342 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.object; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; import java.sql.ResultSetMetaData; import java.util.HashMap; import java.util.List; import java.util.Map; import java.math.BigDecimal; import javax.sql.DataSource; import org.easymock.MockControl; import org.apache.commons.logging.LogFactory; import org.springframework.dao.DataAccessException; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.jdbc.AbstractJdbcTests; import org.springframework.jdbc.BadSqlGrammarException; import org.springframework.jdbc.core.CallableStatementCreator; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.ParameterMapper; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.SimpleRowCountCallbackHandler; import org.springframework.jdbc.core.SqlOutParameter; import org.springframework.jdbc.core.SqlParameter; import org.springframework.jdbc.core.SqlReturnResultSet; import org.springframework.jdbc.core.support.AbstractSqlTypeValue; import org.springframework.jdbc.datasource.ConnectionHolder; import org.springframework.jdbc.support.SQLExceptionTranslator; import org.springframework.jdbc.support.SQLStateSQLExceptionTranslator; import org.springframework.transaction.support.TransactionSynchronizationManager; /** * @author Thomas Risberg * @author Trevor Cook * @author Rod Johnson */ public class StoredProcedureTests extends AbstractJdbcTests { private final boolean debugEnabled = LogFactory.getLog(JdbcTemplate.class).isDebugEnabled(); private MockControl ctrlCallable; private CallableStatement mockCallable; protected void setUp() throws Exception { super.setUp(); ctrlCallable = MockControl.createControl(CallableStatement.class); mockCallable = (CallableStatement) ctrlCallable.getMock(); } protected void tearDown() throws Exception { super.tearDown(); if (shouldVerify()) { ctrlCallable.verify(); } } protected void replay() { super.replay(); ctrlCallable.replay(); } public void testNoSuchStoredProcedure() throws Exception { SQLException sex = new SQLException( "Syntax error or access violation exception", "42000"); mockCallable.execute(); ctrlCallable.setThrowable(sex); mockCallable.close(); ctrlCallable.setVoidCallable(); mockConnection.prepareCall( "{call " + NoSuchStoredProcedure.SQL + "()}"); ctrlConnection.setReturnValue(mockCallable); replay(); NoSuchStoredProcedure sproc = new NoSuchStoredProcedure(mockDataSource); try { sproc.execute(); fail("Shouldn't succeed in running stored procedure which doesn't exist"); } catch (BadSqlGrammarException ex) { // OK } } private void testAddInvoice(final int amount, final int custid) throws Exception { AddInvoice adder = new AddInvoice(mockDataSource); int id = adder.execute(amount, custid); assertEquals(4, id); } private void testAddInvoiceUsingObjectArray(final int amount, final int custid) throws Exception { AddInvoiceUsingObjectArray adder = new AddInvoiceUsingObjectArray(mockDataSource); int id = adder.execute(amount, custid); assertEquals(5, id); } public void testAddInvoices() throws Exception { mockCallable.setObject(1, new Integer(1106), Types.INTEGER); ctrlCallable.setVoidCallable(); mockCallable.setObject(2, new Integer(3), Types.INTEGER); ctrlCallable.setVoidCallable(); mockCallable.registerOutParameter(3, Types.INTEGER); ctrlCallable.setVoidCallable(); mockCallable.execute(); ctrlCallable.setReturnValue(false); mockCallable.getUpdateCount(); ctrlCallable.setReturnValue(-1); mockCallable.getObject(3); ctrlCallable.setReturnValue(new Integer(4)); if (debugEnabled) { mockCallable.getWarnings(); ctrlCallable.setReturnValue(null); } mockCallable.close(); ctrlCallable.setVoidCallable(); mockConnection.prepareCall("{call " + AddInvoice.SQL + "(?, ?, ?)}"); ctrlConnection.setReturnValue(mockCallable); replay(); testAddInvoice(1106, 3); } public void testAddInvoicesUsingObjectArray() throws Exception { mockCallable.setObject(1, new Integer(1106), Types.INTEGER); ctrlCallable.setVoidCallable(); mockCallable.setObject(2, new Integer(4), Types.INTEGER); ctrlCallable.setVoidCallable(); mockCallable.registerOutParameter(3, Types.INTEGER); ctrlCallable.setVoidCallable(); mockCallable.execute(); ctrlCallable.setReturnValue(false); mockCallable.getUpdateCount(); ctrlCallable.setReturnValue(-1); mockCallable.getObject(3); ctrlCallable.setReturnValue(new Integer(5)); if (debugEnabled) { mockCallable.getWarnings(); ctrlCallable.setReturnValue(null); } mockCallable.close(); ctrlCallable.setVoidCallable(); mockConnection.prepareCall("{call " + AddInvoice.SQL + "(?, ?, ?)}"); ctrlConnection.setReturnValue(mockCallable); replay(); testAddInvoiceUsingObjectArray(1106, 4); } public void testAddInvoicesWithinTransaction() throws Exception { mockCallable.setObject(1, new Integer(1106), Types.INTEGER); ctrlCallable.setVoidCallable(); mockCallable.setObject(2, new Integer(3), Types.INTEGER); ctrlCallable.setVoidCallable(); mockCallable.registerOutParameter(3, Types.INTEGER); ctrlCallable.setVoidCallable(); mockCallable.execute(); ctrlCallable.setReturnValue(false); mockCallable.getUpdateCount(); ctrlCallable.setReturnValue(-1); mockCallable.getObject(3); ctrlCallable.setReturnValue(new Integer(4)); if (debugEnabled) { mockCallable.getWarnings(); ctrlCallable.setReturnValue(null); } mockCallable.close(); ctrlCallable.setVoidCallable(); mockConnection.prepareCall("{call " + AddInvoice.SQL + "(?, ?, ?)}"); ctrlConnection.setReturnValue(mockCallable); replay(); TransactionSynchronizationManager.bindResource( mockDataSource, new ConnectionHolder(mockConnection)); try { testAddInvoice(1106, 3); } finally { TransactionSynchronizationManager.unbindResource(mockDataSource); } } /** * Confirm no connection was used to get metadata. * Does not use superclass replay mechanism. * @throws Exception */ public void testStoredProcedureConfiguredViaJdbcTemplateWithCustomExceptionTranslator() throws Exception { mockCallable.setObject(1, new Integer(11), Types.INTEGER); ctrlCallable.setVoidCallable(1); mockCallable.registerOutParameter(2, Types.INTEGER); ctrlCallable.setVoidCallable(1); mockCallable.execute(); ctrlCallable.setReturnValue(false, 1); mockCallable.getUpdateCount(); ctrlCallable.setReturnValue(-1); mockCallable.getObject(2); ctrlCallable.setReturnValue(new Integer(5), 1); if (debugEnabled) { mockCallable.getWarnings(); ctrlCallable.setReturnValue(null); } mockCallable.close(); ctrlCallable.setVoidCallable(1); // Must call this here as we're not using setUp()/tearDown() mechanism ctrlCallable.replay(); ctrlConnection = MockControl.createControl(Connection.class); mockConnection = (Connection) ctrlConnection.getMock(); mockConnection.prepareCall("{call " + StoredProcedureConfiguredViaJdbcTemplate.SQL + "(?, ?)}"); ctrlConnection.setReturnValue(mockCallable, 1); mockConnection.close(); ctrlConnection.setVoidCallable(1); ctrlConnection.replay(); MockControl dsControl = MockControl.createControl(DataSource.class); DataSource localDs = (DataSource) dsControl.getMock(); localDs.getConnection(); dsControl.setReturnValue(mockConnection, 1); dsControl.replay(); class TestJdbcTemplate extends JdbcTemplate { int calls; public Map call(CallableStatementCreator csc, List declaredParameters) throws DataAccessException { calls++; return super.call(csc, declaredParameters); } } TestJdbcTemplate t = new TestJdbcTemplate(); t.setDataSource(localDs); // Will fail without the following, because we're not able to get a connection from the // DataSource here if we need to to create an ExceptionTranslator t.setExceptionTranslator(new SQLStateSQLExceptionTranslator()); StoredProcedureConfiguredViaJdbcTemplate sp = new StoredProcedureConfiguredViaJdbcTemplate(t); assertEquals(sp.execute(11), 5); assertEquals(1, t.calls); dsControl.verify(); ctrlCallable.verify(); ctrlConnection.verify(); } /** * Confirm our JdbcTemplate is used * @throws Exception */ public void testStoredProcedureConfiguredViaJdbcTemplate() throws Exception { mockCallable.setObject(1, new Integer(1106), Types.INTEGER); ctrlCallable.setVoidCallable(); mockCallable.registerOutParameter(2, Types.INTEGER); ctrlCallable.setVoidCallable(); mockCallable.execute(); ctrlCallable.setReturnValue(false); mockCallable.getUpdateCount(); ctrlCallable.setReturnValue(-1); mockCallable.getObject(2); ctrlCallable.setReturnValue(new Integer(4)); if (debugEnabled) { mockCallable.getWarnings(); ctrlCallable.setReturnValue(null); } mockCallable.close(); ctrlCallable.setVoidCallable(); mockConnection.prepareCall("{call " + StoredProcedureConfiguredViaJdbcTemplate.SQL + "(?, ?)}"); ctrlConnection.setReturnValue(mockCallable); replay(); JdbcTemplate t = new JdbcTemplate(); t.setDataSource(mockDataSource); StoredProcedureConfiguredViaJdbcTemplate sp = new StoredProcedureConfiguredViaJdbcTemplate(t); assertEquals(sp.execute(1106), 4); } public void testNullArg() throws Exception { MockControl ctrlResultSet = MockControl.createControl(ResultSet.class); ResultSet mockResultSet = (ResultSet) ctrlResultSet.getMock(); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockCallable.setNull(1, Types.VARCHAR); ctrlCallable.setVoidCallable(); mockCallable.execute(); ctrlCallable.setReturnValue(false); mockCallable.getUpdateCount(); ctrlCallable.setReturnValue(-1); if (debugEnabled) { mockCallable.getWarnings(); ctrlCallable.setReturnValue(null); } mockCallable.close(); ctrlCallable.setVoidCallable(); mockConnection.prepareCall("{call " + NullArg.SQL + "(?)}"); ctrlConnection.setReturnValue(mockCallable); replay(); ctrlResultSet.replay(); NullArg na = new NullArg(mockDataSource); na.execute((String) null); } public void testUnnamedParameter() throws Exception { replay(); try { UnnamedParameterStoredProcedure unp = new UnnamedParameterStoredProcedure(mockDataSource); fail("Shouldn't succeed in creating stored procedure with unnamed parameter"); } catch (InvalidDataAccessApiUsageException idaauex) { // OK } } public void testMissingParameter() throws Exception { replay(); try { MissingParameterStoredProcedure mp = new MissingParameterStoredProcedure(mockDataSource); mp.execute(); fail("Shouldn't succeed in running stored procedure with missing required parameter"); } catch (InvalidDataAccessApiUsageException idaauex) { // OK } } public void testStoredProcedureExceptionTranslator() throws Exception { SQLException sex = new SQLException( "Syntax error or access violation exception", "42000"); mockCallable.execute(); ctrlCallable.setThrowable(sex); mockCallable.close(); ctrlCallable.setVoidCallable(); mockConnection.prepareCall( "{call " + StoredProcedureExceptionTranslator.SQL + "()}"); ctrlConnection.setReturnValue(mockCallable); replay(); StoredProcedureExceptionTranslator sproc = new StoredProcedureExceptionTranslator(mockDataSource); try { sproc.execute(); fail("Custom exception should be thrown"); } catch (CustomDataException ex) { // OK } } public void testStoredProcedureWithResultSet() throws Exception { MockControl ctrlResultSet = MockControl.createControl(ResultSet.class); ResultSet mockResultSet = (ResultSet) ctrlResultSet.getMock(); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.next(); ctrlResultSet.setReturnValue(false); if (debugEnabled) { mockCallable.getWarnings(); ctrlCallable.setReturnValue(null); } mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockCallable.execute(); ctrlCallable.setReturnValue(true); mockCallable.getUpdateCount(); ctrlCallable.setReturnValue(-1); mockCallable.getResultSet(); ctrlCallable.setReturnValue(mockResultSet); mockCallable.getMoreResults(); ctrlCallable.setReturnValue(false); mockCallable.getUpdateCount(); ctrlCallable.setReturnValue(-1); mockCallable.close(); ctrlCallable.setVoidCallable(); mockConnection.prepareCall("{call " + StoredProcedureWithResultSet.SQL + "()}"); ctrlConnection.setReturnValue(mockCallable); replay(); ctrlResultSet.replay(); StoredProcedureWithResultSet sproc = new StoredProcedureWithResultSet(mockDataSource); sproc.execute(); ctrlResultSet.verify(); assertEquals(2, sproc.getCount()); } public void testStoredProcedureWithResultSetMapped() throws Exception { MockControl ctrlResultSet = MockControl.createControl(ResultSet.class); ResultSet mockResultSet = (ResultSet) ctrlResultSet.getMock(); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getString(2); ctrlResultSet.setReturnValue("Foo"); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getString(2); ctrlResultSet.setReturnValue("Bar"); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockCallable.execute(); ctrlCallable.setReturnValue(true); mockCallable.getUpdateCount(); ctrlCallable.setReturnValue(-1); mockCallable.getResultSet(); ctrlCallable.setReturnValue(mockResultSet); mockCallable.getMoreResults(); ctrlCallable.setReturnValue(false); mockCallable.getUpdateCount(); ctrlCallable.setReturnValue(-1); if (debugEnabled) { mockCallable.getWarnings(); ctrlCallable.setReturnValue(null); } mockCallable.close(); ctrlCallable.setVoidCallable(); mockConnection.prepareCall("{call " + StoredProcedureWithResultSetMapped.SQL + "()}"); ctrlConnection.setReturnValue(mockCallable); replay(); ctrlResultSet.replay(); StoredProcedureWithResultSetMapped sproc = new StoredProcedureWithResultSetMapped(mockDataSource); Map res = sproc.execute(); ctrlResultSet.verify(); List rs = (List) res.get("rs"); assertEquals(2, rs.size()); assertEquals("Foo", rs.get(0)); assertEquals("Bar", rs.get(1)); } public void testStoredProcedureWithUndeclaredResults() throws Exception { MockControl ctrlResultSet1 = MockControl.createControl(ResultSet.class); ResultSet mockResultSet1 = (ResultSet) ctrlResultSet1.getMock(); mockResultSet1.next(); ctrlResultSet1.setReturnValue(true); mockResultSet1.getString(2); ctrlResultSet1.setReturnValue("Foo"); mockResultSet1.next(); ctrlResultSet1.setReturnValue(true); mockResultSet1.getString(2); ctrlResultSet1.setReturnValue("Bar"); mockResultSet1.next(); ctrlResultSet1.setReturnValue(false); mockResultSet1.close(); ctrlResultSet1.setVoidCallable(); MockControl ctrlMetaData = MockControl.createControl(ResultSetMetaData.class); ResultSetMetaData mockMetaData = (ResultSetMetaData) ctrlMetaData.getMock(); mockMetaData.getColumnCount(); ctrlMetaData.setReturnValue(2); mockMetaData.getColumnLabel(1); ctrlMetaData.setReturnValue("spam"); mockMetaData.getColumnLabel(2); ctrlMetaData.setReturnValue("eggs"); MockControl ctrlResultSet2 = MockControl.createControl(ResultSet.class); ResultSet mockResultSet2 = (ResultSet) ctrlResultSet2.getMock(); mockResultSet2.getMetaData(); ctrlResultSet2.setReturnValue(mockMetaData); mockResultSet2.next(); ctrlResultSet2.setReturnValue(true); mockResultSet2.getObject(1); ctrlResultSet2.setReturnValue("Spam"); mockResultSet2.getObject(2); ctrlResultSet2.setReturnValue("Eggs"); mockResultSet2.next(); ctrlResultSet2.setReturnValue(false); mockResultSet2.close(); ctrlResultSet2.setVoidCallable(); mockCallable.execute(); ctrlCallable.setReturnValue(true); mockCallable.getUpdateCount(); ctrlCallable.setReturnValue(-1); mockCallable.getResultSet(); ctrlCallable.setReturnValue(mockResultSet1); mockCallable.getMoreResults(); ctrlCallable.setReturnValue(true); mockCallable.getUpdateCount(); ctrlCallable.setReturnValue(-1); mockCallable.getResultSet(); ctrlCallable.setReturnValue(mockResultSet2); mockCallable.getMoreResults(); ctrlCallable.setReturnValue(false); mockCallable.getUpdateCount(); ctrlCallable.setReturnValue(0); mockCallable.getMoreResults(); ctrlCallable.setReturnValue(false); mockCallable.getUpdateCount(); ctrlCallable.setReturnValue(-1); if (debugEnabled) { mockCallable.getWarnings(); ctrlCallable.setReturnValue(null); } mockCallable.close(); ctrlCallable.setVoidCallable(); mockConnection.prepareCall("{call " + StoredProcedureWithResultSetMapped.SQL + "()}"); ctrlConnection.setReturnValue(mockCallable); replay(); ctrlResultSet1.replay(); ctrlMetaData.replay(); ctrlResultSet2.replay(); StoredProcedureWithResultSetMapped sproc = new StoredProcedureWithResultSetMapped(mockDataSource); Map res = sproc.execute(); ctrlResultSet1.verify(); ctrlResultSet2.verify(); assertEquals("incorrect number of returns", 3, res.size()); List rs1 = (List) res.get("rs"); assertEquals(2, rs1.size()); assertEquals("Foo", rs1.get(0)); assertEquals("Bar", rs1.get(1)); List rs2 = (List) res.get("#result-set-2"); assertEquals(1, rs2.size()); Object o2 = rs2.get(0); assertTrue("wron type returned for result set 2", o2 instanceof Map); Map m2 = (Map) o2; assertEquals("Spam", m2.get("spam")); assertEquals("Eggs", m2.get("eggs")); Number n = (Number) res.get("#update-count-1"); assertEquals("wrong update count", 0, n.intValue()); } public void testStoredProcedureSkippingResultsProcessing() throws Exception { mockCallable.execute(); ctrlCallable.setReturnValue(true); mockCallable.getUpdateCount(); ctrlCallable.setReturnValue(-1); if (debugEnabled) { mockCallable.getWarnings(); ctrlCallable.setReturnValue(null); } mockCallable.close(); ctrlCallable.setVoidCallable(); mockConnection.prepareCall("{call " + StoredProcedureWithResultSetMapped.SQL + "()}"); ctrlConnection.setReturnValue(mockCallable); replay(); JdbcTemplate jdbcTemplate = new JdbcTemplate(mockDataSource); jdbcTemplate.setSkipResultsProcessing(true); StoredProcedureWithResultSetMapped sproc = new StoredProcedureWithResultSetMapped(jdbcTemplate); Map res = sproc.execute(); assertEquals("incorrect number of returns", 0, res.size()); } public void testStoredProcedureSkippingUndeclaredResults() throws Exception { MockControl ctrlResultSet1 = MockControl.createControl(ResultSet.class); ResultSet mockResultSet1 = (ResultSet) ctrlResultSet1.getMock(); mockResultSet1.next(); ctrlResultSet1.setReturnValue(true); mockResultSet1.getString(2); ctrlResultSet1.setReturnValue("Foo"); mockResultSet1.next(); ctrlResultSet1.setReturnValue(true); mockResultSet1.getString(2); ctrlResultSet1.setReturnValue("Bar"); mockResultSet1.next(); ctrlResultSet1.setReturnValue(false); mockResultSet1.close(); ctrlResultSet1.setVoidCallable(); mockCallable.execute(); ctrlCallable.setReturnValue(true); mockCallable.getUpdateCount(); ctrlCallable.setReturnValue(-1); mockCallable.getResultSet(); ctrlCallable.setReturnValue(mockResultSet1); mockCallable.getMoreResults(); ctrlCallable.setReturnValue(true); mockCallable.getUpdateCount(); ctrlCallable.setReturnValue(-1); mockCallable.getMoreResults(); ctrlCallable.setReturnValue(false); mockCallable.getUpdateCount(); ctrlCallable.setReturnValue(-1); if (debugEnabled) { mockCallable.getWarnings(); ctrlCallable.setReturnValue(null); } mockCallable.close(); ctrlCallable.setVoidCallable(); mockConnection.prepareCall("{call " + StoredProcedureWithResultSetMapped.SQL + "()}"); ctrlConnection.setReturnValue(mockCallable); replay(); ctrlResultSet1.replay(); JdbcTemplate jdbcTemplate = new JdbcTemplate(mockDataSource); jdbcTemplate.setSkipUndeclaredResults(true); StoredProcedureWithResultSetMapped sproc = new StoredProcedureWithResultSetMapped(jdbcTemplate); Map res = sproc.execute(); ctrlResultSet1.verify(); assertEquals("incorrect number of returns", 1, res.size()); List rs1 = (List) res.get("rs"); assertEquals(2, rs1.size()); assertEquals("Foo", rs1.get(0)); assertEquals("Bar", rs1.get(1)); } public void testParameterMapper() throws Exception { mockCallable.setString(1, "EasyMock for interface java.sql.Connection"); ctrlCallable.setVoidCallable(); mockCallable.registerOutParameter(2, Types.VARCHAR); ctrlCallable.setVoidCallable(); mockCallable.execute(); ctrlCallable.setReturnValue(false); mockCallable.getUpdateCount(); ctrlCallable.setReturnValue(-1); mockCallable.getObject(2); ctrlCallable.setReturnValue("OK"); if (debugEnabled) { mockCallable.getWarnings(); ctrlCallable.setReturnValue(null); } mockCallable.close(); ctrlCallable.setVoidCallable(); mockConnection.prepareCall( "{call " + ParameterMapperStoredProcedure.SQL + "(?, ?)}"); ctrlConnection.setReturnValue(mockCallable); replay(); ParameterMapperStoredProcedure pmsp = new ParameterMapperStoredProcedure(mockDataSource); Map out = pmsp.executeTest(); assertEquals("OK", out.get("out")); } public void testSqlTypeValue() throws Exception { int[] testVal = new int[] {1, 2}; mockCallable.getConnection(); ctrlCallable.setDefaultReturnValue(mockConnection); mockCallable.setObject(1, testVal, Types.ARRAY); ctrlCallable.setVoidCallable(); mockCallable.registerOutParameter(2, Types.VARCHAR); ctrlCallable.setVoidCallable(); mockCallable.execute(); ctrlCallable.setReturnValue(false); mockCallable.getUpdateCount(); ctrlCallable.setReturnValue(-1); mockCallable.getObject(2); ctrlCallable.setReturnValue("OK"); if (debugEnabled) { mockCallable.getWarnings(); ctrlCallable.setReturnValue(null); } mockCallable.close(); ctrlCallable.setVoidCallable(); mockConnection.prepareCall( "{call " + SqlTypeValueStoredProcedure.SQL + "(?, ?)}"); ctrlConnection.setReturnValue(mockCallable); replay(); SqlTypeValueStoredProcedure stvsp = new SqlTypeValueStoredProcedure(mockDataSource); Map out = stvsp.executeTest(testVal); assertEquals("OK", out.get("out")); } public void testNumericWithScale() throws Exception { mockCallable.getConnection(); ctrlCallable.setDefaultReturnValue(mockConnection); mockCallable.registerOutParameter(1, Types.DECIMAL, 4); ctrlCallable.setVoidCallable(); mockCallable.execute(); ctrlCallable.setReturnValue(false); mockCallable.getUpdateCount(); ctrlCallable.setReturnValue(-1); mockCallable.getObject(1); ctrlCallable.setReturnValue(new BigDecimal("12345.6789")); if (debugEnabled) { mockCallable.getWarnings(); ctrlCallable.setReturnValue(null); } mockCallable.close(); ctrlCallable.setVoidCallable(); mockConnection.prepareCall( "{call " + NumericWithScaleStoredProcedure.SQL + "(?)}"); ctrlConnection.setReturnValue(mockCallable); replay(); NumericWithScaleStoredProcedure nwssp = new NumericWithScaleStoredProcedure(mockDataSource); Map out = nwssp.executeTest(); assertEquals(new BigDecimal("12345.6789"), out.get("out")); } private static class StoredProcedureConfiguredViaJdbcTemplate extends StoredProcedure { public static final String SQL = "configured_via_jt"; public StoredProcedureConfiguredViaJdbcTemplate(JdbcTemplate t) { setJdbcTemplate(t); setSql(SQL); declareParameter(new SqlParameter("intIn", Types.INTEGER)); declareParameter(new SqlOutParameter("intOut", Types.INTEGER)); compile(); } public int execute(int intIn) { Map in = new HashMap(); in.put("intIn", new Integer(intIn)); Map out = execute(in); Number intOut = (Number) out.get("intOut"); return intOut.intValue(); } } private static class AddInvoice extends StoredProcedure { public static final String SQL = "add_invoice"; public AddInvoice(DataSource ds) { setDataSource(ds); setSql(SQL); declareParameter(new SqlParameter("amount", Types.INTEGER)); declareParameter(new SqlParameter("custid", Types.INTEGER)); declareParameter(new SqlOutParameter("newid", Types.INTEGER)); compile(); } public int execute(int amount, int custid) { Map in = new HashMap(); in.put("amount", new Integer(amount)); in.put("custid", new Integer(custid)); Map out = execute(in); Number id = (Number) out.get("newid"); return id.intValue(); } } private static class AddInvoiceUsingObjectArray extends StoredProcedure { public static final String SQL = "add_invoice"; public AddInvoiceUsingObjectArray(DataSource ds) { setDataSource(ds); setSql(SQL); declareParameter(new SqlParameter("amount", Types.INTEGER)); declareParameter(new SqlParameter("custid", Types.INTEGER)); declareParameter(new SqlOutParameter("newid", Types.INTEGER)); compile(); } public int execute(int amount, int custid) { Map out = execute(new Object[] {amount, custid}); System.out.println("####### " + out); Number id = (Number) out.get("newid"); return id.intValue(); } } private static class NullArg extends StoredProcedure { public static final String SQL = "takes_null"; public NullArg(DataSource ds) { setDataSource(ds); setSql(SQL); declareParameter(new SqlParameter("ptest", Types.VARCHAR)); compile(); } public void execute(String s) { Map in = new HashMap(); in.put("ptest", s); Map out = execute(in); } } private static class NoSuchStoredProcedure extends StoredProcedure { public static final String SQL = "no_sproc_with_this_name"; public NoSuchStoredProcedure(DataSource ds) { setDataSource(ds); setSql(SQL); compile(); } public void execute() { execute(new HashMap()); } } private static class UnnamedParameterStoredProcedure extends StoredProcedure { public UnnamedParameterStoredProcedure(DataSource ds) { super(ds, "unnamed_parameter_sp"); declareParameter(new SqlParameter(Types.INTEGER)); compile(); } public void execute(int id) { Map in = new HashMap(); in.put("id", new Integer(id)); Map out = execute(in); } } private static class MissingParameterStoredProcedure extends StoredProcedure { public MissingParameterStoredProcedure(DataSource ds) { setDataSource(ds); setSql("takes_string"); declareParameter(new SqlParameter("mystring", Types.VARCHAR)); compile(); } public void execute() { execute(new HashMap()); } } private static class StoredProcedureWithResultSet extends StoredProcedure { public static final String SQL = "sproc_with_result_set"; private final SimpleRowCountCallbackHandler handler = new SimpleRowCountCallbackHandler(); public StoredProcedureWithResultSet(DataSource ds) { setDataSource(ds); setSql(SQL); declareParameter(new SqlReturnResultSet("rs", this.handler)); compile(); } public void execute() { execute(new HashMap()); } public int getCount() { return this.handler.getCount(); } } private static class StoredProcedureWithResultSetMapped extends StoredProcedure { public static final String SQL = "sproc_with_result_set"; public StoredProcedureWithResultSetMapped(DataSource ds) { setDataSource(ds); setSql(SQL); declareParameter( new SqlReturnResultSet("rs", new RowMapperImpl())); compile(); } public StoredProcedureWithResultSetMapped(JdbcTemplate jt) { setJdbcTemplate(jt); setSql(SQL); declareParameter( new SqlReturnResultSet("rs", new RowMapperImpl())); compile(); } public Map execute() { Map out = execute(new HashMap()); return out; } private static class RowMapperImpl implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { return rs.getString(2); } } } private static class ParameterMapperStoredProcedure extends StoredProcedure { public static final String SQL = "parameter_mapper_sp"; public ParameterMapperStoredProcedure(DataSource ds) { setDataSource(ds); setSql(SQL); declareParameter(new SqlParameter("in", Types.VARCHAR)); declareParameter(new SqlOutParameter("out", Types.VARCHAR)); compile(); } public Map executeTest() { Map out = null; out = execute(new TestParameterMapper()); return out; } private static class TestParameterMapper implements ParameterMapper { private TestParameterMapper() { } public Map createMap(Connection conn) throws SQLException { Map inParms = new HashMap(); String testValue = conn.toString(); inParms.put("in", testValue); return inParms; } } } private static class SqlTypeValueStoredProcedure extends StoredProcedure { public static final String SQL = "sql_type_value_sp"; public SqlTypeValueStoredProcedure(DataSource ds) { setDataSource(ds); setSql(SQL); declareParameter(new SqlParameter("in", Types.ARRAY, "NUMBERS")); declareParameter(new SqlOutParameter("out", Types.VARCHAR)); compile(); } public Map executeTest(final int[] inValue) { Map in = new HashMap(1); in.put("in", new AbstractSqlTypeValue() { public Object createTypeValue(Connection con, int type, String typeName) { //assertEquals(Connection.class, con.getClass()); //assertEquals(Types.ARRAY, type); //assertEquals("NUMBER", typeName); return inValue; } }); Map out = null; out = execute(in); return out; } } private static class NumericWithScaleStoredProcedure extends StoredProcedure { public static final String SQL = "numeric_with_scale_sp"; public NumericWithScaleStoredProcedure(DataSource ds) { setDataSource(ds); setSql(SQL); declareParameter(new SqlOutParameter("out", Types.DECIMAL, 4)); compile(); } public Map executeTest() { Map in = new HashMap(1); Map out = null; out = execute(in); return out; } } private static class StoredProcedureExceptionTranslator extends StoredProcedure { public static final String SQL = "no_sproc_with_this_name"; public StoredProcedureExceptionTranslator(DataSource ds) { setDataSource(ds); setSql(SQL); getJdbcTemplate().setExceptionTranslator(new SQLExceptionTranslator() { public DataAccessException translate( String task, String sql, SQLException sqlex) { return new CustomDataException(sql, sqlex); } }); compile(); } public void execute() { execute(new HashMap()); } } private static class CustomDataException extends DataAccessException { public CustomDataException(String s) { super(s); } public CustomDataException(String s, Throwable ex) { super(s, ex); } } } ././@LongLink0000000000000000000000000000020000000000000011555 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/object/SqlQueryTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000011335711623223526033337 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.object; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Types; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.sql.DataSource; import org.easymock.MockControl; import org.apache.commons.logging.LogFactory; import org.springframework.dao.IncorrectResultSizeDataAccessException; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.jdbc.AbstractJdbcTests; import org.springframework.jdbc.Customer; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.SqlParameter; import junit.framework.Assert; /** * @author Trevor Cook * @author Thomas Risberg * @author Juergen Hoeller */ public class SqlQueryTests extends AbstractJdbcTests { private static final String SELECT_ID = "select id from custmr"; private static final String SELECT_ID_WHERE = "select id from custmr where forename = ? and id = ?"; private static final String SELECT_FORENAME = "select forename from custmr"; private static final String SELECT_FORENAME_EMPTY = "select forename from custmr WHERE 1 = 2"; private static final String SELECT_ID_FORENAME_WHERE = "select id, forename from prefix:custmr where forename = ?"; private static final String SELECT_ID_FORENAME_NAMED_PARAMETERS = "select id, forename from custmr where id = :id and country = :country"; private static final String SELECT_ID_FORENAME_NAMED_PARAMETERS_PARSED = "select id, forename from custmr where id = ? and country = ?"; private static final String SELECT_ID_FORENAME_WHERE_ID_IN_LIST_1 = "select id, forename from custmr where id in (?, ?)"; private static final String SELECT_ID_FORENAME_WHERE_ID_IN_LIST_2 = "select id, forename from custmr where id in (:ids)"; private static final String SELECT_ID_FORENAME_WHERE_ID_REUSED_1 = "select id, forename from custmr where id = ? or id = ?)"; private static final String SELECT_ID_FORENAME_WHERE_ID_REUSED_2 = "select id, forename from custmr where id = :id1 or id = :id1)"; private static final String SELECT_ID_FORENAME_WHERE_ID = "select id, forename from custmr where id <= ?"; private static final String[] COLUMN_NAMES = new String[] {"id", "forename"}; private static final int[] COLUMN_TYPES = new int[] {Types.INTEGER, Types.VARCHAR}; private final boolean debugEnabled = LogFactory.getLog(JdbcTemplate.class).isDebugEnabled(); private MockControl ctrlPreparedStatement; private PreparedStatement mockPreparedStatement; private MockControl ctrlResultSet; private ResultSet mockResultSet; protected void setUp() throws Exception { super.setUp(); ctrlPreparedStatement = MockControl.createControl(PreparedStatement.class); mockPreparedStatement = (PreparedStatement) ctrlPreparedStatement.getMock(); ctrlResultSet = MockControl.createControl(ResultSet.class); mockResultSet = (ResultSet) ctrlResultSet.getMock(); } protected void tearDown() throws Exception { super.tearDown(); if (shouldVerify()) { ctrlPreparedStatement.verify(); ctrlResultSet.verify(); } } protected void replay() { super.replay(); ctrlPreparedStatement.replay(); ctrlResultSet.replay(); } public void testQueryWithoutParams() throws SQLException { mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getInt(1); ctrlResultSet.setReturnValue(1); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockPreparedStatement.executeQuery(); ctrlPreparedStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(SELECT_ID); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); SqlQuery query = new MappingSqlQueryWithParameters() { protected Object mapRow(ResultSet rs, int rownum, Object[] params, Map context) throws SQLException { assertTrue("params were null", params == null); assertTrue("context was null", context == null); return new Integer(rs.getInt(1)); } }; query.setDataSource(mockDataSource); query.setSql(SELECT_ID); query.compile(); List list = query.execute(); assertTrue("Found customers", list.size() != 0); for (Iterator itr = list.iterator(); itr.hasNext();) { Integer id = (Integer) itr.next(); assertTrue( "Customer id was assigned correctly", id.intValue() == 1); } } public void testQueryWithoutEnoughParams() { replay(); MappingSqlQuery query = new MappingSqlQuery() { protected Object mapRow(ResultSet rs, int rownum) throws SQLException { return new Integer(rs.getInt(1)); } }; query.setDataSource(mockDataSource); query.setSql(SELECT_ID_WHERE); query.declareParameter( new SqlParameter(COLUMN_NAMES[0], COLUMN_TYPES[0])); query.declareParameter( new SqlParameter(COLUMN_NAMES[1], COLUMN_TYPES[1])); query.compile(); try { List list = query.execute(); fail("Shouldn't succeed in running query without enough params"); } catch (InvalidDataAccessApiUsageException ex) { // OK } } public void testQueryWithMissingMapParams() { replay(); MappingSqlQuery query = new MappingSqlQuery() { protected Object mapRow(ResultSet rs, int rownum) throws SQLException { return new Integer(rs.getInt(1)); } }; query.setDataSource(mockDataSource); query.setSql(SELECT_ID_WHERE); query.declareParameter( new SqlParameter(COLUMN_NAMES[0], COLUMN_TYPES[0])); query.declareParameter( new SqlParameter(COLUMN_NAMES[1], COLUMN_TYPES[1])); query.compile(); try { Map params = new HashMap(); params.put(COLUMN_NAMES[0], "Value"); List list = query.executeByNamedParam(params); fail("Shouldn't succeed in running query with missing params"); } catch (InvalidDataAccessApiUsageException ex) { // OK } } public void testStringQueryWithResults() throws Exception { String[] dbResults = new String[] { "alpha", "beta", "charlie" }; MockControl[] ctrlCountResultSetMetaData = new MockControl[3]; ResultSetMetaData[] mockCountResultSetMetaData = new ResultSetMetaData[3]; MockControl[] ctrlCountResultSet = new MockControl[3]; ResultSet[] mockCountResultSet = new ResultSet[3]; MockControl[] ctrlCountPreparedStatement = new MockControl[3]; PreparedStatement[] mockCountPreparedStatement = new PreparedStatement[3]; mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getString(1); ctrlResultSet.setReturnValue(dbResults[0]); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getString(1); ctrlResultSet.setReturnValue(dbResults[1]); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getString(1); ctrlResultSet.setReturnValue(dbResults[2]); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockPreparedStatement.executeQuery(); ctrlPreparedStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(SELECT_FORENAME); ctrlConnection.setReturnValue(mockPreparedStatement); for (int i = 0; i < dbResults.length; i++) { ctrlCountResultSetMetaData[i] = MockControl.createControl(ResultSetMetaData.class); mockCountResultSetMetaData[i] = (ResultSetMetaData) ctrlCountResultSetMetaData[i].getMock(); mockCountResultSetMetaData[i].getColumnCount(); ctrlCountResultSetMetaData[i].setReturnValue(1); ctrlCountResultSet[i] = MockControl.createControl(ResultSet.class); mockCountResultSet[i] = (ResultSet) ctrlCountResultSet[i].getMock(); mockCountResultSet[i].getMetaData(); ctrlCountResultSet[i].setReturnValue(mockCountResultSetMetaData[i]); mockCountResultSet[i].next(); ctrlCountResultSet[i].setReturnValue(true); mockCountResultSet[i].getInt(1); ctrlCountResultSet[i].setReturnValue(1); mockCountResultSet[i].wasNull(); ctrlCountResultSet[i].setReturnValue(false); mockCountResultSet[i].next(); ctrlCountResultSet[i].setReturnValue(false); mockCountResultSet[i].close(); ctrlCountResultSet[i].setVoidCallable(); ctrlCountPreparedStatement[i] = MockControl.createControl(PreparedStatement.class); mockCountPreparedStatement[i] = (PreparedStatement) ctrlCountPreparedStatement[i].getMock(); mockCountPreparedStatement[i].executeQuery(); ctrlCountPreparedStatement[i].setReturnValue(mockCountResultSet[i]); if (debugEnabled) { mockCountPreparedStatement[i].getWarnings(); ctrlCountPreparedStatement[i].setReturnValue(null); } mockCountPreparedStatement[i].close(); ctrlCountPreparedStatement[i].setVoidCallable(); mockConnection.prepareStatement( "SELECT COUNT(FORENAME) FROM CUSTMR WHERE FORENAME='" + dbResults[i] + "'"); ctrlConnection.setReturnValue(mockCountPreparedStatement[i]); ctrlCountResultSetMetaData[i].replay(); ctrlCountResultSet[i].replay(); ctrlCountPreparedStatement[i].replay(); } replay(); StringQuery query = new StringQuery(mockDataSource, SELECT_FORENAME); query.setRowsExpected(3); String[] results = query.run(); assertTrue("Array is non null", results != null); assertTrue("Found results", results.length > 0); assertTrue( "Found expected number of results", query.getRowsExpected() == 3); JdbcTemplate helper = new JdbcTemplate(mockDataSource); for (int i = 0; i < results.length; i++) { // BREAKS ON ' in name int dbCount = helper.queryForInt( "SELECT COUNT(FORENAME) FROM CUSTMR WHERE FORENAME='" + results[i] + "'", (Object[]) null); assertTrue("found in db", dbCount == 1); } for (int i = 0; i < dbResults.length; i++) { ctrlCountResultSetMetaData[i].verify(); ctrlCountResultSet[i].verify(); ctrlCountPreparedStatement[i].verify(); } } public void testStringQueryWithoutResults() throws SQLException { mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockPreparedStatement.executeQuery(); ctrlPreparedStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(SELECT_FORENAME_EMPTY); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); StringQuery query = new StringQuery(mockDataSource, SELECT_FORENAME_EMPTY); String[] results = query.run(); assertTrue("Array is non null", results != null); assertTrue("Found 0 results", results.length == 0); } public void testFindCustomerIntInt() throws SQLException { mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getInt("id"); ctrlResultSet.setReturnValue(1); mockResultSet.getString("forename"); ctrlResultSet.setReturnValue("rod"); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockPreparedStatement.setObject(1, new Integer(1), Types.NUMERIC); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.setObject(2, new Integer(1), Types.NUMERIC); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeQuery(); ctrlPreparedStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(SELECT_ID_WHERE); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); class CustomerQuery extends MappingSqlQuery { public CustomerQuery(DataSource ds) { super(ds, SELECT_ID_WHERE); declareParameter(new SqlParameter(Types.NUMERIC)); declareParameter(new SqlParameter(Types.NUMERIC)); compile(); } protected Object mapRow(ResultSet rs, int rownum) throws SQLException { Customer cust = new Customer(); cust.setId(rs.getInt(COLUMN_NAMES[0])); cust.setForename(rs.getString(COLUMN_NAMES[1])); return cust; } public Customer findCustomer(int id, int otherNum) { return (Customer) findObject(id, otherNum); } } CustomerQuery query = new CustomerQuery(mockDataSource); Customer cust = query.findCustomer(1, 1); assertTrue("Customer id was assigned correctly", cust.getId() == 1); assertTrue( "Customer forename was assigned correctly", cust.getForename().equals("rod")); } public void testFindCustomerString() throws SQLException { mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getInt("id"); ctrlResultSet.setReturnValue(1); mockResultSet.getString("forename"); ctrlResultSet.setReturnValue("rod"); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockPreparedStatement.setString(1, "rod"); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeQuery(); ctrlPreparedStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(SELECT_ID_FORENAME_WHERE); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); class CustomerQuery extends MappingSqlQuery { public CustomerQuery(DataSource ds) { super(ds, SELECT_ID_FORENAME_WHERE); declareParameter(new SqlParameter(Types.VARCHAR)); compile(); } protected Object mapRow(ResultSet rs, int rownum) throws SQLException { Customer cust = new Customer(); cust.setId(rs.getInt(COLUMN_NAMES[0])); cust.setForename(rs.getString(COLUMN_NAMES[1])); return cust; } public Customer findCustomer(String id) { return (Customer) findObject(id); } } CustomerQuery query = new CustomerQuery(mockDataSource); Customer cust = query.findCustomer("rod"); assertTrue("Customer id was assigned correctly", cust.getId() == 1); assertTrue("Customer forename was assigned correctly", cust.getForename().equals("rod")); } public void testFindCustomerMixed() throws SQLException { MockControl ctrlResultSet2; ResultSet mockResultSet2; MockControl ctrlPreparedStatement2; PreparedStatement mockPreparedStatement2; mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getInt("id"); ctrlResultSet.setReturnValue(1); mockResultSet.getString("forename"); ctrlResultSet.setReturnValue("rod"); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockPreparedStatement.setObject(1, new Integer(1), Types.INTEGER); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.setString(2, "rod"); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeQuery(); ctrlPreparedStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); ctrlResultSet2 = MockControl.createControl(ResultSet.class); mockResultSet2 = (ResultSet) ctrlResultSet2.getMock(); mockResultSet2.next(); ctrlResultSet2.setReturnValue(false); mockResultSet2.close(); ctrlResultSet2.setVoidCallable(); ctrlPreparedStatement2 = MockControl.createControl(PreparedStatement.class); mockPreparedStatement2 = (PreparedStatement) ctrlPreparedStatement2.getMock(); mockPreparedStatement2.setObject(1, new Integer(1), Types.INTEGER); ctrlPreparedStatement2.setVoidCallable(); mockPreparedStatement2.setString(2, "Roger"); ctrlPreparedStatement2.setVoidCallable(); mockPreparedStatement2.executeQuery(); ctrlPreparedStatement2.setReturnValue(mockResultSet2); if (debugEnabled) { mockPreparedStatement2.getWarnings(); ctrlPreparedStatement2.setReturnValue(null); } mockPreparedStatement2.close(); ctrlPreparedStatement2.setVoidCallable(); mockConnection.prepareStatement(SELECT_ID_WHERE); ctrlConnection.setReturnValue(mockPreparedStatement); mockConnection.prepareStatement(SELECT_ID_WHERE); ctrlConnection.setReturnValue(mockPreparedStatement2); ctrlResultSet2.replay(); ctrlPreparedStatement2.replay(); replay(); class CustomerQuery extends MappingSqlQuery { public CustomerQuery(DataSource ds) { super(ds, SELECT_ID_WHERE); declareParameter( new SqlParameter(COLUMN_NAMES[0], COLUMN_TYPES[0])); declareParameter( new SqlParameter(COLUMN_NAMES[1], COLUMN_TYPES[1])); compile(); } protected Object mapRow(ResultSet rs, int rownum) throws SQLException { Customer cust = new Customer(); cust.setId(rs.getInt(COLUMN_NAMES[0])); cust.setForename(rs.getString(COLUMN_NAMES[1])); return cust; } public Customer findCustomer(int id, String name) { return (Customer) findObject( new Object[] { new Integer(id), name }); } } CustomerQuery query = new CustomerQuery(mockDataSource); Customer cust1 = query.findCustomer(1, "rod"); assertTrue("Found customer", cust1 != null); assertTrue("Customer id was assigned correctly", cust1.getId() == 1); Customer cust2 = query.findCustomer(1, "Roger"); assertTrue("No customer found", cust2 == null); } public void testFindTooManyCustomers() throws SQLException { mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getInt("id"); ctrlResultSet.setReturnValue(1); mockResultSet.getString("forename"); ctrlResultSet.setReturnValue("rod"); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getInt("id"); ctrlResultSet.setReturnValue(2); mockResultSet.getString("forename"); ctrlResultSet.setReturnValue("rod"); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockPreparedStatement.setString(1, "rod"); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeQuery(); ctrlPreparedStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(SELECT_ID_FORENAME_WHERE); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); class CustomerQuery extends MappingSqlQuery { public CustomerQuery(DataSource ds) { super(ds, SELECT_ID_FORENAME_WHERE); declareParameter(new SqlParameter(Types.VARCHAR)); compile(); } protected Object mapRow(ResultSet rs, int rownum) throws SQLException { Customer cust = new Customer(); cust.setId(rs.getInt(COLUMN_NAMES[0])); cust.setForename(rs.getString(COLUMN_NAMES[1])); return cust; } public Customer findCustomer(String id) { return (Customer) findObject(id); } } CustomerQuery query = new CustomerQuery(mockDataSource); try { Customer cust = query.findCustomer("rod"); fail("Should fail if more than one row found"); } catch (IncorrectResultSizeDataAccessException ex) { // OK } } public void testListCustomersIntInt() throws SQLException { mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getInt("id"); ctrlResultSet.setReturnValue(1); mockResultSet.getString("forename"); ctrlResultSet.setReturnValue("rod"); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getInt("id"); ctrlResultSet.setReturnValue(2); mockResultSet.getString("forename"); ctrlResultSet.setReturnValue("dave"); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockPreparedStatement.setObject(1, new Integer(1), Types.NUMERIC); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.setObject(2, new Integer(1), Types.NUMERIC); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeQuery(); ctrlPreparedStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(SELECT_ID_WHERE); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); class CustomerQuery extends MappingSqlQuery { public CustomerQuery(DataSource ds) { super(ds, SELECT_ID_WHERE); declareParameter(new SqlParameter(Types.NUMERIC)); declareParameter(new SqlParameter(Types.NUMERIC)); compile(); } protected Object mapRow(ResultSet rs, int rownum) throws SQLException { Customer cust = new Customer(); cust.setId(rs.getInt(COLUMN_NAMES[0])); cust.setForename(rs.getString(COLUMN_NAMES[1])); return cust; } } CustomerQuery query = new CustomerQuery(mockDataSource); List list = query.execute(1, 1); assertTrue("2 results in list", list.size() == 2); for (Iterator itr = list.iterator(); itr.hasNext();) { Customer cust = (Customer) itr.next(); } } public void testListCustomersString() throws SQLException { mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getInt("id"); ctrlResultSet.setReturnValue(1); mockResultSet.getString("forename"); ctrlResultSet.setReturnValue("rod"); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getInt("id"); ctrlResultSet.setReturnValue(2); mockResultSet.getString("forename"); ctrlResultSet.setReturnValue("dave"); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockPreparedStatement.setString(1, "one"); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeQuery(); ctrlPreparedStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(SELECT_ID_FORENAME_WHERE); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); class CustomerQuery extends MappingSqlQuery { public CustomerQuery(DataSource ds) { super(ds, SELECT_ID_FORENAME_WHERE); declareParameter(new SqlParameter(Types.VARCHAR)); compile(); } protected Object mapRow(ResultSet rs, int rownum) throws SQLException { Customer cust = new Customer(); cust.setId(rs.getInt(COLUMN_NAMES[0])); cust.setForename(rs.getString(COLUMN_NAMES[1])); return cust; } } CustomerQuery query = new CustomerQuery(mockDataSource); List list = query.execute("one"); assertTrue("2 results in list", list.size() == 2); for (Iterator itr = list.iterator(); itr.hasNext();) { Customer cust = (Customer) itr.next(); } } public void testFancyCustomerQuery() throws SQLException { mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getInt("id"); ctrlResultSet.setReturnValue(1); mockResultSet.getString("forename"); ctrlResultSet.setReturnValue("rod"); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockPreparedStatement.setObject(1, new Integer(1), Types.NUMERIC); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeQuery(); ctrlPreparedStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement( SELECT_ID_FORENAME_WHERE, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); class CustomerQuery extends MappingSqlQuery { public CustomerQuery(DataSource ds) { super(ds, SELECT_ID_FORENAME_WHERE); setResultSetType(ResultSet.TYPE_SCROLL_SENSITIVE); declareParameter(new SqlParameter(Types.NUMERIC)); compile(); } protected Object mapRow(ResultSet rs, int rownum) throws SQLException { Customer cust = new Customer(); cust.setId(rs.getInt(COLUMN_NAMES[0])); cust.setForename(rs.getString(COLUMN_NAMES[1])); return cust; } public Customer findCustomer(int id) { return (Customer) findObject(id); } } CustomerQuery query = new CustomerQuery(mockDataSource); Customer cust = query.findCustomer(1); assertTrue("Customer id was assigned correctly", cust.getId() == 1); assertTrue("Customer forename was assigned correctly", cust.getForename().equals("rod")); } public void testUnnamedParameterDeclarationWithNamedParameterQuery() throws SQLException { replay(); class CustomerQuery extends MappingSqlQuery { public CustomerQuery(DataSource ds) { super(ds, SELECT_ID_FORENAME_WHERE); setResultSetType(ResultSet.TYPE_SCROLL_SENSITIVE); declareParameter(new SqlParameter(Types.NUMERIC)); compile(); } protected Object mapRow(ResultSet rs, int rownum) throws SQLException { Customer cust = new Customer(); cust.setId(rs.getInt(COLUMN_NAMES[0])); cust.setForename(rs.getString(COLUMN_NAMES[1])); return cust; } public Customer findCustomer(int id) { Map params = new HashMap(); params.put("id", new Integer(id)); return (Customer) executeByNamedParam(params).get(0); } } CustomerQuery query = new CustomerQuery(mockDataSource); try { Customer cust = query.findCustomer(1); fail("Query should not succeed since parameter declaration did not specify parameter name"); } catch (InvalidDataAccessApiUsageException ex) { // OK - it worked } } public void testNamedParameterCustomerQueryWithUnnamedDeclarations() throws SQLException { doTestNamedParameterCustomerQuery(false); } public void testNamedParameterCustomerQueryWithNamedDeclarations() throws SQLException { doTestNamedParameterCustomerQuery(true); } private void doTestNamedParameterCustomerQuery(final boolean namedDeclarations) throws SQLException { mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getInt("id"); ctrlResultSet.setReturnValue(1); mockResultSet.getString("forename"); ctrlResultSet.setReturnValue("rod"); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockPreparedStatement.setObject(1, new Integer(1), Types.NUMERIC); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.setString(2, "UK"); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeQuery(); ctrlPreparedStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement( SELECT_ID_FORENAME_NAMED_PARAMETERS_PARSED, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); class CustomerQuery extends MappingSqlQuery { public CustomerQuery(DataSource ds) { super(ds, SELECT_ID_FORENAME_NAMED_PARAMETERS); setResultSetType(ResultSet.TYPE_SCROLL_SENSITIVE); if (namedDeclarations) { declareParameter(new SqlParameter("country", Types.VARCHAR)); declareParameter(new SqlParameter("id", Types.NUMERIC)); } else { declareParameter(new SqlParameter(Types.NUMERIC)); declareParameter(new SqlParameter(Types.VARCHAR)); } compile(); } protected Object mapRow(ResultSet rs, int rownum) throws SQLException { Customer cust = new Customer(); cust.setId(rs.getInt(COLUMN_NAMES[0])); cust.setForename(rs.getString(COLUMN_NAMES[1])); return cust; } public Customer findCustomer(int id, String country) { Map params = new HashMap(); params.put("id", new Integer(id)); params.put("country", country); return (Customer) executeByNamedParam(params).get(0); } } CustomerQuery query = new CustomerQuery(mockDataSource); Customer cust = query.findCustomer(1, "UK"); assertTrue("Customer id was assigned correctly", cust.getId() == 1); assertTrue("Customer forename was assigned correctly", cust.getForename().equals("rod")); } public void testNamedParameterInListQuery() throws SQLException { mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getInt("id"); ctrlResultSet.setReturnValue(1); mockResultSet.getString("forename"); ctrlResultSet.setReturnValue("rod"); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getInt("id"); ctrlResultSet.setReturnValue(2); mockResultSet.getString("forename"); ctrlResultSet.setReturnValue("juergen"); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockPreparedStatement.setObject(1, new Integer(1), Types.NUMERIC); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.setObject(2, new Integer(2), Types.NUMERIC); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeQuery(); ctrlPreparedStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement( SELECT_ID_FORENAME_WHERE_ID_IN_LIST_1, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); class CustomerQuery extends MappingSqlQuery { public CustomerQuery(DataSource ds) { super(ds, SELECT_ID_FORENAME_WHERE_ID_IN_LIST_2); setResultSetType(ResultSet.TYPE_SCROLL_SENSITIVE); declareParameter(new SqlParameter("ids", Types.NUMERIC)); compile(); } protected Object mapRow(ResultSet rs, int rownum) throws SQLException { Customer cust = new Customer(); cust.setId(rs.getInt(COLUMN_NAMES[0])); cust.setForename(rs.getString(COLUMN_NAMES[1])); return cust; } public List findCustomers(List ids) { Map params = new HashMap(); params.put("ids", ids); return (List) executeByNamedParam(params); } } CustomerQuery query = new CustomerQuery(mockDataSource); List ids = new ArrayList(); ids.add(new Integer(1)); ids.add(new Integer(2)); List cust = query.findCustomers(ids); assertEquals("We got two customers back", cust.size(), 2); Assert.assertEquals("First customer id was assigned correctly", ((Customer)cust.get(0)).getId(), 1); Assert.assertEquals("First customer forename was assigned correctly", ((Customer)cust.get(0)).getForename(), "rod"); Assert.assertEquals("Second customer id was assigned correctly", ((Customer)cust.get(1)).getId(), 2); Assert.assertEquals("Second customer forename was assigned correctly", ((Customer)cust.get(1)).getForename(), "juergen"); } public void testNamedParameterQueryReusingParameter() throws SQLException { mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getInt("id"); ctrlResultSet.setReturnValue(1); mockResultSet.getString("forename"); ctrlResultSet.setReturnValue("rod"); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getInt("id"); ctrlResultSet.setReturnValue(2); mockResultSet.getString("forename"); ctrlResultSet.setReturnValue("juergen"); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockPreparedStatement.setObject(1, new Integer(1), Types.NUMERIC); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.setObject(2, new Integer(1), Types.NUMERIC); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeQuery(); ctrlPreparedStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement( SELECT_ID_FORENAME_WHERE_ID_REUSED_1, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); class CustomerQuery extends MappingSqlQuery { public CustomerQuery(DataSource ds) { super(ds, SELECT_ID_FORENAME_WHERE_ID_REUSED_2); setResultSetType(ResultSet.TYPE_SCROLL_SENSITIVE); declareParameter(new SqlParameter("id1", Types.NUMERIC)); compile(); } protected Object mapRow(ResultSet rs, int rownum) throws SQLException { Customer cust = new Customer(); cust.setId(rs.getInt(COLUMN_NAMES[0])); cust.setForename(rs.getString(COLUMN_NAMES[1])); return cust; } public List findCustomers(Integer id) { Map params = new HashMap(); params.put("id1", id); return (List) executeByNamedParam(params); } } CustomerQuery query = new CustomerQuery(mockDataSource); List cust = query.findCustomers(new Integer(1)); assertEquals("We got two customers back", cust.size(), 2); Assert.assertEquals("First customer id was assigned correctly", ((Customer)cust.get(0)).getId(), 1); Assert.assertEquals("First customer forename was assigned correctly", ((Customer)cust.get(0)).getForename(), "rod"); Assert.assertEquals("Second customer id was assigned correctly", ((Customer)cust.get(1)).getId(), 2); Assert.assertEquals("Second customer forename was assigned correctly", ((Customer)cust.get(1)).getForename(), "juergen"); } public void testNamedParameterUsingInvalidQuestionMarkPlaceHolders() throws SQLException { mockConnection.prepareStatement( SELECT_ID_FORENAME_WHERE_ID_REUSED_1, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); class CustomerQuery extends MappingSqlQuery { public CustomerQuery(DataSource ds) { super(ds, SELECT_ID_FORENAME_WHERE_ID_REUSED_1); setResultSetType(ResultSet.TYPE_SCROLL_SENSITIVE); declareParameter(new SqlParameter("id1", Types.NUMERIC)); compile(); } protected Object mapRow(ResultSet rs, int rownum) throws SQLException { Customer cust = new Customer(); cust.setId(rs.getInt(COLUMN_NAMES[0])); cust.setForename(rs.getString(COLUMN_NAMES[1])); return cust; } public List findCustomers(Integer id1) { Map params = new HashMap(); params.put("id1", id1); return (List) executeByNamedParam(params); } } CustomerQuery query = new CustomerQuery(mockDataSource); try { List cust = query.findCustomers(new Integer(1)); fail("Should have caused an InvalidDataAccessApiUsageException"); } catch (InvalidDataAccessApiUsageException e){ } } public void testUpdateCustomers() throws SQLException { mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getInt("id"); ctrlResultSet.setReturnValue(1); mockResultSet.updateString(2, "Rod"); ctrlResultSet.setVoidCallable(); mockResultSet.updateRow(); ctrlResultSet.setVoidCallable(); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getInt("id"); ctrlResultSet.setReturnValue(2); mockResultSet.updateString(2, "Thomas"); ctrlResultSet.setVoidCallable(); mockResultSet.updateRow(); ctrlResultSet.setVoidCallable(); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockPreparedStatement.setObject(1, new Integer(2), Types.NUMERIC); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeQuery(); ctrlPreparedStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement( SELECT_ID_FORENAME_WHERE_ID, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); class CustomerUpdateQuery extends UpdatableSqlQuery { public CustomerUpdateQuery(DataSource ds) { super(ds, SELECT_ID_FORENAME_WHERE_ID); declareParameter(new SqlParameter(Types.NUMERIC)); compile(); } protected Object updateRow(ResultSet rs, int rownum, Map context) throws SQLException { rs.updateString(2, "" + context.get(new Integer(rs.getInt(COLUMN_NAMES[0])))); return null; } } CustomerUpdateQuery query = new CustomerUpdateQuery(mockDataSource); Map values = new HashMap(2); values.put(new Integer(1), "Rod"); values.put(new Integer(2), "Thomas"); List customers = query.execute(2, values); } private static class StringQuery extends MappingSqlQuery { public StringQuery(DataSource ds, String sql) { super(ds, sql); compile(); } protected Object mapRow(ResultSet rs, int rownum) throws SQLException { return rs.getString(1); } public String[] run() { List list = execute(); String[] results = (String[]) list.toArray(new String[list.size()]); return results; } } } ././@LongLink0000000000000000000000000000020100000000000011556 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/object/CustomerMapper.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000000105211623223526033323 0ustar drazzibdrazzibpackage org.springframework.jdbc.object; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.Customer; import java.sql.ResultSet; import java.sql.SQLException; public class CustomerMapper implements RowMapper { private static final String[] COLUMN_NAMES = new String[] {"id", "forename"}; public Customer mapRow(ResultSet rs, int rownum) throws SQLException { Customer cust = new Customer(); cust.setId(rs.getInt(COLUMN_NAMES[0])); cust.setForename(rs.getString(COLUMN_NAMES[1])); return cust; } } ././@LongLink0000000000000000000000000000015600000000000011567 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/config/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000755000175000017500000000000011623223530033316 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000022000000000000011557 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/config/JdbcNamespaceIntegrationTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000000651111623223526033330 0ustar drazzibdrazzib/* * Copyright 2002-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.config; import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; import javax.sql.DataSource; import org.junit.Test; import org.springframework.beans.PropertyValue; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.beans.factory.xml.XmlBeanFactory; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.core.io.ClassPathResource; import org.springframework.jdbc.core.JdbcTemplate; /** * @author Dave Syer */ public class JdbcNamespaceIntegrationTests { @Test public void testCreateEmbeddedDatabase() throws Exception { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( "org/springframework/jdbc/config/jdbc-config.xml"); assertCorrectSetup(context, "dataSource", "h2DataSource", "derbyDataSource"); } @Test public void testCreateEmbeddedDatabaseAgain() throws Exception { // If Derby isn't cleaned up properly this will fail... ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( "org/springframework/jdbc/config/jdbc-config.xml"); assertCorrectSetup(context, "derbyDataSource"); } @Test public void testCreateWithResourcePattern() throws Exception { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( "org/springframework/jdbc/config/jdbc-config-pattern.xml"); assertCorrectSetup(context, "dataSource"); } @Test public void testMultipleDataSourcesHaveDifferentDatabaseNames() throws Exception { DefaultListableBeanFactory factory = new XmlBeanFactory(new ClassPathResource( "org/springframework/jdbc/config/jdbc-config-multiple-datasources.xml")); assertBeanPropertyValueOf("databaseName", "firstDataSource", factory); assertBeanPropertyValueOf("databaseName", "secondDataSource", factory); } private void assertBeanPropertyValueOf(String propertyName, String expected, DefaultListableBeanFactory factory) { BeanDefinition bean = factory.getBeanDefinition(expected); PropertyValue value = bean.getPropertyValues().getPropertyValue(propertyName); assertThat(value, is(notNullValue())); assertThat(value.getValue().toString(), is(expected)); } private void assertCorrectSetup(ConfigurableApplicationContext context, String... dataSources) { try { for (String dataSourceName : dataSources) { DataSource dataSource = context.getBean(dataSourceName, DataSource.class); JdbcTemplate t = new JdbcTemplate(dataSource); assertEquals(1, t.queryForInt("select count(*) from T_TEST")); } } finally { context.close(); } } } ././@LongLink0000000000000000000000000000022500000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/config/InitializeDatabaseIntegrationTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000001002211623223530033313 0ustar drazzibdrazzib/* * Copyright 2002-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.config; import java.util.List; import java.util.Map; import javax.sql.DataSource; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.InitializingBean; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.jdbc.BadSqlGrammarException; import org.springframework.jdbc.core.JdbcTemplate; import static org.junit.Assert.*; /** * @author Dave Syer */ public class InitializeDatabaseIntegrationTests { private String enabled; private ClassPathXmlApplicationContext context; @Before public void init() { enabled = System.setProperty("ENABLED", "true"); } @After public void after() { if (enabled != null) { System.setProperty("ENABLED", enabled); } else { System.clearProperty("ENABLED"); } if (context != null) { context.close(); } } @Test public void testCreateEmbeddedDatabase() throws Exception { context = new ClassPathXmlApplicationContext("org/springframework/jdbc/config/jdbc-initialize-config.xml"); assertCorrectSetup(context.getBean("dataSource", DataSource.class)); } @Test(expected = BadSqlGrammarException.class) public void testDisableCreateEmbeddedDatabase() throws Exception { System.setProperty("ENABLED", "false"); context = new ClassPathXmlApplicationContext("org/springframework/jdbc/config/jdbc-initialize-config.xml"); assertCorrectSetup(context.getBean("dataSource", DataSource.class)); } @Test public void testIgnoreFailedDrops() throws Exception { context = new ClassPathXmlApplicationContext("org/springframework/jdbc/config/jdbc-initialize-fail-config.xml"); assertCorrectSetup(context.getBean("dataSource", DataSource.class)); } @Test public void testScriptNameWithPattern() throws Exception { context = new ClassPathXmlApplicationContext("org/springframework/jdbc/config/jdbc-initialize-pattern-config.xml"); DataSource dataSource = context.getBean("dataSource", DataSource.class); assertCorrectSetup(dataSource); JdbcTemplate t = new JdbcTemplate(dataSource); assertEquals("Dave", t.queryForObject("select name from T_TEST", String.class)); } @Test public void testScriptNameWithPlaceholder() throws Exception { context = new ClassPathXmlApplicationContext("org/springframework/jdbc/config/jdbc-initialize-placeholder-config.xml"); DataSource dataSource = context.getBean("dataSource", DataSource.class); assertCorrectSetup(dataSource); } @Test public void testCacheInitialization() throws Exception { context = new ClassPathXmlApplicationContext("org/springframework/jdbc/config/jdbc-initialize-cache-config.xml"); assertCorrectSetup(context.getBean("dataSource", DataSource.class)); CacheData cache = context.getBean(CacheData.class); assertEquals(1, cache.getCachedData().size()); } private void assertCorrectSetup(DataSource dataSource) { JdbcTemplate t = new JdbcTemplate(dataSource); assertEquals(1, t.queryForInt("select count(*) from T_TEST")); } public static class CacheData implements InitializingBean { private JdbcTemplate jdbcTemplate; private List> cache; public void setDataSource(DataSource dataSource) { this.jdbcTemplate = new JdbcTemplate(dataSource); } public List> getCachedData() { return cache; } public void afterPropertiesSet() throws Exception { cache = jdbcTemplate.queryForList("SELECT * FROM T_TEST"); } } } ././@LongLink0000000000000000000000000000015400000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000755000175000017500000000000011623223530033316 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000016300000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/simple/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000755000175000017500000000000011623223530033316 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000021300000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/simple/SimpleJdbcCallTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000003675511623223526033345 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.simple; import junit.framework.TestCase; import org.easymock.MockControl; import org.apache.commons.logging.LogFactory; import org.springframework.jdbc.BadSqlGrammarException; import org.springframework.jdbc.core.SqlOutParameter; import org.springframework.jdbc.core.SqlParameter; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.simple.SimpleJdbcCall; import org.springframework.dao.InvalidDataAccessApiUsageException; import javax.sql.DataSource; import java.sql.*; /** * Mock object based tests for SimpleJdbcCall. * * @author Thomas Risberg */ public class SimpleJdbcCallTests extends TestCase { private final boolean debugEnabled = LogFactory.getLog(JdbcTemplate.class).isDebugEnabled(); private MockControl ctrlDataSource; private DataSource mockDataSource; private MockControl ctrlConnection; private Connection mockConnection; private MockControl ctrlDatabaseMetaData; private DatabaseMetaData mockDatabaseMetaData; private MockControl ctrlCallable; private CallableStatement mockCallable; protected void setUp() throws Exception { ctrlDatabaseMetaData = MockControl.createControl(DatabaseMetaData.class); mockDatabaseMetaData = (DatabaseMetaData) ctrlDatabaseMetaData.getMock(); ctrlConnection = MockControl.createControl(Connection.class); mockConnection = (Connection) ctrlConnection.getMock(); mockConnection.getMetaData(); ctrlConnection.setDefaultReturnValue(mockDatabaseMetaData); mockConnection.close(); ctrlConnection.setDefaultVoidCallable(); ctrlDataSource = MockControl.createControl(DataSource.class); mockDataSource = (DataSource) ctrlDataSource.getMock(); mockDataSource.getConnection(); ctrlDataSource.setDefaultReturnValue(mockConnection); ctrlCallable = MockControl.createControl(CallableStatement.class); mockCallable = (CallableStatement) ctrlCallable.getMock(); } protected void tearDown() throws Exception { ctrlDatabaseMetaData.verify(); ctrlDataSource.verify(); ctrlCallable.verify(); } protected void replay() { ctrlDatabaseMetaData.replay(); ctrlConnection.replay(); ctrlDataSource.replay(); ctrlCallable.replay(); } public void testNoSuchStoredProcedure() throws Exception { final String NO_SUCH_PROC = "x"; mockDatabaseMetaData.getDatabaseProductName(); ctrlDatabaseMetaData.setReturnValue("MyDB"); mockDatabaseMetaData.getDatabaseProductName(); ctrlDatabaseMetaData.setReturnValue("MyDB"); mockDatabaseMetaData.getUserName(); ctrlDatabaseMetaData.setReturnValue("me"); mockDatabaseMetaData.supportsCatalogsInProcedureCalls(); ctrlDatabaseMetaData.setReturnValue(false); mockDatabaseMetaData.supportsSchemasInProcedureCalls(); ctrlDatabaseMetaData.setReturnValue(false); mockDatabaseMetaData.storesUpperCaseIdentifiers(); ctrlDatabaseMetaData.setReturnValue(false); mockDatabaseMetaData.storesLowerCaseIdentifiers(); ctrlDatabaseMetaData.setReturnValue(true); SQLException sex = new SQLException( "Syntax error or access violation exception", "42000"); mockCallable.execute(); ctrlCallable.setThrowable(sex); mockCallable.close(); ctrlCallable.setVoidCallable(); mockConnection.prepareCall( "{call " + NO_SUCH_PROC + "()}"); ctrlConnection.setReturnValue(mockCallable); replay(); SimpleJdbcCall sproc = new SimpleJdbcCall(mockDataSource).withProcedureName(NO_SUCH_PROC); try { sproc.execute(); fail("Shouldn't succeed in running stored procedure which doesn't exist"); } catch (BadSqlGrammarException ex) { // OK } } public void testUnnamedParameterHandling() throws Exception { final String MY_PROC = "my_proc"; replay(); SimpleJdbcCall sproc = new SimpleJdbcCall(mockDataSource).withProcedureName(MY_PROC); try { sproc.addDeclaredParameter(new SqlParameter(1)); fail("Shouldn't succeed in adding unnamed parameter"); } catch (InvalidDataAccessApiUsageException ex) { // OK } } public void testAddInvoiceProcWithoutMetaDataUsingMapParamSource() throws Exception { final int amount = 1103; final int custid = 3; initializeAddInvoiceWithoutMetaData(false); replay(); SimpleJdbcCall adder = new SimpleJdbcCall(mockDataSource).withProcedureName("add_invoice"); adder.declareParameters(new SqlParameter("amount", Types.INTEGER), new SqlParameter("custid", Types.INTEGER), new SqlOutParameter("newid", Types.INTEGER)); Number newId = adder.executeObject(Number.class, new MapSqlParameterSource() .addValue("amount", amount) .addValue("custid", custid)); assertEquals(4, newId.intValue()); } public void testAddInvoiceProcWithoutMetaDataUsingArrayParams() throws Exception { final int amount = 1103; final int custid = 3; initializeAddInvoiceWithoutMetaData(false); replay(); SimpleJdbcCall adder = new SimpleJdbcCall(mockDataSource).withProcedureName("add_invoice"); adder.declareParameters(new SqlParameter("amount", Types.INTEGER), new SqlParameter("custid", Types.INTEGER), new SqlOutParameter("newid", Types.INTEGER)); Number newId = adder.executeObject(Number.class, amount, custid); assertEquals(4, newId.intValue()); } public void testAddInvoiceProcWithMetaDataUsingMapParamSource() throws Exception { final int amount = 1103; final int custid = 3; MockControl ctrlResultSet = initializeAddInvoiceWithMetaData(false); ctrlResultSet.replay(); replay(); SimpleJdbcCall adder = new SimpleJdbcCall(mockDataSource).withProcedureName("add_invoice"); Number newId = adder.executeObject(Number.class, new MapSqlParameterSource() .addValue("amount", amount) .addValue("custid", custid)); assertEquals(4, newId.intValue()); ctrlResultSet.verify(); } public void testAddInvoiceProcWithMetaDataUsingArrayParams() throws Exception { final int amount = 1103; final int custid = 3; MockControl ctrlResultSet = initializeAddInvoiceWithMetaData(false); ctrlResultSet.replay(); replay(); SimpleJdbcCall adder = new SimpleJdbcCall(mockDataSource).withProcedureName("add_invoice"); Number newId = adder.executeObject(Number.class, amount, custid); assertEquals(4, newId.intValue()); ctrlResultSet.verify(); } public void testAddInvoiceFuncWithoutMetaDataUsingMapParamSource() throws Exception { final int amount = 1103; final int custid = 3; initializeAddInvoiceWithoutMetaData(true); replay(); SimpleJdbcCall adder = new SimpleJdbcCall(mockDataSource).withFunctionName("add_invoice"); adder.declareParameters(new SqlOutParameter("return", Types.INTEGER), new SqlParameter("amount", Types.INTEGER), new SqlParameter("custid", Types.INTEGER)); Number newId = adder.executeFunction(Number.class, new MapSqlParameterSource() .addValue("amount", amount) .addValue("custid", custid)); assertEquals(4, newId.intValue()); } public void testAddInvoiceFuncWithoutMetaDataUsingArrayParams() throws Exception { final int amount = 1103; final int custid = 3; initializeAddInvoiceWithoutMetaData(true); replay(); SimpleJdbcCall adder = new SimpleJdbcCall(mockDataSource).withFunctionName("add_invoice"); adder.declareParameters(new SqlOutParameter("return", Types.INTEGER), new SqlParameter("amount", Types.INTEGER), new SqlParameter("custid", Types.INTEGER)); Number newId = adder.executeFunction(Number.class, amount, custid); assertEquals(4, newId.intValue()); } public void testAddInvoiceFuncWithMetaDataUsingMapParamSource() throws Exception { final int amount = 1103; final int custid = 3; MockControl ctrlResultSet = initializeAddInvoiceWithMetaData(true); ctrlResultSet.replay(); replay(); SimpleJdbcCall adder = new SimpleJdbcCall(mockDataSource).withFunctionName("add_invoice"); Number newId = adder.executeFunction(Number.class, new MapSqlParameterSource() .addValue("amount", amount) .addValue("custid", custid)); assertEquals(4, newId.intValue()); ctrlResultSet.verify(); } public void testAddInvoiceFuncWithMetaDataUsingArrayParams() throws Exception { final int amount = 1103; final int custid = 3; MockControl ctrlResultSet = initializeAddInvoiceWithMetaData(true); ctrlResultSet.replay(); replay(); SimpleJdbcCall adder = new SimpleJdbcCall(mockDataSource).withFunctionName("add_invoice"); Number newId = adder.executeFunction(Number.class, amount, custid); assertEquals(4, newId.intValue()); ctrlResultSet.verify(); } private void initializeAddInvoiceWithoutMetaData(boolean isFunction) throws SQLException { mockDatabaseMetaData.getDatabaseProductName(); ctrlDatabaseMetaData.setReturnValue("MyDB"); mockDatabaseMetaData.getUserName(); ctrlDatabaseMetaData.setReturnValue("me"); mockDatabaseMetaData.supportsCatalogsInProcedureCalls(); ctrlDatabaseMetaData.setReturnValue(false); mockDatabaseMetaData.supportsSchemasInProcedureCalls(); ctrlDatabaseMetaData.setReturnValue(false); mockDatabaseMetaData.storesUpperCaseIdentifiers(); ctrlDatabaseMetaData.setReturnValue(false); mockDatabaseMetaData.storesLowerCaseIdentifiers(); ctrlDatabaseMetaData.setReturnValue(true); if (isFunction) { mockCallable.registerOutParameter(1, 4); ctrlCallable.setVoidCallable(); mockCallable.setObject(2, 1103, 4); ctrlCallable.setVoidCallable(); mockCallable.setObject(3, 3, 4); ctrlCallable.setVoidCallable(); } else { mockCallable.setObject(1, 1103, 4); ctrlCallable.setVoidCallable(); mockCallable.setObject(2, 3, 4); ctrlCallable.setVoidCallable(); mockCallable.registerOutParameter(3, 4); ctrlCallable.setVoidCallable(); } mockCallable.execute(); ctrlCallable.setReturnValue(false); mockCallable.getUpdateCount(); ctrlCallable.setReturnValue(-1); if (isFunction) { mockCallable.getObject(1); } else { mockCallable.getObject(3); } ctrlCallable.setReturnValue(new Long(4)); if (debugEnabled) { mockCallable.getWarnings(); ctrlCallable.setReturnValue(null); } mockCallable.close(); ctrlCallable.setVoidCallable(); if (isFunction) { mockConnection.prepareCall( "{? = call add_invoice(?, ?)}"); ctrlConnection.setReturnValue(mockCallable); } else { mockConnection.prepareCall( "{call add_invoice(?, ?, ?)}"); ctrlConnection.setReturnValue(mockCallable); } } private MockControl initializeAddInvoiceWithMetaData(boolean isFunction) throws SQLException { MockControl ctrlResultSet = MockControl.createControl(ResultSet.class); ResultSet mockResultSet = (ResultSet) ctrlResultSet.getMock(); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getString("PROCEDURE_CAT"); ctrlResultSet.setReturnValue(null); mockResultSet.getString("PROCEDURE_SCHEM"); ctrlResultSet.setReturnValue(null); mockResultSet.getString("PROCEDURE_NAME"); ctrlResultSet.setReturnValue("add_invoice"); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockResultSet.next(); ctrlResultSet.setReturnValue(true); if (isFunction) { mockResultSet.getString("COLUMN_NAME"); ctrlResultSet.setReturnValue(null); mockResultSet.getInt("COLUMN_TYPE"); ctrlResultSet.setReturnValue(5); } else { mockResultSet.getString("COLUMN_NAME"); ctrlResultSet.setReturnValue("amount"); mockResultSet.getInt("COLUMN_TYPE"); ctrlResultSet.setReturnValue(1); } mockResultSet.getInt("DATA_TYPE"); ctrlResultSet.setReturnValue(4); mockResultSet.getString("TYPE_NAME"); ctrlResultSet.setReturnValue(null); mockResultSet.getBoolean("NULLABLE"); ctrlResultSet.setReturnValue(false); mockResultSet.next(); ctrlResultSet.setReturnValue(true); if (isFunction) { mockResultSet.getString("COLUMN_NAME"); ctrlResultSet.setReturnValue("amount"); mockResultSet.getInt("COLUMN_TYPE"); ctrlResultSet.setReturnValue(1); } else { mockResultSet.getString("COLUMN_NAME"); ctrlResultSet.setReturnValue("custid"); mockResultSet.getInt("COLUMN_TYPE"); ctrlResultSet.setReturnValue(1); } mockResultSet.getInt("DATA_TYPE"); ctrlResultSet.setReturnValue(4); mockResultSet.getString("TYPE_NAME"); ctrlResultSet.setReturnValue(null); mockResultSet.getBoolean("NULLABLE"); ctrlResultSet.setReturnValue(false); mockResultSet.next(); ctrlResultSet.setReturnValue(true); if (isFunction) { mockResultSet.getString("COLUMN_NAME"); ctrlResultSet.setReturnValue("custid"); mockResultSet.getInt("COLUMN_TYPE"); ctrlResultSet.setReturnValue(1); } else { mockResultSet.getString("COLUMN_NAME"); ctrlResultSet.setReturnValue("newid"); mockResultSet.getInt("COLUMN_TYPE"); ctrlResultSet.setReturnValue(4); } mockResultSet.getInt("DATA_TYPE"); ctrlResultSet.setReturnValue(4); mockResultSet.getString("TYPE_NAME"); ctrlResultSet.setReturnValue(null); mockResultSet.getBoolean("NULLABLE"); ctrlResultSet.setReturnValue(false); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockDatabaseMetaData.getDatabaseProductName(); ctrlDatabaseMetaData.setReturnValue("Oracle"); mockDatabaseMetaData.getUserName(); ctrlDatabaseMetaData.setReturnValue("ME"); mockDatabaseMetaData.supportsCatalogsInProcedureCalls(); ctrlDatabaseMetaData.setReturnValue(false); mockDatabaseMetaData.supportsSchemasInProcedureCalls(); ctrlDatabaseMetaData.setReturnValue(false); mockDatabaseMetaData.storesUpperCaseIdentifiers(); ctrlDatabaseMetaData.setReturnValue(true); mockDatabaseMetaData.storesLowerCaseIdentifiers(); ctrlDatabaseMetaData.setReturnValue(false); mockDatabaseMetaData.getProcedures("", "ME", "ADD_INVOICE"); ctrlDatabaseMetaData.setReturnValue(mockResultSet); mockDatabaseMetaData.getProcedureColumns("", "ME", "ADD_INVOICE", null); ctrlDatabaseMetaData.setReturnValue(mockResultSet); if (isFunction) { mockCallable.registerOutParameter(1, 4); ctrlCallable.setVoidCallable(); mockCallable.setObject(2, 1103, 4); ctrlCallable.setVoidCallable(); mockCallable.setObject(3, 3, 4); ctrlCallable.setVoidCallable(); } else { mockCallable.setObject(1, 1103, 4); ctrlCallable.setVoidCallable(); mockCallable.setObject(2, 3, 4); ctrlCallable.setVoidCallable(); mockCallable.registerOutParameter(3, 4); ctrlCallable.setVoidCallable(); } mockCallable.execute(); ctrlCallable.setReturnValue(false); mockCallable.getUpdateCount(); ctrlCallable.setReturnValue(-1); if (isFunction) { mockCallable.getObject(1); ctrlCallable.setReturnValue(new Long(4)); } else { mockCallable.getObject(3); ctrlCallable.setReturnValue(new Long(4)); } if (debugEnabled) { mockCallable.getWarnings(); ctrlCallable.setReturnValue(null); } mockCallable.close(); ctrlCallable.setVoidCallable(); if (isFunction) { mockConnection.prepareCall( "{? = call ADD_INVOICE(?, ?)}"); ctrlConnection.setReturnValue(mockCallable); } else { mockConnection.prepareCall( "{call ADD_INVOICE(?, ?, ?)}"); ctrlConnection.setReturnValue(mockCallable); } return ctrlResultSet; } } ././@LongLink0000000000000000000000000000021500000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/simple/SimpleJdbcInsertTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000000740211623223530033323 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.simple; import junit.framework.TestCase; import org.easymock.MockControl; import org.springframework.dao.InvalidDataAccessApiUsageException; import javax.sql.DataSource; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.ResultSet; import java.util.HashMap; /** * Mock object based tests for SimpleJdbcInsert. * * @author Thomas Risberg */ public class SimpleJdbcInsertTests extends TestCase { private MockControl ctrlDataSource; private DataSource mockDataSource; private MockControl ctrlConnection; private Connection mockConnection; private MockControl ctrlDatabaseMetaData; private DatabaseMetaData mockDatabaseMetaData; protected void setUp() throws Exception { super.setUp(); ctrlDatabaseMetaData = MockControl.createControl(DatabaseMetaData.class); mockDatabaseMetaData = (DatabaseMetaData) ctrlDatabaseMetaData.getMock(); ctrlConnection = MockControl.createControl(Connection.class); mockConnection = (Connection) ctrlConnection.getMock(); mockConnection.getMetaData(); ctrlConnection.setDefaultReturnValue(mockDatabaseMetaData); mockConnection.close(); ctrlConnection.setDefaultVoidCallable(); ctrlDataSource = MockControl.createControl(DataSource.class); mockDataSource = (DataSource) ctrlDataSource.getMock(); mockDataSource.getConnection(); ctrlDataSource.setDefaultReturnValue(mockConnection); } protected void tearDown() throws Exception { super.tearDown(); ctrlDatabaseMetaData.verify(); ctrlDataSource.verify(); } protected void replay() { ctrlDatabaseMetaData.replay(); ctrlConnection.replay(); ctrlDataSource.replay(); } public void testNoSuchTable() throws Exception { final String NO_SUCH_TABLE = "x"; final String USER = "me"; MockControl ctrlResultSet = MockControl.createControl(ResultSet.class); ResultSet mockResultSet = (ResultSet) ctrlResultSet.getMock(); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockDatabaseMetaData.getDatabaseProductName(); ctrlDatabaseMetaData.setReturnValue("MyDB"); mockDatabaseMetaData.supportsGetGeneratedKeys(); ctrlDatabaseMetaData.setReturnValue(false); mockDatabaseMetaData.getDatabaseProductName(); ctrlDatabaseMetaData.setReturnValue("MyDB"); mockDatabaseMetaData.getDatabaseProductVersion(); ctrlDatabaseMetaData.setReturnValue("1.0"); mockDatabaseMetaData.getUserName(); ctrlDatabaseMetaData.setReturnValue(USER); mockDatabaseMetaData.storesUpperCaseIdentifiers(); ctrlDatabaseMetaData.setReturnValue(false); mockDatabaseMetaData.storesLowerCaseIdentifiers(); ctrlDatabaseMetaData.setReturnValue(true); mockDatabaseMetaData.getTables(null, null, NO_SUCH_TABLE, null); ctrlDatabaseMetaData.setReturnValue(mockResultSet); ctrlResultSet.replay(); replay(); SimpleJdbcInsert insert = new SimpleJdbcInsert(mockDataSource).withTableName(NO_SUCH_TABLE); try { insert.execute(new HashMap()); fail("Shouldn't succeed in inserting into table which doesn't exist"); } catch (InvalidDataAccessApiUsageException ex) { // OK } } public void testInsert() throws Exception { replay(); } } ././@LongLink0000000000000000000000000000022100000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/simple/TableMetaDataContextTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000002265611623223530033333 0ustar drazzibdrazzibpackage org.springframework.jdbc.core.simple; import junit.framework.TestCase; import org.springframework.jdbc.core.metadata.TableMetaDataContext; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.SqlParameterValue; import org.easymock.MockControl; import javax.sql.DataSource; import java.util.Date; import java.util.List; import java.util.ArrayList; import java.sql.Types; import java.sql.DatabaseMetaData; import java.sql.Connection; import java.sql.ResultSet; /** * Mock object based tests for TableMetaDataContext. * * @author Thomas Risberg */ public class TableMetaDataContextTests extends TestCase { private MockControl ctrlDataSource; private DataSource mockDataSource; private MockControl ctrlConnection; private Connection mockConnection; private MockControl ctrlDatabaseMetaData; private DatabaseMetaData mockDatabaseMetaData; private TableMetaDataContext context = new TableMetaDataContext(); protected void setUp() throws Exception { super.setUp(); ctrlDatabaseMetaData = MockControl.createControl(DatabaseMetaData.class); mockDatabaseMetaData = (DatabaseMetaData) ctrlDatabaseMetaData.getMock(); ctrlConnection = MockControl.createControl(Connection.class); mockConnection = (Connection) ctrlConnection.getMock(); mockConnection.getMetaData(); ctrlConnection.setDefaultReturnValue(mockDatabaseMetaData); mockConnection.close(); ctrlConnection.setDefaultVoidCallable(); ctrlDataSource = MockControl.createControl(DataSource.class); mockDataSource = (DataSource) ctrlDataSource.getMock(); mockDataSource.getConnection(); ctrlDataSource.setDefaultReturnValue(mockConnection); } protected void tearDown() throws Exception { super.tearDown(); ctrlDatabaseMetaData.verify(); ctrlDataSource.verify(); } protected void replay() { ctrlDatabaseMetaData.replay(); ctrlConnection.replay(); ctrlDataSource.replay(); } public void testMatchInParametersAndSqlTypeInfoWrapping() throws Exception { final String TABLE = "customers"; final String USER = "me"; MockControl ctrlMetaDataResultSet = MockControl.createControl(ResultSet.class); ResultSet mockMetaDataResultSet = (ResultSet) ctrlMetaDataResultSet.getMock(); mockMetaDataResultSet.next(); ctrlMetaDataResultSet.setReturnValue(true); mockMetaDataResultSet.getString("TABLE_CAT"); ctrlMetaDataResultSet.setReturnValue(null); mockMetaDataResultSet.getString("TABLE_SCHEM"); ctrlMetaDataResultSet.setReturnValue(USER); mockMetaDataResultSet.getString("TABLE_NAME"); ctrlMetaDataResultSet.setReturnValue(TABLE); mockMetaDataResultSet.getString("TABLE_TYPE"); ctrlMetaDataResultSet.setReturnValue("TABLE"); mockMetaDataResultSet.next(); ctrlMetaDataResultSet.setReturnValue(false); mockMetaDataResultSet.close(); ctrlMetaDataResultSet.setVoidCallable(); MockControl ctrlColumnsResultSet = MockControl.createControl(ResultSet.class); ResultSet mockColumnsResultSet = (ResultSet) ctrlColumnsResultSet.getMock(); mockColumnsResultSet.next(); ctrlColumnsResultSet.setReturnValue(true); mockColumnsResultSet.getString("COLUMN_NAME"); ctrlColumnsResultSet.setReturnValue("id"); mockColumnsResultSet.getInt("DATA_TYPE"); ctrlColumnsResultSet.setReturnValue(Types.INTEGER); mockColumnsResultSet.getBoolean("NULLABLE"); ctrlColumnsResultSet.setReturnValue(false); mockColumnsResultSet.next(); ctrlColumnsResultSet.setReturnValue(true); mockColumnsResultSet.getString("COLUMN_NAME"); ctrlColumnsResultSet.setReturnValue("name"); mockColumnsResultSet.getInt("DATA_TYPE"); ctrlColumnsResultSet.setReturnValue(Types.VARCHAR); mockColumnsResultSet.getBoolean("NULLABLE"); ctrlColumnsResultSet.setReturnValue(true); mockColumnsResultSet.next(); ctrlColumnsResultSet.setReturnValue(true); mockColumnsResultSet.getString("COLUMN_NAME"); ctrlColumnsResultSet.setReturnValue("customersince"); mockColumnsResultSet.getInt("DATA_TYPE"); ctrlColumnsResultSet.setReturnValue(Types.DATE); mockColumnsResultSet.getBoolean("NULLABLE"); ctrlColumnsResultSet.setReturnValue(true); mockColumnsResultSet.next(); ctrlColumnsResultSet.setReturnValue(true); mockColumnsResultSet.getString("COLUMN_NAME"); ctrlColumnsResultSet.setReturnValue("version"); mockColumnsResultSet.getInt("DATA_TYPE"); ctrlColumnsResultSet.setReturnValue(Types.NUMERIC); mockColumnsResultSet.getBoolean("NULLABLE"); ctrlColumnsResultSet.setReturnValue(false); mockColumnsResultSet.next(); ctrlColumnsResultSet.setReturnValue(false); mockColumnsResultSet.close(); ctrlColumnsResultSet.setVoidCallable(); mockDatabaseMetaData.getDatabaseProductName(); ctrlDatabaseMetaData.setReturnValue("MyDB"); mockDatabaseMetaData.supportsGetGeneratedKeys(); ctrlDatabaseMetaData.setReturnValue(false); mockDatabaseMetaData.getDatabaseProductName(); ctrlDatabaseMetaData.setReturnValue("MyDB"); mockDatabaseMetaData.getDatabaseProductVersion(); ctrlDatabaseMetaData.setReturnValue("1.0"); mockDatabaseMetaData.getUserName(); ctrlDatabaseMetaData.setReturnValue(USER); mockDatabaseMetaData.storesUpperCaseIdentifiers(); ctrlDatabaseMetaData.setReturnValue(false); mockDatabaseMetaData.storesLowerCaseIdentifiers(); ctrlDatabaseMetaData.setReturnValue(true); mockDatabaseMetaData.getTables(null, null, TABLE, null); ctrlDatabaseMetaData.setReturnValue(mockMetaDataResultSet); mockDatabaseMetaData.getColumns(null, USER, TABLE, null); ctrlDatabaseMetaData.setReturnValue(mockColumnsResultSet); ctrlMetaDataResultSet.replay(); ctrlColumnsResultSet.replay(); replay(); MapSqlParameterSource map = new MapSqlParameterSource(); map.addValue("id", 1); map.addValue("name", "Sven"); map.addValue("customersince", new Date()); map.addValue("version", 0); map.registerSqlType("customersince", Types.DATE); map.registerSqlType("version", Types.NUMERIC); context.setTableName(TABLE); context.processMetaData(mockDataSource, new ArrayList(), new String[] {}); List values = context.matchInParameterValuesWithInsertColumns(map); assertEquals("wrong number of parameters: ", 4, values.size()); assertTrue("id not wrapped with type info", values.get(0) instanceof Number); assertTrue("name not wrapped with type info", values.get(1) instanceof String); assertTrue("date wrapped with type info", values.get(2) instanceof SqlParameterValue); assertTrue("version wrapped with type info", values.get(3) instanceof SqlParameterValue); } public void testTableWithSingleColumnGeneratedKey() throws Exception { final String TABLE = "customers"; final String USER = "me"; MockControl ctrlMetaDataResultSet = MockControl.createControl(ResultSet.class); ResultSet mockMetaDataResultSet = (ResultSet) ctrlMetaDataResultSet.getMock(); mockMetaDataResultSet.next(); ctrlMetaDataResultSet.setReturnValue(true); mockMetaDataResultSet.getString("TABLE_CAT"); ctrlMetaDataResultSet.setReturnValue(null); mockMetaDataResultSet.getString("TABLE_SCHEM"); ctrlMetaDataResultSet.setReturnValue(USER); mockMetaDataResultSet.getString("TABLE_NAME"); ctrlMetaDataResultSet.setReturnValue(TABLE); mockMetaDataResultSet.getString("TABLE_TYPE"); ctrlMetaDataResultSet.setReturnValue("TABLE"); mockMetaDataResultSet.next(); ctrlMetaDataResultSet.setReturnValue(false); mockMetaDataResultSet.close(); ctrlMetaDataResultSet.setVoidCallable(); MockControl ctrlColumnsResultSet = MockControl.createControl(ResultSet.class); ResultSet mockColumnsResultSet = (ResultSet) ctrlColumnsResultSet.getMock(); mockColumnsResultSet.next(); ctrlColumnsResultSet.setReturnValue(true); mockColumnsResultSet.getString("COLUMN_NAME"); ctrlColumnsResultSet.setReturnValue("id"); mockColumnsResultSet.getInt("DATA_TYPE"); ctrlColumnsResultSet.setReturnValue(Types.INTEGER); mockColumnsResultSet.getBoolean("NULLABLE"); ctrlColumnsResultSet.setReturnValue(false); mockColumnsResultSet.next(); ctrlColumnsResultSet.setReturnValue(false); mockColumnsResultSet.close(); ctrlColumnsResultSet.setVoidCallable(); mockDatabaseMetaData.getDatabaseProductName(); ctrlDatabaseMetaData.setReturnValue("MyDB"); mockDatabaseMetaData.supportsGetGeneratedKeys(); ctrlDatabaseMetaData.setReturnValue(false); mockDatabaseMetaData.getDatabaseProductName(); ctrlDatabaseMetaData.setReturnValue("MyDB"); mockDatabaseMetaData.getDatabaseProductVersion(); ctrlDatabaseMetaData.setReturnValue("1.0"); mockDatabaseMetaData.getUserName(); ctrlDatabaseMetaData.setReturnValue(USER); mockDatabaseMetaData.storesUpperCaseIdentifiers(); ctrlDatabaseMetaData.setReturnValue(false); mockDatabaseMetaData.storesLowerCaseIdentifiers(); ctrlDatabaseMetaData.setReturnValue(true); mockDatabaseMetaData.getTables(null, null, TABLE, null); ctrlDatabaseMetaData.setReturnValue(mockMetaDataResultSet); mockDatabaseMetaData.getColumns(null, USER, TABLE, null); ctrlDatabaseMetaData.setReturnValue(mockColumnsResultSet); ctrlMetaDataResultSet.replay(); ctrlColumnsResultSet.replay(); replay(); MapSqlParameterSource map = new MapSqlParameterSource(); String[] keyCols = new String[] {"id"}; context.setTableName(TABLE); context.processMetaData(mockDataSource, new ArrayList(), keyCols); List values = context.matchInParameterValuesWithInsertColumns(map); String insertString = context.createInsertString(keyCols); assertEquals("wrong number of parameters: ", 0, values.size()); assertEquals("empty insert not generated correctly", "INSERT INTO customers () VALUES()", insertString); } } ././@LongLink0000000000000000000000000000023700000000000011567 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/simple/ParameterizedBeanPropertyRowMapperTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000000477511623223530033335 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.simple; import java.sql.SQLException; import java.util.List; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.jdbc.core.AbstractRowMapperTests; import org.springframework.jdbc.core.test.ConcretePerson; import org.springframework.jdbc.core.test.Person; /** * @author Thomas Risberg */ public class ParameterizedBeanPropertyRowMapperTests extends AbstractRowMapperTests { private SimpleJdbcTemplate simpleJdbcTemplate; protected void setUp() throws SQLException { super.setUp(); simpleJdbcTemplate = new SimpleJdbcTemplate(jdbcTemplate); } public void testOverridingClassDefinedForMapping() { ParameterizedBeanPropertyRowMapper mapper = ParameterizedBeanPropertyRowMapper.newInstance(Person.class); try { ((ParameterizedBeanPropertyRowMapper) mapper).setMappedClass(Long.class); fail("Setting new class should have thrown InvalidDataAccessApiUsageException"); } catch (InvalidDataAccessApiUsageException ex) { // expected } try { mapper.setMappedClass(Person.class); } catch (InvalidDataAccessApiUsageException ex) { fail("Setting same class should not have thrown InvalidDataAccessApiUsageException"); } } public void testStaticQueryWithRowMapper() throws SQLException { List result = simpleJdbcTemplate.query("select name, age, birth_date, balance from people", ParameterizedBeanPropertyRowMapper.newInstance(Person.class)); assertEquals(1, result.size()); Person bean = result.get(0); verifyPerson(bean); } public void testMappingWithInheritance() throws SQLException { List result = simpleJdbcTemplate.query("select name, age, birth_date, balance from people", ParameterizedBeanPropertyRowMapper.newInstance(ConcretePerson.class)); assertEquals(1, result.size()); ConcretePerson bean = result.get(0); verifyConcretePerson(bean); } } ././@LongLink0000000000000000000000000000022000000000000011557 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/simple/CallMetaDataContextTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000000773411623223526033340 0ustar drazzibdrazzibpackage org.springframework.jdbc.core.simple; import junit.framework.TestCase; import org.easymock.MockControl; import org.springframework.jdbc.core.metadata.CallMetaDataContext; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.SqlParameter; import org.springframework.jdbc.core.SqlOutParameter; import org.springframework.jdbc.core.SqlInOutParameter; import javax.sql.DataSource; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.Types; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * Mock object based tests for CallMetaDataContext. * * @author Thomas Risberg */ public class CallMetaDataContextTests extends TestCase { private MockControl ctrlDataSource; private DataSource mockDataSource; private MockControl ctrlConnection; private Connection mockConnection; private MockControl ctrlDatabaseMetaData; private DatabaseMetaData mockDatabaseMetaData; private CallMetaDataContext context = new CallMetaDataContext(); protected void setUp() throws Exception { super.setUp(); ctrlDatabaseMetaData = MockControl.createControl(DatabaseMetaData.class); mockDatabaseMetaData = (DatabaseMetaData) ctrlDatabaseMetaData.getMock(); ctrlConnection = MockControl.createControl(Connection.class); mockConnection = (Connection) ctrlConnection.getMock(); mockConnection.getMetaData(); ctrlConnection.setDefaultReturnValue(mockDatabaseMetaData); mockConnection.close(); ctrlConnection.setDefaultVoidCallable(); ctrlDataSource = MockControl.createControl(DataSource.class); mockDataSource = (DataSource) ctrlDataSource.getMock(); mockDataSource.getConnection(); ctrlDataSource.setDefaultReturnValue(mockConnection); } protected void tearDown() throws Exception { super.tearDown(); ctrlDatabaseMetaData.verify(); ctrlDataSource.verify(); } protected void replay() { ctrlDatabaseMetaData.replay(); ctrlConnection.replay(); ctrlDataSource.replay(); } public void testMatchParameterValuesAndSqlInOutParameters() throws Exception { final String TABLE = "customers"; final String USER = "me"; mockDatabaseMetaData.getDatabaseProductName(); ctrlDatabaseMetaData.setReturnValue("MyDB"); mockDatabaseMetaData.supportsCatalogsInProcedureCalls(); ctrlDatabaseMetaData.setReturnValue(false); mockDatabaseMetaData.supportsSchemasInProcedureCalls(); ctrlDatabaseMetaData.setReturnValue(false); mockDatabaseMetaData.getUserName(); ctrlDatabaseMetaData.setReturnValue(USER); mockDatabaseMetaData.storesUpperCaseIdentifiers(); ctrlDatabaseMetaData.setReturnValue(false); mockDatabaseMetaData.storesLowerCaseIdentifiers(); ctrlDatabaseMetaData.setReturnValue(true); replay(); List parameters = new ArrayList(); parameters.add(new SqlParameter("id", Types.NUMERIC)); parameters.add(new SqlInOutParameter("name", Types.NUMERIC)); parameters.add(new SqlOutParameter("customer_no", Types.NUMERIC)); MapSqlParameterSource parameterSource = new MapSqlParameterSource(); parameterSource.addValue("id", 1); parameterSource.addValue("name", "Sven"); parameterSource.addValue("customer_no", "12345XYZ"); context.setProcedureName(TABLE); context.initializeMetaData(mockDataSource); context.processParameters(parameters); Map inParameters = context.matchInParameterValuesWithCallParameters(parameterSource); assertEquals("Wrong number of matched in parameter values", 2, inParameters.size()); assertTrue("in parameter value missing", inParameters.containsKey("id")); assertTrue("in out parameter value missing", inParameters.containsKey("name")); assertTrue("out parameter value matched", !inParameters.containsKey("customer_no")); List names = context.getOutParameterNames(); assertEquals("Wrong number of out parameters", 2, names.size()); List callParameters = context.getCallParameters(); assertEquals("Wrong number of call parameters", 3, callParameters.size()); } } ././@LongLink0000000000000000000000000000021700000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/simple/SimpleJdbcTemplateTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000005407011623223526033333 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.simple; import java.lang.reflect.Method; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.Types; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import javax.sql.DataSource; import junit.framework.TestCase; import org.apache.commons.logging.LogFactory; import org.easymock.MockControl; import org.easymock.internal.ArrayMatcher; import org.springframework.jdbc.core.BatchUpdateTestHelper; import org.springframework.jdbc.core.JdbcOperations; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; import org.springframework.jdbc.core.namedparam.SqlParameterSource; /** * @author Rod Johnson * @author Rob Harrop * @author Juergen Hoeller * @author Thomas Risberg */ public class SimpleJdbcTemplateTests extends TestCase { private final boolean debugEnabled = LogFactory.getLog(JdbcTemplate.class).isDebugEnabled(); public void testQueryForIntWithoutArgs() { String sql = "SELECT COUNT(0) FROM BAR"; int expectedResult = 666; MockControl mc = MockControl.createControl(JdbcOperations.class); JdbcOperations jo = (JdbcOperations) mc.getMock(); jo.queryForInt(sql); mc.setReturnValue(expectedResult); mc.replay(); SimpleJdbcTemplate jth = new SimpleJdbcTemplate(jo); assertSame(jo, jth.getJdbcOperations()); int result = jth.queryForInt(sql); assertEquals(expectedResult, result); mc.verify(); } public void testQueryForIntWithArgs() { String sql = "SELECT COUNT(0) FROM BAR WHERE ID=? AND XY=?"; int expectedResult = 666; int arg1 = 24; String arg2 = "foo"; MockControl mc = MockControl.createControl(JdbcOperations.class); JdbcOperations jo = (JdbcOperations) mc.getMock(); jo.queryForInt(sql, new Object[]{arg1, arg2}); mc.setDefaultMatcher(new ArrayMatcher()); mc.setReturnValue(expectedResult); mc.replay(); SimpleJdbcTemplate jth = new SimpleJdbcTemplate(jo); int result = jth.queryForInt(sql, arg1, arg2); assertEquals(expectedResult, result); mc.verify(); } public void testQueryForIntWithMap() { String sql = "SELECT COUNT(0) FROM BAR WHERE ID=:id AND XY=:xy"; int expectedResult = 666; int arg1 = 24; String arg2 = "foo"; MockControl mc = MockControl.createControl(NamedParameterJdbcOperations.class); NamedParameterJdbcOperations npjo = (NamedParameterJdbcOperations) mc.getMock(); Map args = new HashMap(2); args.put("id", arg1); args.put("xy", arg2); npjo.queryForInt(sql, args); mc.setDefaultMatcher(new ArrayMatcher()); mc.setReturnValue(expectedResult); mc.replay(); SimpleJdbcTemplate jth = new SimpleJdbcTemplate(npjo); int result = jth.queryForInt(sql, args); assertEquals(expectedResult, result); mc.verify(); } public void testQueryForIntWitSqlParameterSource() { String sql = "SELECT COUNT(0) FROM BAR WHERE ID=:id AND XY=:xy"; int expectedResult = 666; int arg1 = 24; String arg2 = "foo"; MockControl mc = MockControl.createControl(NamedParameterJdbcOperations.class); NamedParameterJdbcOperations npjo = (NamedParameterJdbcOperations) mc.getMock(); SqlParameterSource args = new MapSqlParameterSource().addValue("id", arg1).addValue("xy", arg2); npjo.queryForInt(sql, args); mc.setDefaultMatcher(new ArrayMatcher()); mc.setReturnValue(expectedResult); mc.replay(); SimpleJdbcTemplate jth = new SimpleJdbcTemplate(npjo); int result = jth.queryForInt(sql, args); assertEquals(expectedResult, result); mc.verify(); } public void testQueryForLongWithoutArgs() { String sql = "SELECT COUNT(0) FROM BAR"; long expectedResult = 666; MockControl mc = MockControl.createControl(JdbcOperations.class); JdbcOperations jo = (JdbcOperations) mc.getMock(); jo.queryForLong(sql); mc.setReturnValue(expectedResult); mc.replay(); SimpleJdbcTemplate jth = new SimpleJdbcTemplate(jo); long result = jth.queryForLong(sql); assertEquals(expectedResult, result); mc.verify(); } public void testQueryForLongWithArgs() { String sql = "SELECT COUNT(0) FROM BAR WHERE ID=? AND XY=?"; long expectedResult = 666; double arg1 = 24.7; String arg2 = "foo"; Object arg3 = new Object(); MockControl mc = MockControl.createControl(JdbcOperations.class); JdbcOperations jo = (JdbcOperations) mc.getMock(); jo.queryForLong(sql, new Object[]{arg1, arg2, arg3}); mc.setDefaultMatcher(new ArrayMatcher()); mc.setReturnValue(expectedResult); mc.replay(); SimpleJdbcTemplate jth = new SimpleJdbcTemplate(jo); long result = jth.queryForLong(sql, arg1, arg2, arg3); assertEquals(expectedResult, result); mc.verify(); } public void testQueryForObjectWithoutArgs() throws Exception { String sql = "SELECT SYSDATE FROM DUAL"; Date expectedResult = new Date(); MockControl mc = MockControl.createControl(JdbcOperations.class); JdbcOperations jo = (JdbcOperations) mc.getMock(); jo.queryForObject(sql, Date.class); mc.setReturnValue(expectedResult); mc.replay(); SimpleJdbcTemplate jth = new SimpleJdbcTemplate(jo); Date result = jth.queryForObject(sql, Date.class); assertEquals(expectedResult, result); mc.verify(); } public void testQueryForObjectWithArgs() throws Exception { String sql = "SELECT SOMEDATE FROM BAR WHERE ID=? AND XY=?"; Date expectedResult = new Date(); double arg1 = 24.7; String arg2 = "foo"; Object arg3 = new Object(); MockControl mc = MockControl.createControl(JdbcOperations.class); JdbcOperations jo = (JdbcOperations) mc.getMock(); jo.queryForObject(sql, new Object[]{arg1, arg2, arg3}, Date.class); mc.setDefaultMatcher(new ArrayMatcher()); mc.setReturnValue(expectedResult); mc.replay(); SimpleJdbcTemplate jth = new SimpleJdbcTemplate(jo); Date result = jth.queryForObject(sql, Date.class, arg1, arg2, arg3); assertEquals(expectedResult, result); mc.verify(); } public void testQueryForObjectWithArgArray() throws Exception { String sql = "SELECT SOMEDATE FROM BAR WHERE ID=? AND XY=?"; Date expectedResult = new Date(); double arg1 = 24.7; String arg2 = "foo"; Object arg3 = new Object(); MockControl mc = MockControl.createControl(JdbcOperations.class); JdbcOperations jo = (JdbcOperations) mc.getMock(); jo.queryForObject(sql, new Object[]{arg1, arg2, arg3}, Date.class); mc.setDefaultMatcher(new ArrayMatcher()); mc.setReturnValue(expectedResult); mc.replay(); SimpleJdbcTemplate jth = new SimpleJdbcTemplate(jo); Object args = new Object[] {arg1, arg2, arg3}; Date result = jth.queryForObject(sql, Date.class, args); assertEquals(expectedResult, result); mc.verify(); } public void testQueryForObjectWithMap() throws Exception { String sql = "SELECT SOMEDATE FROM BAR WHERE ID=? AND XY=?"; Date expectedResult = new Date(); double arg1 = 24.7; String arg2 = "foo"; Object arg3 = new Object(); MockControl mc = MockControl.createControl(JdbcOperations.class); JdbcOperations jo = (JdbcOperations) mc.getMock(); jo.queryForObject(sql, new Object[]{arg1, arg2, arg3}, Date.class); mc.setDefaultMatcher(new ArrayMatcher()); mc.setReturnValue(expectedResult); mc.replay(); SimpleJdbcTemplate jth = new SimpleJdbcTemplate(jo); Date result = jth.queryForObject(sql, Date.class, arg1, arg2, arg3); assertEquals(expectedResult, result); mc.verify(); } public void testQueryForObjectWithRowMapperAndWithoutArgs() throws Exception { String sql = "SELECT SYSDATE FROM DUAL"; Date expectedResult = new Date(); ParameterizedRowMapper rm = new ParameterizedRowMapper() { public Date mapRow(ResultSet rs, int rowNum) { return new Date(); } }; MockControl mc = MockControl.createControl(JdbcOperations.class); JdbcOperations jo = (JdbcOperations) mc.getMock(); jo.queryForObject(sql, rm); mc.setReturnValue(expectedResult); mc.replay(); SimpleJdbcTemplate jth = new SimpleJdbcTemplate(jo); Date result = jth.queryForObject(sql, rm); assertEquals(expectedResult, result); mc.verify(); } public void testQueryForObjectWithRowMapperAndArgs() throws Exception { String sql = "SELECT SOMEDATE FROM BAR WHERE ID=? AND XY=?"; Date expectedResult = new Date(); double arg1 = 24.7; String arg2 = "foo"; Object arg3 = new Object(); ParameterizedRowMapper rm = new ParameterizedRowMapper() { public Date mapRow(ResultSet rs, int rowNum) { return new Date(); } }; MockControl mc = MockControl.createControl(JdbcOperations.class); JdbcOperations jo = (JdbcOperations) mc.getMock(); jo.queryForObject(sql, new Object[]{arg1, arg2, arg3}, rm); mc.setDefaultMatcher(new ArrayMatcher()); mc.setReturnValue(expectedResult); mc.replay(); SimpleJdbcTemplate jth = new SimpleJdbcTemplate(jo); Date result = jth.queryForObject(sql, rm, arg1, arg2, arg3); assertEquals(expectedResult, result); mc.verify(); } public void testQueryForObjectWithRowMapperAndMap() throws Exception { String sql = "SELECT SOMEDATE FROM BAR WHERE ID=? AND XY=?"; Date expectedResult = new Date(); double arg1 = 24.7; String arg2 = "foo"; Object arg3 = new Object(); ParameterizedRowMapper rm = new ParameterizedRowMapper() { public Date mapRow(ResultSet rs, int rowNum) { return new Date(); } }; MockControl mc = MockControl.createControl(JdbcOperations.class); JdbcOperations jo = (JdbcOperations) mc.getMock(); jo.queryForObject(sql, new Object[]{arg1, arg2, arg3}, rm); mc.setDefaultMatcher(new ArrayMatcher()); mc.setReturnValue(expectedResult); mc.replay(); SimpleJdbcTemplate jth = new SimpleJdbcTemplate(jo); Date result = jth.queryForObject(sql, rm, arg1, arg2, arg3); assertEquals(expectedResult, result); mc.verify(); } public void testQueryForListWithoutArgs() throws Exception { testDelegation("queryForList", new Object[]{"sql"}, new Object[]{}, Collections.singletonList(new Object())); } public void testQueryForListWithArgs() throws Exception { testDelegation("queryForList", new Object[]{"sql"}, new Object[]{1, 2, 3}, new LinkedList()); } public void testQueryForListWithMap() throws Exception { HashMap args = new HashMap(3); args.put("1", 1); args.put("2", 2); args.put("3", 3); testDelegation("queryForList", new Object[]{"sql"}, new Object[]{args}, new LinkedList()); } public void testQueryForListWithSqlParameterSource() throws Exception { MapSqlParameterSource args = new MapSqlParameterSource(); args.addValue("1", 1); args.addValue("2", 2); args.addValue("3", 3); testDelegation("queryForList", new Object[]{"sql"}, new Object[]{args}, new LinkedList()); } public void testQueryForMapWithoutArgs() throws Exception { testDelegation("queryForMap", new Object[]{"sql"}, new Object[]{}, new HashMap()); } public void testQueryForMapWithArgs() throws Exception { testDelegation("queryForMap", new Object[]{"sql"}, new Object[]{1, 2, 3}, new HashMap()); // TODO test generic type } public void testQueryForMapWithMap() throws Exception { HashMap args = new HashMap(3); args.put("1", 1); args.put("2", 2); args.put("3", 3); testDelegation("queryForMap", new Object[]{"sql"}, new Object[]{args}, new HashMap()); } public void testQueryForMapWithSqlParameterSource() throws Exception { MapSqlParameterSource args = new MapSqlParameterSource(); args.addValue("1", 1); args.addValue("2", 2); args.addValue("3", 3); testDelegation("queryForMap", new Object[]{"sql"}, new Object[]{args}, new HashMap()); } public void testUpdateWithoutArgs() throws Exception { testDelegation("update", new Object[]{"sql"}, new Object[]{}, 666); } public void testUpdateWithArgs() throws Exception { testDelegation("update", new Object[]{"sql"}, new Object[]{1, 2, 3}, 666); } public void testUpdateWithMap() throws Exception { HashMap args = new HashMap(3); args.put("1", 1); args.put("2", 2); args.put("3", 3); testDelegation("update", new Object[]{"sql"}, new Object[]{args}, 666); } public void testUpdateWithSqlParameterSource() throws Exception { MapSqlParameterSource args = new MapSqlParameterSource(); args.addValue("1", 1); args.addValue("2", 2); args.addValue("3", 3); testDelegation("update", new Object[]{"sql"}, new Object[]{args}, 666); } private Object testDelegation(String methodName, Object[] typedArgs, Object[] varargs, Object expectedResult) throws Exception { Class[] unifiedTypes; Object[] unifiedArgs; Class[] unifiedTypes2; Object[] unifiedArgs2; boolean namedParameters = false; if (varargs != null && varargs.length > 0) { // Allow for Map if (varargs[0].getClass().equals(HashMap.class)) { unifiedTypes = new Class[typedArgs.length + 1]; unifiedArgs = new Object[typedArgs.length + 1]; for (int i = 0; i < typedArgs.length; i++) { unifiedTypes[i] = typedArgs[i].getClass(); unifiedArgs[i] = typedArgs[i]; } unifiedTypes[unifiedTypes.length - 1] = Map.class; unifiedArgs[unifiedArgs.length - 1] = varargs[0]; unifiedTypes2 = unifiedTypes; unifiedArgs2 = unifiedArgs; namedParameters = true; } else if (varargs[0].getClass().equals(MapSqlParameterSource.class)) { unifiedTypes = new Class[typedArgs.length + 1]; unifiedArgs = new Object[typedArgs.length + 1]; for (int i = 0; i < typedArgs.length; i++) { unifiedTypes[i] = typedArgs[i].getClass(); unifiedArgs[i] = typedArgs[i]; } unifiedTypes[unifiedTypes.length - 1] = SqlParameterSource.class; unifiedArgs[unifiedArgs.length - 1] = varargs[0]; unifiedTypes2 = unifiedTypes; unifiedArgs2 = unifiedArgs; namedParameters = true; } else { // Allow for varargs.length unifiedTypes = new Class[typedArgs.length + 1]; unifiedArgs = new Object[typedArgs.length + 1]; for (int i = 0; i < unifiedTypes.length - 1; i++) { unifiedTypes[i] = typedArgs[i].getClass(); unifiedArgs[i] = typedArgs[i]; } unifiedTypes[unifiedTypes.length - 1] = Object[].class; unifiedArgs[unifiedTypes.length - 1] = varargs; } unifiedTypes2 = unifiedTypes; unifiedArgs2 = unifiedArgs; } else { unifiedTypes = new Class[typedArgs.length]; unifiedTypes2 = new Class[typedArgs.length + 1]; unifiedArgs = new Object[typedArgs.length]; unifiedArgs2 = new Object[typedArgs.length + 1]; for (int i = 0; i < typedArgs.length; i++) { unifiedTypes[i] = unifiedTypes2[i] = typedArgs[i].getClass(); unifiedArgs[i] = unifiedArgs2[i] = typedArgs[i]; } unifiedTypes2[unifiedTypes2.length - 1] = Object[].class; unifiedArgs2[unifiedArgs2.length - 1] = new Object[]{}; } MockControl mc; JdbcOperations jo = null; NamedParameterJdbcOperations npjo = null; Method joMethod = null; SimpleJdbcTemplate jth = null; if (namedParameters) { mc = MockControl.createControl(NamedParameterJdbcOperations.class); npjo = (NamedParameterJdbcOperations) mc.getMock(); joMethod = NamedParameterJdbcOperations.class.getMethod(methodName, unifiedTypes); joMethod.invoke(npjo, unifiedArgs); jth = new SimpleJdbcTemplate(npjo); } else { mc = MockControl.createControl(JdbcOperations.class); jo = (JdbcOperations) mc.getMock(); joMethod = JdbcOperations.class.getMethod(methodName, unifiedTypes); joMethod.invoke(jo, unifiedArgs); jth = new SimpleJdbcTemplate(jo); } mc.setDefaultMatcher(new ArrayMatcher()); if (joMethod.getReturnType().isPrimitive()) { // TODO bit of a hack with autoboxing passing up Integer when the return // type is an int mc.setReturnValue(((Integer) expectedResult).intValue()); } else { mc.setReturnValue(expectedResult); } mc.replay(); Method jthMethod = SimpleJdbcTemplate.class.getMethod(methodName, unifiedTypes2); Object result = jthMethod.invoke(jth, unifiedArgs2); assertEquals(expectedResult, result); mc.verify(); return result; } public void testBatchUpdateWithSqlParameterSource() throws Exception { final String sqlToUse = "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = ?"; final String sql = "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = :id"; final SqlParameterSource[] ids = new SqlParameterSource[2]; ids[0] = new MapSqlParameterSource("id", 100); ids[1] = new MapSqlParameterSource("id", 200); final int[] rowsAffected = new int[] { 1, 2 }; MockControl ctrlDataSource = MockControl.createControl(DataSource.class); DataSource mockDataSource = (DataSource) ctrlDataSource.getMock(); MockControl ctrlConnection = MockControl.createControl(Connection.class); Connection mockConnection = (Connection) ctrlConnection.getMock(); MockControl ctrlPreparedStatement = MockControl.createControl(PreparedStatement.class); PreparedStatement mockPreparedStatement = (PreparedStatement) ctrlPreparedStatement.getMock(); MockControl ctrlDatabaseMetaData = MockControl.createControl(DatabaseMetaData.class); DatabaseMetaData mockDatabaseMetaData = (DatabaseMetaData) ctrlDatabaseMetaData.getMock(); BatchUpdateTestHelper.prepareBatchUpdateMocks(sqlToUse, ids, null, rowsAffected, ctrlDataSource, mockDataSource, ctrlConnection, mockConnection, ctrlPreparedStatement, mockPreparedStatement, ctrlDatabaseMetaData, mockDatabaseMetaData); BatchUpdateTestHelper.replayBatchUpdateMocks(ctrlDataSource, ctrlConnection, ctrlPreparedStatement, ctrlDatabaseMetaData); JdbcTemplate template = new JdbcTemplate(mockDataSource, false); SimpleJdbcTemplate simpleJdbcTemplate = new SimpleJdbcTemplate(template); int[] actualRowsAffected = simpleJdbcTemplate.batchUpdate(sql, ids); assertTrue("executed 2 updates", actualRowsAffected.length == 2); assertEquals(rowsAffected[0], actualRowsAffected[0]); assertEquals(rowsAffected[1], actualRowsAffected[1]); BatchUpdateTestHelper.verifyBatchUpdateMocks(ctrlPreparedStatement, ctrlDatabaseMetaData); } public void testBatchUpdateWithListOfObjectArrays() throws Exception { final String sql = "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = ?"; final List ids = new ArrayList(); ids.add(new Object[] {100}); ids.add(new Object[] {200}); final int[] rowsAffected = new int[] { 1, 2 }; MockControl ctrlDataSource = MockControl.createControl(DataSource.class); DataSource mockDataSource = (DataSource) ctrlDataSource.getMock(); MockControl ctrlConnection = MockControl.createControl(Connection.class); Connection mockConnection = (Connection) ctrlConnection.getMock(); MockControl ctrlPreparedStatement = MockControl.createControl(PreparedStatement.class); PreparedStatement mockPreparedStatement = (PreparedStatement) ctrlPreparedStatement.getMock(); MockControl ctrlDatabaseMetaData = MockControl.createControl(DatabaseMetaData.class); DatabaseMetaData mockDatabaseMetaData = (DatabaseMetaData) ctrlDatabaseMetaData.getMock(); BatchUpdateTestHelper.prepareBatchUpdateMocks(sql, ids, null, rowsAffected, ctrlDataSource, mockDataSource, ctrlConnection, mockConnection, ctrlPreparedStatement, mockPreparedStatement, ctrlDatabaseMetaData, mockDatabaseMetaData); BatchUpdateTestHelper.replayBatchUpdateMocks(ctrlDataSource, ctrlConnection, ctrlPreparedStatement, ctrlDatabaseMetaData); JdbcTemplate template = new JdbcTemplate(mockDataSource, false); SimpleJdbcTemplate simpleJdbcTemplate = new SimpleJdbcTemplate(template); int[] actualRowsAffected = simpleJdbcTemplate.batchUpdate(sql, ids); assertTrue("executed 2 updates", actualRowsAffected.length == 2); assertEquals(rowsAffected[0], actualRowsAffected[0]); assertEquals(rowsAffected[1], actualRowsAffected[1]); BatchUpdateTestHelper.verifyBatchUpdateMocks(ctrlPreparedStatement, ctrlDatabaseMetaData); } public void testBatchUpdateWithListOfObjectArraysPlusTypeInfo() throws Exception { final String sql = "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = ?"; final List ids = new ArrayList(); ids.add(new Object[] {100}); ids.add(new Object[] {200}); final int[] sqlTypes = new int[] {Types.NUMERIC}; final int[] rowsAffected = new int[] { 1, 2 }; MockControl ctrlDataSource = MockControl.createControl(DataSource.class); DataSource mockDataSource = (DataSource) ctrlDataSource.getMock(); MockControl ctrlConnection = MockControl.createControl(Connection.class); Connection mockConnection = (Connection) ctrlConnection.getMock(); MockControl ctrlPreparedStatement = MockControl.createControl(PreparedStatement.class); PreparedStatement mockPreparedStatement = (PreparedStatement) ctrlPreparedStatement.getMock(); MockControl ctrlDatabaseMetaData = MockControl.createControl(DatabaseMetaData.class); DatabaseMetaData mockDatabaseMetaData = (DatabaseMetaData) ctrlDatabaseMetaData.getMock(); BatchUpdateTestHelper.prepareBatchUpdateMocks(sql, ids, sqlTypes, rowsAffected, ctrlDataSource, mockDataSource, ctrlConnection, mockConnection, ctrlPreparedStatement, mockPreparedStatement, ctrlDatabaseMetaData, mockDatabaseMetaData); BatchUpdateTestHelper.replayBatchUpdateMocks(ctrlDataSource, ctrlConnection, ctrlPreparedStatement, ctrlDatabaseMetaData); JdbcTemplate template = new JdbcTemplate(mockDataSource, false); SimpleJdbcTemplate simpleJdbcTemplate = new SimpleJdbcTemplate(template); int[] actualRowsAffected = simpleJdbcTemplate.batchUpdate(sql, ids, sqlTypes); assertTrue("executed 2 updates", actualRowsAffected.length == 2); assertEquals(rowsAffected[0], actualRowsAffected[0]); assertEquals(rowsAffected[1], actualRowsAffected[1]); BatchUpdateTestHelper.verifyBatchUpdateMocks(ctrlPreparedStatement, ctrlDatabaseMetaData); } } ././@LongLink0000000000000000000000000000020700000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/JdbcTemplateQueryTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000007373211623223526033341 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; import java.math.BigDecimal; import java.math.BigInteger; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; import java.util.List; import java.util.Map; import org.easymock.MockControl; import org.apache.commons.logging.LogFactory; import org.springframework.dao.IncorrectResultSizeDataAccessException; import org.springframework.jdbc.AbstractJdbcTests; /** * @author Juergen Hoeller * @since 19.12.2004 */ public class JdbcTemplateQueryTests extends AbstractJdbcTests { private final boolean debugEnabled = LogFactory.getLog(JdbcTemplate.class).isDebugEnabled(); private MockControl ctrlStatement; private Statement mockStatement; private MockControl ctrlPreparedStatement; private PreparedStatement mockPreparedStatement; private MockControl ctrlResultSet; private ResultSet mockResultSet; private MockControl ctrlResultSetMetaData; private ResultSetMetaData mockResultSetMetaData; protected void setUp() throws Exception { super.setUp(); ctrlStatement = MockControl.createControl(Statement.class); mockStatement = (Statement) ctrlStatement.getMock(); ctrlPreparedStatement = MockControl.createControl(PreparedStatement.class); mockPreparedStatement = (PreparedStatement) ctrlPreparedStatement.getMock(); ctrlResultSet = MockControl.createControl(ResultSet.class); mockResultSet = (ResultSet) ctrlResultSet.getMock(); ctrlResultSetMetaData = MockControl.createControl(ResultSetMetaData.class); mockResultSetMetaData = (ResultSetMetaData) ctrlResultSetMetaData.getMock(); } protected void replay() { super.replay(); ctrlStatement.replay(); ctrlPreparedStatement.replay(); ctrlResultSet.replay(); ctrlResultSetMetaData.replay(); } protected void tearDown() throws Exception { super.tearDown(); if (shouldVerify()) { ctrlStatement.verify(); ctrlPreparedStatement.verify(); ctrlResultSet.verify(); ctrlResultSetMetaData.verify(); } } public void testQueryForList() throws Exception { String sql = "SELECT AGE FROM CUSTMR WHERE ID < 3"; mockResultSetMetaData.getColumnCount(); ctrlResultSetMetaData.setReturnValue(1, 2); mockResultSetMetaData.getColumnLabel(1); ctrlResultSetMetaData.setReturnValue("age", 2); mockResultSet.getMetaData(); ctrlResultSet.setReturnValue(mockResultSetMetaData, 2); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getObject(1); ctrlResultSet.setReturnValue(new Integer(11)); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getObject(1); ctrlResultSet.setReturnValue(new Integer(12)); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockStatement.executeQuery(sql); ctrlStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockStatement.getWarnings(); ctrlStatement.setReturnValue(null); } mockStatement.close(); ctrlStatement.setVoidCallable(); mockConnection.createStatement(); ctrlConnection.setReturnValue(mockStatement); replay(); JdbcTemplate template = new JdbcTemplate(mockDataSource); List li = template.queryForList(sql); assertEquals("All rows returned", 2, li.size()); assertEquals("First row is Integer", 11, ((Integer)((Map)li.get(0)).get("age")).intValue()); assertEquals("Second row is Integer", 12, ((Integer)((Map)li.get(1)).get("age")).intValue()); } public void testQueryForListWithEmptyResult() throws Exception { String sql = "SELECT AGE FROM CUSTMR WHERE ID < 3"; mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockStatement.executeQuery(sql); ctrlStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockStatement.getWarnings(); ctrlStatement.setReturnValue(null); } mockStatement.close(); ctrlStatement.setVoidCallable(); mockConnection.createStatement(); ctrlConnection.setReturnValue(mockStatement); replay(); JdbcTemplate template = new JdbcTemplate(mockDataSource); List li = template.queryForList(sql); assertEquals("All rows returned", 0, li.size()); } public void testQueryForListWithSingleRowAndColumn() throws Exception { String sql = "SELECT AGE FROM CUSTMR WHERE ID < 3"; mockResultSetMetaData.getColumnCount(); ctrlResultSetMetaData.setReturnValue(1); mockResultSetMetaData.getColumnLabel(1); ctrlResultSetMetaData.setReturnValue("age", 1); mockResultSet.getMetaData(); ctrlResultSet.setReturnValue(mockResultSetMetaData); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getObject(1); ctrlResultSet.setReturnValue(new Integer(11)); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockStatement.executeQuery(sql); ctrlStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockStatement.getWarnings(); ctrlStatement.setReturnValue(null); } mockStatement.close(); ctrlStatement.setVoidCallable(); mockConnection.createStatement(); ctrlConnection.setReturnValue(mockStatement); replay(); JdbcTemplate template = new JdbcTemplate(mockDataSource); List li = template.queryForList(sql); assertEquals("All rows returned", 1, li.size()); assertEquals("First row is Integer", 11, ((Integer)((Map)li.get(0)).get("age")).intValue()); } public void testQueryForListWithIntegerElement() throws Exception { String sql = "SELECT AGE FROM CUSTMR WHERE ID < 3"; mockResultSetMetaData.getColumnCount(); ctrlResultSetMetaData.setReturnValue(1); mockResultSet.getMetaData(); ctrlResultSet.setReturnValue(mockResultSetMetaData); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getInt(1); ctrlResultSet.setReturnValue(11); mockResultSet.wasNull(); ctrlResultSet.setReturnValue(false); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockStatement.executeQuery(sql); ctrlStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockStatement.getWarnings(); ctrlStatement.setReturnValue(null); } mockStatement.close(); ctrlStatement.setVoidCallable(); mockConnection.createStatement(); ctrlConnection.setReturnValue(mockStatement); replay(); JdbcTemplate template = new JdbcTemplate(mockDataSource); List li = template.queryForList(sql, Integer.class); assertEquals("All rows returned", 1, li.size()); assertEquals("Element is Integer", 11, ((Integer) li.get(0)).intValue()); } public void testQueryForMapWithSingleRowAndColumn() throws Exception { String sql = "SELECT AGE FROM CUSTMR WHERE ID < 3"; mockResultSetMetaData.getColumnCount(); ctrlResultSetMetaData.setReturnValue(1); mockResultSetMetaData.getColumnLabel(1); ctrlResultSetMetaData.setReturnValue("age", 1); mockResultSet.getMetaData(); ctrlResultSet.setReturnValue(mockResultSetMetaData); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getObject(1); ctrlResultSet.setReturnValue(new Integer(11)); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockStatement.executeQuery(sql); ctrlStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockStatement.getWarnings(); ctrlStatement.setReturnValue(null); } mockStatement.close(); ctrlStatement.setVoidCallable(); mockConnection.createStatement(); ctrlConnection.setReturnValue(mockStatement); replay(); JdbcTemplate template = new JdbcTemplate(mockDataSource); Map map = template.queryForMap(sql); assertEquals("Wow is Integer", 11, ((Integer) map.get("age")).intValue()); } public void testQueryForObjectThrowsIncorrectResultSizeForMoreThanOneRow() throws Exception { String sql = "select pass from t_account where first_name='Alef'"; mockResultSetMetaData.getColumnCount(); ctrlResultSetMetaData.setReturnValue(1); mockResultSet.getMetaData(); ctrlResultSet.setReturnValue(mockResultSetMetaData); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getString(1); ctrlResultSet.setReturnValue("pass"); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getMetaData(); ctrlResultSet.setReturnValue(mockResultSetMetaData); mockResultSetMetaData.getColumnCount(); ctrlResultSetMetaData.setReturnValue(1); mockResultSet.getString(1); ctrlResultSet.setReturnValue("pass"); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockStatement.executeQuery(sql); ctrlStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockStatement.getWarnings(); ctrlStatement.setReturnValue(null); } mockStatement.close(); ctrlStatement.setVoidCallable(); mockConnection.createStatement(); ctrlConnection.setReturnValue(mockStatement); replay(); JdbcTemplate template = new JdbcTemplate(mockDataSource); try { template.queryForObject(sql, String.class); fail("Should have thrown IncorrectResultSizeDataAccessException"); } catch (IncorrectResultSizeDataAccessException ex) { // expected } } public void testQueryForObjectWithRowMapper() throws Exception { String sql = "SELECT AGE FROM CUSTMR WHERE ID = 3"; mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getInt(1); ctrlResultSet.setReturnValue(22); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockStatement.executeQuery(sql); ctrlStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockStatement.getWarnings(); ctrlStatement.setReturnValue(null); } mockStatement.close(); ctrlStatement.setVoidCallable(); mockConnection.createStatement(); ctrlConnection.setReturnValue(mockStatement); replay(); JdbcTemplate template = new JdbcTemplate(mockDataSource); Object o = template.queryForObject(sql, new RowMapper() { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { return new Integer(rs.getInt(1)); } }); assertTrue("Correct result type", o instanceof Integer); } public void testQueryForObjectWithString() throws Exception { String sql = "SELECT AGE FROM CUSTMR WHERE ID = 3"; mockResultSetMetaData.getColumnCount(); ctrlResultSetMetaData.setReturnValue(1); mockResultSet.getMetaData(); ctrlResultSet.setReturnValue(mockResultSetMetaData); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getString(1); ctrlResultSet.setReturnValue("myvalue"); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockStatement.executeQuery(sql); ctrlStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockStatement.getWarnings(); ctrlStatement.setReturnValue(null); } mockStatement.close(); ctrlStatement.setVoidCallable(); mockConnection.createStatement(); ctrlConnection.setReturnValue(mockStatement); replay(); JdbcTemplate template = new JdbcTemplate(mockDataSource); assertEquals("myvalue", template.queryForObject(sql, String.class)); } public void testQueryForObjectWithBigInteger() throws Exception { String sql = "SELECT AGE FROM CUSTMR WHERE ID = 3"; mockResultSetMetaData.getColumnCount(); ctrlResultSetMetaData.setReturnValue(1); mockResultSet.getMetaData(); ctrlResultSet.setReturnValue(mockResultSetMetaData); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getObject(1); ctrlResultSet.setReturnValue("22"); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockStatement.executeQuery(sql); ctrlStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockStatement.getWarnings(); ctrlStatement.setReturnValue(null); } mockStatement.close(); ctrlStatement.setVoidCallable(); mockConnection.createStatement(); ctrlConnection.setReturnValue(mockStatement); replay(); JdbcTemplate template = new JdbcTemplate(mockDataSource); assertEquals(new BigInteger("22"), template.queryForObject(sql, BigInteger.class)); } public void testQueryForObjectWithBigDecimal() throws Exception { String sql = "SELECT AGE FROM CUSTMR WHERE ID = 3"; mockResultSetMetaData.getColumnCount(); ctrlResultSetMetaData.setReturnValue(1); mockResultSet.getMetaData(); ctrlResultSet.setReturnValue(mockResultSetMetaData); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getBigDecimal(1); ctrlResultSet.setReturnValue(new BigDecimal(22.5)); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockStatement.executeQuery(sql); ctrlStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockStatement.getWarnings(); ctrlStatement.setReturnValue(null); } mockStatement.close(); ctrlStatement.setVoidCallable(); mockConnection.createStatement(); ctrlConnection.setReturnValue(mockStatement); replay(); JdbcTemplate template = new JdbcTemplate(mockDataSource); assertEquals(new BigDecimal(22.5), template.queryForObject(sql, BigDecimal.class)); } public void testQueryForObjectWithInteger() throws Exception { String sql = "SELECT AGE FROM CUSTMR WHERE ID = 3"; mockResultSetMetaData.getColumnCount(); ctrlResultSetMetaData.setReturnValue(1); mockResultSet.getMetaData(); ctrlResultSet.setReturnValue(mockResultSetMetaData); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getInt(1); ctrlResultSet.setReturnValue(22); mockResultSet.wasNull(); ctrlResultSet.setReturnValue(false); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockStatement.executeQuery(sql); ctrlStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockStatement.getWarnings(); ctrlStatement.setReturnValue(null); } mockStatement.close(); ctrlStatement.setVoidCallable(); mockConnection.createStatement(); ctrlConnection.setReturnValue(mockStatement); replay(); JdbcTemplate template = new JdbcTemplate(mockDataSource); assertEquals(new Integer(22), template.queryForObject(sql, Integer.class)); } public void testQueryForObjectWithIntegerAndNull() throws Exception { String sql = "SELECT AGE FROM CUSTMR WHERE ID = 3"; mockResultSetMetaData.getColumnCount(); ctrlResultSetMetaData.setReturnValue(1); mockResultSet.getMetaData(); ctrlResultSet.setReturnValue(mockResultSetMetaData); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getInt(1); ctrlResultSet.setReturnValue(0); mockResultSet.wasNull(); ctrlResultSet.setReturnValue(true); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockStatement.executeQuery(sql); ctrlStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockStatement.getWarnings(); ctrlStatement.setReturnValue(null); } mockStatement.close(); ctrlStatement.setVoidCallable(); mockConnection.createStatement(); ctrlConnection.setReturnValue(mockStatement); replay(); JdbcTemplate template = new JdbcTemplate(mockDataSource); assertNull(template.queryForObject(sql, Integer.class)); } public void testQueryForInt() throws Exception { String sql = "SELECT AGE FROM CUSTMR WHERE ID = 3"; mockResultSetMetaData.getColumnCount(); ctrlResultSetMetaData.setReturnValue(1); mockResultSet.getMetaData(); ctrlResultSet.setReturnValue(mockResultSetMetaData); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getInt(1); ctrlResultSet.setReturnValue(22); mockResultSet.wasNull(); ctrlResultSet.setReturnValue(false); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockStatement.executeQuery(sql); ctrlStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockStatement.getWarnings(); ctrlStatement.setReturnValue(null); } mockStatement.close(); ctrlStatement.setVoidCallable(); mockConnection.createStatement(); ctrlConnection.setReturnValue(mockStatement); replay(); JdbcTemplate template = new JdbcTemplate(mockDataSource); int i = template.queryForInt(sql); assertEquals("Return of an int", 22, i); } public void testQueryForLong() throws Exception { String sql = "SELECT AGE FROM CUSTMR WHERE ID = 3"; mockResultSetMetaData.getColumnCount(); ctrlResultSetMetaData.setReturnValue(1); mockResultSet.getMetaData(); ctrlResultSet.setReturnValue(mockResultSetMetaData); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getLong(1); ctrlResultSet.setReturnValue(87); mockResultSet.wasNull(); ctrlResultSet.setReturnValue(false); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockStatement.executeQuery(sql); ctrlStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockStatement.getWarnings(); ctrlStatement.setReturnValue(null); } mockStatement.close(); ctrlStatement.setVoidCallable(); mockConnection.createStatement(); ctrlConnection.setReturnValue(mockStatement); replay(); JdbcTemplate template = new JdbcTemplate(mockDataSource); long l = template.queryForLong(sql); assertEquals("Return of a long", 87, l); } public void testQueryForListWithArgs() throws Exception { doTestQueryForListWithArgs("SELECT AGE FROM CUSTMR WHERE ID < ?"); } public void testQueryForListIsNotConfusedByNamedParameterPrefix() throws Exception { doTestQueryForListWithArgs("SELECT AGE FROM PREFIX:CUSTMR WHERE ID < ?"); } private void doTestQueryForListWithArgs(String sql) throws Exception { mockResultSetMetaData.getColumnCount(); ctrlResultSetMetaData.setReturnValue(1, 2); mockResultSetMetaData.getColumnLabel(1); ctrlResultSetMetaData.setReturnValue("age", 2); mockResultSet.getMetaData(); ctrlResultSet.setReturnValue(mockResultSetMetaData, 2); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getObject(1); ctrlResultSet.setReturnValue(new Integer(11)); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getObject(1); ctrlResultSet.setReturnValue(new Integer(12)); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockPreparedStatement.setObject(1, new Integer(3)); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeQuery(); ctrlPreparedStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(sql); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); JdbcTemplate template = new JdbcTemplate(mockDataSource); List li = template.queryForList(sql, new Object[] {new Integer(3)}); assertEquals("All rows returned", 2, li.size()); assertEquals("First row is Integer", 11, ((Integer)((Map)li.get(0)).get("age")).intValue()); assertEquals("Second row is Integer", 12, ((Integer)((Map)li.get(1)).get("age")).intValue()); } public void testQueryForListWithArgsAndEmptyResult() throws Exception { String sql = "SELECT AGE FROM CUSTMR WHERE ID < ?"; ctrlResultSet = MockControl.createControl(ResultSet.class); mockResultSet = (ResultSet) ctrlResultSet.getMock(); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockPreparedStatement.setObject(1, new Integer(3)); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeQuery(); ctrlPreparedStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(sql); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); JdbcTemplate template = new JdbcTemplate(mockDataSource); List li = template.queryForList(sql, new Object[] {new Integer(3)}); assertEquals("All rows returned", 0, li.size()); } public void testQueryForListWithArgsAndSingleRowAndColumn() throws Exception { String sql = "SELECT AGE FROM CUSTMR WHERE ID < ?"; mockResultSetMetaData.getColumnCount(); ctrlResultSetMetaData.setReturnValue(1); mockResultSetMetaData.getColumnLabel(1); ctrlResultSetMetaData.setReturnValue("age", 1); mockResultSet.getMetaData(); ctrlResultSet.setReturnValue(mockResultSetMetaData); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getObject(1); ctrlResultSet.setReturnValue(new Integer(11)); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockPreparedStatement.setObject(1, new Integer(3)); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeQuery(); ctrlPreparedStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(sql); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); JdbcTemplate template = new JdbcTemplate(mockDataSource); List li = template.queryForList(sql, new Object[] {new Integer(3)}); assertEquals("All rows returned", 1, li.size()); assertEquals("First row is Integer", 11, ((Integer)((Map)li.get(0)).get("age")).intValue()); } public void testQueryForListWithArgsAndIntegerElementAndSingleRowAndColumn() throws Exception { String sql = "SELECT AGE FROM CUSTMR WHERE ID < ?"; mockResultSetMetaData.getColumnCount(); ctrlResultSetMetaData.setReturnValue(1); mockResultSet.getMetaData(); ctrlResultSet.setReturnValue(mockResultSetMetaData); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getInt(1); ctrlResultSet.setReturnValue(11); mockResultSet.wasNull(); ctrlResultSet.setReturnValue(false); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockPreparedStatement.setObject(1, new Integer(3)); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeQuery(); ctrlPreparedStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(sql); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); JdbcTemplate template = new JdbcTemplate(mockDataSource); List li = template.queryForList(sql, new Object[] {new Integer(3)}, Integer.class); assertEquals("All rows returned", 1, li.size()); assertEquals("First row is Integer", 11, ((Integer) li.get(0)).intValue()); } public void testQueryForMapWithArgsAndSingleRowAndColumn() throws Exception { String sql = "SELECT AGE FROM CUSTMR WHERE ID < ?"; mockResultSetMetaData.getColumnCount(); ctrlResultSetMetaData.setReturnValue(1); mockResultSetMetaData.getColumnLabel(1); ctrlResultSetMetaData.setReturnValue("age", 1); mockResultSet.getMetaData(); ctrlResultSet.setReturnValue(mockResultSetMetaData); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getObject(1); ctrlResultSet.setReturnValue(new Integer(11)); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockPreparedStatement.setObject(1, new Integer(3)); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeQuery(); ctrlPreparedStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(sql); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); JdbcTemplate template = new JdbcTemplate(mockDataSource); Map map = template.queryForMap(sql, new Object[] {new Integer(3)}); assertEquals("Row is Integer", 11, ((Integer) map.get("age")).intValue()); } public void testQueryForObjectWithArgsAndRowMapper() throws Exception { String sql = "SELECT AGE FROM CUSTMR WHERE ID = ?"; mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getInt(1); ctrlResultSet.setReturnValue(22); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockPreparedStatement.setObject(1, new Integer(3)); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeQuery(); ctrlPreparedStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(sql); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); JdbcTemplate template = new JdbcTemplate(mockDataSource); Object o = template.queryForObject(sql, new Object[] {new Integer(3)}, new RowMapper() { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { return new Integer(rs.getInt(1)); } }); assertTrue("Correct result type", o instanceof Integer); } public void testQueryForObjectWithArgsAndInteger() throws Exception { String sql = "SELECT AGE FROM CUSTMR WHERE ID = ?"; mockResultSetMetaData.getColumnCount(); ctrlResultSetMetaData.setReturnValue(1); mockResultSet.getMetaData(); ctrlResultSet.setReturnValue(mockResultSetMetaData); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getInt(1); ctrlResultSet.setReturnValue(22); mockResultSet.wasNull(); ctrlResultSet.setReturnValue(false); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockPreparedStatement.setObject(1, new Integer(3)); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeQuery(); ctrlPreparedStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(sql); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); JdbcTemplate template = new JdbcTemplate(mockDataSource); Object o = template.queryForObject(sql, new Object[] {new Integer(3)}, Integer.class); assertTrue("Correct result type", o instanceof Integer); } public void testQueryForIntWithArgs() throws Exception { String sql = "SELECT AGE FROM CUSTMR WHERE ID = ?"; mockResultSetMetaData.getColumnCount(); ctrlResultSetMetaData.setReturnValue(1); mockResultSet.getMetaData(); ctrlResultSet.setReturnValue(mockResultSetMetaData); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getInt(1); ctrlResultSet.setReturnValue(22); mockResultSet.wasNull(); ctrlResultSet.setReturnValue(false); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockPreparedStatement.setObject(1, new Integer(3)); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeQuery(); ctrlPreparedStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(sql); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); JdbcTemplate template = new JdbcTemplate(mockDataSource); int i = template.queryForInt(sql, new Object[] {new Integer(3)}); assertEquals("Return of an int", 22, i); } public void testQueryForLongWithArgs() throws Exception { String sql = "SELECT AGE FROM CUSTMR WHERE ID = ?"; mockResultSetMetaData.getColumnCount(); ctrlResultSetMetaData.setReturnValue(1); mockResultSet.getMetaData(); ctrlResultSet.setReturnValue(mockResultSetMetaData); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getLong(1); ctrlResultSet.setReturnValue(87); mockResultSet.wasNull(); ctrlResultSet.setReturnValue(false); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockPreparedStatement.setObject(1, new Integer(3)); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeQuery(); ctrlPreparedStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(sql); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); JdbcTemplate template = new JdbcTemplate(mockDataSource); long l = template.queryForLong(sql, new Object[] {new Integer(3)}); assertEquals("Return of a long", 87, l); } } ././@LongLink0000000000000000000000000000021600000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/SimpleRowCountCallbackHandler.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000000212511623223530033320 0ustar drazzibdrazzib/* * Copyright 2002-2006 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; import java.sql.ResultSet; import java.sql.SQLException; /** * Simple row count callback handler for testing purposes. * Does not call any JDBC methods on the given ResultSet. * * @author Juergen Hoeller * @since 2.0 */ public class SimpleRowCountCallbackHandler implements RowCallbackHandler { private int count; public void processRow(ResultSet rs) throws SQLException { count++; } public int getCount() { return count; } } ././@LongLink0000000000000000000000000000017700000000000011572 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/RowMapperTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000001525611623223526033336 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.sql.Types; import java.util.List; import junit.framework.TestCase; import org.easymock.MockControl; import org.apache.commons.logging.LogFactory; import org.springframework.beans.TestBean; import org.springframework.jdbc.datasource.SingleConnectionDataSource; import org.springframework.jdbc.support.SQLStateSQLExceptionTranslator; /** * @author Juergen Hoeller * @since 02.08.2004 */ public class RowMapperTests extends TestCase { private final boolean debugEnabled = LogFactory.getLog(JdbcTemplate.class).isDebugEnabled(); private MockControl conControl; private Connection con; private MockControl rsControl; private ResultSet rs; private JdbcTemplate jdbcTemplate; private List result; protected void setUp() throws SQLException { conControl = MockControl.createControl(Connection.class); con = (Connection) conControl.getMock(); con.isClosed(); conControl.setDefaultReturnValue(false); rsControl = MockControl.createControl(ResultSet.class); rs = (ResultSet) rsControl.getMock(); rs.next(); rsControl.setReturnValue(true, 1); rs.getString(1); rsControl.setReturnValue("tb1", 1); rs.getInt(2); rsControl.setReturnValue(1, 1); rs.next(); rsControl.setReturnValue(true, 1); rs.getString(1); rsControl.setReturnValue("tb2", 1); rs.getInt(2); rsControl.setReturnValue(2, 1); rs.next(); rsControl.setReturnValue(false, 1); rs.close(); rsControl.setVoidCallable(1); rsControl.replay(); jdbcTemplate = new JdbcTemplate(); jdbcTemplate.setDataSource(new SingleConnectionDataSource(con, false)); jdbcTemplate.setExceptionTranslator(new SQLStateSQLExceptionTranslator()); jdbcTemplate.afterPropertiesSet(); } public void testStaticQueryWithRowMapper() throws SQLException { MockControl stmtControl = MockControl.createControl(Statement.class); Statement stmt = (Statement) stmtControl.getMock(); con.createStatement(); conControl.setReturnValue(stmt, 1); stmt.executeQuery("some SQL"); stmtControl.setReturnValue(rs, 1); if (debugEnabled) { stmt.getWarnings(); stmtControl.setReturnValue(null, 1); } stmt.close(); stmtControl.setVoidCallable(1); conControl.replay(); stmtControl.replay(); result = jdbcTemplate.query("some SQL", new TestRowMapper()); stmtControl.verify(); verify(); } public void testPreparedStatementCreatorWithRowMapper() throws SQLException { MockControl psControl = MockControl.createControl(PreparedStatement.class); final PreparedStatement ps = (PreparedStatement) psControl.getMock(); ps.executeQuery(); psControl.setReturnValue(rs, 1); if (debugEnabled) { ps.getWarnings(); psControl.setReturnValue(null, 1); } ps.close(); psControl.setVoidCallable(1); conControl.replay(); psControl.replay(); result = jdbcTemplate.query( new PreparedStatementCreator() { public PreparedStatement createPreparedStatement(Connection con) throws SQLException { return ps; } }, new TestRowMapper()); psControl.verify(); verify(); } public void testPreparedStatementSetterWithRowMapper() throws SQLException { MockControl psControl = MockControl.createControl(PreparedStatement.class); final PreparedStatement ps = (PreparedStatement) psControl.getMock(); con.prepareStatement("some SQL"); conControl.setReturnValue(ps, 1); ps.setString(1, "test"); psControl.setVoidCallable(1); ps.executeQuery(); psControl.setReturnValue(rs, 1); if (debugEnabled) { ps.getWarnings(); psControl.setReturnValue(null, 1); } ps.close(); psControl.setVoidCallable(1); conControl.replay(); psControl.replay(); result = jdbcTemplate.query( "some SQL", new PreparedStatementSetter() { public void setValues(PreparedStatement ps) throws SQLException { ps.setString(1, "test"); } }, new TestRowMapper()); psControl.verify(); verify(); } public void testQueryWithArgsAndRowMapper() throws SQLException { MockControl psControl = MockControl.createControl(PreparedStatement.class); final PreparedStatement ps = (PreparedStatement) psControl.getMock(); con.prepareStatement("some SQL"); conControl.setReturnValue(ps, 1); ps.setString(1, "test1"); ps.setString(2, "test2"); psControl.setVoidCallable(1); ps.executeQuery(); psControl.setReturnValue(rs, 1); if (debugEnabled) { ps.getWarnings(); psControl.setReturnValue(null, 1); } ps.close(); psControl.setVoidCallable(1); conControl.replay(); psControl.replay(); result = jdbcTemplate.query( "some SQL", new Object[] {"test1", "test2"}, new TestRowMapper()); psControl.verify(); verify(); } public void testQueryWithArgsAndTypesAndRowMapper() throws SQLException { MockControl psControl = MockControl.createControl(PreparedStatement.class); final PreparedStatement ps = (PreparedStatement) psControl.getMock(); con.prepareStatement("some SQL"); conControl.setReturnValue(ps, 1); ps.setString(1, "test1"); ps.setString(2, "test2"); psControl.setVoidCallable(1); ps.executeQuery(); psControl.setReturnValue(rs, 1); if (debugEnabled) { ps.getWarnings(); psControl.setReturnValue(null, 1); } ps.close(); psControl.setVoidCallable(1); conControl.replay(); psControl.replay(); result = jdbcTemplate.query( "some SQL", new Object[] {"test1", "test2"}, new int[] {Types.VARCHAR, Types.VARCHAR}, new TestRowMapper()); psControl.verify(); verify(); } protected void verify() { conControl.verify(); rsControl.verify(); assertTrue(result != null); assertEquals(2, result.size()); TestBean tb1 = (TestBean) result.get(0); TestBean tb2 = (TestBean) result.get(1); assertEquals("tb1", tb1.getName()); assertEquals(1, tb1.getAge()); assertEquals("tb2", tb2.getName()); assertEquals(2, tb2.getAge()); } private static class TestRowMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { return new TestBean(rs.getString(1), rs.getInt(2)); } } } ././@LongLink0000000000000000000000000000021300000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/BeanPropertyRowMapperTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000001054511623223526033332 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; import java.sql.SQLException; import java.util.List; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.jdbc.core.test.ConcretePerson; import org.springframework.jdbc.core.test.ExtendedPerson; import org.springframework.jdbc.core.test.Person; import org.springframework.jdbc.core.test.SpacePerson; import org.springframework.beans.TypeMismatchException; /** * @author Thomas Risberg * @author Juergen Hoeller */ public class BeanPropertyRowMapperTests extends AbstractRowMapperTests { public void testOverridingClassDefinedForMapping() { BeanPropertyRowMapper mapper = new BeanPropertyRowMapper(Person.class); try { mapper.setMappedClass(Long.class); fail("Setting new class should have thrown InvalidDataAccessApiUsageException"); } catch (InvalidDataAccessApiUsageException ex) { } try { mapper.setMappedClass(Person.class); } catch (InvalidDataAccessApiUsageException ex) { fail("Setting same class should not have thrown InvalidDataAccessApiUsageException"); } } public void testStaticQueryWithRowMapper() throws SQLException { List result = jdbcTemplate.query("select name, age, birth_date, balance from people", new BeanPropertyRowMapper(Person.class)); assertEquals(1, result.size()); Person bean = (Person) result.get(0); verifyPerson(bean); } public void testMappingWithInheritance() throws SQLException { List result = jdbcTemplate.query("select name, age, birth_date, balance from people", new BeanPropertyRowMapper(ConcretePerson.class)); assertEquals(1, result.size()); ConcretePerson bean = (ConcretePerson) result.get(0); verifyConcretePerson(bean); } public void testMappingWithNoUnpopulatedFieldsFound() throws SQLException { List result = jdbcTemplate.query("select name, age, birth_date, balance from people", new BeanPropertyRowMapper(ConcretePerson.class, true)); assertEquals(1, result.size()); ConcretePerson bean = (ConcretePerson) result.get(0); verifyConcretePerson(bean); } public void testMappingWithUnpopulatedFieldsNotChecked() throws SQLException { List result = jdbcTemplate.query("select name, age, birth_date, balance from people", new BeanPropertyRowMapper(ExtendedPerson.class)); assertEquals(1, result.size()); ExtendedPerson bean = (ExtendedPerson) result.get(0); verifyConcretePerson(bean); } public void testMappingWithUnpopulatedFieldsNotAccepted() throws SQLException { try { List result = jdbcTemplate.query("select name, age, birth_date, balance from people", new BeanPropertyRowMapper(ExtendedPerson.class, true)); fail("Should have thrown InvalidDataAccessApiUsageException because of missing field"); } catch (InvalidDataAccessApiUsageException ex) { // expected } } public void testMappingNullValue() throws SQLException { BeanPropertyRowMapper mapper = new BeanPropertyRowMapper(Person.class); try { List result1 = jdbcTemplate2.query("select name, null as age, birth_date, balance from people", mapper); fail("Should have thrown TypeMismatchException because of null value"); } catch (TypeMismatchException ex) { // expected } mapper.setPrimitivesDefaultedForNullValue(true); List result2 = jdbcTemplate2.query("select name, null as age, birth_date, balance from people", mapper); assertEquals(1, result2.size()); Person bean = (Person) result2.get(0); verifyPersonWithZeroAge(bean); } public void testQueryWithSpaceInColumnName() throws SQLException { List result = jdbcTemplate3.query("select last_name as \"Last Name\", age, birth_date, balance from people", new BeanPropertyRowMapper(SpacePerson.class)); assertEquals(1, result.size()); SpacePerson bean = (SpacePerson) result.get(0); verifySpacePerson(bean); } } ././@LongLink0000000000000000000000000000020700000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/AbstractRowMapperTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000002355111623223530033326 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; import java.math.BigDecimal; import java.sql.Connection; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; import java.sql.Timestamp; import java.sql.Types; import junit.framework.TestCase; import org.easymock.MockControl; import org.apache.commons.logging.LogFactory; import org.springframework.jdbc.core.test.ConcretePerson; import org.springframework.jdbc.core.test.Person; import org.springframework.jdbc.core.test.SpacePerson; import org.springframework.jdbc.datasource.SingleConnectionDataSource; import org.springframework.jdbc.support.SQLStateSQLExceptionTranslator; /** * Mock object based abstract class for RowMapper tests. * Initializes mock objects and verifies results. * * @author Thomas Risberg */ public abstract class AbstractRowMapperTests extends TestCase { private final boolean debugEnabled = LogFactory.getLog(JdbcTemplate.class).isDebugEnabled(); protected MockControl conControl; protected Connection con; protected MockControl conControl2; protected Connection con2; protected MockControl conControl3; protected Connection con3; protected MockControl rsmdControl; protected ResultSetMetaData rsmd; protected MockControl rsControl; protected ResultSet rs; protected MockControl stmtControl; protected Statement stmt; protected JdbcTemplate jdbcTemplate; protected MockControl rsmdControl2; protected ResultSetMetaData rsmd2; protected MockControl rsControl2; protected ResultSet rs2; protected MockControl stmtControl2; protected Statement stmt2; protected JdbcTemplate jdbcTemplate2; protected MockControl rsmdControl3; protected ResultSetMetaData rsmd3; protected MockControl rsControl3; protected ResultSet rs3; protected MockControl stmtControl3; protected Statement stmt3; protected JdbcTemplate jdbcTemplate3; protected void setUp() throws SQLException { conControl = MockControl.createControl(Connection.class); con = (Connection) conControl.getMock(); con.isClosed(); conControl.setDefaultReturnValue(false); rsmdControl = MockControl.createControl(ResultSetMetaData.class); rsmd = (ResultSetMetaData)rsmdControl.getMock(); rsmd.getColumnCount(); rsmdControl.setReturnValue(4, 1); rsmd.getColumnLabel(1); rsmdControl.setReturnValue("name", 1); rsmd.getColumnLabel(2); rsmdControl.setReturnValue("age", 1); rsmd.getColumnLabel(3); rsmdControl.setReturnValue("birth_date", 1); rsmd.getColumnLabel(4); rsmdControl.setReturnValue("balance", 1); rsmdControl.replay(); rsControl = MockControl.createControl(ResultSet.class); rs = (ResultSet) rsControl.getMock(); rs.getMetaData(); rsControl.setReturnValue(rsmd, 1); rs.next(); rsControl.setReturnValue(true, 1); rs.getString(1); rsControl.setReturnValue("Bubba", 1); rs.wasNull(); rsControl.setReturnValue(false, 1); rs.getLong(2); rsControl.setReturnValue(22, 1); rs.getTimestamp(3); rsControl.setReturnValue(new Timestamp(1221222L), 1); rs.getBigDecimal(4); rsControl.setReturnValue(new BigDecimal("1234.56"), 1); rs.next(); rsControl.setReturnValue(false, 1); rs.close(); rsControl.setVoidCallable(1); rsControl.replay(); stmtControl = MockControl.createControl(Statement.class); stmt = (Statement) stmtControl.getMock(); con.createStatement(); conControl.setReturnValue(stmt, 1); stmt.executeQuery("select name, age, birth_date, balance from people"); stmtControl.setReturnValue(rs, 1); if (debugEnabled) { stmt.getWarnings(); stmtControl.setReturnValue(null, 1); } stmt.close(); stmtControl.setVoidCallable(1); conControl.replay(); stmtControl.replay(); conControl2 = MockControl.createControl(Connection.class); con2 = (Connection) conControl2.getMock(); con2.isClosed(); conControl2.setDefaultReturnValue(false); rsmdControl2 = MockControl.createControl(ResultSetMetaData.class); rsmd2 = (ResultSetMetaData)rsmdControl2.getMock(); rsmd2.getColumnCount(); rsmdControl2.setReturnValue(4, 2); rsmd2.getColumnLabel(1); rsmdControl2.setReturnValue("name", 2); rsmd2.getColumnLabel(2); rsmdControl2.setReturnValue("age", 2); rsmd2.getColumnLabel(3); rsmdControl2.setReturnValue("birth_date", 1); rsmd2.getColumnLabel(4); rsmdControl2.setReturnValue("balance", 1); rsmdControl2.replay(); rsControl2 = MockControl.createControl(ResultSet.class); rs2 = (ResultSet) rsControl2.getMock(); rs2.getMetaData(); rsControl2.setReturnValue(rsmd2, 2); rs2.next(); rsControl2.setReturnValue(true, 2); rs2.getString(1); rsControl2.setReturnValue("Bubba", 2); rs2.wasNull(); rsControl2.setReturnValue(true, 2); rs2.getLong(2); rsControl2.setReturnValue(0, 2); rs2.getTimestamp(3); rsControl2.setReturnValue(new Timestamp(1221222L), 1); rs2.getBigDecimal(4); rsControl2.setReturnValue(new BigDecimal("1234.56"), 1); rs2.next(); rsControl2.setReturnValue(false, 1); rs2.close(); rsControl2.setVoidCallable(2); rsControl2.replay(); stmtControl2 = MockControl.createControl(Statement.class); stmt2 = (Statement) stmtControl2.getMock(); con2.createStatement(); conControl2.setReturnValue(stmt2, 2); stmt2.executeQuery("select name, null as age, birth_date, balance from people"); stmtControl2.setReturnValue(rs2, 2); if (debugEnabled) { stmt2.getWarnings(); stmtControl2.setReturnValue(null, 2); } stmt2.close(); stmtControl2.setVoidCallable(2); conControl2.replay(); stmtControl2.replay(); conControl3 = MockControl.createControl(Connection.class); con3 = (Connection) conControl3.getMock(); con3.isClosed(); conControl3.setDefaultReturnValue(false); rsmdControl3 = MockControl.createControl(ResultSetMetaData.class); rsmd3 = (ResultSetMetaData)rsmdControl3.getMock(); rsmd3.getColumnCount(); rsmdControl3.setReturnValue(4, 1); rsmd3.getColumnLabel(1); rsmdControl3.setReturnValue("Last Name", 1); rsmd3.getColumnLabel(2); rsmdControl3.setReturnValue("age", 1); rsmd3.getColumnLabel(3); rsmdControl3.setReturnValue("birth_date", 1); rsmd3.getColumnLabel(4); rsmdControl3.setReturnValue("balance", 1); rsmdControl3.replay(); rsControl3 = MockControl.createControl(ResultSet.class); rs3 = (ResultSet) rsControl3.getMock(); rs3.getMetaData(); rsControl3.setReturnValue(rsmd3, 1); rs3.next(); rsControl3.setReturnValue(true, 1); rs3.getString(1); rsControl3.setReturnValue("Gagarin", 1); rs3.wasNull(); rsControl3.setReturnValue(false, 1); rs3.getLong(2); rsControl3.setReturnValue(22, 1); rs3.getTimestamp(3); rsControl3.setReturnValue(new Timestamp(1221222L), 1); rs3.getBigDecimal(4); rsControl3.setReturnValue(new BigDecimal("1234.56"), 1); rs3.next(); rsControl3.setReturnValue(false, 1); rs3.close(); rsControl3.setVoidCallable(1); rsControl3.replay(); stmtControl3 = MockControl.createControl(Statement.class); stmt3 = (Statement) stmtControl3.getMock(); con3.createStatement(); conControl3.setReturnValue(stmt3, 1); stmt3.executeQuery("select last_name as \"Last Name\", age, birth_date, balance from people"); stmtControl3.setReturnValue(rs3, 1); if (debugEnabled) { stmt3.getWarnings(); stmtControl3.setReturnValue(null, 1); } stmt3.close(); stmtControl3.setVoidCallable(1); conControl3.replay(); stmtControl3.replay(); jdbcTemplate = new JdbcTemplate(); jdbcTemplate.setDataSource(new SingleConnectionDataSource(con, false)); jdbcTemplate.setExceptionTranslator(new SQLStateSQLExceptionTranslator()); jdbcTemplate.afterPropertiesSet(); jdbcTemplate2 = new JdbcTemplate(); jdbcTemplate2.setDataSource(new SingleConnectionDataSource(con2, false)); jdbcTemplate2.setExceptionTranslator(new SQLStateSQLExceptionTranslator()); jdbcTemplate2.afterPropertiesSet(); jdbcTemplate3 = new JdbcTemplate(); jdbcTemplate3.setDataSource(new SingleConnectionDataSource(con3, false)); jdbcTemplate3.setExceptionTranslator(new SQLStateSQLExceptionTranslator()); jdbcTemplate3.afterPropertiesSet(); } protected void verifyPerson(Person bean) { verify(); assertEquals("Bubba", bean.getName()); assertEquals(22L, bean.getAge()); assertEquals(new java.util.Date(1221222L), bean.getBirth_date()); assertEquals(new BigDecimal("1234.56"), bean.getBalance()); } protected void verifyPersonWithZeroAge(Person bean) { conControl2.verify(); rsControl2.verify(); rsmdControl2.verify(); stmtControl2.verify(); assertEquals("Bubba", bean.getName()); assertEquals(0L, bean.getAge()); assertEquals(new java.util.Date(1221222L), bean.getBirth_date()); assertEquals(new BigDecimal("1234.56"), bean.getBalance()); } protected void verifyConcretePerson(ConcretePerson bean) { verify(); assertEquals("Bubba", bean.getName()); assertEquals(22L, bean.getAge()); assertEquals(new java.util.Date(1221222L), bean.getBirth_date()); assertEquals(new BigDecimal("1234.56"), bean.getBalance()); } protected void verifySpacePerson(SpacePerson bean) { conControl3.verify(); rsControl3.verify(); rsmdControl3.verify(); stmtControl3.verify(); assertEquals("Gagarin", bean.getLastName()); assertEquals(22L, bean.getAge()); assertEquals(new java.util.Date(1221222L), bean.getBirthDate()); assertEquals(new BigDecimal("1234.56"), bean.getBalance()); } private void verify() { conControl.verify(); rsControl.verify(); rsmdControl.verify(); stmtControl.verify(); } } ././@LongLink0000000000000000000000000000016400000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/support/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000755000175000017500000000000011623223530033316 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000021000000000000011556 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/support/LobSupportTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000001247411623223526033335 0ustar drazzibdrazzib/* * Copyright 2002-2005 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.support; import java.io.IOException; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import junit.framework.TestCase; import org.easymock.MockControl; import org.springframework.dao.DataAccessException; import org.springframework.dao.IncorrectResultSizeDataAccessException; import org.springframework.jdbc.LobRetrievalFailureException; import org.springframework.jdbc.support.lob.LobCreator; import org.springframework.jdbc.support.lob.LobHandler; /** * @author Alef Arendsen */ public class LobSupportTests extends TestCase { public void testCreatingPreparedStatementCallback() throws SQLException { // - return value should match // - lob creator should be closed // - set return value should be called // - execute update should be called MockControl lobHandlerControl = MockControl.createControl(LobHandler.class); LobHandler handler = (LobHandler)lobHandlerControl.getMock(); MockControl lobCreatorControl = MockControl.createControl(LobCreator.class); LobCreator creator = (LobCreator)lobCreatorControl.getMock(); MockControl psControl = MockControl.createControl(PreparedStatement.class); PreparedStatement ps = (PreparedStatement)psControl.getMock(); handler.getLobCreator(); lobHandlerControl.setReturnValue(creator); ps.executeUpdate(); psControl.setReturnValue(3); creator.close(); lobHandlerControl.replay(); lobCreatorControl.replay(); psControl.replay(); class SetValuesCalled { boolean b = false; } final SetValuesCalled svc = new SetValuesCalled(); AbstractLobCreatingPreparedStatementCallback psc = new AbstractLobCreatingPreparedStatementCallback(handler) { protected void setValues(PreparedStatement ps, LobCreator lobCreator) throws SQLException, DataAccessException { svc.b = true; } }; assertEquals(new Integer(3), psc.doInPreparedStatement(ps)); lobHandlerControl.verify(); lobCreatorControl.verify(); psControl.verify(); assertTrue(svc.b); } public void testAbstractLobStreamingResultSetExtractorNoRows() throws SQLException { MockControl rsetControl = MockControl.createControl(ResultSet.class); ResultSet rset = (ResultSet)rsetControl.getMock(); rset.next(); rsetControl.setReturnValue(false); rsetControl.replay(); AbstractLobStreamingResultSetExtractor lobRse = getResultSetExtractor(false); try { lobRse.extractData(rset); fail("IncorrectResultSizeDataAccessException should have been thrown"); } catch (IncorrectResultSizeDataAccessException e) { // expected } } public void testAbstractLobStreamingResultSetExtractorOneRow() throws SQLException { MockControl rsetControl = MockControl.createControl(ResultSet.class); ResultSet rset = (ResultSet)rsetControl.getMock(); rset.next(); rsetControl.setReturnValue(true); // see if it's called rset.clearWarnings(); rset.next(); rsetControl.setReturnValue(false); rsetControl.replay(); AbstractLobStreamingResultSetExtractor lobRse = getResultSetExtractor(false); lobRse.extractData(rset); rsetControl.verify(); } public void testAbstractLobStreamingResultSetExtractorMultipleRows() throws SQLException { MockControl rsetControl = MockControl.createControl(ResultSet.class); ResultSet rset = (ResultSet)rsetControl.getMock(); rset.next(); rsetControl.setReturnValue(true); // see if it's called rset.clearWarnings(); rset.next(); rsetControl.setReturnValue(true); rsetControl.replay(); AbstractLobStreamingResultSetExtractor lobRse = getResultSetExtractor(false); try { lobRse.extractData(rset); fail("IncorrectResultSizeDataAccessException should have been thrown"); } catch (IncorrectResultSizeDataAccessException e) { // expected } rsetControl.verify(); } public void testAbstractLobStreamingResultSetExtractorCorrectException() throws SQLException { MockControl rsetControl = MockControl.createControl(ResultSet.class); ResultSet rset = (ResultSet)rsetControl.getMock(); rset.next(); rsetControl.setReturnValue(true); rsetControl.replay(); AbstractLobStreamingResultSetExtractor lobRse = getResultSetExtractor(true); try { lobRse.extractData(rset); fail("LobRetrievalFailureException should have been thrown"); } catch (LobRetrievalFailureException e) { // expected } rsetControl.verify(); } private AbstractLobStreamingResultSetExtractor getResultSetExtractor(final boolean ex) { AbstractLobStreamingResultSetExtractor lobRse = new AbstractLobStreamingResultSetExtractor() { protected void streamData(ResultSet rs) throws SQLException, IOException { if (ex) { throw new IOException(); } else { rs.clearWarnings(); } } }; return lobRse; } } ././@LongLink0000000000000000000000000000021400000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/support/JdbcDaoSupportTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000000374511623223530033331 0ustar drazzibdrazzib/* * Copyright 2002-2005 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.support; import java.util.ArrayList; import java.util.List; import javax.sql.DataSource; import junit.framework.TestCase; import org.easymock.MockControl; import org.springframework.jdbc.core.JdbcTemplate; /** * @author Juergen Hoeller * @since 30.07.2003 */ public class JdbcDaoSupportTests extends TestCase { public void testJdbcDaoSupportWithDataSource() throws Exception { MockControl dsControl = MockControl.createControl(DataSource.class); DataSource ds = (DataSource) dsControl.getMock(); final List test = new ArrayList(); JdbcDaoSupport dao = new JdbcDaoSupport() { protected void initDao() { test.add("test"); } }; dao.setDataSource(ds); dao.afterPropertiesSet(); assertEquals("Correct DataSource", ds, dao.getDataSource()); assertEquals("Correct JdbcTemplate", ds, dao.getJdbcTemplate().getDataSource()); assertEquals("initDao called", test.size(), 1); } public void testJdbcDaoSupportWithJdbcTemplate() throws Exception { JdbcTemplate template = new JdbcTemplate(); final List test = new ArrayList(); JdbcDaoSupport dao = new JdbcDaoSupport() { protected void initDao() { test.add("test"); } }; dao.setJdbcTemplate(template); dao.afterPropertiesSet(); assertEquals("Correct JdbcTemplate", dao.getJdbcTemplate(), template); assertEquals("initDao called", test.size(), 1); } } ././@LongLink0000000000000000000000000000022600000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/support/JdbcBeanDefinitionReaderTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000000612011623223526033324 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.support; import java.sql.ResultSet; import java.sql.Statement; import org.easymock.MockControl; import org.apache.commons.logging.LogFactory; import org.springframework.beans.TestBean; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.jdbc.AbstractJdbcTests; import org.springframework.jdbc.core.JdbcTemplate; /** * @author Rod Johnson */ public class JdbcBeanDefinitionReaderTests extends AbstractJdbcTests { private final boolean debugEnabled = LogFactory.getLog(JdbcTemplate.class).isDebugEnabled(); public void testValid() throws Exception { String sql = "SELECT NAME AS NAME, PROPERTY AS PROPERTY, VALUE AS VALUE FROM T"; MockControl ctrlResultSet = MockControl.createControl(ResultSet.class); ResultSet mockResultSet = (ResultSet) ctrlResultSet.getMock(); ctrlResultSet.expectAndReturn(mockResultSet.next(), true, 2); ctrlResultSet.expectAndReturn(mockResultSet.next(), false); // first row ctrlResultSet.expectAndReturn(mockResultSet.getString(1), "one"); ctrlResultSet.expectAndReturn(mockResultSet.getString(2), "(class)"); ctrlResultSet.expectAndReturn(mockResultSet.getString(3), "org.springframework.beans.TestBean"); // second row ctrlResultSet.expectAndReturn(mockResultSet.getString(1), "one"); ctrlResultSet.expectAndReturn(mockResultSet.getString(2), "age"); ctrlResultSet.expectAndReturn(mockResultSet.getString(3), "53"); mockResultSet.close(); ctrlResultSet.setVoidCallable(); MockControl ctrlStatement = MockControl.createControl(Statement.class); Statement mockStatement = (Statement) ctrlStatement.getMock(); ctrlStatement.expectAndReturn(mockStatement.executeQuery(sql), mockResultSet); if (debugEnabled) { ctrlStatement.expectAndReturn(mockStatement.getWarnings(), null); } mockStatement.close(); ctrlStatement.setVoidCallable(); mockConnection.createStatement(); ctrlConnection.setReturnValue(mockStatement); ctrlResultSet.replay(); ctrlStatement.replay(); replay(); DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); JdbcBeanDefinitionReader reader = new JdbcBeanDefinitionReader(bf); reader.setDataSource(mockDataSource); reader.loadBeanDefinitions(sql); assertEquals("Incorrect number of bean definitions", 1, bf.getBeanDefinitionCount()); TestBean tb = (TestBean) bf.getBean("one"); assertEquals("Age in TestBean was wrong.", 53, tb.getAge()); ctrlResultSet.verify(); ctrlStatement.verify(); } } ././@LongLink0000000000000000000000000000021100000000000011557 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/support/SqlLobValueTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000001705711623223530033332 0ustar drazzibdrazzib/* * Copyright 2002-2005 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.support; import java.io.ByteArrayInputStream; import java.io.InputStreamReader; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Types; import java.util.Arrays; import java.util.Date; import junit.framework.TestCase; import org.easymock.ArgumentsMatcher; import org.easymock.MockControl; import org.springframework.jdbc.support.lob.LobCreator; import org.springframework.jdbc.support.lob.LobHandler; /** * Test cases for the sql lob value: * * BLOB: * 1. Types.BLOB: setBlobAsBytes (byte[]) * 2. String: setBlobAsBytes (byte[]) * 3. else: IllegalArgumentException * * CLOB: * 4. String or NULL: setClobAsString (String) * 5. InputStream: setClobAsAsciiStream (InputStream) * 6. Reader: setClobAsCharacterStream (Reader) * 7. else: IllegalArgumentException * * @author Alef Arendsen */ public class SqlLobValueTests extends TestCase { private MockControl psControl; private PreparedStatement ps; private MockControl lobHandlerControl; private LobHandler handler; private MockControl lobCreatorControl; private LobCreator creator; public void setUp() { // create preparedstatement psControl = MockControl.createControl(PreparedStatement.class); ps = (PreparedStatement) psControl.getMock(); // create handler controler lobHandlerControl = MockControl.createControl(LobHandler.class); handler = (LobHandler) lobHandlerControl.getMock(); // create creator control lobCreatorControl = MockControl.createControl(LobCreator.class); creator = (LobCreator) lobCreatorControl.getMock(); // set initial state handler.getLobCreator(); lobHandlerControl.setReturnValue(creator); } private void replay() { psControl.replay(); lobHandlerControl.replay(); lobCreatorControl.replay(); } public void test1() throws SQLException { byte[] testBytes = "Bla".getBytes(); creator.setBlobAsBytes(ps, 1, testBytes); replay(); SqlLobValue lob = new SqlLobValue(testBytes, handler); lob.setTypeValue(ps, 1, Types.BLOB, "test"); lobHandlerControl.verify(); lobCreatorControl.verify(); } public void test2() throws SQLException { String testString = "Bla"; creator.setBlobAsBytes(ps, 1, testString.getBytes()); // set a matcher to match the byte array! lobCreatorControl.setMatcher(new ArgumentsMatcher() { public boolean matches(Object[] arg0, Object[] arg1) { byte[] one = (byte[]) arg0[2]; byte[] two = (byte[]) arg1[2]; return Arrays.equals(one, two); } public String toString(Object[] arg0) { return "bla"; } }); replay(); SqlLobValue lob = new SqlLobValue(testString, handler); lob.setTypeValue(ps, 1, Types.BLOB, "test"); lobHandlerControl.verify(); lobCreatorControl.verify(); } public void test3() throws SQLException { Date testContent = new Date(); SqlLobValue lob = new SqlLobValue(new InputStreamReader(new ByteArrayInputStream("Bla".getBytes())), 12); try { lob.setTypeValue(ps, 1, Types.BLOB, "test"); fail("IllegalArgumentException should have been thrown"); } catch (IllegalArgumentException e) { // expected } } public void test4() throws SQLException { String testContent = "Bla"; creator.setClobAsString(ps, 1, testContent); replay(); SqlLobValue lob = new SqlLobValue(testContent, handler); lob.setTypeValue(ps, 1, Types.CLOB, "test"); lobHandlerControl.verify(); lobCreatorControl.verify(); } public void test5() throws SQLException { byte[] testContent = "Bla".getBytes(); ByteArrayInputStream bais = new ByteArrayInputStream(testContent); creator.setClobAsAsciiStream(ps, 1, bais, 3); lobCreatorControl.setMatcher(new ArgumentsMatcher() { public boolean matches(Object[] arg0, Object[] arg1) { // for now, match always return true; } public String toString(Object[] arg0) { return null; } }); replay(); SqlLobValue lob = new SqlLobValue(new ByteArrayInputStream(testContent), 3, handler); lob.setTypeValue(ps, 1, Types.CLOB, "test"); lobHandlerControl.verify(); lobCreatorControl.verify(); } public void test6()throws SQLException { byte[] testContent = "Bla".getBytes(); ByteArrayInputStream bais = new ByteArrayInputStream(testContent); InputStreamReader reader = new InputStreamReader(bais); creator.setClobAsCharacterStream(ps, 1, reader, 3); lobCreatorControl.setMatcher(new ArgumentsMatcher() { public boolean matches(Object[] arg0, Object[] arg1) { // for now, match always return true; } public String toString(Object[] arg0) { return null; } }); replay(); SqlLobValue lob = new SqlLobValue(reader, 3, handler); lob.setTypeValue(ps, 1, Types.CLOB, "test"); lobHandlerControl.verify(); lobCreatorControl.verify(); } public void test7() throws SQLException { Date testContent = new Date(); SqlLobValue lob = new SqlLobValue("bla".getBytes()); try { lob.setTypeValue(ps, 1, Types.CLOB, "test"); fail("IllegalArgumentException should have been thrown"); } catch (IllegalArgumentException e) { // expected } } public void testOtherConstructors() throws SQLException { // a bit BS, but we need to test them, as long as they don't throw exceptions SqlLobValue lob = new SqlLobValue("bla"); lob.setTypeValue(ps, 1, Types.CLOB, "test"); try { lob = new SqlLobValue("bla".getBytes()); lob.setTypeValue(ps, 1, Types.CLOB, "test"); fail("IllegalArgumentException should have been thrown"); } catch (IllegalArgumentException e) { // expected } lob = new SqlLobValue(new ByteArrayInputStream("bla".getBytes()), 3); lob.setTypeValue(ps, 1, Types.CLOB, "test"); lob = new SqlLobValue(new InputStreamReader( new ByteArrayInputStream("bla".getBytes())), 3); lob.setTypeValue(ps, 1, Types.CLOB, "test"); // same for BLOB lob = new SqlLobValue("bla"); lob.setTypeValue(ps, 1, Types.BLOB, "test"); lob = new SqlLobValue("bla".getBytes()); lob.setTypeValue(ps, 1, Types.BLOB, "test"); lob = new SqlLobValue(new ByteArrayInputStream("bla".getBytes()), 3); lob.setTypeValue(ps, 1, Types.BLOB, "test"); lob = new SqlLobValue(new InputStreamReader( new ByteArrayInputStream("bla".getBytes())), 3); try { lob.setTypeValue(ps, 1, Types.BLOB, "test"); fail("IllegalArgumentException should have been thrown"); } catch (IllegalArgumentException e) { // expected } } public void testCorrectCleanup() throws SQLException { creator.setClobAsString(ps, 1, "Bla"); creator.close(); replay(); SqlLobValue lob = new SqlLobValue("Bla", handler); lob.setTypeValue(ps, 1, Types.CLOB, "test"); lob.cleanup(); lobCreatorControl.verify(); } public void testOtherSqlType() throws SQLException { replay(); SqlLobValue lob = new SqlLobValue("Bla", handler); try { lob.setTypeValue(ps, 1, Types.SMALLINT, "test"); fail("IllegalArgumentException should have been thrown"); } catch (IllegalArgumentException e) { // expected } } } ././@LongLink0000000000000000000000000000020200000000000011557 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/JdbcTemplateTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000021173411623223530033330 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.SQLWarning; import java.sql.Statement; import java.sql.Types; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.Map; import javax.sql.DataSource; import org.apache.commons.logging.LogFactory; import org.easymock.MockControl; import org.springframework.dao.DataAccessException; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.dao.UncategorizedDataAccessException; import org.springframework.jdbc.AbstractJdbcTests; import org.springframework.jdbc.BadSqlGrammarException; import org.springframework.jdbc.CannotGetJdbcConnectionException; import org.springframework.jdbc.SQLWarningException; import org.springframework.jdbc.UncategorizedSQLException; import org.springframework.jdbc.core.support.AbstractInterruptibleBatchPreparedStatementSetter; import org.springframework.jdbc.datasource.SingleConnectionDataSource; import org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator; import org.springframework.jdbc.support.SQLStateSQLExceptionTranslator; import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor; import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractorAdapter; import org.springframework.util.LinkedCaseInsensitiveMap; /** * Mock object based tests for JdbcTemplate. * * @author Rod Johnson * @author Thomas Risberg * @author Juergen Hoeller */ public class JdbcTemplateTests extends AbstractJdbcTests { private final boolean debugEnabled = LogFactory.getLog(JdbcTemplate.class).isDebugEnabled(); public void testBeanProperties() throws Exception { replay(); JdbcTemplate template = new JdbcTemplate(mockDataSource); assertTrue("datasource ok", template.getDataSource() == mockDataSource); assertTrue("ignores warnings by default", template.isIgnoreWarnings()); template.setIgnoreWarnings(false); assertTrue("can set NOT to ignore warnings", !template.isIgnoreWarnings()); } public void testUpdateCount() throws Exception { final String sql = "UPDATE INVOICE SET DATE_DISPATCHED = SYSDATE WHERE ID = ?"; int idParam = 11111; MockControl ctrlPreparedStatement = MockControl.createControl(PreparedStatement.class); PreparedStatement mockPreparedStatement = (PreparedStatement) ctrlPreparedStatement.getMock(); mockPreparedStatement.setInt(1, idParam); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeUpdate(); ctrlPreparedStatement.setReturnValue(1); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(sql); ctrlConnection.setReturnValue(mockPreparedStatement); ctrlPreparedStatement.replay(); replay(); Dispatcher d = new Dispatcher(idParam, sql); JdbcTemplate template = new JdbcTemplate(mockDataSource); int rowsAffected = template.update(d); assertTrue("1 update affected 1 row", rowsAffected == 1); /* d = new Dispatcher(idParam); rowsAffected = template.update(d); assertTrue("bogus update affected 0 rows", rowsAffected == 0); */ ctrlPreparedStatement.verify(); } public void testBogusUpdate() throws Exception { final String sql = "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = ?"; final int idParam = 6666; // It's because Integers aren't canonical SQLException sex = new SQLException("bad update"); MockControl ctrlPreparedStatement = MockControl.createControl(PreparedStatement.class); PreparedStatement mockPreparedStatement = (PreparedStatement) ctrlPreparedStatement.getMock(); mockPreparedStatement.setInt(1, idParam); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeUpdate(); ctrlPreparedStatement.setThrowable(sex); mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(sql); ctrlConnection.setReturnValue(mockPreparedStatement); ctrlPreparedStatement.replay(); replay(); Dispatcher d = new Dispatcher(idParam, sql); JdbcTemplate template = new JdbcTemplate(mockDataSource); try { template.update(d); fail("Bogus update should throw exception"); } catch (UncategorizedDataAccessException ex) { // pass assertTrue( "Correct exception", ex instanceof UncategorizedSQLException); assertTrue("Root cause is correct", ex.getCause() == sex); //assertTrue("no update occurred", !je.getDataWasUpdated()); } ctrlPreparedStatement.verify(); } public void testStringsWithStaticSql() throws Exception { doTestStrings(new JdbcTemplateCallback() { public void doInJdbcTemplate(JdbcTemplate template, String sql, RowCallbackHandler rch) { template.query(sql, rch); } }, false, null, null, null, null); } public void testStringsWithStaticSqlAndFetchSizeAndMaxRows() throws Exception { doTestStrings(new JdbcTemplateCallback() { public void doInJdbcTemplate(JdbcTemplate template, String sql, RowCallbackHandler rch) { template.query(sql, rch); } }, false, new Integer(10), new Integer(20), new Integer(30), null); } public void testStringsWithEmptyPreparedStatementSetter() throws Exception { doTestStrings(new JdbcTemplateCallback() { public void doInJdbcTemplate(JdbcTemplate template, String sql, RowCallbackHandler rch) { template.query(sql, (PreparedStatementSetter) null, rch); } }, true, null, null, null, null); } public void testStringsWithPreparedStatementSetter() throws Exception { final Integer argument = new Integer(99); doTestStrings(new JdbcTemplateCallback() { public void doInJdbcTemplate(JdbcTemplate template, String sql, RowCallbackHandler rch) { template.query(sql, new PreparedStatementSetter() { public void setValues(PreparedStatement ps) throws SQLException { ps.setObject(1, argument); } }, rch); } }, true, null, null, null, argument); } public void testStringsWithEmptyPreparedStatementArgs() throws Exception { doTestStrings(new JdbcTemplateCallback() { public void doInJdbcTemplate(JdbcTemplate template, String sql, RowCallbackHandler rch) { template.query(sql, (Object[]) null, rch); } }, true, null, null, null, null); } public void testStringsWithPreparedStatementArgs() throws Exception { final Integer argument = new Integer(99); doTestStrings(new JdbcTemplateCallback() { public void doInJdbcTemplate(JdbcTemplate template, String sql, RowCallbackHandler rch) { template.query(sql, new Object[] {argument}, rch); } }, true, null, null, null, argument); } private void doTestStrings( JdbcTemplateCallback jdbcTemplateCallback, boolean usePreparedStatement, Integer fetchSize, Integer maxRows, Integer queryTimeout, Object argument) throws Exception { String sql = "SELECT FORENAME FROM CUSTMR"; String[] results = { "rod", "gary", " portia" }; class StringHandler implements RowCallbackHandler { private List list = new LinkedList(); public void processRow(ResultSet rs) throws SQLException { list.add(rs.getString(1)); } public String[] getStrings() { return (String[]) list.toArray(new String[list.size()]); } } MockControl ctrlResultSet = MockControl.createControl(ResultSet.class); ResultSet mockResultSet = (ResultSet) ctrlResultSet.getMock(); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getString(1); ctrlResultSet.setReturnValue(results[0]); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getString(1); ctrlResultSet.setReturnValue(results[1]); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getString(1); ctrlResultSet.setReturnValue(results[2]); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); MockControl ctrlStatement = MockControl.createControl(PreparedStatement.class); PreparedStatement mockStatement = (PreparedStatement) ctrlStatement.getMock(); if (fetchSize != null) { mockStatement.setFetchSize(fetchSize.intValue()); } if (maxRows != null) { mockStatement.setMaxRows(maxRows.intValue()); } if (queryTimeout != null) { mockStatement.setQueryTimeout(queryTimeout.intValue()); } if (argument != null) { mockStatement.setObject(1, argument); } if (usePreparedStatement) { mockStatement.executeQuery(); } else { mockStatement.executeQuery(sql); } ctrlStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockStatement.getWarnings(); ctrlStatement.setReturnValue(null); } mockStatement.close(); ctrlStatement.setVoidCallable(); if (usePreparedStatement) { mockConnection.prepareStatement(sql); } else { mockConnection.createStatement(); } ctrlConnection.setReturnValue(mockStatement); ctrlResultSet.replay(); ctrlStatement.replay(); replay(); StringHandler sh = new StringHandler(); JdbcTemplate template = new JdbcTemplate(); template.setDataSource(mockDataSource); if (fetchSize != null) { template.setFetchSize(fetchSize.intValue()); } if (maxRows != null) { template.setMaxRows(maxRows.intValue()); } if (queryTimeout != null) { template.setQueryTimeout(queryTimeout.intValue()); } jdbcTemplateCallback.doInJdbcTemplate(template, sql, sh); // Match String[] forenames = sh.getStrings(); assertTrue("same length", forenames.length == results.length); for (int i = 0; i < forenames.length; i++) { assertTrue("Row " + i + " matches", forenames[i].equals(results[i])); } ctrlResultSet.verify(); ctrlStatement.verify(); } public void testLeaveConnectionOpenOnRequest() throws Exception { String sql = "SELECT ID, FORENAME FROM CUSTMR WHERE ID < 3"; MockControl ctrlResultSet = MockControl.createControl(ResultSet.class); ResultSet mockResultSet = (ResultSet) ctrlResultSet.getMock(); ctrlResultSet = MockControl.createControl(ResultSet.class); mockResultSet = (ResultSet) ctrlResultSet.getMock(); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); MockControl ctrlStatement = MockControl.createControl(PreparedStatement.class); PreparedStatement mockStatement = (PreparedStatement) ctrlStatement.getMock(); ctrlStatement = MockControl.createControl(PreparedStatement.class); mockStatement = (PreparedStatement) ctrlStatement.getMock(); mockStatement.executeQuery(sql); ctrlStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockStatement.getWarnings(); ctrlStatement.setReturnValue(null); } mockStatement.close(); ctrlStatement.setVoidCallable(); mockConnection.isClosed(); ctrlConnection.setReturnValue(false, 2); mockConnection.createStatement(); ctrlConnection.setReturnValue(mockStatement); // if close is called entire test will fail mockConnection.close(); ctrlConnection.setDefaultThrowable(new RuntimeException()); ctrlResultSet.replay(); ctrlStatement.replay(); replay(); SingleConnectionDataSource scf = new SingleConnectionDataSource(mockDataSource.getConnection(), false); JdbcTemplate template2 = new JdbcTemplate(scf, false); RowCountCallbackHandler rcch = new RowCountCallbackHandler(); template2.query(sql, rcch); ctrlResultSet.verify(); ctrlStatement.verify(); } public void testConnectionCallback() throws Exception { replay(); JdbcTemplate template = new JdbcTemplate(mockDataSource); template.setNativeJdbcExtractor(new PlainNativeJdbcExtractor()); Object result = template.execute(new ConnectionCallback() { public Object doInConnection(Connection con) { assertSame(mockConnection, con); return "test"; } }); assertEquals("test", result); } public void testConnectionCallbackWithStatementSettings() throws Exception { MockControl ctrlStatement = MockControl.createControl(PreparedStatement.class); PreparedStatement mockStatement = (PreparedStatement) ctrlStatement.getMock(); mockConnection.prepareStatement("some SQL"); ctrlConnection.setReturnValue(mockStatement, 1); mockStatement.setFetchSize(10); ctrlStatement.setVoidCallable(1); mockStatement.setMaxRows(20); ctrlStatement.setVoidCallable(1); mockStatement.close(); ctrlStatement.setVoidCallable(1); replay(); JdbcTemplate template = new JdbcTemplate(mockDataSource); Object result = template.execute(new ConnectionCallback() { public Object doInConnection(Connection con) throws SQLException { PreparedStatement ps = con.prepareStatement("some SQL"); ps.close(); assertSame(mockConnection, new PlainNativeJdbcExtractor().getNativeConnection(con)); return "test"; } }); assertEquals("test", result); } public void testCloseConnectionOnRequest() throws Exception { String sql = "SELECT ID, FORENAME FROM CUSTMR WHERE ID < 3"; MockControl ctrlResultSet = MockControl.createControl(ResultSet.class); ResultSet mockResultSet = (ResultSet) ctrlResultSet.getMock(); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); MockControl ctrlStatement = MockControl.createControl(PreparedStatement.class); PreparedStatement mockStatement = (PreparedStatement) ctrlStatement.getMock(); mockStatement.executeQuery(sql); ctrlStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockStatement.getWarnings(); ctrlStatement.setReturnValue(null); } mockStatement.close(); ctrlStatement.setVoidCallable(); mockConnection.createStatement(); ctrlConnection.setReturnValue(mockStatement); ctrlResultSet.replay(); ctrlStatement.replay(); replay(); JdbcTemplate template = new JdbcTemplate(mockDataSource); RowCountCallbackHandler rcch = new RowCountCallbackHandler(); template.query(sql, rcch); ctrlResultSet.verify(); ctrlStatement.verify(); } /** * Test that we see a runtime exception come back. */ public void testExceptionComesBack() throws Exception { final String sql = "SELECT ID FROM CUSTMR"; final RuntimeException rex = new RuntimeException("What I want to see"); MockControl ctrlResultSet = MockControl.createControl(ResultSet.class); ResultSet mockResultSet = (ResultSet) ctrlResultSet.getMock(); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.close(); ctrlResultSet.setVoidCallable(); MockControl ctrlStatement = MockControl.createControl(PreparedStatement.class); PreparedStatement mockStatement = (PreparedStatement) ctrlStatement.getMock(); mockStatement.executeQuery(sql); ctrlStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockStatement.getWarnings(); ctrlStatement.setReturnValue(null); } mockStatement.close(); ctrlStatement.setVoidCallable(); mockConnection.createStatement(); ctrlConnection.setReturnValue(mockStatement); ctrlResultSet.replay(); ctrlStatement.replay(); replay(); JdbcTemplate template = new JdbcTemplate(mockDataSource); try { template.query(sql, new RowCallbackHandler() { public void processRow(ResultSet rs) { throw rex; } }); fail("Should have thrown exception"); } catch (RuntimeException ex) { assertTrue("Wanted same exception back, not " + ex, ex == rex); } } /** * Test update with static SQL. */ public void testSqlUpdate() throws Exception { final String sql = "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = 4"; int rowsAffected = 33; MockControl ctrlStatement = MockControl.createControl(Statement.class); Statement mockStatement = (Statement) ctrlStatement.getMock(); mockStatement.executeUpdate(sql); ctrlStatement.setReturnValue(rowsAffected); if (debugEnabled) { mockStatement.getWarnings(); ctrlStatement.setReturnValue(null); } mockStatement.close(); ctrlStatement.setVoidCallable(); mockConnection.createStatement(); ctrlConnection.setReturnValue(mockStatement); ctrlStatement.replay(); replay(); JdbcTemplate template = new JdbcTemplate(mockDataSource); int actualRowsAffected = template.update(sql); assertTrue("Actual rows affected is correct", actualRowsAffected == rowsAffected); ctrlStatement.verify(); } /** * Test update with dynamic SQL. */ public void testSqlUpdateWithArguments() throws Exception { final String sql = "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = ? and PR = ?"; int rowsAffected = 33; MockControl ctrlStatement = MockControl.createControl(PreparedStatement.class); PreparedStatement mockStatement = (PreparedStatement) ctrlStatement.getMock(); mockStatement.setObject(1, new Integer(4)); ctrlStatement.setVoidCallable(); mockStatement.setObject(2, new Float(1.4142), Types.NUMERIC, 2); ctrlStatement.setVoidCallable(); mockStatement.executeUpdate(); ctrlStatement.setReturnValue(33); if (debugEnabled) { mockStatement.getWarnings(); ctrlStatement.setReturnValue(null); } mockStatement.close(); ctrlStatement.setVoidCallable(); mockConnection.prepareStatement(sql); ctrlConnection.setReturnValue(mockStatement); ctrlStatement.replay(); replay(); JdbcTemplate template = new JdbcTemplate(mockDataSource); int actualRowsAffected = template.update(sql, new Object[] {new Integer(4), new SqlParameterValue(Types.NUMERIC, 2, new Float(1.4142))}); assertTrue("Actual rows affected is correct", actualRowsAffected == rowsAffected); ctrlStatement.verify(); } public void testSqlUpdateEncountersSqlException() throws Exception { SQLException sex = new SQLException("bad update"); final String sql = "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = 4"; MockControl ctrlStatement = MockControl.createControl(Statement.class); Statement mockStatement = (Statement) ctrlStatement.getMock(); mockStatement.executeUpdate(sql); ctrlStatement.setThrowable(sex); mockStatement.close(); ctrlStatement.setVoidCallable(); mockConnection.createStatement(); ctrlConnection.setReturnValue(mockStatement); ctrlStatement.replay(); replay(); JdbcTemplate template = new JdbcTemplate(mockDataSource); try { template.update(sql); } catch (DataAccessException ex) { assertTrue("root cause is correct", ex.getCause() == sex); } ctrlStatement.verify(); } public void testSqlUpdateWithThreadConnection() throws Exception { final String sql = "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = 4"; int rowsAffected = 33; MockControl ctrlStatement = MockControl.createControl(Statement.class); Statement mockStatement = (Statement) ctrlStatement.getMock(); mockStatement.executeUpdate(sql); ctrlStatement.setReturnValue(rowsAffected); if (debugEnabled) { mockStatement.getWarnings(); ctrlStatement.setReturnValue(null); } mockStatement.close(); ctrlStatement.setVoidCallable(); mockConnection.createStatement(); ctrlConnection.setReturnValue(mockStatement); ctrlStatement.replay(); replay(); JdbcTemplate template = new JdbcTemplate(mockDataSource); int actualRowsAffected = template.update(sql); assertTrue( "Actual rows affected is correct", actualRowsAffected == rowsAffected); ctrlStatement.verify(); } public void testBatchUpdate() throws Exception { final String[] sql = {"UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = 1", "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = 2"}; MockControl ctrlStatement = MockControl.createControl(Statement.class); Statement mockStatement = (Statement) ctrlStatement.getMock(); mockStatement.getConnection(); ctrlStatement.setReturnValue(mockConnection); mockStatement.addBatch(sql[0]); ctrlStatement.setVoidCallable(); mockStatement.addBatch(sql[1]); ctrlStatement.setVoidCallable(); mockStatement.executeBatch(); ctrlStatement.setReturnValue(new int[] {1, 1}); if (debugEnabled) { mockStatement.getWarnings(); ctrlStatement.setReturnValue(null); } mockStatement.close(); ctrlStatement.setVoidCallable(); MockControl ctrlDatabaseMetaData = MockControl.createControl(DatabaseMetaData.class); DatabaseMetaData mockDatabaseMetaData = (DatabaseMetaData) ctrlDatabaseMetaData.getMock(); mockDatabaseMetaData.getDatabaseProductName(); ctrlDatabaseMetaData.setReturnValue("MySQL"); mockDatabaseMetaData.supportsBatchUpdates(); ctrlDatabaseMetaData.setReturnValue(true); mockConnection.getMetaData(); ctrlConnection.setReturnValue(mockDatabaseMetaData, 2); mockConnection.createStatement(); ctrlConnection.setReturnValue(mockStatement); ctrlStatement.replay(); ctrlDatabaseMetaData.replay(); replay(); JdbcTemplate template = new JdbcTemplate(mockDataSource, false); int[] actualRowsAffected = template.batchUpdate(sql); assertTrue("executed 2 updates", actualRowsAffected.length == 2); ctrlStatement.verify(); ctrlDatabaseMetaData.verify(); } public void testBatchUpdateWithNoBatchSupport() throws Exception { final String[] sql = {"UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = 1", "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = 2"}; MockControl ctrlStatement = MockControl.createControl(Statement.class); Statement mockStatement = (Statement) ctrlStatement.getMock(); mockStatement.getConnection(); ctrlStatement.setReturnValue(mockConnection); mockStatement.execute(sql[0]); ctrlStatement.setReturnValue(false); mockStatement.getUpdateCount(); ctrlStatement.setReturnValue(1); mockStatement.execute(sql[1]); ctrlStatement.setReturnValue(false); mockStatement.getUpdateCount(); ctrlStatement.setReturnValue(1); if (debugEnabled) { mockStatement.getWarnings(); ctrlStatement.setReturnValue(null); } mockStatement.close(); ctrlStatement.setVoidCallable(); MockControl ctrlDatabaseMetaData = MockControl.createControl(DatabaseMetaData.class); DatabaseMetaData mockDatabaseMetaData = (DatabaseMetaData) ctrlDatabaseMetaData.getMock(); mockDatabaseMetaData.getDatabaseProductName(); ctrlDatabaseMetaData.setReturnValue("MySQL"); mockDatabaseMetaData.supportsBatchUpdates(); ctrlDatabaseMetaData.setReturnValue(false); mockConnection.getMetaData(); ctrlConnection.setReturnValue(mockDatabaseMetaData, 2); mockConnection.createStatement(); ctrlConnection.setReturnValue(mockStatement); ctrlStatement.replay(); ctrlDatabaseMetaData.replay(); replay(); JdbcTemplate template = new JdbcTemplate(mockDataSource, false); int[] actualRowsAffected = template.batchUpdate(sql); assertTrue("executed 2 updates", actualRowsAffected.length == 2); ctrlStatement.verify(); ctrlDatabaseMetaData.verify(); } public void testBatchUpdateWithNoBatchSupportAndSelect() throws Exception { final String[] sql = {"UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = 1", "SELECT * FROM NOSUCHTABLE"}; MockControl ctrlStatement = MockControl.createControl(Statement.class); Statement mockStatement = (Statement) ctrlStatement.getMock(); mockStatement.getConnection(); ctrlStatement.setReturnValue(mockConnection); mockStatement.execute(sql[0]); ctrlStatement.setReturnValue(false); mockStatement.getUpdateCount(); ctrlStatement.setReturnValue(1); mockStatement.execute(sql[1]); ctrlStatement.setReturnValue(true); mockStatement.close(); ctrlStatement.setVoidCallable(); MockControl ctrlDatabaseMetaData = MockControl.createControl(DatabaseMetaData.class); DatabaseMetaData mockDatabaseMetaData = (DatabaseMetaData) ctrlDatabaseMetaData.getMock(); mockDatabaseMetaData.getDatabaseProductName(); ctrlDatabaseMetaData.setReturnValue("MySQL"); mockDatabaseMetaData.supportsBatchUpdates(); ctrlDatabaseMetaData.setReturnValue(false); mockConnection.getMetaData(); ctrlConnection.setReturnValue(mockDatabaseMetaData, 2); mockConnection.createStatement(); ctrlConnection.setReturnValue(mockStatement); ctrlStatement.replay(); ctrlDatabaseMetaData.replay(); replay(); JdbcTemplate template = new JdbcTemplate(mockDataSource, false); try { template.batchUpdate(sql); fail("Shouldn't have executed batch statement with a select"); } catch (DataAccessException ex) { // pass assertTrue("Check exception type", ex.getClass() == InvalidDataAccessApiUsageException.class); } ctrlStatement.verify(); ctrlDatabaseMetaData.verify(); } public void testBatchUpdateWithPreparedStatement() throws Exception { final String sql = "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = ?"; final int[] ids = new int[] { 100, 200 }; final int[] rowsAffected = new int[] { 1, 2 }; MockControl ctrlPreparedStatement = MockControl.createControl(PreparedStatement.class); PreparedStatement mockPreparedStatement = (PreparedStatement) ctrlPreparedStatement.getMock(); mockPreparedStatement.getConnection(); ctrlPreparedStatement.setReturnValue(mockConnection); mockPreparedStatement.setInt(1, ids[0]); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.addBatch(); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.setInt(1, ids[1]); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.addBatch(); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeBatch(); ctrlPreparedStatement.setReturnValue(rowsAffected); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); MockControl ctrlDatabaseMetaData = MockControl.createControl(DatabaseMetaData.class); DatabaseMetaData mockDatabaseMetaData = (DatabaseMetaData) ctrlDatabaseMetaData.getMock(); mockDatabaseMetaData.getDatabaseProductName(); ctrlDatabaseMetaData.setReturnValue("MySQL"); mockDatabaseMetaData.supportsBatchUpdates(); ctrlDatabaseMetaData.setReturnValue(true); mockConnection.prepareStatement(sql); ctrlConnection.setReturnValue(mockPreparedStatement); mockConnection.getMetaData(); ctrlConnection.setReturnValue(mockDatabaseMetaData, 2); ctrlPreparedStatement.replay(); ctrlDatabaseMetaData.replay(); replay(); BatchPreparedStatementSetter setter = new BatchPreparedStatementSetter() { public void setValues(PreparedStatement ps, int i) throws SQLException { ps.setInt(1, ids[i]); } public int getBatchSize() { return ids.length; } }; JdbcTemplate template = new JdbcTemplate(mockDataSource, false); int[] actualRowsAffected = template.batchUpdate(sql, setter); assertTrue("executed 2 updates", actualRowsAffected.length == 2); assertEquals(rowsAffected[0], actualRowsAffected[0]); assertEquals(rowsAffected[1], actualRowsAffected[1]); ctrlPreparedStatement.verify(); ctrlDatabaseMetaData.verify(); } public void testInterruptibleBatchUpdate() throws Exception { final String sql = "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = ?"; final int[] ids = new int[] { 100, 200 }; final int[] rowsAffected = new int[] { 1, 2 }; MockControl ctrlPreparedStatement = MockControl.createControl(PreparedStatement.class); PreparedStatement mockPreparedStatement = (PreparedStatement) ctrlPreparedStatement.getMock(); mockPreparedStatement.getConnection(); ctrlPreparedStatement.setReturnValue(mockConnection); mockPreparedStatement.setInt(1, ids[0]); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.addBatch(); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.setInt(1, ids[1]); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.addBatch(); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeBatch(); ctrlPreparedStatement.setReturnValue(rowsAffected); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); MockControl ctrlDatabaseMetaData = MockControl.createControl(DatabaseMetaData.class); DatabaseMetaData mockDatabaseMetaData = (DatabaseMetaData) ctrlDatabaseMetaData.getMock(); mockDatabaseMetaData.getDatabaseProductName(); ctrlDatabaseMetaData.setReturnValue("MySQL"); mockDatabaseMetaData.supportsBatchUpdates(); ctrlDatabaseMetaData.setReturnValue(true); mockConnection.prepareStatement(sql); ctrlConnection.setReturnValue(mockPreparedStatement); mockConnection.getMetaData(); ctrlConnection.setReturnValue(mockDatabaseMetaData, 2); ctrlPreparedStatement.replay(); ctrlDatabaseMetaData.replay(); replay(); BatchPreparedStatementSetter setter = new InterruptibleBatchPreparedStatementSetter() { public void setValues(PreparedStatement ps, int i) throws SQLException { if (i < ids.length) { ps.setInt(1, ids[i]); } } public int getBatchSize() { return 1000; } public boolean isBatchExhausted(int i) { return (i >= ids.length); } }; JdbcTemplate template = new JdbcTemplate(mockDataSource, false); int[] actualRowsAffected = template.batchUpdate(sql, setter); assertTrue("executed 2 updates", actualRowsAffected.length == 2); assertEquals(rowsAffected[0], actualRowsAffected[0]); assertEquals(rowsAffected[1], actualRowsAffected[1]); ctrlPreparedStatement.verify(); ctrlDatabaseMetaData.verify(); } public void testInterruptibleBatchUpdateWithBaseClass() throws Exception { final String sql = "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = ?"; final int[] ids = new int[] { 100, 200 }; final int[] rowsAffected = new int[] { 1, 2 }; MockControl ctrlPreparedStatement = MockControl.createControl(PreparedStatement.class); PreparedStatement mockPreparedStatement = (PreparedStatement) ctrlPreparedStatement.getMock(); mockPreparedStatement.getConnection(); ctrlPreparedStatement.setReturnValue(mockConnection); mockPreparedStatement.setInt(1, ids[0]); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.addBatch(); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.setInt(1, ids[1]); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.addBatch(); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeBatch(); ctrlPreparedStatement.setReturnValue(rowsAffected); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); MockControl ctrlDatabaseMetaData = MockControl.createControl(DatabaseMetaData.class); DatabaseMetaData mockDatabaseMetaData = (DatabaseMetaData) ctrlDatabaseMetaData.getMock(); mockDatabaseMetaData.getDatabaseProductName(); ctrlDatabaseMetaData.setReturnValue("MySQL"); mockDatabaseMetaData.supportsBatchUpdates(); ctrlDatabaseMetaData.setReturnValue(true); mockConnection.prepareStatement(sql); ctrlConnection.setReturnValue(mockPreparedStatement); mockConnection.getMetaData(); ctrlConnection.setReturnValue(mockDatabaseMetaData, 2); ctrlPreparedStatement.replay(); ctrlDatabaseMetaData.replay(); replay(); BatchPreparedStatementSetter setter = new AbstractInterruptibleBatchPreparedStatementSetter() { protected boolean setValuesIfAvailable(PreparedStatement ps, int i) throws SQLException { if (i < ids.length) { ps.setInt(1, ids[i]); return true; } else { return false; } } }; JdbcTemplate template = new JdbcTemplate(mockDataSource, false); int[] actualRowsAffected = template.batchUpdate(sql, setter); assertTrue("executed 2 updates", actualRowsAffected.length == 2); assertEquals(rowsAffected[0], actualRowsAffected[0]); assertEquals(rowsAffected[1], actualRowsAffected[1]); ctrlPreparedStatement.verify(); ctrlDatabaseMetaData.verify(); } public void testInterruptibleBatchUpdateWithBaseClassAndNoBatchSupport() throws Exception { final String sql = "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = ?"; final int[] ids = new int[] { 100, 200 }; final int[] rowsAffected = new int[] { 1, 2 }; MockControl ctrlPreparedStatement = MockControl.createControl(PreparedStatement.class); PreparedStatement mockPreparedStatement = (PreparedStatement) ctrlPreparedStatement.getMock(); mockPreparedStatement.getConnection(); ctrlPreparedStatement.setReturnValue(mockConnection); mockPreparedStatement.setInt(1, ids[0]); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeUpdate(); ctrlPreparedStatement.setReturnValue(rowsAffected[0]); mockPreparedStatement.setInt(1, ids[1]); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeUpdate(); ctrlPreparedStatement.setReturnValue(rowsAffected[1]); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); MockControl ctrlDatabaseMetaData = MockControl.createControl(DatabaseMetaData.class); DatabaseMetaData mockDatabaseMetaData = (DatabaseMetaData) ctrlDatabaseMetaData.getMock(); mockDatabaseMetaData.getDatabaseProductName(); ctrlDatabaseMetaData.setReturnValue("MySQL"); mockDatabaseMetaData.supportsBatchUpdates(); ctrlDatabaseMetaData.setReturnValue(false); mockConnection.prepareStatement(sql); ctrlConnection.setReturnValue(mockPreparedStatement); mockConnection.getMetaData(); ctrlConnection.setReturnValue(mockDatabaseMetaData, 2); ctrlPreparedStatement.replay(); ctrlDatabaseMetaData.replay(); replay(); BatchPreparedStatementSetter setter = new AbstractInterruptibleBatchPreparedStatementSetter() { protected boolean setValuesIfAvailable(PreparedStatement ps, int i) throws SQLException { if (i < ids.length) { ps.setInt(1, ids[i]); return true; } else { return false; } } }; JdbcTemplate template = new JdbcTemplate(mockDataSource, false); int[] actualRowsAffected = template.batchUpdate(sql, setter); assertTrue("executed 2 updates", actualRowsAffected.length == 2); assertEquals(rowsAffected[0], actualRowsAffected[0]); assertEquals(rowsAffected[1], actualRowsAffected[1]); ctrlPreparedStatement.verify(); ctrlDatabaseMetaData.verify(); } public void testBatchUpdateWithPreparedStatementAndNoBatchSupport() throws Exception { final String sql = "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = ?"; final int[] ids = new int[] { 100, 200 }; final int[] rowsAffected = new int[] { 1, 2 }; MockControl ctrlPreparedStatement = MockControl.createControl(PreparedStatement.class); PreparedStatement mockPreparedStatement = (PreparedStatement) ctrlPreparedStatement.getMock(); mockPreparedStatement.getConnection(); ctrlPreparedStatement.setReturnValue(mockConnection); mockPreparedStatement.setInt(1, ids[0]); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeUpdate(); ctrlPreparedStatement.setReturnValue(rowsAffected[0]); mockPreparedStatement.setInt(1, ids[1]); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeUpdate(); ctrlPreparedStatement.setReturnValue(rowsAffected[1]); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(sql); ctrlConnection.setReturnValue(mockPreparedStatement); ctrlPreparedStatement.replay(); replay(); BatchPreparedStatementSetter setter = new BatchPreparedStatementSetter() { public void setValues(PreparedStatement ps, int i) throws SQLException { ps.setInt(1, ids[i]); } public int getBatchSize() { return ids.length; } }; JdbcTemplate template = new JdbcTemplate(mockDataSource); int[] actualRowsAffected = template.batchUpdate(sql, setter); assertTrue("executed 2 updates", actualRowsAffected.length == 2); assertEquals(rowsAffected[0], actualRowsAffected[0]); assertEquals(rowsAffected[1], actualRowsAffected[1]); ctrlPreparedStatement.verify(); } public void testBatchUpdateFails() throws Exception { final String sql = "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = ?"; final int[] ids = new int[] { 100, 200 }; SQLException sex = new SQLException(); MockControl ctrlPreparedStatement = MockControl.createControl(PreparedStatement.class); PreparedStatement mockPreparedStatement = (PreparedStatement) ctrlPreparedStatement.getMock(); mockPreparedStatement.getConnection(); ctrlPreparedStatement.setReturnValue(mockConnection); mockPreparedStatement.setInt(1, ids[0]); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.addBatch(); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.setInt(1, ids[1]); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.addBatch(); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeBatch(); ctrlPreparedStatement.setThrowable(sex); mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); MockControl ctrlDatabaseMetaData = MockControl.createControl(DatabaseMetaData.class); DatabaseMetaData mockDatabaseMetaData = (DatabaseMetaData) ctrlDatabaseMetaData.getMock(); mockDatabaseMetaData.getDatabaseProductName(); ctrlDatabaseMetaData.setReturnValue("MySQL"); mockDatabaseMetaData.supportsBatchUpdates(); ctrlDatabaseMetaData.setReturnValue(true); ctrlConnection.reset(); mockConnection.prepareStatement(sql); ctrlConnection.setReturnValue(mockPreparedStatement); mockConnection.getMetaData(); ctrlConnection.setReturnValue(mockDatabaseMetaData, 2); mockConnection.close(); ctrlConnection.setVoidCallable(2); ctrlPreparedStatement.replay(); ctrlDatabaseMetaData.replay(); replay(); BatchPreparedStatementSetter setter = new BatchPreparedStatementSetter() { public void setValues(PreparedStatement ps, int i) throws SQLException { ps.setInt(1, ids[i]); } public int getBatchSize() { return ids.length; } }; try { JdbcTemplate template = new JdbcTemplate(mockDataSource); template.batchUpdate(sql, setter); fail("Should have failed because of SQLException in bulk update"); } catch (DataAccessException ex) { assertTrue("Root cause is SQLException", ex.getCause() == sex); } ctrlPreparedStatement.verify(); ctrlDatabaseMetaData.verify(); } public void testCouldntGetConnectionOrExceptionTranslator() throws SQLException { SQLException sex = new SQLException("foo", "07xxx"); ctrlDataSource = MockControl.createControl(DataSource.class); mockDataSource = (DataSource) ctrlDataSource.getMock(); mockDataSource.getConnection(); // Expect two calls (one call after caching data product name): make get metadata fail also ctrlDataSource.setThrowable(sex, 2); replay(); try { JdbcTemplate template = new JdbcTemplate(mockDataSource, false); RowCountCallbackHandler rcch = new RowCountCallbackHandler(); template.query("SELECT ID, FORENAME FROM CUSTMR WHERE ID < 3", rcch); fail("Shouldn't have executed query without a connection"); } catch (CannotGetJdbcConnectionException ex) { // pass assertTrue("Check root cause", ex.getCause() == sex); } ctrlDataSource.verify(); } public void testCouldntGetConnectionForOperationOrExceptionTranslator() throws SQLException { SQLException sex = new SQLException("foo", "07xxx"); // Change behavior in setUp() because we only expect one call to getConnection(): // none is necessary to get metadata for exception translator ctrlDataSource = MockControl.createControl(DataSource.class); mockDataSource = (DataSource) ctrlDataSource.getMock(); mockDataSource.getConnection(); // Expect two calls (one call after caching data product name): make get Metadata fail also ctrlDataSource.setThrowable(sex, 2); replay(); try { JdbcTemplate template = new JdbcTemplate(mockDataSource, false); RowCountCallbackHandler rcch = new RowCountCallbackHandler(); template.query("SELECT ID, FORENAME FROM CUSTMR WHERE ID < 3", rcch); fail("Shouldn't have executed query without a connection"); } catch (CannotGetJdbcConnectionException ex) { // pass assertTrue("Check root cause", ex.getCause() == sex); } ctrlDataSource.verify(); } public void testCouldntGetConnectionForOperationWithLazyExceptionTranslator() throws SQLException { SQLException sex = new SQLException("foo", "07xxx"); ctrlDataSource = MockControl.createControl(DataSource.class); mockDataSource = (DataSource) ctrlDataSource.getMock(); mockDataSource.getConnection(); ctrlDataSource.setThrowable(sex, 1); replay(); try { JdbcTemplate template2 = new JdbcTemplate(); template2.setDataSource(mockDataSource); template2.afterPropertiesSet(); RowCountCallbackHandler rcch = new RowCountCallbackHandler(); template2.query("SELECT ID, FORENAME FROM CUSTMR WHERE ID < 3", rcch); fail("Shouldn't have executed query without a connection"); } catch (CannotGetJdbcConnectionException ex) { // pass assertTrue("Check root cause", ex.getCause() == sex); } ctrlDataSource.verify(); } /** * Verify that afterPropertiesSet invokes exception translator. */ public void testCouldntGetConnectionInOperationWithExceptionTranslatorInitialized() throws SQLException { SQLException sex = new SQLException("foo", "07xxx"); ctrlDataSource = MockControl.createControl(DataSource.class); mockDataSource = (DataSource) ctrlDataSource.getMock(); //mockConnection.getMetaData(); //ctrlConnection.setReturnValue(null, 1); //mockConnection.close(); //ctrlConnection.setVoidCallable(1); ctrlConnection.replay(); // Change behaviour in setUp() because we only expect one call to getConnection(): // none is necessary to get metadata for exception translator ctrlDataSource = MockControl.createControl(DataSource.class); mockDataSource = (DataSource) ctrlDataSource.getMock(); // Upfront call for metadata - no longer the case //mockDataSource.getConnection(); //ctrlDataSource.setReturnValue(mockConnection, 1); // One call for operation mockDataSource.getConnection(); ctrlDataSource.setThrowable(sex, 2); ctrlDataSource.replay(); try { JdbcTemplate template = new JdbcTemplate(mockDataSource, false); RowCountCallbackHandler rcch = new RowCountCallbackHandler(); template.query("SELECT ID, FORENAME FROM CUSTMR WHERE ID < 3", rcch); fail("Shouldn't have executed query without a connection"); } catch (CannotGetJdbcConnectionException ex) { // pass assertTrue("Check root cause", ex.getCause() == sex); } ctrlDataSource.verify(); ctrlConnection.verify(); } public void testCouldntGetConnectionInOperationWithExceptionTranslatorInitializedViaBeanProperty() throws Exception { doTestCouldntGetConnectionInOperationWithExceptionTranslatorInitialized(true); } public void testCouldntGetConnectionInOperationWithExceptionTranslatorInitializedInAfterPropertiesSet() throws Exception { doTestCouldntGetConnectionInOperationWithExceptionTranslatorInitialized(false); } /** * If beanProperty is true, initialize via exception translator bean property; * if false, use afterPropertiesSet(). */ private void doTestCouldntGetConnectionInOperationWithExceptionTranslatorInitialized(boolean beanProperty) throws SQLException { SQLException sex = new SQLException("foo", "07xxx"); ctrlConnection = MockControl.createControl(Connection.class); mockConnection = (Connection) ctrlConnection.getMock(); //mockConnection.getMetaData(); //ctrlConnection.setReturnValue(null, 1); //mockConnection.close(); //ctrlConnection.setVoidCallable(1); ctrlConnection.replay(); // Change behaviour in setUp() because we only expect one call to getConnection(): // none is necessary to get metadata for exception translator ctrlDataSource = MockControl.createControl(DataSource.class); mockDataSource = (DataSource) ctrlDataSource.getMock(); // Upfront call for metadata - no longer the case //mockDataSource.getConnection(); //ctrlDataSource.setReturnValue(mockConnection, 1); // One call for operation mockDataSource.getConnection(); ctrlDataSource.setThrowable(sex, 2); ctrlDataSource.replay(); try { JdbcTemplate template2 = new JdbcTemplate(); template2.setDataSource(mockDataSource); template2.setLazyInit(false); if (beanProperty) { // This will get a connection. template2.setExceptionTranslator(new SQLErrorCodeSQLExceptionTranslator(mockDataSource)); } else { // This will cause creation of default SQL translator. // Note that only call should be effective. template2.afterPropertiesSet(); template2.afterPropertiesSet(); } RowCountCallbackHandler rcch = new RowCountCallbackHandler(); template2.query( "SELECT ID, FORENAME FROM CUSTMR WHERE ID < 3", rcch); fail("Shouldn't have executed query without a connection"); } catch (CannotGetJdbcConnectionException ex) { // pass assertTrue("Check root cause", ex.getCause() == sex); } ctrlDataSource.verify(); ctrlConnection.verify(); } public void testPreparedStatementSetterSucceeds() throws Exception { final String sql = "UPDATE FOO SET NAME=? WHERE ID = 1"; final String name = "Gary"; int expectedRowsUpdated = 1; MockControl ctrlPreparedStatement = MockControl.createControl(PreparedStatement.class); PreparedStatement mockPreparedStatement = (PreparedStatement) ctrlPreparedStatement.getMock(); mockPreparedStatement.setString(1, name); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeUpdate(); ctrlPreparedStatement.setReturnValue(expectedRowsUpdated); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(sql); ctrlConnection.setReturnValue(mockPreparedStatement); ctrlPreparedStatement.replay(); replay(); PreparedStatementSetter pss = new PreparedStatementSetter() { public void setValues(PreparedStatement ps) throws SQLException { ps.setString(1, name); } }; int actualRowsUpdated = new JdbcTemplate(mockDataSource).update(sql, pss); assertTrue( "updated correct # of rows", actualRowsUpdated == expectedRowsUpdated); ctrlPreparedStatement.verify(); } public void testPreparedStatementSetterFails() throws Exception { final String sql = "UPDATE FOO SET NAME=? WHERE ID = 1"; final String name = "Gary"; SQLException sex = new SQLException(); MockControl ctrlPreparedStatement = MockControl.createControl(PreparedStatement.class); PreparedStatement mockPreparedStatement = (PreparedStatement) ctrlPreparedStatement.getMock(); mockPreparedStatement.setString(1, name); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeUpdate(); ctrlPreparedStatement.setThrowable(sex); mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(sql); ctrlConnection.setReturnValue(mockPreparedStatement); ctrlPreparedStatement.replay(); replay(); PreparedStatementSetter pss = new PreparedStatementSetter() { public void setValues(PreparedStatement ps) throws SQLException { ps.setString(1, name); } }; try { new JdbcTemplate(mockDataSource).update(sql, pss); fail("Should have failed with SQLException"); } catch (DataAccessException ex) { assertTrue("root cause was preserved", ex.getCause() == sex); } ctrlPreparedStatement.verify(); } public void testCouldntClose() throws Exception { MockControl ctrlStatement = MockControl.createControl(Statement.class); Statement mockStatement = (Statement) ctrlStatement.getMock(); MockControl ctrlResultSet = MockControl.createControl(ResultSet.class); ResultSet mockResultSet = (ResultSet) ctrlResultSet.getMock(); mockConnection.createStatement(); ctrlConnection.setReturnValue(mockStatement); String sql = "SELECT ID, FORENAME FROM CUSTMR WHERE ID < 3"; mockStatement.executeQuery(sql); ctrlStatement.setReturnValue(mockResultSet); mockResultSet.next(); ctrlResultSet.setReturnValue(false); SQLException sex = new SQLException("bar"); mockResultSet.close(); ctrlResultSet.setThrowable(sex); if (debugEnabled) { mockStatement.getWarnings(); ctrlStatement.setReturnValue(null); } mockStatement.close(); ctrlStatement.setThrowable(sex); mockConnection.close(); ctrlConnection.setThrowable(sex); ctrlStatement.replay(); ctrlResultSet.replay(); replay(); JdbcTemplate template2 = new JdbcTemplate(mockDataSource); RowCountCallbackHandler rcch = new RowCountCallbackHandler(); template2.query("SELECT ID, FORENAME FROM CUSTMR WHERE ID < 3", rcch); ctrlStatement.verify(); ctrlResultSet.verify(); } /** * Mock objects allow us to produce warnings at will */ public void testFatalWarning() throws Exception { String sql = "SELECT forename from custmr"; SQLWarning warnings = new SQLWarning("My warning"); MockControl ctrlResultSet = MockControl.createControl(ResultSet.class); ResultSet mockResultSet = (ResultSet) ctrlResultSet.getMock(); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); MockControl ctrlStatement = MockControl.createControl(PreparedStatement.class); PreparedStatement mockStatement = (PreparedStatement) ctrlStatement.getMock(); mockStatement.executeQuery(sql); ctrlStatement.setReturnValue(mockResultSet); mockStatement.getWarnings(); ctrlStatement.setReturnValue(warnings); mockStatement.close(); ctrlStatement.setVoidCallable(); mockConnection.createStatement(); ctrlConnection.setReturnValue(mockStatement); ctrlResultSet.replay(); ctrlStatement.replay(); replay(); JdbcTemplate t = new JdbcTemplate(mockDataSource); t.setIgnoreWarnings(false); try { t.query(sql, new RowCallbackHandler() { public void processRow(ResultSet rs) throws SQLException { rs.getByte(1); } }); fail("Should have thrown exception on warning"); } catch (SQLWarningException ex) { // Pass assertTrue( "Root cause of warning was correct", ex.getCause() == warnings); } ctrlResultSet.verify(); ctrlStatement.verify(); } public void testIgnoredWarning() throws Exception { String sql = "SELECT forename from custmr"; SQLWarning warnings = new SQLWarning("My warning"); MockControl ctrlResultSet = MockControl.createControl(ResultSet.class); ResultSet mockResultSet = (ResultSet) ctrlResultSet.getMock(); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); MockControl ctrlStatement = MockControl.createControl(PreparedStatement.class); PreparedStatement mockStatement = (PreparedStatement) ctrlStatement.getMock(); mockStatement.executeQuery(sql); ctrlStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockStatement.getWarnings(); ctrlStatement.setReturnValue(null); } mockStatement.close(); ctrlStatement.setVoidCallable(); mockConnection.createStatement(); ctrlConnection.setReturnValue(mockStatement); ctrlResultSet.replay(); ctrlStatement.replay(); replay(); // Too long: truncation JdbcTemplate template = new JdbcTemplate(mockDataSource); template.setIgnoreWarnings(true); template.query(sql, new RowCallbackHandler() { public void processRow(ResultSet rs) throws java.sql.SQLException { rs.getByte(1); } }); ctrlResultSet.verify(); ctrlStatement.verify(); } public void testSQLErrorCodeTranslation() throws Exception { final SQLException sex = new SQLException("I have a known problem", "99999", 1054); final String sql = "SELECT ID FROM CUSTOMER"; MockControl ctrlResultSet = MockControl.createControl(ResultSet.class); ResultSet mockResultSet = (ResultSet) ctrlResultSet.getMock(); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.close(); ctrlResultSet.setVoidCallable(); MockControl ctrlStatement = MockControl.createControl(PreparedStatement.class); PreparedStatement mockStatement = (PreparedStatement) ctrlStatement.getMock(); mockStatement.executeQuery(sql); ctrlStatement.setReturnValue(mockResultSet); mockStatement.close(); ctrlStatement.setVoidCallable(); MockControl ctrlDatabaseMetaData = MockControl.createControl(DatabaseMetaData.class); DatabaseMetaData mockDatabaseMetaData = (DatabaseMetaData) ctrlDatabaseMetaData.getMock(); mockDatabaseMetaData.getDatabaseProductName(); ctrlDatabaseMetaData.setReturnValue("MySQL"); mockConnection.createStatement(); ctrlConnection.setReturnValue(mockStatement); mockConnection.getMetaData(); ctrlConnection.setReturnValue(mockDatabaseMetaData); ctrlResultSet.replay(); ctrlStatement.replay(); ctrlDatabaseMetaData.replay(); replay(); JdbcTemplate template = new JdbcTemplate(mockDataSource); try { template.query(sql, new RowCallbackHandler() { public void processRow(ResultSet rs) throws SQLException { throw sex; } }); fail("Should have thrown BadSqlGrammarException"); } catch (BadSqlGrammarException ex) { // expected assertTrue("Wanted same exception back, not " + ex, sex == ex.getCause()); } ctrlResultSet.verify(); ctrlStatement.verify(); ctrlDatabaseMetaData.verify(); } public void testSQLErrorCodeTranslationWithSpecifiedDbName() throws Exception { final SQLException sex = new SQLException("I have a known problem", "99999", 1054); final String sql = "SELECT ID FROM CUSTOMER"; MockControl ctrlResultSet = MockControl.createControl(ResultSet.class); ResultSet mockResultSet = (ResultSet) ctrlResultSet.getMock(); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.close(); ctrlResultSet.setVoidCallable(); MockControl ctrlStatement = MockControl.createControl(PreparedStatement.class); PreparedStatement mockStatement = (PreparedStatement) ctrlStatement.getMock(); mockStatement.executeQuery(sql); ctrlStatement.setReturnValue(mockResultSet); mockStatement.close(); ctrlStatement.setVoidCallable(); mockConnection.createStatement(); ctrlConnection.setReturnValue(mockStatement); ctrlResultSet.replay(); ctrlStatement.replay(); replay(); JdbcTemplate template = new JdbcTemplate(); template.setDataSource(mockDataSource); template.setDatabaseProductName("MySQL"); template.afterPropertiesSet(); try { template.query(sql, new RowCallbackHandler() { public void processRow(ResultSet rs) throws SQLException { throw sex; } }); fail("Should have thrown BadSqlGrammarException"); } catch (BadSqlGrammarException ex) { // expected assertTrue("Wanted same exception back, not " + ex, sex == ex.getCause()); } ctrlResultSet.verify(); ctrlStatement.verify(); } /** * Test that we see an SQLException translated using Error Code. * If we provide the SQLExceptionTranslator, we shouldn't use a connection * to get the metadata */ public void testUseCustomSQLErrorCodeTranslator() throws Exception { // Bad SQL state final SQLException sex = new SQLException("I have a known problem", "07000", 1054); final String sql = "SELECT ID FROM CUSTOMER"; MockControl ctrlResultSet = MockControl.createControl(ResultSet.class); ResultSet mockResultSet = (ResultSet) ctrlResultSet.getMock(); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.close(); ctrlResultSet.setVoidCallable(); MockControl ctrlStatement = MockControl.createControl(PreparedStatement.class); PreparedStatement mockStatement = (PreparedStatement) ctrlStatement.getMock(); mockStatement.executeQuery(sql); ctrlStatement.setReturnValue(mockResultSet); mockStatement.close(); ctrlStatement.setVoidCallable(); mockConnection.createStatement(); ctrlConnection.setReturnValue(mockStatement); // Change behaviour in setUp() because we only expect one call to getConnection(): // none is necessary to get metadata for exception translator ctrlConnection = MockControl.createControl(Connection.class); mockConnection = (Connection) ctrlConnection.getMock(); mockConnection.createStatement(); ctrlConnection.setReturnValue(mockStatement, 1); mockConnection.close(); ctrlConnection.setVoidCallable(1); ctrlConnection.replay(); ctrlDataSource = MockControl.createControl(DataSource.class); mockDataSource = (DataSource) ctrlDataSource.getMock(); mockDataSource.getConnection(); ctrlDataSource.setReturnValue(mockConnection, 1); ctrlDataSource.replay(); ///// end changed behaviour ctrlResultSet.replay(); ctrlStatement.replay(); JdbcTemplate template = new JdbcTemplate(); template.setDataSource(mockDataSource); // Set custom exception translator template.setExceptionTranslator(new SQLStateSQLExceptionTranslator()); template.afterPropertiesSet(); try { template.query(sql, new RowCallbackHandler() { public void processRow(ResultSet rs) throws SQLException { throw sex; } }); fail("Should have thrown exception"); } catch (BadSqlGrammarException ex) { assertTrue( "Wanted same exception back, not " + ex, sex == ex.getCause()); } ctrlResultSet.verify(); ctrlStatement.verify(); // We didn't call superclass replay() so we need to check these ourselves ctrlDataSource.verify(); ctrlConnection.verify(); } public void testNativeJdbcExtractorInvoked() throws Exception { MockControl ctrlResultSet = MockControl.createControl(ResultSet.class); final ResultSet mockResultSet = (ResultSet) ctrlResultSet.getMock(); mockResultSet.close(); ctrlResultSet.setVoidCallable(2); MockControl ctrlStatement = MockControl.createControl(Statement.class); final Statement mockStatement = (Statement) ctrlStatement.getMock(); if (debugEnabled) { mockStatement.getWarnings(); ctrlStatement.setReturnValue(null); } mockStatement.close(); ctrlStatement.setVoidCallable(); MockControl ctrlStatement2 = MockControl.createControl(Statement.class); final Statement mockStatement2 = (Statement) ctrlStatement2.getMock(); mockStatement2.executeQuery("my query"); ctrlStatement2.setReturnValue(mockResultSet, 1); MockControl ctrlPreparedStatement = MockControl.createControl(PreparedStatement.class); final PreparedStatement mockPreparedStatement = (PreparedStatement) ctrlPreparedStatement.getMock(); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); MockControl ctrlPreparedStatement2 = MockControl.createControl(PreparedStatement.class); final PreparedStatement mockPreparedStatement2 = (PreparedStatement) ctrlPreparedStatement2.getMock(); mockPreparedStatement2.executeQuery(); ctrlPreparedStatement2.setReturnValue(mockResultSet, 1); MockControl ctrlReturnResultSet = MockControl.createControl(ResultSet.class); final ResultSet mockReturnResultSet = (ResultSet) ctrlReturnResultSet.getMock(); mockReturnResultSet.next(); ctrlReturnResultSet.setReturnValue(false); mockReturnResultSet.close(); ctrlReturnResultSet.setVoidCallable(2); MockControl ctrlCallableStatement = MockControl.createControl(CallableStatement.class); final CallableStatement mockCallableStatement = (CallableStatement) ctrlCallableStatement.getMock(); if (debugEnabled) { mockCallableStatement.getWarnings(); ctrlCallableStatement.setReturnValue(null); } mockCallableStatement.close(); ctrlCallableStatement.setVoidCallable(); MockControl ctrlCallableStatement2 = MockControl.createControl(CallableStatement.class); final CallableStatement mockCallableStatement2 = (CallableStatement) ctrlCallableStatement2.getMock(); mockCallableStatement2.execute(); ctrlCallableStatement2.setReturnValue(true); mockCallableStatement2.getUpdateCount(); ctrlCallableStatement2.setReturnValue(-1); mockCallableStatement2.getResultSet(); ctrlCallableStatement2.setReturnValue(mockReturnResultSet); mockCallableStatement2.getMoreResults(); ctrlCallableStatement2.setReturnValue(false); mockCallableStatement2.getUpdateCount(); ctrlCallableStatement2.setReturnValue(-1); ctrlResultSet.replay(); ctrlStatement.replay(); ctrlStatement2.replay(); ctrlPreparedStatement.replay(); ctrlPreparedStatement2.replay(); ctrlReturnResultSet.replay();; ctrlCallableStatement.replay(); ctrlCallableStatement2.replay(); mockConnection.createStatement(); ctrlConnection.setReturnValue(mockStatement, 1); replay(); JdbcTemplate template = new JdbcTemplate(mockDataSource); template.setNativeJdbcExtractor(new NativeJdbcExtractor() { public boolean isNativeConnectionNecessaryForNativeStatements() { return false; } public boolean isNativeConnectionNecessaryForNativePreparedStatements() { return false; } public boolean isNativeConnectionNecessaryForNativeCallableStatements() { return false; } public Connection getNativeConnection(Connection con) { return con; } public Connection getNativeConnectionFromStatement(Statement stmt) throws SQLException { return stmt.getConnection(); } public Statement getNativeStatement(Statement stmt) { assertTrue(stmt == mockStatement); return mockStatement2; } public PreparedStatement getNativePreparedStatement(PreparedStatement ps) { assertTrue(ps == mockPreparedStatement); return mockPreparedStatement2; } public CallableStatement getNativeCallableStatement(CallableStatement cs) { assertTrue(cs == mockCallableStatement); return mockCallableStatement2; } public ResultSet getNativeResultSet(ResultSet rs) { return rs; } }); template.query("my query", new ResultSetExtractor() { public Object extractData(ResultSet rs2) { assertEquals(mockResultSet, rs2); return null; } }); template.query(new PreparedStatementCreator() { public PreparedStatement createPreparedStatement(Connection conn) { return mockPreparedStatement; } }, new ResultSetExtractor() { public Object extractData(ResultSet rs2) { assertEquals(mockResultSet, rs2); return null; } }); template.call(new CallableStatementCreator() { public CallableStatement createCallableStatement(Connection con) { return mockCallableStatement; } }, new ArrayList()); ctrlStatement.verify(); ctrlStatement2.verify(); ctrlPreparedStatement.verify(); ctrlPreparedStatement2.verify(); ctrlCallableStatement.verify(); ctrlCallableStatement2.verify(); } public void testStaticResultSetClosed() throws Exception { MockControl ctrlResultSet; ResultSet mockResultSet; MockControl ctrlStatement; Statement mockStatement; MockControl ctrlResultSet2; ResultSet mockResultSet2; MockControl ctrlPreparedStatement; PreparedStatement mockPreparedStatement; ctrlResultSet = MockControl.createControl(ResultSet.class); mockResultSet = (ResultSet) ctrlResultSet.getMock(); mockResultSet.close(); ctrlResultSet.setVoidCallable(); ctrlStatement = MockControl.createControl(Statement.class); mockStatement = (Statement) ctrlStatement.getMock(); mockStatement.executeQuery("my query"); ctrlStatement.setReturnValue(mockResultSet); mockStatement.close(); ctrlStatement.setVoidCallable(); ctrlResultSet2 = MockControl.createControl(ResultSet.class); mockResultSet2 = (ResultSet) ctrlResultSet2.getMock(); mockResultSet2.close(); ctrlResultSet2.setVoidCallable(); ctrlPreparedStatement = MockControl.createControl(PreparedStatement.class); mockPreparedStatement = (PreparedStatement) ctrlPreparedStatement.getMock(); mockPreparedStatement.executeQuery(); ctrlPreparedStatement.setReturnValue(mockResultSet2); mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.createStatement(); ctrlConnection.setReturnValue(mockStatement); mockConnection.prepareStatement("my query"); ctrlConnection.setReturnValue(mockPreparedStatement); ctrlResultSet.replay(); ctrlStatement.replay(); ctrlResultSet2.replay(); ctrlPreparedStatement.replay(); replay(); JdbcTemplate template = new JdbcTemplate(mockDataSource); try { template.query("my query", new ResultSetExtractor() { public Object extractData(ResultSet rs) { throw new InvalidDataAccessApiUsageException(""); } }); fail("Should have thrown InvalidDataAccessApiUsageException"); } catch (InvalidDataAccessApiUsageException idaauex) { // ok } try { template.query(new PreparedStatementCreator() { public PreparedStatement createPreparedStatement(Connection con) throws SQLException { return con.prepareStatement("my query"); } public String getSql() { return null; } }, new ResultSetExtractor() { public Object extractData(ResultSet rs2) { throw new InvalidDataAccessApiUsageException(""); } }); fail("Should have thrown InvalidDataAccessApiUsageException"); } catch (InvalidDataAccessApiUsageException idaauex) { // ok } // verify confirms if test is successful by checking if close() called ctrlResultSet.verify(); ctrlStatement.verify(); ctrlResultSet2.verify(); ctrlPreparedStatement.verify(); } public void testExecuteClosed() throws Exception { MockControl ctrlResultSet; ResultSet mockResultSet; MockControl ctrlCallable; CallableStatement mockCallable; ctrlResultSet = MockControl.createControl(ResultSet.class); mockResultSet = (ResultSet) ctrlResultSet.getMock(); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.close(); ctrlResultSet.setVoidCallable(); ctrlCallable = MockControl.createControl(CallableStatement.class); mockCallable = (CallableStatement) ctrlCallable.getMock(); mockCallable.execute(); ctrlCallable.setReturnValue(true); mockCallable.getUpdateCount(); ctrlCallable.setReturnValue(-1); mockCallable.getResultSet(); ctrlCallable.setReturnValue(mockResultSet); mockCallable.close(); ctrlCallable.setVoidCallable(); mockConnection.prepareCall("my query"); ctrlConnection.setReturnValue(mockCallable); ctrlResultSet.replay(); ctrlCallable.replay(); replay(); List params = new ArrayList(); params.add(new SqlReturnResultSet("", new RowCallbackHandler() { public void processRow(ResultSet rs) { throw new InvalidDataAccessApiUsageException(""); } })); JdbcTemplate template = new JdbcTemplate(mockDataSource); try { template.call(new CallableStatementCreator() { public CallableStatement createCallableStatement(Connection conn) throws SQLException { return conn.prepareCall("my query"); } }, params); } catch (InvalidDataAccessApiUsageException idaauex) { // ok } // verify confirms if test is successful by checking if close() called ctrlResultSet.verify(); ctrlCallable.verify(); } public void testCaseInsensitiveResultsMap() throws Exception { MockControl ctrlCallable; CallableStatement mockCallable; ctrlCallable = MockControl.createControl(CallableStatement.class); mockCallable = (CallableStatement) ctrlCallable.getMock(); mockCallable.execute(); ctrlCallable.setReturnValue(false); mockCallable.getUpdateCount(); ctrlCallable.setReturnValue(-1); mockCallable.getObject(1); ctrlCallable.setReturnValue("X"); if (debugEnabled) { mockCallable.getWarnings(); ctrlCallable.setReturnValue(null); } mockCallable.close(); ctrlCallable.setVoidCallable(); mockConnection.prepareCall("my query"); ctrlConnection.setReturnValue(mockCallable); ctrlCallable.replay(); replay(); JdbcTemplate template = new JdbcTemplate(mockDataSource); assertTrue("default should have been NOT case insensitive", !template.isResultsMapCaseInsensitive()); template.setResultsMapCaseInsensitive(true); assertTrue("now it should have been set to case insensitive", template.isResultsMapCaseInsensitive()); List params = new ArrayList(); params.add(new SqlOutParameter("a", 12)); Map out = template.call(new CallableStatementCreator() { public CallableStatement createCallableStatement(Connection conn) throws SQLException { return conn.prepareCall("my query"); } }, params); assertTrue("this should have been a LinkedCaseInsensitiveMap", out instanceof LinkedCaseInsensitiveMap); assertNotNull("we should have gotten the result with upper case", out.get("A")); assertNotNull("we should have gotten the result with lower case", out.get("a")); ctrlCallable.verify(); } private static class PlainNativeJdbcExtractor extends NativeJdbcExtractorAdapter { protected Connection doGetNativeConnection(Connection con) throws SQLException { return con; } } private static interface JdbcTemplateCallback { void doInJdbcTemplate(JdbcTemplate template, String sql, RowCallbackHandler rch); } private static class Dispatcher implements PreparedStatementCreator, SqlProvider { private int id; private String sql; public Dispatcher(int id, String sql) { this.id = id; this.sql = sql; } public PreparedStatement createPreparedStatement(Connection conn) throws SQLException { PreparedStatement ps = conn.prepareStatement(sql); ps.setInt(1, id); return ps; } public String getSql() { return sql; } } } ././@LongLink0000000000000000000000000000021300000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/StatementCreatorUtilsTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000001777711623223530033343 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Types; import java.util.GregorianCalendar; import junit.framework.TestCase; import org.easymock.MockControl; /** * @author Juergen Hoeller * @since 31.08.2004 */ public class StatementCreatorUtilsTests extends TestCase { private MockControl psControl; private PreparedStatement ps; protected void setUp() { psControl = MockControl.createControl(PreparedStatement.class); ps = (PreparedStatement) psControl.getMock(); } protected void tearDown() { psControl.verify(); } public void testSetParameterValueWithNullAndType() throws SQLException { ps.setNull(1, Types.VARCHAR); psControl.setVoidCallable(1); psControl.replay(); StatementCreatorUtils.setParameterValue(ps, 1, Types.VARCHAR, null, null); } public void testSetParameterValueWithNullAndTypeName() throws SQLException { ps.setNull(1, Types.VARCHAR, "mytype"); psControl.setVoidCallable(1); psControl.replay(); StatementCreatorUtils.setParameterValue(ps, 1, Types.VARCHAR, "mytype", null); } public void testSetParameterValueWithNullAndUnknownType() throws SQLException { ps.setNull(1, Types.NULL); psControl.setVoidCallable(1); psControl.replay(); StatementCreatorUtils.setParameterValue(ps, 1, SqlTypeValue.TYPE_UNKNOWN, null, null); } public void testSetParameterValueWithNullAndUnknownTypeOnInformix() throws SQLException { MockControl conControl = MockControl.createControl(Connection.class); Connection con = (Connection) conControl.getMock(); MockControl metaDataControl = MockControl.createControl(DatabaseMetaData.class); DatabaseMetaData metaData = (DatabaseMetaData) metaDataControl.getMock(); ps.getConnection(); psControl.setReturnValue(con, 1); con.getMetaData(); conControl.setReturnValue(metaData, 1); metaData.getDatabaseProductName(); metaDataControl.setReturnValue("Informix Dynamic Server"); metaData.getDriverName(); metaDataControl.setReturnValue("Informix Driver"); ps.setObject(1, null); psControl.setVoidCallable(1); psControl.replay(); conControl.replay(); metaDataControl.replay(); StatementCreatorUtils.setParameterValue(ps, 1, SqlTypeValue.TYPE_UNKNOWN, null, null); conControl.verify(); metaDataControl.verify(); } public void testSetParameterValueWithNullAndUnknownTypeOnDerbyEmbedded() throws SQLException { MockControl conControl = MockControl.createControl(Connection.class); Connection con = (Connection) conControl.getMock(); MockControl metaDataControl = MockControl.createControl(DatabaseMetaData.class); DatabaseMetaData metaData = (DatabaseMetaData) metaDataControl.getMock(); ps.getConnection(); psControl.setReturnValue(con, 1); con.getMetaData(); conControl.setReturnValue(metaData, 1); metaData.getDatabaseProductName(); metaDataControl.setReturnValue("Apache Derby"); metaData.getDriverName(); metaDataControl.setReturnValue("Apache Derby Embedded Driver"); ps.setNull(1, Types.VARCHAR); psControl.setVoidCallable(1); psControl.replay(); conControl.replay(); metaDataControl.replay(); StatementCreatorUtils.setParameterValue(ps, 1, SqlTypeValue.TYPE_UNKNOWN, null, null); conControl.verify(); metaDataControl.verify(); } public void testSetParameterValueWithString() throws SQLException { ps.setString(1, "test"); psControl.setVoidCallable(1); psControl.replay(); StatementCreatorUtils.setParameterValue(ps, 1, Types.VARCHAR, null, "test"); } public void testSetParameterValueWithStringAndSpecialType() throws SQLException { ps.setObject(1, "test", Types.CHAR); psControl.setVoidCallable(1); psControl.replay(); StatementCreatorUtils.setParameterValue(ps, 1, Types.CHAR, null, "test"); } public void testSetParameterValueWithStringAndUnknownType() throws SQLException { ps.setString(1, "test"); psControl.setVoidCallable(1); psControl.replay(); StatementCreatorUtils.setParameterValue(ps, 1, SqlTypeValue.TYPE_UNKNOWN, null, "test"); } public void testSetParameterValueWithSqlDate() throws SQLException { java.sql.Date date = new java.sql.Date(1000); ps.setDate(1, date); psControl.setVoidCallable(1); psControl.replay(); StatementCreatorUtils.setParameterValue(ps, 1, Types.DATE, null, date); } public void testSetParameterValueWithDateAndUtilDate() throws SQLException { java.util.Date date = new java.util.Date(1000); ps.setDate(1, new java.sql.Date(1000)); psControl.setVoidCallable(1); psControl.replay(); StatementCreatorUtils.setParameterValue(ps, 1, Types.DATE, null, date); } public void testSetParameterValueWithDateAndCalendar() throws SQLException { java.util.Calendar cal = new GregorianCalendar(); ps.setDate(1, new java.sql.Date(cal.getTime().getTime()), cal); psControl.setVoidCallable(1); psControl.replay(); StatementCreatorUtils.setParameterValue(ps, 1, Types.DATE, null, cal); } public void testSetParameterValueWithSqlTime() throws SQLException { java.sql.Time time = new java.sql.Time(1000); ps.setTime(1, time); psControl.setVoidCallable(1); psControl.replay(); StatementCreatorUtils.setParameterValue(ps, 1, Types.TIME, null, time); } public void testSetParameterValueWithTimeAndUtilDate() throws SQLException { java.util.Date date = new java.util.Date(1000); ps.setTime(1, new java.sql.Time(1000)); psControl.setVoidCallable(1); psControl.replay(); StatementCreatorUtils.setParameterValue(ps, 1, Types.TIME, null, date); } public void testSetParameterValueWithTimeAndCalendar() throws SQLException { java.util.Calendar cal = new GregorianCalendar(); ps.setTime(1, new java.sql.Time(cal.getTime().getTime()), cal); psControl.setVoidCallable(1); psControl.replay(); StatementCreatorUtils.setParameterValue(ps, 1, Types.TIME, null, cal); } public void testSetParameterValueWithSqlTimestamp() throws SQLException { java.sql.Timestamp timestamp = new java.sql.Timestamp(1000); ps.setTimestamp(1, timestamp); psControl.setVoidCallable(1); psControl.replay(); StatementCreatorUtils.setParameterValue(ps, 1, Types.TIMESTAMP, null, timestamp); } public void testSetParameterValueWithTimestampAndUtilDate() throws SQLException { java.util.Date date = new java.util.Date(1000); ps.setTimestamp(1, new java.sql.Timestamp(1000)); psControl.setVoidCallable(1); psControl.replay(); StatementCreatorUtils.setParameterValue(ps, 1, Types.TIMESTAMP, null, date); } public void testSetParameterValueWithTimestampAndCalendar() throws SQLException { java.util.Calendar cal = new GregorianCalendar(); ps.setTimestamp(1, new java.sql.Timestamp(cal.getTime().getTime()), cal); psControl.setVoidCallable(1); psControl.replay(); StatementCreatorUtils.setParameterValue(ps, 1, Types.TIMESTAMP, null, cal); } public void testSetParameterValueWithDateAndUnknownType() throws SQLException { java.util.Date date = new java.util.Date(1000); ps.setTimestamp(1, new java.sql.Timestamp(1000)); psControl.setVoidCallable(1); psControl.replay(); StatementCreatorUtils.setParameterValue(ps, 1, SqlTypeValue.TYPE_UNKNOWN, null, date); } public void testSetParameterValueWithCalendarAndUnknownType() throws SQLException { java.util.Calendar cal = new GregorianCalendar(); ps.setTimestamp(1, new java.sql.Timestamp(cal.getTime().getTime()), cal); psControl.setVoidCallable(1); psControl.replay(); StatementCreatorUtils.setParameterValue(ps, 1, SqlTypeValue.TYPE_UNKNOWN, null, cal); } } ././@LongLink0000000000000000000000000000016100000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/test/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000755000175000017500000000000011623223530033316 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000020400000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/test/AbstractPerson.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000000223111623223526033323 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.test; import java.util.Date; /** * @author Thomas Risberg */ public abstract class AbstractPerson { private String name; private long age; private Date birth_date; public String getName() { return name; } public void setName(String name) { this.name = name; } public long getAge() { return age; } public void setAge(long age) { this.age = age; } public Date getBirth_date() { return birth_date; } public void setBirth_date(Date birth_date) { this.birth_date = birth_date; } }././@LongLink0000000000000000000000000000017400000000000011567 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/test/Person.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000000252011623223530033317 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.test; import java.math.BigDecimal; /** * @author Thomas Risberg */ public class Person { private String name; private long age; private java.util.Date birth_date; private BigDecimal balance; public String getName() { return name; } public void setName(String name) { this.name = name; } public long getAge() { return age; } public void setAge(long age) { this.age = age; } public java.util.Date getBirth_date() { return birth_date; } public void setBirth_date(java.util.Date birth_date) { this.birth_date = birth_date; } public BigDecimal getBalance() { return balance; } public void setBalance(BigDecimal balanace) { this.balance = balanace; } }././@LongLink0000000000000000000000000000020400000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/test/ConcretePerson.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000000166511623223530033330 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.test; import java.math.BigDecimal; /** * @author Thomas Risberg */ public class ConcretePerson extends AbstractPerson { private BigDecimal balance; public BigDecimal getBalance() { return balance; } public void setBalance(BigDecimal balance) { this.balance = balance; } }././@LongLink0000000000000000000000000000020100000000000011556 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/test/SpacePerson.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000000255211623223530033324 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.test; import java.math.BigDecimal; /** * @author Thomas Risberg */ public class SpacePerson { private String lastName; private long age; private java.util.Date birthDate; private BigDecimal balance; public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public long getAge() { return age; } public void setAge(long age) { this.age = age; } public java.util.Date getBirthDate() { return birthDate; } public void setBirth_date(java.util.Date birthDate) { this.birthDate = birthDate; } public BigDecimal getBalance() { return balance; } public void setBalance(BigDecimal balanace) { this.balance = balanace; } }././@LongLink0000000000000000000000000000020400000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/test/ExtendedPerson.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000000163211623223530033322 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.test; /** * @author Juergen Hoeller */ public class ExtendedPerson extends ConcretePerson { private Object someField; public Object getSomeField() { return someField; } public void setSomeField(Object someField) { this.someField = someField; } }././@LongLink0000000000000000000000000000020600000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/BatchUpdateTestHelper.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000000700311623223530033320 0ustar drazzibdrazzibpackage org.springframework.jdbc.core; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.DatabaseMetaData; import java.sql.SQLException; import java.util.List; import java.util.Map; import javax.sql.DataSource; import org.easymock.MockControl; import org.apache.commons.logging.LogFactory; import org.springframework.jdbc.core.namedparam.SqlParameterSource; /** * @author Thomas Risberg */ public abstract class BatchUpdateTestHelper { public static void prepareBatchUpdateMocks(String sqlToUse, Object ids, int[] sqlTypes, int[] rowsAffected, MockControl ctrlDataSource, DataSource mockDataSource, MockControl ctrlConnection, Connection mockConnection, MockControl ctrlPreparedStatement, PreparedStatement mockPreparedStatement, MockControl ctrlDatabaseMetaData, DatabaseMetaData mockDatabaseMetaData) throws SQLException { mockConnection.getMetaData(); ctrlConnection.setDefaultReturnValue(null); mockConnection.close(); ctrlConnection.setDefaultVoidCallable(); mockDataSource.getConnection(); ctrlDataSource.setDefaultReturnValue(mockConnection); mockPreparedStatement.getConnection(); ctrlPreparedStatement.setReturnValue(mockConnection); int idLength = 0; if (ids instanceof SqlParameterSource[]) { idLength = ((SqlParameterSource[])ids).length; } else if (ids instanceof Map[]) { idLength = ((Map[])ids).length; } else { idLength = ((List)ids).size(); } for (int i = 0; i < idLength; i++) { if (ids instanceof SqlParameterSource[]) { if (sqlTypes != null) { mockPreparedStatement.setObject(1, ((SqlParameterSource[])ids)[i].getValue("id"), sqlTypes[0]); } else { mockPreparedStatement.setObject(1, ((SqlParameterSource[])ids)[i].getValue("id")); } } else if (ids instanceof Map[]) { if (sqlTypes != null) { mockPreparedStatement.setObject(1, ((Map[])ids)[i].get("id"), sqlTypes[0]); } else { mockPreparedStatement.setObject(1, ((Map[])ids)[i].get("id")); } } else { if (sqlTypes != null) { mockPreparedStatement.setObject(1, ((Object[])((List)ids).get(i))[0], sqlTypes[0]); } else { mockPreparedStatement.setObject(1, ((Object[])((List)ids).get(i))[0]); } } ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.addBatch(); ctrlPreparedStatement.setVoidCallable(); } mockPreparedStatement.executeBatch(); ctrlPreparedStatement.setReturnValue(rowsAffected); if (LogFactory.getLog(JdbcTemplate.class).isDebugEnabled()) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockDatabaseMetaData.getDatabaseProductName(); ctrlDatabaseMetaData.setReturnValue("MySQL"); mockDatabaseMetaData.supportsBatchUpdates(); ctrlDatabaseMetaData.setReturnValue(true); mockConnection.prepareStatement(sqlToUse); ctrlConnection.setReturnValue(mockPreparedStatement); mockConnection.getMetaData(); ctrlConnection.setReturnValue(mockDatabaseMetaData, 2); } public static void replayBatchUpdateMocks(MockControl ctrlDataSource, MockControl ctrlConnection, MockControl ctrlPreparedStatement, MockControl ctrlDatabaseMetaData) { ctrlPreparedStatement.replay(); ctrlDatabaseMetaData.replay(); ctrlDataSource.replay(); ctrlConnection.replay(); } public static void verifyBatchUpdateMocks(MockControl ctrlPreparedStatement, MockControl ctrlDatabaseMetaData) { ctrlPreparedStatement.verify(); ctrlDatabaseMetaData.verify(); } } ././@LongLink0000000000000000000000000000016700000000000011571 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/namedparam/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000755000175000017500000000000011623223530033316 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000023300000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/namedparam/NamedParameterJdbcTemplateTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000005175611623223526033343 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.namedparam; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Collections; import javax.sql.DataSource; import org.easymock.MockControl; import org.apache.commons.logging.LogFactory; import org.springframework.dao.DataAccessException; import org.springframework.jdbc.AbstractJdbcTests; import org.springframework.jdbc.Customer; import org.springframework.jdbc.core.JdbcOperations; import org.springframework.jdbc.core.PreparedStatementCallback; import org.springframework.jdbc.core.ResultSetExtractor; import org.springframework.jdbc.core.RowCallbackHandler; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.SqlParameterValue; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.BatchUpdateTestHelper; /** * @author Rick Evans * @author Juergen Hoeller * @author Chris Beams */ public class NamedParameterJdbcTemplateTests extends AbstractJdbcTests { private static final String SELECT_NAMED_PARAMETERS = "select id, forename from custmr where id = :id and country = :country"; private static final String SELECT_NAMED_PARAMETERS_PARSED = "select id, forename from custmr where id = ? and country = ?"; private static final String UPDATE_NAMED_PARAMETERS = "update seat_status set booking_id = null where performance_id = :perfId and price_band_id = :priceId"; private static final String UPDATE_NAMED_PARAMETERS_PARSED = "update seat_status set booking_id = null where performance_id = ? and price_band_id = ?"; private static final String[] COLUMN_NAMES = new String[] {"id", "forename"}; private final boolean debugEnabled = LogFactory.getLog(JdbcTemplate.class).isDebugEnabled(); private MockControl ctrlPreparedStatement; private PreparedStatement mockPreparedStatement; private MockControl ctrlResultSet; private ResultSet mockResultSet; protected void setUp() throws Exception { super.setUp(); ctrlPreparedStatement = MockControl.createControl(PreparedStatement.class); mockPreparedStatement = (PreparedStatement) ctrlPreparedStatement.getMock(); ctrlResultSet = MockControl.createControl(ResultSet.class); mockResultSet = (ResultSet) ctrlResultSet.getMock(); } protected void tearDown() throws Exception { super.tearDown(); if (shouldVerify()) { ctrlPreparedStatement.verify(); ctrlResultSet.verify(); } } protected void replay() { super.replay(); ctrlPreparedStatement.replay(); ctrlResultSet.replay(); } public void testNullDataSourceProvidedToCtor() throws Exception { try { new NamedParameterJdbcTemplate((DataSource) null); fail("should have thrown IllegalArgumentException"); } catch (IllegalArgumentException ex) { /* expected */ } } public void testNullJdbcTemplateProvidedToCtor() throws Exception { try { new NamedParameterJdbcTemplate((JdbcOperations) null); fail("should have thrown IllegalArgumentException"); } catch (IllegalArgumentException ex) { /* expected */ } } public void testExecute() throws SQLException { mockPreparedStatement.setObject(1, new Integer(1)); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.setObject(2, new Integer(1)); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeUpdate(); ctrlPreparedStatement.setReturnValue(1); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(UPDATE_NAMED_PARAMETERS_PARSED); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); NamedParameterJdbcTemplate jt = new NamedParameterJdbcTemplate(mockDataSource); Map params = new HashMap(); params.put("perfId", new Integer(1)); params.put("priceId", new Integer(1)); assertEquals("result", jt.execute(UPDATE_NAMED_PARAMETERS, params, new PreparedStatementCallback() { public Object doInPreparedStatement(PreparedStatement ps) throws SQLException { assertEquals(mockPreparedStatement, ps); ps.executeUpdate(); return "result"; } })); } public void testExecuteWithTypedParameters() throws SQLException { mockPreparedStatement.setObject(1, new Integer(1), Types.DECIMAL); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.setObject(2, new Integer(1), Types.INTEGER); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeUpdate(); ctrlPreparedStatement.setReturnValue(1); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(UPDATE_NAMED_PARAMETERS_PARSED); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); NamedParameterJdbcTemplate jt = new NamedParameterJdbcTemplate(mockDataSource); Map params = new HashMap(); params.put("perfId", new SqlParameterValue(Types.DECIMAL, new Integer(1))); params.put("priceId", new SqlParameterValue(Types.INTEGER, new Integer(1))); assertEquals("result", jt.execute(UPDATE_NAMED_PARAMETERS, params, new PreparedStatementCallback() { public Object doInPreparedStatement(PreparedStatement ps) throws SQLException { assertEquals(mockPreparedStatement, ps); ps.executeUpdate(); return "result"; } })); } public void testUpdate() throws SQLException { mockPreparedStatement.setObject(1, new Integer(1)); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.setObject(2, new Integer(1)); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeUpdate(); ctrlPreparedStatement.setReturnValue(1); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(UPDATE_NAMED_PARAMETERS_PARSED); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); NamedParameterJdbcTemplate jt = new NamedParameterJdbcTemplate(mockDataSource); Map params = new HashMap(); params.put("perfId", new Integer(1)); params.put("priceId", new Integer(1)); int rowsAffected = jt.update(UPDATE_NAMED_PARAMETERS, params); assertEquals(1, rowsAffected); } public void testUpdateWithTypedParameters() throws SQLException { mockPreparedStatement.setObject(1, new Integer(1), Types.DECIMAL); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.setObject(2, new Integer(1), Types.INTEGER); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeUpdate(); ctrlPreparedStatement.setReturnValue(1); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(UPDATE_NAMED_PARAMETERS_PARSED); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); NamedParameterJdbcTemplate jt = new NamedParameterJdbcTemplate(mockDataSource); Map params = new HashMap(); params.put("perfId", new SqlParameterValue(Types.DECIMAL, new Integer(1))); params.put("priceId", new SqlParameterValue(Types.INTEGER, new Integer(1))); int rowsAffected = jt.update(UPDATE_NAMED_PARAMETERS, params); assertEquals(1, rowsAffected); } public void testQueryWithResultSetExtractor() throws SQLException { mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getInt("id"); ctrlResultSet.setReturnValue(1); mockResultSet.getString("forename"); ctrlResultSet.setReturnValue("rod"); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockPreparedStatement.setObject(1, new Integer(1), Types.DECIMAL); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.setString(2, "UK"); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeQuery(); ctrlPreparedStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(SELECT_NAMED_PARAMETERS_PARSED); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); NamedParameterJdbcTemplate jt = new NamedParameterJdbcTemplate(mockDataSource); Map params = new HashMap(); params.put("id", new SqlParameterValue(Types.DECIMAL, new Integer(1))); params.put("country", "UK"); Customer cust = (Customer) jt.query(SELECT_NAMED_PARAMETERS, params, new ResultSetExtractor() { public Object extractData(ResultSet rs) throws SQLException, DataAccessException { rs.next(); Customer cust = new Customer(); cust.setId(rs.getInt(COLUMN_NAMES[0])); cust.setForename(rs.getString(COLUMN_NAMES[1])); return cust; } }); assertTrue("Customer id was assigned correctly", cust.getId() == 1); assertTrue("Customer forename was assigned correctly", cust.getForename().equals("rod")); } public void testQueryWithRowCallbackHandler() throws SQLException { mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getInt("id"); ctrlResultSet.setReturnValue(1); mockResultSet.getString("forename"); ctrlResultSet.setReturnValue("rod"); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockPreparedStatement.setObject(1, new Integer(1), Types.DECIMAL); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.setString(2, "UK"); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeQuery(); ctrlPreparedStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(SELECT_NAMED_PARAMETERS_PARSED); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); NamedParameterJdbcTemplate jt = new NamedParameterJdbcTemplate(mockDataSource); Map params = new HashMap(); params.put("id", new SqlParameterValue(Types.DECIMAL, new Integer(1))); params.put("country", "UK"); final List customers = new LinkedList(); jt.query(SELECT_NAMED_PARAMETERS, params, new RowCallbackHandler() { public void processRow(ResultSet rs) throws SQLException { Customer cust = new Customer(); cust.setId(rs.getInt(COLUMN_NAMES[0])); cust.setForename(rs.getString(COLUMN_NAMES[1])); customers.add(cust); } }); assertEquals(1, customers.size()); Customer cust = (Customer) customers.get(0); assertTrue("Customer id was assigned correctly", cust.getId() == 1); assertTrue("Customer forename was assigned correctly", cust.getForename().equals("rod")); } public void testQueryWithRowMapper() throws SQLException { mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getInt("id"); ctrlResultSet.setReturnValue(1); mockResultSet.getString("forename"); ctrlResultSet.setReturnValue("rod"); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockPreparedStatement.setObject(1, new Integer(1), Types.DECIMAL); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.setString(2, "UK"); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeQuery(); ctrlPreparedStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(SELECT_NAMED_PARAMETERS_PARSED); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); NamedParameterJdbcTemplate jt = new NamedParameterJdbcTemplate(mockDataSource); Map params = new HashMap(); params.put("id", new SqlParameterValue(Types.DECIMAL, new Integer(1))); params.put("country", "UK"); List customers = jt.query(SELECT_NAMED_PARAMETERS, params, new RowMapper() { public Object mapRow(ResultSet rs, int rownum) throws SQLException { Customer cust = new Customer(); cust.setId(rs.getInt(COLUMN_NAMES[0])); cust.setForename(rs.getString(COLUMN_NAMES[1])); return cust; } }); assertEquals(1, customers.size()); Customer cust = (Customer) customers.get(0); assertTrue("Customer id was assigned correctly", cust.getId() == 1); assertTrue("Customer forename was assigned correctly", cust.getForename().equals("rod")); } public void testQueryForObjectWithRowMapper() throws SQLException { mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getInt("id"); ctrlResultSet.setReturnValue(1); mockResultSet.getString("forename"); ctrlResultSet.setReturnValue("rod"); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockPreparedStatement.setObject(1, new Integer(1), Types.DECIMAL); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.setString(2, "UK"); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeQuery(); ctrlPreparedStatement.setReturnValue(mockResultSet); if (debugEnabled) { mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); } mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(SELECT_NAMED_PARAMETERS_PARSED); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); NamedParameterJdbcTemplate jt = new NamedParameterJdbcTemplate(mockDataSource); Map params = new HashMap(); params.put("id", new SqlParameterValue(Types.DECIMAL, new Integer(1))); params.put("country", "UK"); Customer cust = (Customer) jt.queryForObject(SELECT_NAMED_PARAMETERS, params, new RowMapper() { public Object mapRow(ResultSet rs, int rownum) throws SQLException { Customer cust = new Customer(); cust.setId(rs.getInt(COLUMN_NAMES[0])); cust.setForename(rs.getString(COLUMN_NAMES[1])); return cust; } }); assertTrue("Customer id was assigned correctly", cust.getId() == 1); assertTrue("Customer forename was assigned correctly", cust.getForename().equals("rod")); } public void testBatchUpdateWithPlainMap() throws Exception { final String sqlToUse = "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = ?"; final String sql = "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = :id"; final Map[] ids = new Map[2]; ids[0] = Collections.singletonMap("id", 100); ids[1] = Collections.singletonMap("id", 200); final int[] rowsAffected = new int[] { 1, 2 }; MockControl ctrlDataSource = MockControl.createControl(DataSource.class); DataSource mockDataSource = (DataSource) ctrlDataSource.getMock(); MockControl ctrlConnection = MockControl.createControl(Connection.class); Connection mockConnection = (Connection) ctrlConnection.getMock(); MockControl ctrlPreparedStatement = MockControl.createControl(PreparedStatement.class); PreparedStatement mockPreparedStatement = (PreparedStatement) ctrlPreparedStatement.getMock(); MockControl ctrlDatabaseMetaData = MockControl.createControl(DatabaseMetaData.class); DatabaseMetaData mockDatabaseMetaData = (DatabaseMetaData) ctrlDatabaseMetaData.getMock(); BatchUpdateTestHelper.prepareBatchUpdateMocks(sqlToUse, ids, null, rowsAffected, ctrlDataSource, mockDataSource, ctrlConnection, mockConnection, ctrlPreparedStatement, mockPreparedStatement, ctrlDatabaseMetaData, mockDatabaseMetaData); BatchUpdateTestHelper.replayBatchUpdateMocks(ctrlDataSource, ctrlConnection, ctrlPreparedStatement, ctrlDatabaseMetaData); JdbcTemplate template = new JdbcTemplate(mockDataSource, false); NamedParameterJdbcTemplate namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(template); int[] actualRowsAffected = namedParameterJdbcTemplate.batchUpdate(sql, ids); assertTrue("executed 2 updates", actualRowsAffected.length == 2); assertEquals(rowsAffected[0], actualRowsAffected[0]); assertEquals(rowsAffected[1], actualRowsAffected[1]); BatchUpdateTestHelper.verifyBatchUpdateMocks(ctrlPreparedStatement, ctrlDatabaseMetaData); } public void testBatchUpdateWithSqlParameterSource() throws Exception { final String sqlToUse = "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = ?"; final String sql = "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = :id"; final SqlParameterSource[] ids = new SqlParameterSource[2]; ids[0] = new MapSqlParameterSource("id", 100); ids[1] = new MapSqlParameterSource("id", 200); final int[] rowsAffected = new int[] { 1, 2 }; MockControl ctrlDataSource = MockControl.createControl(DataSource.class); DataSource mockDataSource = (DataSource) ctrlDataSource.getMock(); MockControl ctrlConnection = MockControl.createControl(Connection.class); Connection mockConnection = (Connection) ctrlConnection.getMock(); MockControl ctrlPreparedStatement = MockControl.createControl(PreparedStatement.class); PreparedStatement mockPreparedStatement = (PreparedStatement) ctrlPreparedStatement.getMock(); MockControl ctrlDatabaseMetaData = MockControl.createControl(DatabaseMetaData.class); DatabaseMetaData mockDatabaseMetaData = (DatabaseMetaData) ctrlDatabaseMetaData.getMock(); BatchUpdateTestHelper.prepareBatchUpdateMocks(sqlToUse, ids, null, rowsAffected, ctrlDataSource, mockDataSource, ctrlConnection, mockConnection, ctrlPreparedStatement, mockPreparedStatement, ctrlDatabaseMetaData, mockDatabaseMetaData); BatchUpdateTestHelper.replayBatchUpdateMocks(ctrlDataSource, ctrlConnection, ctrlPreparedStatement, ctrlDatabaseMetaData); JdbcTemplate template = new JdbcTemplate(mockDataSource, false); NamedParameterJdbcTemplate namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(template); int[] actualRowsAffected = namedParameterJdbcTemplate.batchUpdate(sql, ids); assertTrue("executed 2 updates", actualRowsAffected.length == 2); assertEquals(rowsAffected[0], actualRowsAffected[0]); assertEquals(rowsAffected[1], actualRowsAffected[1]); BatchUpdateTestHelper.verifyBatchUpdateMocks(ctrlPreparedStatement, ctrlDatabaseMetaData); } public void testBatchUpdateWithSqlParameterSourcePlusTypeInfo() throws Exception { final String sqlToUse = "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = ?"; final String sql = "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = :id"; final SqlParameterSource[] ids = new SqlParameterSource[2]; ids[0] = new MapSqlParameterSource().addValue("id", 100, Types.NUMERIC); ids[1] = new MapSqlParameterSource().addValue("id", 200, Types.NUMERIC); final int[] sqlTypes = new int[] {Types.NUMERIC}; final int[] rowsAffected = new int[] { 1, 2 }; MockControl ctrlDataSource = MockControl.createControl(DataSource.class); DataSource mockDataSource = (DataSource) ctrlDataSource.getMock(); MockControl ctrlConnection = MockControl.createControl(Connection.class); Connection mockConnection = (Connection) ctrlConnection.getMock(); MockControl ctrlPreparedStatement = MockControl.createControl(PreparedStatement.class); PreparedStatement mockPreparedStatement = (PreparedStatement) ctrlPreparedStatement.getMock(); MockControl ctrlDatabaseMetaData = MockControl.createControl(DatabaseMetaData.class); DatabaseMetaData mockDatabaseMetaData = (DatabaseMetaData) ctrlDatabaseMetaData.getMock(); BatchUpdateTestHelper.prepareBatchUpdateMocks(sqlToUse, ids, sqlTypes, rowsAffected, ctrlDataSource, mockDataSource, ctrlConnection, mockConnection, ctrlPreparedStatement, mockPreparedStatement, ctrlDatabaseMetaData, mockDatabaseMetaData); BatchUpdateTestHelper.replayBatchUpdateMocks(ctrlDataSource, ctrlConnection, ctrlPreparedStatement, ctrlDatabaseMetaData); JdbcTemplate template = new JdbcTemplate(mockDataSource, false); NamedParameterJdbcTemplate namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(template); int[] actualRowsAffected = namedParameterJdbcTemplate.batchUpdate(sql, ids); assertTrue("executed 2 updates", actualRowsAffected.length == 2); assertEquals(rowsAffected[0], actualRowsAffected[0]); assertEquals(rowsAffected[1], actualRowsAffected[1]); BatchUpdateTestHelper.verifyBatchUpdateMocks(ctrlPreparedStatement, ctrlDatabaseMetaData); } } ././@LongLink0000000000000000000000000000022400000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/namedparam/NamedParameterQueryTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000005044711623223526033337 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.namedparam; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Types; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import org.easymock.MockControl; import org.springframework.jdbc.AbstractJdbcTests; import org.springframework.jdbc.core.RowMapper; /** * @author Thomas Risberg */ public class NamedParameterQueryTests extends AbstractJdbcTests { private MockControl ctrlPreparedStatement; private PreparedStatement mockPreparedStatement; private MockControl ctrlResultSet; private ResultSet mockResultSet; private MockControl ctrlResultSetMetaData; private ResultSetMetaData mockResultSetMetaData; protected void setUp() throws Exception { super.setUp(); ctrlPreparedStatement = MockControl.createControl(PreparedStatement.class); mockPreparedStatement = (PreparedStatement) ctrlPreparedStatement.getMock(); ctrlResultSet = MockControl.createControl(ResultSet.class); mockResultSet = (ResultSet) ctrlResultSet.getMock(); ctrlResultSetMetaData = MockControl.createControl(ResultSetMetaData.class); mockResultSetMetaData = (ResultSetMetaData) ctrlResultSetMetaData.getMock(); } protected void replay() { super.replay(); ctrlPreparedStatement.replay(); ctrlResultSet.replay(); ctrlResultSetMetaData.replay(); } protected void tearDown() throws Exception { super.tearDown(); if (false && shouldVerify()) { ctrlPreparedStatement.verify(); ctrlResultSet.verify(); ctrlResultSetMetaData.verify(); } } public void testQueryForListWithParamMap() throws Exception { String sql = "SELECT AGE FROM CUSTMR WHERE ID < :id"; String sqlToUse = "SELECT AGE FROM CUSTMR WHERE ID < ?"; mockResultSetMetaData.getColumnCount(); ctrlResultSetMetaData.setReturnValue(1, 2); mockResultSetMetaData.getColumnLabel(1); ctrlResultSetMetaData.setReturnValue("age", 2); mockResultSet.getMetaData(); ctrlResultSet.setReturnValue(mockResultSetMetaData, 2); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getObject(1); ctrlResultSet.setReturnValue(new Integer(11)); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getObject(1); ctrlResultSet.setReturnValue(new Integer(12)); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockPreparedStatement.setObject(1, new Integer(3)); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeQuery(); ctrlPreparedStatement.setReturnValue(mockResultSet); mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(sqlToUse); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(mockDataSource); MapSqlParameterSource parms = new MapSqlParameterSource(); parms.addValue("id", new Integer(3)); List li = template.queryForList(sql, parms); assertEquals("All rows returned", 2, li.size()); assertEquals("First row is Integer", 11, ((Integer)((Map)li.get(0)).get("age")).intValue()); assertEquals("Second row is Integer", 12, ((Integer)((Map)li.get(1)).get("age")).intValue()); } public void testQueryForListWithParamMapAndEmptyResult() throws Exception { String sql = "SELECT AGE FROM CUSTMR WHERE ID < :id"; String sqlToUse = "SELECT AGE FROM CUSTMR WHERE ID < ?"; ctrlResultSet = MockControl.createControl(ResultSet.class); mockResultSet = (ResultSet) ctrlResultSet.getMock(); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockPreparedStatement.setObject(1, new Integer(3)); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeQuery(); ctrlPreparedStatement.setReturnValue(mockResultSet); mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(sqlToUse); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(mockDataSource); MapSqlParameterSource parms = new MapSqlParameterSource(); parms.addValue("id", new Integer(3)); List li = template.queryForList(sql, parms); assertEquals("All rows returned", 0, li.size()); } public void testQueryForListWithParamMapAndSingleRowAndColumn() throws Exception { String sql = "SELECT AGE FROM CUSTMR WHERE ID < :id"; String sqlToUse = "SELECT AGE FROM CUSTMR WHERE ID < ?"; mockResultSetMetaData.getColumnCount(); ctrlResultSetMetaData.setReturnValue(1); mockResultSetMetaData.getColumnLabel(1); ctrlResultSetMetaData.setReturnValue("age", 1); mockResultSet.getMetaData(); ctrlResultSet.setReturnValue(mockResultSetMetaData); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getObject(1); ctrlResultSet.setReturnValue(new Integer(11)); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockPreparedStatement.setObject(1, new Integer(3)); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeQuery(); ctrlPreparedStatement.setReturnValue(mockResultSet); mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(sqlToUse); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(mockDataSource); MapSqlParameterSource parms = new MapSqlParameterSource(); parms.addValue("id", new Integer(3)); List li = template.queryForList(sql, parms); assertEquals("All rows returned", 1, li.size()); assertEquals("First row is Integer", 11, ((Integer)((Map)li.get(0)).get("age")).intValue()); } public void testQueryForListWithParamMapAndIntegerElementAndSingleRowAndColumn() throws Exception { String sql = "SELECT AGE FROM CUSTMR WHERE ID < :id"; String sqlToUse = "SELECT AGE FROM CUSTMR WHERE ID < ?"; mockResultSetMetaData.getColumnCount(); ctrlResultSetMetaData.setReturnValue(1); mockResultSet.getMetaData(); ctrlResultSet.setReturnValue(mockResultSetMetaData); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getInt(1); ctrlResultSet.setReturnValue(11); mockResultSet.wasNull(); ctrlResultSet.setReturnValue(false); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockPreparedStatement.setObject(1, new Integer(3)); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeQuery(); ctrlPreparedStatement.setReturnValue(mockResultSet); mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(sqlToUse); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(mockDataSource); MapSqlParameterSource parms = new MapSqlParameterSource(); parms.addValue("id", new Integer(3)); List li = template.queryForList(sql, parms, Integer.class); assertEquals("All rows returned", 1, li.size()); assertEquals("First row is Integer", 11, ((Integer) li.get(0)).intValue()); } public void testQueryForMapWithParamMapAndSingleRowAndColumn() throws Exception { String sql = "SELECT AGE FROM CUSTMR WHERE ID < :id"; String sqlToUse = "SELECT AGE FROM CUSTMR WHERE ID < ?"; mockResultSetMetaData.getColumnCount(); ctrlResultSetMetaData.setReturnValue(1); mockResultSetMetaData.getColumnLabel(1); ctrlResultSetMetaData.setReturnValue("age", 1); mockResultSet.getMetaData(); ctrlResultSet.setReturnValue(mockResultSetMetaData); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getObject(1); ctrlResultSet.setReturnValue(new Integer(11)); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockPreparedStatement.setObject(1, new Integer(3)); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeQuery(); ctrlPreparedStatement.setReturnValue(mockResultSet); mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(sqlToUse); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(mockDataSource); MapSqlParameterSource parms = new MapSqlParameterSource(); parms.addValue("id", new Integer(3)); Map map = template.queryForMap(sql, parms); assertEquals("Row is Integer", 11, ((Integer) map.get("age")).intValue()); } public void testQueryForObjectWithParamMapAndRowMapper() throws Exception { String sql = "SELECT AGE FROM CUSTMR WHERE ID = :id"; String sqlToUse = "SELECT AGE FROM CUSTMR WHERE ID = ?"; mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getInt(1); ctrlResultSet.setReturnValue(22); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockPreparedStatement.setObject(1, new Integer(3)); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeQuery(); ctrlPreparedStatement.setReturnValue(mockResultSet); mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(sqlToUse); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(mockDataSource); MapSqlParameterSource parms = new MapSqlParameterSource(); parms.addValue("id", new Integer(3)); Object o = template.queryForObject(sql, parms, new RowMapper() { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { return new Integer(rs.getInt(1)); } }); assertTrue("Correct result type", o instanceof Integer); } public void testQueryForObjectWithMapAndInteger() throws Exception { String sql = "SELECT AGE FROM CUSTMR WHERE ID = :id"; String sqlToUse = "SELECT AGE FROM CUSTMR WHERE ID = ?"; mockResultSetMetaData.getColumnCount(); ctrlResultSetMetaData.setReturnValue(1); mockResultSet.getMetaData(); ctrlResultSet.setReturnValue(mockResultSetMetaData); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getInt(1); ctrlResultSet.setReturnValue(22); mockResultSet.wasNull(); ctrlResultSet.setReturnValue(false); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockPreparedStatement.setObject(1, new Integer(3)); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeQuery(); ctrlPreparedStatement.setReturnValue(mockResultSet); mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(sqlToUse); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(mockDataSource); Map parms = new HashMap(); parms.put("id", new Integer(3)); Object o = template.queryForObject(sql, parms, Integer.class); assertTrue("Correct result type", o instanceof Integer); } public void testQueryForObjectWithParamMapAndInteger() throws Exception { String sql = "SELECT AGE FROM CUSTMR WHERE ID = :id"; String sqlToUse = "SELECT AGE FROM CUSTMR WHERE ID = ?"; mockResultSetMetaData.getColumnCount(); ctrlResultSetMetaData.setReturnValue(1); mockResultSet.getMetaData(); ctrlResultSet.setReturnValue(mockResultSetMetaData); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getInt(1); ctrlResultSet.setReturnValue(22); mockResultSet.wasNull(); ctrlResultSet.setReturnValue(false); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockPreparedStatement.setObject(1, new Integer(3)); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeQuery(); ctrlPreparedStatement.setReturnValue(mockResultSet); mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(sqlToUse); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(mockDataSource); MapSqlParameterSource parms = new MapSqlParameterSource(); parms.addValue("id", new Integer(3)); Object o = template.queryForObject(sql, parms, Integer.class); assertTrue("Correct result type", o instanceof Integer); } public void testQueryForObjectWithParamMapAndList() throws Exception { String sql = "SELECT AGE FROM CUSTMR WHERE ID IN (:ids)"; String sqlToUse = "SELECT AGE FROM CUSTMR WHERE ID IN (?, ?)"; mockResultSetMetaData.getColumnCount(); ctrlResultSetMetaData.setReturnValue(1); mockResultSet.getMetaData(); ctrlResultSet.setReturnValue(mockResultSetMetaData); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getInt(1); ctrlResultSet.setReturnValue(22); mockResultSet.wasNull(); ctrlResultSet.setReturnValue(false); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockPreparedStatement.setObject(1, new Integer(3)); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.setObject(2, new Integer(4)); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeQuery(); ctrlPreparedStatement.setReturnValue(mockResultSet); mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(sqlToUse); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(mockDataSource); MapSqlParameterSource parms = new MapSqlParameterSource(); parms.addValue("ids", Arrays.asList(new Object[] {new Integer(3), new Integer(4)})); Object o = template.queryForObject(sql, parms, Integer.class); assertTrue("Correct result type", o instanceof Integer); } public void testQueryForObjectWithParamMapAndListOfExpressionLists() throws Exception { String sql = "SELECT AGE FROM CUSTMR WHERE (ID, NAME) IN (:multiExpressionList)"; String sqlToUse = "SELECT AGE FROM CUSTMR WHERE (ID, NAME) IN ((?, ?), (?, ?))"; mockResultSetMetaData.getColumnCount(); ctrlResultSetMetaData.setReturnValue(1); mockResultSet.getMetaData(); ctrlResultSet.setReturnValue(mockResultSetMetaData); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getInt(1); ctrlResultSet.setReturnValue(22); mockResultSet.wasNull(); ctrlResultSet.setReturnValue(false); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockPreparedStatement.setObject(1, new Integer(3)); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.setString(2, "Rod"); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.setObject(3, new Integer(4)); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.setString(4, "Juergen"); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeQuery(); ctrlPreparedStatement.setReturnValue(mockResultSet); mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(sqlToUse); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(mockDataSource); MapSqlParameterSource parms = new MapSqlParameterSource(); List l1 = new ArrayList(); l1.add(new Object[] {new Integer(3), "Rod"}); l1.add(new Object[] {new Integer(4), "Juergen"}); parms.addValue("multiExpressionList", l1); Object o = template.queryForObject(sql, parms, Integer.class); assertTrue("Correct result type", o instanceof Integer); } public void testQueryForIntWithParamMap() throws Exception { String sql = "SELECT AGE FROM CUSTMR WHERE ID = :id"; String sqlToUse = "SELECT AGE FROM CUSTMR WHERE ID = ?"; mockResultSetMetaData.getColumnCount(); ctrlResultSetMetaData.setReturnValue(1); mockResultSet.getMetaData(); ctrlResultSet.setReturnValue(mockResultSetMetaData); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getDouble(1); ctrlResultSet.setReturnValue(22.0d); mockResultSet.wasNull(); ctrlResultSet.setReturnValue(false); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockPreparedStatement.setObject(1, new Integer(3)); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeQuery(); ctrlPreparedStatement.setReturnValue(mockResultSet); mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(sqlToUse); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(mockDataSource); MapSqlParameterSource parms = new MapSqlParameterSource(); parms.addValue("id", new Integer(3)); int i = template.queryForInt(sql, parms); assertEquals("Return of an int", 22, i); } public void testQueryForLongWithParamBean() throws Exception { String sql = "SELECT AGE FROM CUSTMR WHERE ID = :id"; String sqlToUse = "SELECT AGE FROM CUSTMR WHERE ID = ?"; mockResultSetMetaData.getColumnCount(); ctrlResultSetMetaData.setReturnValue(1); mockResultSet.getMetaData(); ctrlResultSet.setReturnValue(mockResultSetMetaData); mockResultSet.next(); ctrlResultSet.setReturnValue(true); mockResultSet.getDouble(1); ctrlResultSet.setReturnValue(87.0d); mockResultSet.wasNull(); ctrlResultSet.setReturnValue(false); mockResultSet.next(); ctrlResultSet.setReturnValue(false); mockResultSet.close(); ctrlResultSet.setVoidCallable(); mockPreparedStatement.setObject(1, new Integer(3), Types.INTEGER); ctrlPreparedStatement.setVoidCallable(); mockPreparedStatement.executeQuery(); ctrlPreparedStatement.setReturnValue(mockResultSet); mockPreparedStatement.getWarnings(); ctrlPreparedStatement.setReturnValue(null); mockPreparedStatement.close(); ctrlPreparedStatement.setVoidCallable(); mockConnection.prepareStatement(sqlToUse); ctrlConnection.setReturnValue(mockPreparedStatement); replay(); NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(mockDataSource); BeanPropertySqlParameterSource parms = new BeanPropertySqlParameterSource(new ParameterBean(3)); long l = template.queryForLong(sql, parms); assertEquals("Return of a long", 87, l); } private static class ParameterBean { private int id; public ParameterBean(int id) { this.id = id; } public int getId() { return id; } } } ././@LongLink0000000000000000000000000000023700000000000011567 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/namedparam/BeanPropertySqlParameterSourceTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000000620611623223530033324 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.namedparam; import java.sql.Types; import java.util.Arrays; import static org.junit.Assert.*; import org.junit.Test; import org.springframework.beans.TestBean; /** * @author Rick Evans * @author Juergen Hoeller * @author Arjen Poutsma */ public class BeanPropertySqlParameterSourceTests { @Test(expected = IllegalArgumentException.class) public void withNullBeanPassedToCtor() throws Exception { new BeanPropertySqlParameterSource(null); } @Test(expected = IllegalArgumentException.class) public void getValueWhereTheUnderlyingBeanHasNoSuchProperty() throws Exception { BeanPropertySqlParameterSource source = new BeanPropertySqlParameterSource(new TestBean()); source.getValue("thisPropertyDoesNotExist"); } @Test public void successfulPropertyAccess() { BeanPropertySqlParameterSource source = new BeanPropertySqlParameterSource(new TestBean("tb", 99)); assertTrue(Arrays.asList(source.getReadablePropertyNames()).contains("name")); assertTrue(Arrays.asList(source.getReadablePropertyNames()).contains("age")); assertEquals("tb", source.getValue("name")); assertEquals(99, source.getValue("age")); assertEquals(Types.VARCHAR, source.getSqlType("name")); assertEquals(Types.INTEGER, source.getSqlType("age")); } @Test public void successfulPropertyAccessWithOverriddenSqlType() { BeanPropertySqlParameterSource source = new BeanPropertySqlParameterSource(new TestBean("tb", 99)); source.registerSqlType("age", Types.NUMERIC); assertEquals("tb", source.getValue("name")); assertEquals(99, source.getValue("age")); assertEquals(Types.VARCHAR, source.getSqlType("name")); assertEquals(Types.NUMERIC, source.getSqlType("age")); } @Test public void hasValueWhereTheUnderlyingBeanHasNoSuchProperty() throws Exception { BeanPropertySqlParameterSource source = new BeanPropertySqlParameterSource(new TestBean()); assertFalse(source.hasValue("thisPropertyDoesNotExist")); } @Test(expected = IllegalArgumentException.class) public void getValueWhereTheUnderlyingBeanPropertyIsNotReadable() throws Exception { BeanPropertySqlParameterSource source = new BeanPropertySqlParameterSource(new NoReadableProperties()); source.getValue("noOp"); } @Test public void hasValueWhereTheUnderlyingBeanPropertyIsNotReadable() throws Exception { BeanPropertySqlParameterSource source = new BeanPropertySqlParameterSource(new NoReadableProperties()); assertFalse(source.hasValue("noOp")); } private static final class NoReadableProperties { public void setNoOp(String noOp) { } } } ././@LongLink0000000000000000000000000000022600000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/namedparam/MapSqlParameterSourceTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000000322311623223530033320 0ustar drazzibdrazzib/* * Copyright 2002-2006 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.namedparam; import static org.junit.Assert.assertEquals; import org.junit.Test; import org.springframework.jdbc.core.SqlParameterValue; /** * @author Rick Evans * @author Arjen Poutsma */ public final class MapSqlParameterSourceTests { @Test public void nullParameterValuesPassedToCtorIsOk() throws Exception { new MapSqlParameterSource(null); } @Test(expected = IllegalArgumentException.class) public void getValueChokesIfParameterIsNotPresent() throws Exception { MapSqlParameterSource source = new MapSqlParameterSource(); source.getValue("pechorin was right!"); } @Test public void sqlParameterValueRegistersSqlType() throws Exception { MapSqlParameterSource msps = new MapSqlParameterSource("FOO", new SqlParameterValue(2, "Foo")); assertEquals("Correct SQL Type not registered", 2, msps.getSqlType("FOO")); MapSqlParameterSource msps2 = new MapSqlParameterSource(); msps2.addValues(msps.getValues()); assertEquals("Correct SQL Type not registered", 2, msps2.getSqlType("FOO")); } } ././@LongLink0000000000000000000000000000022400000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/core/namedparam/NamedParameterUtilsTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000002214011623223530033317 0ustar drazzibdrazzib/* * Copyright 2002-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.core.namedparam; import java.util.Collections; import java.util.HashMap; import java.util.Map; import static org.junit.Assert.*; import org.junit.Test; import org.springframework.dao.InvalidDataAccessApiUsageException; /** * @author Thomas Risberg * @author Juergen Hoeller * @author Rick Evans */ public class NamedParameterUtilsTests { @Test public void parseSql() { String sql = "xxx :a yyyy :b :c :a zzzzz"; ParsedSql psql = NamedParameterUtils.parseSqlStatement(sql); assertEquals("xxx ? yyyy ? ? ? zzzzz", NamedParameterUtils.substituteNamedParameters(psql, null)); assertEquals("a", psql.getParameterNames().get(0)); assertEquals("c", psql.getParameterNames().get(2)); assertEquals("a", psql.getParameterNames().get(3)); assertEquals(4, psql.getTotalParameterCount()); assertEquals(3, psql.getNamedParameterCount()); String sql2 = "xxx &a yyyy ? zzzzz"; ParsedSql psql2 = NamedParameterUtils.parseSqlStatement(sql2); assertEquals("xxx ? yyyy ? zzzzz", NamedParameterUtils.substituteNamedParameters(psql2, null)); assertEquals("a", psql2.getParameterNames().get(0)); assertEquals(2, psql2.getTotalParameterCount()); assertEquals(1, psql2.getNamedParameterCount()); String sql3 = "xxx &a+:b" + '\t' + ":c%10 yyyy ? zzzzz"; ParsedSql psql3 = NamedParameterUtils.parseSqlStatement(sql3); assertEquals("a", psql3.getParameterNames().get(0)); assertEquals("b", psql3.getParameterNames().get(1)); assertEquals("c", psql3.getParameterNames().get(2)); } @Test public void substituteNamedParameters() { MapSqlParameterSource namedParams = new MapSqlParameterSource(); namedParams.addValue("a", "a").addValue("b", "b").addValue("c", "c"); assertEquals("xxx ? ? ?", NamedParameterUtils.substituteNamedParameters("xxx :a :b :c", namedParams)); assertEquals("xxx ? ? ? xx ? ?", NamedParameterUtils.substituteNamedParameters("xxx :a :b :c xx :a :a", namedParams)); } @Test public void convertParamMapToArray() { Map paramMap = new HashMap(); paramMap.put("a", "a"); paramMap.put("b", "b"); paramMap.put("c", "c"); assertSame(3, NamedParameterUtils.buildValueArray("xxx :a :b :c", paramMap).length); assertSame(5, NamedParameterUtils.buildValueArray("xxx :a :b :c xx :a :b", paramMap).length); assertSame(5, NamedParameterUtils.buildValueArray("xxx :a :a :a xx :a :a", paramMap).length); assertEquals("b", NamedParameterUtils.buildValueArray("xxx :a :b :c xx :a :b", paramMap)[4]); try { NamedParameterUtils.buildValueArray("xxx :a :b ?", paramMap); fail("mixed named parameters and ? placeholders not detected"); } catch (InvalidDataAccessApiUsageException expected) { } } @Test public void convertTypeMapToArray() { MapSqlParameterSource namedParams = new MapSqlParameterSource(); namedParams.addValue("a", "a", 1).addValue("b", "b", 2).addValue("c", "c", 3); assertSame(3, NamedParameterUtils .buildSqlTypeArray(NamedParameterUtils.parseSqlStatement("xxx :a :b :c"), namedParams).length); assertSame(5, NamedParameterUtils .buildSqlTypeArray(NamedParameterUtils.parseSqlStatement("xxx :a :b :c xx :a :b"), namedParams).length); assertSame(5, NamedParameterUtils .buildSqlTypeArray(NamedParameterUtils.parseSqlStatement("xxx :a :a :a xx :a :a"), namedParams).length); assertEquals(2, NamedParameterUtils .buildSqlTypeArray(NamedParameterUtils.parseSqlStatement("xxx :a :b :c xx :a :b"), namedParams)[4]); } @Test public void convertTypeMapToSqlParameterList() { MapSqlParameterSource namedParams = new MapSqlParameterSource(); namedParams.addValue("a", "a", 1).addValue("b", "b", 2).addValue("c", "c", 3, "SQL_TYPE"); assertSame(3, NamedParameterUtils .buildSqlParameterList(NamedParameterUtils.parseSqlStatement("xxx :a :b :c"), namedParams).size()); assertSame(5, NamedParameterUtils .buildSqlParameterList(NamedParameterUtils.parseSqlStatement("xxx :a :b :c xx :a :b"), namedParams).size()); assertSame(5, NamedParameterUtils .buildSqlParameterList(NamedParameterUtils.parseSqlStatement("xxx :a :a :a xx :a :a"), namedParams).size()); assertEquals(2, NamedParameterUtils .buildSqlParameterList(NamedParameterUtils.parseSqlStatement("xxx :a :b :c xx :a :b"), namedParams).get(4).getSqlType()); assertEquals("SQL_TYPE", NamedParameterUtils .buildSqlParameterList(NamedParameterUtils.parseSqlStatement("xxx :a :b :c"), namedParams).get(2).getTypeName()); } @Test(expected = InvalidDataAccessApiUsageException.class) public void buildValueArrayWithMissingParameterValue() throws Exception { String sql = "select count(0) from foo where id = :id"; NamedParameterUtils.buildValueArray(sql, new HashMap()); } @Test public void substituteNamedParametersWithStringContainingQuotes() throws Exception { String expectedSql = "select 'first name' from artists where id = ? and quote = 'exsqueeze me?'"; String sql = "select 'first name' from artists where id = :id and quote = 'exsqueeze me?'"; String newSql = NamedParameterUtils.substituteNamedParameters(sql, new MapSqlParameterSource()); assertEquals(expectedSql, newSql); } @Test public void testParseSqlStatementWithStringContainingQuotes() throws Exception { String expectedSql = "select 'first name' from artists where id = ? and quote = 'exsqueeze me?'"; String sql = "select 'first name' from artists where id = :id and quote = 'exsqueeze me?'"; ParsedSql parsedSql = NamedParameterUtils.parseSqlStatement(sql); assertEquals(expectedSql, NamedParameterUtils.substituteNamedParameters(parsedSql, null)); } /* * SPR-4789 */ @Test public void parseSqlContainingComments() { String sql1 = "/*+ HINT */ xxx /* comment ? */ :a yyyy :b :c :a zzzzz -- :xx XX\n"; ParsedSql psql1 = NamedParameterUtils.parseSqlStatement(sql1); assertEquals("/*+ HINT */ xxx /* comment ? */ ? yyyy ? ? ? zzzzz -- :xx XX\n", NamedParameterUtils.substituteNamedParameters(psql1, null)); MapSqlParameterSource paramMap = new MapSqlParameterSource(); paramMap.addValue("a", "a"); paramMap.addValue("b", "b"); paramMap.addValue("c", "c"); Object[] params = NamedParameterUtils.buildValueArray(psql1, paramMap, null); assertEquals(4, params.length); assertEquals("a", params[0]); assertEquals("b", params[1]); assertEquals("c", params[2]); assertEquals("a", params[3]); String sql2 = "/*+ HINT */ xxx /* comment ? */ :a yyyy :b :c :a zzzzz -- :xx XX"; ParsedSql psql2 = NamedParameterUtils.parseSqlStatement(sql2); assertEquals("/*+ HINT */ xxx /* comment ? */ ? yyyy ? ? ? zzzzz -- :xx XX", NamedParameterUtils.substituteNamedParameters(psql2, null)); String sql3 = "/*+ HINT */ xxx /* comment ? */ :a yyyy :b :c :a zzzzz /* :xx XX*"; ParsedSql psql3 = NamedParameterUtils.parseSqlStatement(sql3); assertEquals("/*+ HINT */ xxx /* comment ? */ ? yyyy ? ? ? zzzzz /* :xx XX*", NamedParameterUtils.substituteNamedParameters(psql3, null)); String sql4 = "/*+ HINT */ xxx /* comment :a ? */ :a yyyy :b :c :a zzzzz /* :xx XX*"; ParsedSql psql4 = NamedParameterUtils.parseSqlStatement(sql4); Map parameters = Collections.singletonMap("a", "0"); assertEquals("/*+ HINT */ xxx /* comment :a ? */ ? yyyy ? ? ? zzzzz /* :xx XX*", NamedParameterUtils.substituteNamedParameters(psql4, new MapSqlParameterSource(parameters))); } /* * SPR-4612 */ @Test public void parseSqlStatementWithPostgresCasting() throws Exception { String expectedSql = "select 'first name' from artists where id = ? and birth_date=?::timestamp"; String sql = "select 'first name' from artists where id = :id and birth_date=:birthDate::timestamp"; ParsedSql parsedSql = NamedParameterUtils.parseSqlStatement(sql); assertEquals(expectedSql, NamedParameterUtils.substituteNamedParameters(parsedSql, null)); } /* * SPR-2544 */ @Test public void parseSqlStatementWithLogicalAnd() { String expectedSql = "xxx & yyyy"; ParsedSql parsedSql = NamedParameterUtils.parseSqlStatement(expectedSql); assertEquals(expectedSql, NamedParameterUtils.substituteNamedParameters(parsedSql, null)); } /* * SPR-2544 */ @Test public void substituteNamedParametersWithLogicalAnd() throws Exception { String expectedSql = "xxx & yyyy"; String newSql = NamedParameterUtils.substituteNamedParameters(expectedSql, new MapSqlParameterSource()); assertEquals(expectedSql, newSql); } /* * SPR-3173 */ @Test public void variableAssignmentOperator() throws Exception { String expectedSql = "x := 1"; String newSql = NamedParameterUtils.substituteNamedParameters(expectedSql, new MapSqlParameterSource()); assertEquals(expectedSql, newSql); } } ././@LongLink0000000000000000000000000000016400000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/Customer.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000000206211623223530033320 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc; /** * @author Juergen Hoeller */ public class Customer { private int id; private String forename; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getForename() { return forename; } public void setForename(String forename) { this.forename = forename; } public String toString() { return "Customer: id=" + id + "; forename=" + forename; } } ././@LongLink0000000000000000000000000000015700000000000011570 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/support/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000755000175000017500000000000011623223530033316 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000020200000000000011557 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/support/KeyHolderTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000000607511623223530033330 0ustar drazzibdrazzib/* * Copyright 2002-2005 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support; import java.util.HashMap; import java.util.LinkedList; import java.util.Map; import org.springframework.dao.DataRetrievalFailureException; import org.springframework.dao.InvalidDataAccessApiUsageException; import junit.framework.TestCase; /** * Tests for the KeyHolder and GeneratedKeyHolder * and it appears that JdbcUtils doesn't work exactly as documented. * * @author trisberg * @since Jul 18, 2004 */ public class KeyHolderTests extends TestCase { private KeyHolder kh; public void setUp() { kh = new GeneratedKeyHolder(); } public void testSingleKey(){ LinkedList l = new LinkedList(); HashMap m = new HashMap(1); m.put("key", new Integer(1)); l.add(m); kh.getKeyList().addAll(l); assertEquals("single key should be returned", 1, kh.getKey().intValue()); } public void testSingleKeyNonNumeric(){ LinkedList l = new LinkedList(); HashMap m = new HashMap(1); m.put("key", "1"); l.add(m); kh.getKeyList().addAll(l); try { kh.getKey().intValue(); } catch (DataRetrievalFailureException e) { assertTrue(e.getMessage().startsWith("The generated key is not of a supported numeric type.")); } } public void testNoKeyReturnedInMap(){ LinkedList l = new LinkedList(); HashMap m = new HashMap(); l.add(m); kh.getKeyList().addAll(l); try { kh.getKey(); } catch (DataRetrievalFailureException e) { assertTrue(e.getMessage().startsWith("Unable to retrieve the generated key.")); } } public void testMultipleKeys(){ LinkedList l = new LinkedList(); HashMap m = new HashMap(1); m.put("key", new Integer(1)); m.put("seq", new Integer(2)); l.add(m); kh.getKeyList().addAll(l); Map keyMap = kh.getKeys(); assertEquals("two keys should be in the map", 2, keyMap.size()); try { kh.getKey(); } catch (InvalidDataAccessApiUsageException e) { assertTrue(e.getMessage().startsWith("The getKey method should only be used when a single key is returned.")); } } public void testMultipleKeyRows(){ LinkedList l = new LinkedList(); HashMap m = new HashMap(1); m.put("key", new Integer(1)); m.put("seq", new Integer(2)); l.add(m); l.add(m); kh.getKeyList().addAll(l); assertEquals("two rows should be in the list", 2, kh.getKeyList().size()); try { kh.getKeys(); } catch (InvalidDataAccessApiUsageException e) { assertTrue(e.getMessage().startsWith("The getKeys method should only be used when keys for a single row are returned.")); } } } ././@LongLink0000000000000000000000000000022000000000000011557 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/support/CustomSqlExceptionTranslator.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000000224111623223530033317 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support; import org.springframework.dao.DataAccessException; import org.springframework.dao.TransientDataAccessResourceException; import java.sql.SQLException; /** * Custom SQLException translation for testing. * * @author Thomas Risberg */ public class CustomSqlExceptionTranslator implements SQLExceptionTranslator { public DataAccessException translate(String task, String sql, SQLException ex) { if (ex.getErrorCode() == 2) { return new TransientDataAccessResourceException("Custom", ex); } return null; } } ././@LongLink0000000000000000000000000000022500000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/support/SQLExceptionCustomTranslatorTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000000427411623223530033327 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support; import org.springframework.dao.DataAccessException; import org.springframework.dao.TransientDataAccessResourceException; import org.springframework.jdbc.BadSqlGrammarException; import java.sql.SQLException; import junit.framework.TestCase; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import org.junit.Test; /** * Class to test custom SQLException translation. * * @author Thomas Risberg */ @RunWith(JUnit4.class) public class SQLExceptionCustomTranslatorTests extends TestCase { private static SQLErrorCodes ERROR_CODES = new SQLErrorCodes(); static { ERROR_CODES.setBadSqlGrammarCodes(new String[] { "1" }); ERROR_CODES.setDataAccessResourceFailureCodes(new String[] { "2" }); ERROR_CODES.setCustomSqlExceptionTranslatorClass(CustomSqlExceptionTranslator.class); } @Test public void testCustomErrorCodeTranslation() { SQLExceptionTranslator sext = new SQLErrorCodeSQLExceptionTranslator(ERROR_CODES); SQLException dataIntegrityViolationEx = SQLExceptionSubclassFactory.newSQLDataException("", "", 1); DataAccessException daeex = sext.translate("task", "SQL", dataIntegrityViolationEx); assertEquals(dataIntegrityViolationEx, daeex.getCause()); assertTrue(daeex instanceof BadSqlGrammarException); SQLException dataAccessResourceEx = SQLExceptionSubclassFactory.newSQLDataException("", "", 2); DataAccessException darex = sext.translate("task", "SQL", dataAccessResourceEx); assertEquals(dataIntegrityViolationEx, daeex.getCause()); assertTrue(darex instanceof TransientDataAccessResourceException); } }././@LongLink0000000000000000000000000000021700000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/support/SQLExceptionSubclassFactory.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000000617311623223526033334 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support; import java.sql.SQLDataException; import java.sql.SQLException; import java.sql.SQLFeatureNotSupportedException; import java.sql.SQLIntegrityConstraintViolationException; import java.sql.SQLInvalidAuthorizationSpecException; import java.sql.SQLNonTransientConnectionException; import java.sql.SQLRecoverableException; import java.sql.SQLSyntaxErrorException; import java.sql.SQLTimeoutException; import java.sql.SQLTransactionRollbackException; import java.sql.SQLTransientConnectionException; /** * Class to generate Java 6 SQLException subclasses for testing purposes. * * @author Thomas Risberg */ public class SQLExceptionSubclassFactory { public static SQLException newSQLDataException(String reason, String SQLState, int vendorCode) { return new SQLDataException(reason, SQLState, vendorCode); } public static SQLException newSQLFeatureNotSupportedException(String reason, String SQLState, int vendorCode) { return new SQLFeatureNotSupportedException(reason, SQLState, vendorCode); } public static SQLException newSQLIntegrityConstraintViolationException(String reason, String SQLState, int vendorCode) { return new SQLIntegrityConstraintViolationException(reason, SQLState, vendorCode); } public static SQLException newSQLInvalidAuthorizationSpecException(String reason, String SQLState, int vendorCode) { return new SQLInvalidAuthorizationSpecException(reason, SQLState, vendorCode); } public static SQLException newSQLNonTransientConnectionException(String reason, String SQLState, int vendorCode) { return new SQLNonTransientConnectionException(reason, SQLState, vendorCode); } public static SQLException newSQLSyntaxErrorException(String reason, String SQLState, int vendorCode) { return new SQLSyntaxErrorException(reason, SQLState, vendorCode); } public static SQLException newSQLTransactionRollbackException(String reason, String SQLState, int vendorCode) { return new SQLTransactionRollbackException(reason, SQLState, vendorCode); } public static SQLException newSQLTransientConnectionException(String reason, String SQLState, int vendorCode) { return new SQLTransientConnectionException(reason, SQLState, vendorCode); } public static SQLException newSQLTimeoutException(String reason, String SQLState, int vendorCode) { return new SQLTimeoutException(reason, SQLState, vendorCode); } public static SQLException newSQLRecoverableException(String reason, String SQLState, int vendorCode) { return new SQLRecoverableException(reason, SQLState, vendorCode); } } ././@LongLink0000000000000000000000000000021500000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/support/SQLErrorCodesFactoryTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000002607011623223530033325 0ustar drazzibdrazzib/* * Copyright 2002-2006 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.SQLException; import java.util.Arrays; import javax.sql.DataSource; import junit.framework.TestCase; import org.easymock.MockControl; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; /** * Tests for SQLErrorCodes loading. * * @author Rod Johnson * @author Thomas Risberg */ public class SQLErrorCodesFactoryTests extends TestCase { /** * Check that a default instance returns empty error codes for an unknown database. */ public void testDefaultInstanceWithNoSuchDatabase() { SQLErrorCodes sec = SQLErrorCodesFactory.getInstance().getErrorCodes("xx"); assertTrue(sec.getBadSqlGrammarCodes().length == 0); assertTrue(sec.getDataIntegrityViolationCodes().length == 0); } /** * Check that a known database produces recognizable codes. */ public void testDefaultInstanceWithOracle() { SQLErrorCodes sec = SQLErrorCodesFactory.getInstance().getErrorCodes("Oracle"); assertIsOracle(sec); } private void assertIsOracle(SQLErrorCodes sec) { assertTrue(sec.getBadSqlGrammarCodes().length > 0); assertTrue(sec.getDataIntegrityViolationCodes().length > 0); // This had better be a Bad SQL Grammar code assertTrue(Arrays.binarySearch(sec.getBadSqlGrammarCodes(), "942") >= 0); // This had better NOT be assertFalse(Arrays.binarySearch(sec.getBadSqlGrammarCodes(), "9xx42") >= 0); } private void assertIsHsql(SQLErrorCodes sec) { assertTrue(sec.getBadSqlGrammarCodes().length > 0); assertTrue(sec.getDataIntegrityViolationCodes().length > 0); // This had better be a Bad SQL Grammar code assertTrue(Arrays.binarySearch(sec.getBadSqlGrammarCodes(), "-22") >= 0); // This had better NOT be assertFalse(Arrays.binarySearch(sec.getBadSqlGrammarCodes(), "-9") >= 0); } private void assertIsDB2(SQLErrorCodes sec) { assertTrue(sec.getBadSqlGrammarCodes().length > 0); assertTrue(sec.getDataIntegrityViolationCodes().length > 0); assertFalse(Arrays.binarySearch(sec.getBadSqlGrammarCodes(), "942") >= 0); // This had better NOT be assertTrue(Arrays.binarySearch(sec.getBadSqlGrammarCodes(), "-204") >= 0); } public void testLookupOrder() { class TestSQLErrorCodesFactory extends SQLErrorCodesFactory { private int lookups = 0; protected Resource loadResource(String path) { ++lookups; if (lookups == 1) { assertEquals(SQLErrorCodesFactory.SQL_ERROR_CODE_DEFAULT_PATH, path); return null; } else { // Should have only one more lookup assertEquals(2, lookups); assertEquals(SQLErrorCodesFactory.SQL_ERROR_CODE_OVERRIDE_PATH, path); return null; } } } // Should have failed to load without error TestSQLErrorCodesFactory sf = new TestSQLErrorCodesFactory(); assertTrue(sf.getErrorCodes("XX").getBadSqlGrammarCodes().length == 0); assertTrue(sf.getErrorCodes("Oracle").getDataIntegrityViolationCodes().length == 0); } /** * Check that user defined error codes take precedence. */ public void testFindUserDefinedCodes() { class TestSQLErrorCodesFactory extends SQLErrorCodesFactory { protected Resource loadResource(String path) { if (SQLErrorCodesFactory.SQL_ERROR_CODE_OVERRIDE_PATH.equals(path)) { return new ClassPathResource("test-error-codes.xml", SQLErrorCodesFactoryTests.class); } return null; } } // Should have loaded without error TestSQLErrorCodesFactory sf = new TestSQLErrorCodesFactory(); assertTrue(sf.getErrorCodes("XX").getBadSqlGrammarCodes().length == 0); assertEquals(2, sf.getErrorCodes("Oracle").getBadSqlGrammarCodes().length); assertEquals("1", sf.getErrorCodes("Oracle").getBadSqlGrammarCodes()[0]); assertEquals("2", sf.getErrorCodes("Oracle").getBadSqlGrammarCodes()[1]); } public void testInvalidUserDefinedCodeFormat() { class TestSQLErrorCodesFactory extends SQLErrorCodesFactory { protected Resource loadResource(String path) { if (SQLErrorCodesFactory.SQL_ERROR_CODE_OVERRIDE_PATH.equals(path)) { // Guaranteed to be on the classpath, but most certainly NOT XML return new ClassPathResource("SQLExceptionTranslator.class", SQLErrorCodesFactoryTests.class); } return null; } } // Should have failed to load without error TestSQLErrorCodesFactory sf = new TestSQLErrorCodesFactory(); assertTrue(sf.getErrorCodes("XX").getBadSqlGrammarCodes().length == 0); assertEquals(0, sf.getErrorCodes("Oracle").getBadSqlGrammarCodes().length); } /** * Check that custom error codes take precedence. */ public void testFindCustomCodes() { class TestSQLErrorCodesFactory extends SQLErrorCodesFactory { protected Resource loadResource(String path) { if (SQLErrorCodesFactory.SQL_ERROR_CODE_OVERRIDE_PATH.equals(path)) { return new ClassPathResource("custom-error-codes.xml", SQLErrorCodesFactoryTests.class); } return null; } } // Should have loaded without error TestSQLErrorCodesFactory sf = new TestSQLErrorCodesFactory(); assertEquals(1, sf.getErrorCodes("Oracle").getCustomTranslations().length); CustomSQLErrorCodesTranslation translation = (CustomSQLErrorCodesTranslation) sf.getErrorCodes("Oracle").getCustomTranslations()[0]; assertEquals(CustomErrorCodeException.class, translation.getExceptionClass()); assertEquals(1, translation.getErrorCodes().length); } public void testDataSourceWithNullMetadata() throws Exception { MockControl ctrlConnection = MockControl.createControl(Connection.class); Connection mockConnection = (Connection) ctrlConnection.getMock(); mockConnection.getMetaData(); ctrlConnection.setReturnValue(null); mockConnection.close(); ctrlConnection.setVoidCallable(); ctrlConnection.replay(); MockControl ctrlDataSource = MockControl.createControl(DataSource.class); DataSource mockDataSource = (DataSource) ctrlDataSource.getMock(); mockDataSource.getConnection(); ctrlDataSource.setDefaultReturnValue(mockConnection); ctrlDataSource.replay(); SQLErrorCodes sec = SQLErrorCodesFactory.getInstance().getErrorCodes(mockDataSource); assertIsEmpty(sec); ctrlConnection.verify(); ctrlDataSource.verify(); } public void testGetFromDataSourceWithSQLException() throws Exception { SQLException expectedSQLException = new SQLException(); MockControl ctrlDataSource = MockControl.createControl(DataSource.class); DataSource mockDataSource = (DataSource) ctrlDataSource.getMock(); mockDataSource.getConnection(); ctrlDataSource.setThrowable(expectedSQLException); ctrlDataSource.replay(); SQLErrorCodes sec = SQLErrorCodesFactory.getInstance().getErrorCodes(mockDataSource); assertIsEmpty(sec); ctrlDataSource.verify(); } private void assertIsEmpty(SQLErrorCodes sec) { // Codes should be empty assertEquals(0, sec.getBadSqlGrammarCodes().length); assertEquals(0, sec.getDataIntegrityViolationCodes().length); } private SQLErrorCodes getErrorCodesFromDataSource(String productName, SQLErrorCodesFactory factory) throws Exception { MockControl mdControl = MockControl.createControl(DatabaseMetaData.class); DatabaseMetaData md = (DatabaseMetaData) mdControl.getMock(); md.getDatabaseProductName(); mdControl.setReturnValue(productName); mdControl.replay(); MockControl ctrlConnection = MockControl.createControl(Connection.class); Connection mockConnection = (Connection) ctrlConnection.getMock(); mockConnection.getMetaData(); ctrlConnection.setReturnValue(md); mockConnection.close(); ctrlConnection.setVoidCallable(); ctrlConnection.replay(); MockControl ctrlDataSource = MockControl.createControl(DataSource.class); DataSource mockDataSource = (DataSource) ctrlDataSource.getMock(); mockDataSource.getConnection(); ctrlDataSource.setDefaultReturnValue(mockConnection); ctrlDataSource.replay(); SQLErrorCodesFactory secf = null; if (factory != null) { secf = factory; } else { secf = SQLErrorCodesFactory.getInstance(); } SQLErrorCodes sec = secf.getErrorCodes(mockDataSource); mdControl.verify(); ctrlConnection.verify(); ctrlDataSource.verify(); SQLErrorCodes sec2 = secf.getErrorCodes(mockDataSource); assertSame("Cached per DataSource", sec2, sec); return sec; } public void testOracleRecognizedFromMetadata() throws Exception { SQLErrorCodes sec = getErrorCodesFromDataSource("Oracle", null); assertIsOracle(sec); } public void testHsqlRecognizedFromMetadata() throws Exception { SQLErrorCodes sec = getErrorCodesFromDataSource("HSQL Database Engine", null); assertIsHsql(sec); } public void testDB2RecognizedFromMetadata() throws Exception { SQLErrorCodes sec = getErrorCodesFromDataSource("DB2", null); assertIsDB2(sec); sec = getErrorCodesFromDataSource("DB2/", null); assertIsDB2(sec); sec = getErrorCodesFromDataSource("DB-2", null); assertIsEmpty(sec); } /** * Check that wild card database name works. */ public void testWildCardNameRecognized() throws Exception { class WildcardSQLErrorCodesFactory extends SQLErrorCodesFactory { protected Resource loadResource(String path) { if (SQLErrorCodesFactory.SQL_ERROR_CODE_OVERRIDE_PATH.equals(path)) { return new ClassPathResource("wildcard-error-codes.xml", SQLErrorCodesFactoryTests.class); } return null; } } WildcardSQLErrorCodesFactory factory = new WildcardSQLErrorCodesFactory(); SQLErrorCodes sec = getErrorCodesFromDataSource("DB2", factory); assertIsDB2(sec); sec = getErrorCodesFromDataSource("DB2 UDB for Xxxxx", factory); assertIsDB2(sec); sec = getErrorCodesFromDataSource("DB3", factory); assertIsDB2(sec); sec = getErrorCodesFromDataSource("DB3/", factory); assertIsDB2(sec); sec = getErrorCodesFromDataSource("/DB3", factory); assertIsDB2(sec); sec = getErrorCodesFromDataSource("/DB3", factory); assertIsDB2(sec); sec = getErrorCodesFromDataSource("/DB3/", factory); assertIsDB2(sec); sec = getErrorCodesFromDataSource("DB-3", factory); assertIsEmpty(sec); sec = getErrorCodesFromDataSource("DB1", factory); assertIsDB2(sec); sec = getErrorCodesFromDataSource("DB1/", factory); assertIsDB2(sec); sec = getErrorCodesFromDataSource("/DB1", factory); assertIsEmpty(sec); sec = getErrorCodesFromDataSource("/DB1/", factory); assertIsEmpty(sec); sec = getErrorCodesFromDataSource("DB0", factory); assertIsDB2(sec); sec = getErrorCodesFromDataSource("/DB0", factory); assertIsDB2(sec); sec = getErrorCodesFromDataSource("DB0/", factory); assertIsEmpty(sec); sec = getErrorCodesFromDataSource("/DB0/", factory); assertIsEmpty(sec); } } ././@LongLink0000000000000000000000000000023300000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/support/SQLErrorCodeSQLExceptionTranslatorTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000001550111623223526033327 0ustar drazzibdrazzib/* * Copyright 2002-2005 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support; import java.sql.SQLException; import java.sql.BatchUpdateException; import junit.framework.TestCase; import org.springframework.dao.CannotAcquireLockException; import org.springframework.dao.CannotSerializeTransactionException; import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.dao.DeadlockLoserDataAccessException; import org.springframework.dao.DuplicateKeyException; import org.springframework.jdbc.BadSqlGrammarException; import org.springframework.jdbc.InvalidResultSetAccessException; /** * @author Rod Johnson */ public class SQLErrorCodeSQLExceptionTranslatorTests extends TestCase { private static SQLErrorCodes ERROR_CODES = new SQLErrorCodes(); static { ERROR_CODES.setBadSqlGrammarCodes(new String[] { "1", "2" }); ERROR_CODES.setInvalidResultSetAccessCodes(new String[] { "3", "4" }); ERROR_CODES.setDuplicateKeyCodes(new String[] {"10"}); ERROR_CODES.setDataAccessResourceFailureCodes(new String[] { "5" }); ERROR_CODES.setDataIntegrityViolationCodes(new String[] { "6" }); ERROR_CODES.setCannotAcquireLockCodes(new String[] { "7" }); ERROR_CODES.setDeadlockLoserCodes(new String[] { "8" }); ERROR_CODES.setCannotSerializeTransactionCodes(new String[] { "9" }); } public void testErrorCodeTranslation() { SQLExceptionTranslator sext = new SQLErrorCodeSQLExceptionTranslator(ERROR_CODES); SQLException badSqlEx = new SQLException("", "", 1); BadSqlGrammarException bsgex = (BadSqlGrammarException) sext.translate("task", "SQL", badSqlEx); assertEquals("SQL", bsgex.getSql()); assertEquals(badSqlEx, bsgex.getSQLException()); SQLException invResEx = new SQLException("", "", 4); InvalidResultSetAccessException irsex = (InvalidResultSetAccessException) sext.translate("task", "SQL", invResEx); assertEquals("SQL", irsex.getSql()); assertEquals(invResEx, irsex.getSQLException()); checkTranslation(sext, 5, DataAccessResourceFailureException.class); checkTranslation(sext, 6, DataIntegrityViolationException.class); checkTranslation(sext, 7, CannotAcquireLockException.class); checkTranslation(sext, 8, DeadlockLoserDataAccessException.class); checkTranslation(sext, 9, CannotSerializeTransactionException.class); checkTranslation(sext, 10, DuplicateKeyException.class); SQLException dupKeyEx = new SQLException("", "", 10); DataAccessException dksex = sext.translate("task", "SQL", dupKeyEx); assertTrue("Not instance of DataIntegrityViolationException", DataIntegrityViolationException.class.isAssignableFrom(dksex.getClass())); // Test fallback. We assume that no database will ever return this error code, // but 07xxx will be bad grammar picked up by the fallback SQLState translator SQLException sex = new SQLException("", "07xxx", 666666666); BadSqlGrammarException bsgex2 = (BadSqlGrammarException) sext.translate("task", "SQL2", sex); assertEquals("SQL2", bsgex2.getSql()); assertEquals(sex, bsgex2.getSQLException()); } private void checkTranslation(SQLExceptionTranslator sext, int errorCode, Class exClass) { SQLException sex = new SQLException("", "", errorCode); DataAccessException ex = sext.translate("", "", sex); assertTrue(exClass.isInstance(ex)); assertTrue(ex.getCause() == sex); } public void testBatchExceptionTranslation() { SQLExceptionTranslator sext = new SQLErrorCodeSQLExceptionTranslator(ERROR_CODES); SQLException badSqlEx = new SQLException("", "", 1); BatchUpdateException batchUdateEx = new BatchUpdateException(); batchUdateEx.setNextException(badSqlEx); BadSqlGrammarException bsgex = (BadSqlGrammarException) sext.translate("task", "SQL", batchUdateEx); assertEquals("SQL", bsgex.getSql()); assertEquals(badSqlEx, bsgex.getSQLException()); } public void testCustomTranslateMethodTranslation() { final String TASK = "TASK"; final String SQL = "SQL SELECT *"; final DataAccessException customDex = new DataAccessException("") {}; final SQLException badSqlEx = new SQLException("", "", 1); SQLException intVioEx = new SQLException("", "", 6); SQLErrorCodeSQLExceptionTranslator sext = new SQLErrorCodeSQLExceptionTranslator() { protected DataAccessException customTranslate(String task, String sql, SQLException sqlex) { assertEquals(TASK, task); assertEquals(SQL, sql); return (sqlex == badSqlEx) ? customDex : null; } }; sext.setSqlErrorCodes(ERROR_CODES); // Shouldn't custom translate this assertEquals(customDex, sext.translate(TASK, SQL, badSqlEx)); DataIntegrityViolationException diex = (DataIntegrityViolationException) sext.translate(TASK, SQL, intVioEx); assertEquals(intVioEx, diex.getCause()); } public void testCustomExceptionTranslation() { final String TASK = "TASK"; final String SQL = "SQL SELECT *"; final SQLErrorCodes customErrorCodes = new SQLErrorCodes(); final CustomSQLErrorCodesTranslation customTranslation = new CustomSQLErrorCodesTranslation(); customErrorCodes.setBadSqlGrammarCodes(new String[] {"1", "2"}); customErrorCodes.setDataIntegrityViolationCodes(new String[] {"3", "4"}); customTranslation.setErrorCodes(new String[] {"1"}); customTranslation.setExceptionClass(CustomErrorCodeException.class); customErrorCodes.setCustomTranslations(new CustomSQLErrorCodesTranslation[] {customTranslation}); SQLErrorCodeSQLExceptionTranslator sext = new SQLErrorCodeSQLExceptionTranslator(); sext.setSqlErrorCodes(customErrorCodes); // Should custom translate this SQLException badSqlEx = new SQLException("", "", 1); assertEquals(CustomErrorCodeException.class, sext.translate(TASK, SQL, badSqlEx).getClass()); assertEquals(badSqlEx, sext.translate(TASK, SQL, badSqlEx).getCause()); // Shouldn't custom translate this SQLException invResEx = new SQLException("", "", 3); DataIntegrityViolationException diex = (DataIntegrityViolationException) sext.translate(TASK, SQL, invResEx); assertEquals(invResEx, diex.getCause()); // Shouldn't custom translate this - invalid class try { customTranslation.setExceptionClass(String.class); fail("Should have thrown IllegalArgumentException"); } catch (IllegalArgumentException ex) { // expected } } } ././@LongLink0000000000000000000000000000020500000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/support/custom-error-codes.xmllibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000000154111623223530033321 0ustar drazzibdrazzib 1,2 1,1400,1722 999 org.springframework.jdbc.support.CustomErrorCodeException ././@LongLink0000000000000000000000000000020700000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/support/wildcard-error-codes.xmllibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000000325011623223530033320 0ustar drazzibdrazzib 1,2,942 1,1400,1722 *DB0 -204,1,2 3,4 DB1* -204,1,2 3,4 *DB2* -204,1,2 3,4 *DB3* -204,1,2 3,4 ././@LongLink0000000000000000000000000000021200000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/support/DefaultLobHandlerTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000001257411623223530033331 0ustar drazzibdrazzib/* * Copyright 2002-2005 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.Reader; import java.io.StringReader; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.ResultSet; import junit.framework.TestCase; import org.easymock.MockControl; import org.springframework.jdbc.support.lob.DefaultLobHandler; import org.springframework.jdbc.support.lob.LobCreator; import org.springframework.jdbc.support.lob.LobHandler; /** * @author Juergen Hoeller * @since 17.12.2003 */ public class DefaultLobHandlerTests extends TestCase { public void testGetBlobAsBytes() throws SQLException { LobHandler lobHandler = new DefaultLobHandler(); MockControl rsControl = MockControl.createControl(ResultSet.class); ResultSet rs = (ResultSet) rsControl.getMock(); rs.getBytes(1); rsControl.setReturnValue(null); rsControl.replay(); lobHandler.getBlobAsBytes(rs, 1); rsControl.verify(); } public void testGetBlobAsBinaryStream() throws SQLException { LobHandler lobHandler = new DefaultLobHandler(); MockControl rsControl = MockControl.createControl(ResultSet.class); ResultSet rs = (ResultSet) rsControl.getMock(); rs.getBinaryStream(1); rsControl.setReturnValue(null); rsControl.replay(); lobHandler.getBlobAsBinaryStream(rs, 1); rsControl.verify(); } public void testGetClobAsString() throws SQLException { LobHandler lobHandler = new DefaultLobHandler(); MockControl rsControl = MockControl.createControl(ResultSet.class); ResultSet rs = (ResultSet) rsControl.getMock(); rs.getString(1); rsControl.setReturnValue(null); rsControl.replay(); lobHandler.getClobAsString(rs, 1); rsControl.verify(); } public void testGetClobAsAsciiStream() throws SQLException { LobHandler lobHandler = new DefaultLobHandler(); MockControl rsControl = MockControl.createControl(ResultSet.class); ResultSet rs = (ResultSet) rsControl.getMock(); rs.getAsciiStream(1); rsControl.setReturnValue(null); rsControl.replay(); lobHandler.getClobAsAsciiStream(rs, 1); rsControl.verify(); } public void testGetClobAsCharacterStream() throws SQLException { LobHandler lobHandler = new DefaultLobHandler(); MockControl rsControl = MockControl.createControl(ResultSet.class); ResultSet rs = (ResultSet) rsControl.getMock(); rs.getCharacterStream(1); rsControl.setReturnValue(null); rsControl.replay(); lobHandler.getClobAsCharacterStream(rs, 1); rsControl.verify(); } public void testSetBlobAsBytes() throws SQLException { LobCreator lobCreator = (new DefaultLobHandler()).getLobCreator(); byte[] content = "testContent".getBytes(); MockControl psControl = MockControl.createControl(PreparedStatement.class); PreparedStatement ps = (PreparedStatement) psControl.getMock(); ps.setBytes(1, content); psControl.replay(); lobCreator.setBlobAsBytes(ps, 1, content); psControl.verify(); } public void testSetBlobAsBinaryStream() throws SQLException, IOException { LobCreator lobCreator = (new DefaultLobHandler()).getLobCreator(); InputStream bis = new ByteArrayInputStream("testContent".getBytes()); MockControl psControl = MockControl.createControl(PreparedStatement.class); PreparedStatement ps = (PreparedStatement) psControl.getMock(); ps.setBinaryStream(1, bis, 11); psControl.replay(); lobCreator.setBlobAsBinaryStream(ps, 1, bis, 11); psControl.verify(); } public void testSetClobAsString() throws SQLException, IOException { LobCreator lobCreator = (new DefaultLobHandler()).getLobCreator(); String content = "testContent"; MockControl psControl = MockControl.createControl(PreparedStatement.class); PreparedStatement ps = (PreparedStatement) psControl.getMock(); ps.setString(1, content); psControl.replay(); lobCreator.setClobAsString(ps, 1, content); psControl.verify(); } public void testSetClobAsAsciiStream() throws SQLException, IOException { LobCreator lobCreator = (new DefaultLobHandler()).getLobCreator(); InputStream bis = new ByteArrayInputStream("testContent".getBytes()); MockControl psControl = MockControl.createControl(PreparedStatement.class); PreparedStatement ps = (PreparedStatement) psControl.getMock(); ps.setAsciiStream(1, bis, 11); psControl.replay(); lobCreator.setClobAsAsciiStream(ps, 1, bis, 11); psControl.verify(); } public void testSetClobAsCharacterStream() throws SQLException, IOException { LobCreator lobCreator = (new DefaultLobHandler()).getLobCreator(); Reader str = new StringReader("testContent"); MockControl psControl = MockControl.createControl(PreparedStatement.class); PreparedStatement ps = (PreparedStatement) psControl.getMock(); ps.setCharacterStream(1, str, 11); psControl.replay(); lobCreator.setClobAsCharacterStream(ps, 1, str, 11); psControl.verify(); } } ././@LongLink0000000000000000000000000000022400000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/support/SQLStateExceptionTranslatorTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000000532211623223530033322 0ustar drazzibdrazzib/* * Copyright 2002-2005 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support; import java.sql.SQLException; import junit.framework.TestCase; import org.springframework.jdbc.BadSqlGrammarException; import org.springframework.jdbc.UncategorizedSQLException; /** * * @author Rod Johnson * @since 13-Jan-03 */ public class SQLStateExceptionTranslatorTests extends TestCase { private SQLStateSQLExceptionTranslator trans = new SQLStateSQLExceptionTranslator(); // ALSO CHECK CHAIN of SQLExceptions!? // also allow chain of translators? default if can't do specific? public void testBadSqlGrammar() { String sql = "SELECT FOO FROM BAR"; SQLException sex = new SQLException("Message", "42001", 1); try { throw this.trans.translate("task", sql, sex); } catch (BadSqlGrammarException ex) { // OK assertTrue("SQL is correct", sql.equals(ex.getSql())); assertTrue("Exception matches", sex.equals(ex.getSQLException())); } } public void testInvalidSqlStateCode() { String sql = "SELECT FOO FROM BAR"; SQLException sex = new SQLException("Message", "NO SUCH CODE", 1); try { throw this.trans.translate("task", sql, sex); } catch (UncategorizedSQLException ex) { // OK assertTrue("SQL is correct", sql.equals(ex.getSql())); assertTrue("Exception matches", sex.equals(ex.getSQLException())); } } /** * PostgreSQL can return null * SAP DB can apparently return empty SQL code * Bug 729170 */ public void testMalformedSqlStateCodes() { String sql = "SELECT FOO FROM BAR"; SQLException sex = new SQLException("Message", null, 1); testMalformedSqlStateCode(sex); sex = new SQLException("Message", "", 1); testMalformedSqlStateCode(sex); // One char's not allowed sex = new SQLException("Message", "I", 1); testMalformedSqlStateCode(sex); } private void testMalformedSqlStateCode(SQLException sex) { String sql = "SELECT FOO FROM BAR"; try { throw this.trans.translate("task", sql, sex); } catch (UncategorizedSQLException ex) { // OK assertTrue("SQL is correct", sql.equals(ex.getSql())); assertTrue("Exception matches", sex.equals(ex.getSQLException())); } } } ././@LongLink0000000000000000000000000000020200000000000011557 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/support/JdbcUtilsTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000000343411623223526033331 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support; import junit.framework.TestCase; /** * Unit tests for JdbcUtils. * * @author Thomas Risberg */ public class JdbcUtilsTests extends TestCase { public void testCommonDatabaseName() { assertEquals("Wrong db name", "Oracle", JdbcUtils.commonDatabaseName("Oracle")); assertEquals("Wrong db name", "DB2", JdbcUtils.commonDatabaseName("DB2-for-Spring")); assertEquals("Wrong db name", "Sybase", JdbcUtils.commonDatabaseName("Sybase SQL Server")); assertEquals("Wrong db name", "Sybase", JdbcUtils.commonDatabaseName("Adaptive Server Enterprise")); assertEquals("Wrong db name", "MySQL", JdbcUtils.commonDatabaseName("MySQL")); } public void testConvertUnderscoreNameToPropertyName() { assertEquals("Wrong property name", "myName", JdbcUtils.convertUnderscoreNameToPropertyName("MY_NAME")); assertEquals("Wrong property name", "yourName", JdbcUtils.convertUnderscoreNameToPropertyName("yOUR_nAME")); assertEquals("Wrong property name", "AName", JdbcUtils.convertUnderscoreNameToPropertyName("a_name")); assertEquals("Wrong property name", "someoneElsesName", JdbcUtils.convertUnderscoreNameToPropertyName("someone_elses_name")); } } ././@LongLink0000000000000000000000000000021400000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/support/NativeJdbcExtractorTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000001201211623223530033314 0ustar drazzibdrazzib/* * Copyright 2002-2006 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import junit.framework.TestCase; import org.easymock.MockControl; import org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor; import org.springframework.jdbc.support.nativejdbc.SimpleNativeJdbcExtractor; /** * @author Andre Biryukov * @author Juergen Hoeller */ public class NativeJdbcExtractorTests extends TestCase { public void testSimpleNativeJdbcExtractor() throws SQLException { SimpleNativeJdbcExtractor extractor = new SimpleNativeJdbcExtractor(); MockControl conControl = MockControl.createControl(Connection.class); Connection con = (Connection) conControl.getMock(); MockControl dbmdControl = MockControl.createControl(DatabaseMetaData.class); DatabaseMetaData dbmd = (DatabaseMetaData) dbmdControl.getMock(); MockControl con2Control = MockControl.createControl(Connection.class); Connection con2 = (Connection) con2Control.getMock(); con.getMetaData(); conControl.setReturnValue(dbmd, 2); dbmd.getConnection(); dbmdControl.setReturnValue(con2, 2); conControl.replay(); dbmdControl.replay(); con2Control.replay(); Connection nativeCon = extractor.getNativeConnection(con); assertEquals(con2, nativeCon); MockControl stmtControl = MockControl.createControl(Statement.class); Statement stmt = (Statement) stmtControl.getMock(); stmt.getConnection(); stmtControl.setReturnValue(con); stmtControl.replay(); nativeCon = extractor.getNativeConnectionFromStatement(stmt); assertEquals(con2, nativeCon); Statement nativeStmt = extractor.getNativeStatement(stmt); assertEquals(nativeStmt, stmt); MockControl psControl = MockControl.createControl(PreparedStatement.class); PreparedStatement ps = (PreparedStatement) psControl.getMock(); psControl.replay(); PreparedStatement nativePs = extractor.getNativePreparedStatement(ps); assertEquals(ps, nativePs); MockControl csControl = MockControl.createControl(CallableStatement.class); CallableStatement cs = (CallableStatement) csControl.getMock(); MockControl rsControl = MockControl.createControl(ResultSet.class); ResultSet rs = (ResultSet) rsControl.getMock(); cs.getResultSet(); csControl.setReturnValue(rs); csControl.replay(); rsControl.replay(); CallableStatement nativeCs = extractor.getNativeCallableStatement(cs); assertEquals(cs, nativeCs); ResultSet nativeRs = extractor.getNativeResultSet(cs.getResultSet()); assertEquals(nativeRs, rs); conControl.verify(); dbmdControl.verify(); con2Control.verify(); stmtControl.verify(); psControl.verify(); csControl.verify(); rsControl.verify(); } public void testCommonsDbcpNativeJdbcExtractor() throws SQLException { CommonsDbcpNativeJdbcExtractor extractor = new CommonsDbcpNativeJdbcExtractor(); assertFalse(extractor.isNativeConnectionNecessaryForNativeStatements()); MockControl conControl = MockControl.createControl(Connection.class); Connection con = (Connection) conControl.getMock(); MockControl stmtControl = MockControl.createControl(Statement.class); Statement stmt = (Statement) stmtControl.getMock(); con.getMetaData(); conControl.setReturnValue(null, 2); stmt.getConnection(); stmtControl.setReturnValue(con, 1); conControl.replay(); stmtControl.replay(); Connection nativeConnection = extractor.getNativeConnection(con); assertEquals(con, nativeConnection); nativeConnection = extractor.getNativeConnectionFromStatement(stmt); assertEquals(con, nativeConnection); assertEquals(stmt, extractor.getNativeStatement(stmt)); MockControl psControl = MockControl.createControl(PreparedStatement.class); PreparedStatement ps = (PreparedStatement) psControl.getMock(); psControl.replay(); assertEquals(ps, extractor.getNativePreparedStatement(ps)); MockControl csControl = MockControl.createControl(CallableStatement.class); CallableStatement cs = (CallableStatement) csControl.getMock(); csControl.replay(); assertEquals(cs, extractor.getNativePreparedStatement(cs)); MockControl rsControl = MockControl.createControl(ResultSet.class); ResultSet rs = (ResultSet) rsControl.getMock(); rsControl.replay(); assertEquals(rs, extractor.getNativeResultSet(rs)); conControl.verify(); stmtControl.verify(); psControl.verify(); } } ././@LongLink0000000000000000000000000000020300000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/support/test-error-codes.xmllibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000000071411623223530033322 0ustar drazzibdrazzib 1,2 1,1400,1722 ././@LongLink0000000000000000000000000000016600000000000011570 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/support/rowset/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000755000175000017500000000000011623223530033316 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000022700000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/support/rowset/ResultSetWrappingRowSetTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000002373111623223530033326 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support.rowset; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.math.BigDecimal; import java.sql.Date; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Time; import java.sql.Timestamp; import junit.framework.TestCase; import org.easymock.MockControl; import org.springframework.jdbc.InvalidResultSetAccessException; /** * @author Thomas Risberg */ public class ResultSetWrappingRowSetTests extends TestCase { private MockControl rsetControl; private ResultSet rset; private ResultSetWrappingSqlRowSet rowset; public void setUp() throws Exception { rsetControl = MockControl.createControl(ResultSet.class); rset = (ResultSet) rsetControl.getMock(); rset.getMetaData(); rsetControl.setReturnValue(null); rset.getMetaData(); rsetControl.setReturnValue(null); } public void testGetBigDecimalInt() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getBigDecimal", new Class[] {int.class}); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getBigDecimal", new Class[] {int.class}); doTest(rset, rowset, new Integer(1), BigDecimal.valueOf(1)); } public void testGetBigDecimalString() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getBigDecimal", new Class[] {int.class}); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getBigDecimal", new Class[] {String.class}); doTest(rset, rowset, "test", BigDecimal.valueOf(1)); } public void testGetStringInt() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getString", new Class[] {int.class}); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getString", new Class[] {int.class}); doTest(rset, rowset, new Integer(1), "test"); } public void testGetStringString() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getString", new Class[] {int.class}); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getString", new Class[] {String.class}); doTest(rset, rowset, "test", "test"); } public void testGetTimestampInt() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getTimestamp", new Class[] {int.class}); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getTimestamp", new Class[] {int.class}); doTest(rset, rowset, new Integer(1), new Timestamp(1234l)); } public void testGetTimestampString() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getTimestamp", new Class[] {int.class}); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getTimestamp", new Class[] {String.class}); doTest(rset, rowset, "test", new Timestamp(1234l)); } public void testGetDateInt() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getDate", new Class[] {int.class}); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getDate", new Class[] {int.class}); doTest(rset, rowset, new Integer(1), new Date(1234l)); } public void testGetDateString() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getDate", new Class[] {int.class}); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getDate", new Class[] {String.class}); doTest(rset, rowset, "test", new Date(1234l)); } public void testGetTimeInt() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getTime", new Class[] {int.class}); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getTime", new Class[] {int.class}); doTest(rset, rowset, new Integer(1), new Time(1234l)); } public void testGetTimeString() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getTime", new Class[] {int.class}); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getTime", new Class[] {String.class}); doTest(rset, rowset, "test", new Time(1234l)); } public void testGetObjectInt() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getObject", new Class[] {int.class}); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getObject", new Class[] {int.class}); doTest(rset, rowset, new Integer(1), new Object()); } public void testGetObjectString() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getObject", new Class[] {int.class}); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getObject", new Class[] {String.class}); doTest(rset, rowset, "test", new Object()); } public void testGetIntInt() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getInt", new Class[] {int.class}); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getInt", new Class[] {int.class}); doTest(rset, rowset, new Integer(1), new Integer(1)); } public void testGetIntString() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getInt", new Class[] {int.class}); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getInt", new Class[] {String.class}); doTest(rset, rowset, "test", new Integer(1)); } public void testGetFloatInt() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getFloat", new Class[] {int.class}); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getFloat", new Class[] {int.class}); doTest(rset, rowset, new Integer(1), new Float(1)); } public void testGetFloatString() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getFloat", new Class[] {int.class}); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getFloat", new Class[] {String.class}); doTest(rset, rowset, "test", new Float(1)); } public void testGetDoubleInt() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getDouble", new Class[] {int.class}); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getDouble", new Class[] {int.class}); doTest(rset, rowset, new Integer(1), new Double(1)); } public void testGetDoubleString() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getDouble", new Class[] {int.class}); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getDouble", new Class[] {String.class}); doTest(rset, rowset, "test", new Double(1)); } public void testGetLongInt() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getLong", new Class[] {int.class}); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getLong", new Class[] {int.class}); doTest(rset, rowset, new Integer(1), new Long(1)); } public void testGetLongString() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getLong", new Class[] {int.class}); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getLong", new Class[] {String.class}); doTest(rset, rowset, "test", new Long(1)); } public void testGetBooleanInt() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getBoolean", new Class[] {int.class}); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getBoolean", new Class[] {int.class}); doTest(rset, rowset, new Integer(1), new Boolean(true)); } public void testGetBooleanString() throws Exception { Method rset = ResultSet.class.getDeclaredMethod("getBoolean", new Class[] {int.class}); Method rowset = ResultSetWrappingSqlRowSet.class.getDeclaredMethod("getBoolean", new Class[] {String.class}); doTest(rset, rowset, "test", new Boolean(true)); } private void doTest(Method rsetMethod, Method rowsetMethod, Object arg, Object ret) throws Exception { if (arg instanceof String) { Method findMethod = ResultSet.class.getDeclaredMethod("findColumn", new Class[] {String.class}); findMethod.invoke(rset, new Object[] {arg}); rsetControl.setReturnValue(1); rsetMethod.invoke(rset, new Object[] {1}); } else { rsetMethod.invoke(rset, new Object[] {arg}); } if (ret instanceof Double) { rsetControl.setReturnValue(((Double) ret).doubleValue()); } else if (ret instanceof Float) { rsetControl.setReturnValue(((Float) ret).floatValue()); } else if (ret instanceof Integer) { rsetControl.setReturnValue(((Integer) ret).intValue()); } else if (ret instanceof Short) { rsetControl.setReturnValue(((Short) ret).shortValue()); } else if (ret instanceof Long) { rsetControl.setReturnValue(((Long) ret).longValue()); } else if (ret instanceof Boolean) { rsetControl.setReturnValue(((Boolean) ret).booleanValue()); } else if (ret instanceof Byte) { rsetControl.setReturnValue(((Byte) ret).byteValue()); } else { rsetControl.setReturnValue(ret); } if (arg instanceof String) { Method findMethod = ResultSet.class.getDeclaredMethod("findColumn", new Class[] {String.class}); findMethod.invoke(rset, new Object[] {arg}); rsetControl.setReturnValue(1); rsetMethod.invoke(rset, new Object[] {1}); } else { rsetMethod.invoke(rset, new Object[] {arg}); } rsetControl.setThrowable(new SQLException("test")); rsetControl.replay(); rowset = new ResultSetWrappingSqlRowSet(rset); rowsetMethod.invoke(rowset, new Object[] {arg}); try { rowsetMethod.invoke(rowset, new Object[] {arg}); fail("InvalidResultSetAccessException should have been thrown"); } catch (InvocationTargetException ex) { assertEquals(InvalidResultSetAccessException.class, ex.getTargetException().getClass()); } } } ././@LongLink0000000000000000000000000000022700000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/support/SQLStateSQLExceptionTranslatorTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000000632411623223530033325 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support; import static org.junit.Assert.*; import java.sql.SQLException; import org.junit.Test; import org.springframework.dao.ConcurrencyFailureException; import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.dao.TransientDataAccessResourceException; import org.springframework.jdbc.BadSqlGrammarException; import org.springframework.jdbc.UncategorizedSQLException; /** * @author Rick Evans * @author Juergen Hoeller * @author Chris Beams */ public class SQLStateSQLExceptionTranslatorTests { private static final String REASON = "The game is afoot!"; private static final String TASK = "Counting sheep... yawn."; private static final String SQL = "select count(0) from t_sheep where over_fence = ... yawn... 1"; @Test(expected=IllegalArgumentException.class) public void testTranslateNullException() throws Exception { new SQLStateSQLExceptionTranslator().translate("", "", null); } @Test public void testTranslateBadSqlGrammar() throws Exception { doTest("07", BadSqlGrammarException.class); } @Test public void testTranslateDataIntegrityViolation() throws Exception { doTest("23", DataIntegrityViolationException.class); } @Test public void testTranslateDataAccessResourceFailure() throws Exception { doTest("53", DataAccessResourceFailureException.class); } @Test public void testTranslateTransientDataAccessResourceFailure() throws Exception { doTest("S1", TransientDataAccessResourceException.class); } @Test public void testTranslateConcurrencyFailure() throws Exception { doTest("40", ConcurrencyFailureException.class); } @Test public void testTranslateUncategorized() throws Exception { doTest("00000000", UncategorizedSQLException.class); } private void doTest(String sqlState, Class dataAccessExceptionType) { SQLException ex = new SQLException(REASON, sqlState); SQLExceptionTranslator translator = new SQLStateSQLExceptionTranslator(); DataAccessException dax = translator.translate(TASK, SQL, ex); assertNotNull("Translation must *never* result in a null DataAccessException being returned.", dax); assertEquals("Wrong DataAccessException type returned as the result of the translation", dataAccessExceptionType, dax.getClass()); assertNotNull("The original SQLException must be preserved in the translated DataAccessException", dax.getCause()); assertSame("The exact same original SQLException must be preserved in the translated DataAccessException", ex, dax.getCause()); } } ././@LongLink0000000000000000000000000000022700000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/support/SQLExceptionSubclassTranslatorTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000001332511623223530033324 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support; import java.sql.SQLException; import junit.framework.TestCase; import org.springframework.core.JdkVersion; import org.springframework.dao.ConcurrencyFailureException; import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.dao.PermissionDeniedDataAccessException; import org.springframework.dao.RecoverableDataAccessException; import org.springframework.dao.TransientDataAccessResourceException; import org.springframework.jdbc.BadSqlGrammarException; /** * @author Thomas Risberg */ public class SQLExceptionSubclassTranslatorTests extends TestCase { private static SQLErrorCodes ERROR_CODES = new SQLErrorCodes(); static { ERROR_CODES.setBadSqlGrammarCodes(new String[] { "1" }); } public void testErrorCodeTranslation() { if (JdkVersion.getMajorJavaVersion() < JdkVersion.JAVA_16) { return; } SQLExceptionTranslator sext = new SQLErrorCodeSQLExceptionTranslator(ERROR_CODES); SQLException dataIntegrityViolationEx = SQLExceptionSubclassFactory.newSQLDataException("", "", 0); DataIntegrityViolationException divex = (DataIntegrityViolationException) sext.translate("task", "SQL", dataIntegrityViolationEx); assertEquals(dataIntegrityViolationEx, divex.getCause()); SQLException featureNotSupEx = SQLExceptionSubclassFactory.newSQLFeatureNotSupportedException("", "", 0); InvalidDataAccessApiUsageException idaex = (InvalidDataAccessApiUsageException) sext.translate("task", "SQL", featureNotSupEx); assertEquals(featureNotSupEx, idaex.getCause()); SQLException dataIntegrityViolationEx2 = SQLExceptionSubclassFactory.newSQLIntegrityConstraintViolationException("", "", 0); DataIntegrityViolationException divex2 = (DataIntegrityViolationException) sext.translate("task", "SQL", dataIntegrityViolationEx2); assertEquals(dataIntegrityViolationEx2, divex2.getCause()); SQLException permissionDeniedEx = SQLExceptionSubclassFactory.newSQLInvalidAuthorizationSpecException("", "", 0); PermissionDeniedDataAccessException pdaex = (PermissionDeniedDataAccessException) sext.translate("task", "SQL", permissionDeniedEx); assertEquals(permissionDeniedEx, pdaex.getCause()); SQLException dataAccessResourceEx = SQLExceptionSubclassFactory.newSQLNonTransientConnectionException("", "", 0); DataAccessResourceFailureException darex = (DataAccessResourceFailureException) sext.translate("task", "SQL", dataAccessResourceEx); assertEquals(dataAccessResourceEx, darex.getCause()); SQLException badSqlEx2 = SQLExceptionSubclassFactory.newSQLSyntaxErrorException("", "", 0); BadSqlGrammarException bsgex2 = (BadSqlGrammarException) sext.translate("task", "SQL2", badSqlEx2); assertEquals("SQL2", bsgex2.getSql()); assertEquals(badSqlEx2, bsgex2.getSQLException()); SQLException tranRollbackEx = SQLExceptionSubclassFactory.newSQLTransactionRollbackException("", "", 0); ConcurrencyFailureException cfex = (ConcurrencyFailureException) sext.translate("task", "SQL", tranRollbackEx); assertEquals(tranRollbackEx, cfex.getCause()); SQLException transientConnEx = SQLExceptionSubclassFactory.newSQLTransientConnectionException("", "", 0); TransientDataAccessResourceException tdarex = (TransientDataAccessResourceException) sext.translate("task", "SQL", transientConnEx); assertEquals(transientConnEx, tdarex.getCause()); SQLException transientConnEx2 = SQLExceptionSubclassFactory.newSQLTimeoutException("", "", 0); TransientDataAccessResourceException tdarex2 = (TransientDataAccessResourceException) sext.translate("task", "SQL", transientConnEx2); assertEquals(transientConnEx2, tdarex2.getCause()); SQLException recoverableEx = SQLExceptionSubclassFactory.newSQLRecoverableException("", "", 0); RecoverableDataAccessException rdaex2 = (RecoverableDataAccessException) sext.translate("task", "SQL", recoverableEx); assertEquals(recoverableEx, rdaex2.getCause()); // Test classic error code translation. We should move there next if the exception we pass in is not one // of the new sub-classes. SQLException sexEct = new SQLException("", "", 1); BadSqlGrammarException bsgEct = (BadSqlGrammarException) sext.translate("task", "SQL-ECT", sexEct); assertEquals("SQL-ECT", bsgEct.getSql()); assertEquals(sexEct, bsgEct.getSQLException()); // Test fallback. We assume that no database will ever return this error code, // but 07xxx will be bad grammar picked up by the fallback SQLState translator SQLException sexFbt = new SQLException("", "07xxx", 666666666); BadSqlGrammarException bsgFbt = (BadSqlGrammarException) sext.translate("task", "SQL-FBT", sexFbt); assertEquals("SQL-FBT", bsgFbt.getSql()); assertEquals(sexFbt, bsgFbt.getSQLException()); // and 08xxx will be data resource failure (non-transient) picked up by the fallback SQLState translator SQLException sexFbt2 = new SQLException("", "08xxx", 666666666); DataAccessResourceFailureException darfFbt = (DataAccessResourceFailureException) sext.translate("task", "SQL-FBT2", sexFbt2); assertEquals(sexFbt2, darfFbt.getCause()); } } ././@LongLink0000000000000000000000000000022500000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/support/DataFieldMaxValueIncrementerTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000002037311623223526033332 0ustar drazzibdrazzib/* * Copyright 2002-2005 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import javax.sql.DataSource; import junit.framework.TestCase; import org.easymock.MockControl; import org.springframework.jdbc.support.incrementer.HsqlMaxValueIncrementer; import org.springframework.jdbc.support.incrementer.MySQLMaxValueIncrementer; import org.springframework.jdbc.support.incrementer.OracleSequenceMaxValueIncrementer; import org.springframework.jdbc.support.incrementer.PostgreSQLSequenceMaxValueIncrementer; /** * @author Juergen Hoeller * @since 27.02.2004 */ public class DataFieldMaxValueIncrementerTests extends TestCase { public void testHsqlMaxValueIncrementer() throws SQLException { MockControl dsControl = MockControl.createControl(DataSource.class); DataSource ds = (DataSource) dsControl.getMock(); MockControl conControl = MockControl.createControl(Connection.class); Connection con = (Connection) conControl.getMock(); MockControl stmtControl = MockControl.createControl(Statement.class); Statement stmt = (Statement) stmtControl.getMock(); MockControl rsControl = MockControl.createControl(ResultSet.class); ResultSet rs = (ResultSet) rsControl.getMock(); ds.getConnection(); dsControl.setReturnValue(con, 2); con.createStatement(); conControl.setReturnValue(stmt, 2); stmt.executeUpdate("insert into myseq values(null)"); stmtControl.setReturnValue(1, 6); stmt.executeQuery("select max(identity()) from myseq"); stmtControl.setReturnValue(rs, 6); rs.next(); rsControl.setReturnValue(true, 6); for (long i = 0; i < 6; i++) { rs.getLong(1); rsControl.setReturnValue(i); } rs.close(); rsControl.setVoidCallable(6); stmt.executeUpdate("delete from myseq where seq < 2"); stmtControl.setReturnValue(1); stmt.executeUpdate("delete from myseq where seq < 5"); stmtControl.setReturnValue(1); stmt.close(); stmtControl.setVoidCallable(2); con.close(); conControl.setVoidCallable(2); dsControl.replay(); conControl.replay(); stmtControl.replay(); rsControl.replay(); HsqlMaxValueIncrementer incrementer = new HsqlMaxValueIncrementer(); incrementer.setDataSource(ds); incrementer.setIncrementerName("myseq"); incrementer.setColumnName("seq"); incrementer.setCacheSize(3); incrementer.setPaddingLength(3); incrementer.afterPropertiesSet(); assertEquals(0, incrementer.nextIntValue()); assertEquals(1, incrementer.nextLongValue()); assertEquals("002", incrementer.nextStringValue()); assertEquals(3, incrementer.nextIntValue()); assertEquals(4, incrementer.nextLongValue()); dsControl.verify(); conControl.verify(); stmtControl.verify(); rsControl.verify(); } public void testMySQLMaxValueIncrementer() throws SQLException { MockControl dsControl = MockControl.createControl(DataSource.class); DataSource ds = (DataSource) dsControl.getMock(); MockControl conControl = MockControl.createControl(Connection.class); Connection con = (Connection) conControl.getMock(); MockControl stmtControl = MockControl.createControl(Statement.class); Statement stmt = (Statement) stmtControl.getMock(); MockControl rsControl = MockControl.createControl(ResultSet.class); ResultSet rs = (ResultSet) rsControl.getMock(); ds.getConnection(); dsControl.setReturnValue(con, 2); con.createStatement(); conControl.setReturnValue(stmt, 2); stmt.executeUpdate("update myseq set seq = last_insert_id(seq + 2)"); stmtControl.setReturnValue(1, 2); stmt.executeQuery("select last_insert_id()"); stmtControl.setReturnValue(rs, 2); rs.next(); rsControl.setReturnValue(true, 2); rs.getLong(1); rsControl.setReturnValue(2); rs.getLong(1); rsControl.setReturnValue(4); rs.close(); rsControl.setVoidCallable(2); stmt.close(); stmtControl.setVoidCallable(2); con.close(); conControl.setVoidCallable(2); dsControl.replay(); conControl.replay(); stmtControl.replay(); rsControl.replay(); MySQLMaxValueIncrementer incrementer = new MySQLMaxValueIncrementer(); incrementer.setDataSource(ds); incrementer.setIncrementerName("myseq"); incrementer.setColumnName("seq"); incrementer.setCacheSize(2); incrementer.setPaddingLength(1); incrementer.afterPropertiesSet(); assertEquals(1, incrementer.nextIntValue()); assertEquals(2, incrementer.nextLongValue()); assertEquals("3", incrementer.nextStringValue()); assertEquals(4, incrementer.nextLongValue()); dsControl.verify(); conControl.verify(); stmtControl.verify(); rsControl.verify(); } public void testPostgreSQLSequenceMaxValueIncrementer() throws SQLException { MockControl dsControl = MockControl.createControl(DataSource.class); DataSource ds = (DataSource) dsControl.getMock(); MockControl conControl = MockControl.createControl(Connection.class); Connection con = (Connection) conControl.getMock(); MockControl stmtControl = MockControl.createControl(Statement.class); Statement stmt = (Statement) stmtControl.getMock(); MockControl rsControl = MockControl.createControl(ResultSet.class); ResultSet rs = (ResultSet) rsControl.getMock(); ds.getConnection(); dsControl.setReturnValue(con, 2); con.createStatement(); conControl.setReturnValue(stmt, 2); stmt.executeQuery("select nextval('myseq')"); stmtControl.setReturnValue(rs, 2); rs.next(); rsControl.setReturnValue(true, 2); rs.getLong(1); rsControl.setReturnValue(10); rs.getLong(1); rsControl.setReturnValue(12); rs.close(); rsControl.setVoidCallable(2); stmt.close(); stmtControl.setVoidCallable(2); con.close(); conControl.setVoidCallable(2); dsControl.replay(); conControl.replay(); stmtControl.replay(); rsControl.replay(); PostgreSQLSequenceMaxValueIncrementer incrementer = new PostgreSQLSequenceMaxValueIncrementer(); incrementer.setDataSource(ds); incrementer.setIncrementerName("myseq"); incrementer.setPaddingLength(5); incrementer.afterPropertiesSet(); assertEquals("00010", incrementer.nextStringValue()); assertEquals(12, incrementer.nextIntValue()); dsControl.verify(); conControl.verify(); stmtControl.verify(); rsControl.verify(); } public void testOracleSequenceMaxValueIncrementer() throws SQLException { MockControl dsControl = MockControl.createControl(DataSource.class); DataSource ds = (DataSource) dsControl.getMock(); MockControl conControl = MockControl.createControl(Connection.class); Connection con = (Connection) conControl.getMock(); MockControl stmtControl = MockControl.createControl(Statement.class); Statement stmt = (Statement) stmtControl.getMock(); MockControl rsControl = MockControl.createControl(ResultSet.class); ResultSet rs = (ResultSet) rsControl.getMock(); ds.getConnection(); dsControl.setReturnValue(con, 2); con.createStatement(); conControl.setReturnValue(stmt, 2); stmt.executeQuery("select myseq.nextval from dual"); stmtControl.setReturnValue(rs, 2); rs.next(); rsControl.setReturnValue(true, 2); rs.getLong(1); rsControl.setReturnValue(10); rs.getLong(1); rsControl.setReturnValue(12); rs.close(); rsControl.setVoidCallable(2); stmt.close(); stmtControl.setVoidCallable(2); con.close(); conControl.setVoidCallable(2); dsControl.replay(); conControl.replay(); stmtControl.replay(); rsControl.replay(); OracleSequenceMaxValueIncrementer incrementer = new OracleSequenceMaxValueIncrementer(); incrementer.setDataSource(ds); incrementer.setIncrementerName("myseq"); incrementer.setPaddingLength(2); incrementer.afterPropertiesSet(); assertEquals(10, incrementer.nextLongValue()); assertEquals("12", incrementer.nextStringValue()); dsControl.verify(); conControl.verify(); stmtControl.verify(); rsControl.verify(); } } ././@LongLink0000000000000000000000000000021400000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/support/CustomErrorCodeException.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000000175211623223530033325 0ustar drazzibdrazzib/* * Copyright 2002-2005 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc.support; import org.springframework.dao.DataAccessException; /** * @author Thomas Risberg */ @SuppressWarnings("serial") public class CustomErrorCodeException extends DataAccessException { public CustomErrorCodeException(String msg) { super(msg); } public CustomErrorCodeException(String msg, Throwable ex) { super(msg, ex); } } ././@LongLink0000000000000000000000000000017500000000000011570 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdbc/AbstractJdbcTests.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/jdb0000644000175000017500000000444411623223526033333 0ustar drazzibdrazzib/* * AbstractJdbcTests.java * * Copyright (C) 2002 by Interprise Software. All rights reserved. */ /* * Copyright 2002-2005 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.jdbc; import java.sql.Connection; import javax.sql.DataSource; import junit.framework.TestCase; import org.easymock.MockControl; /** * @author Trevor D. Cook */ public abstract class AbstractJdbcTests extends TestCase { protected MockControl ctrlDataSource; protected DataSource mockDataSource; protected MockControl ctrlConnection; protected Connection mockConnection; /** * Set to true if the user wants verification, indicated * by a call to replay(). We need to make this optional, * otherwise we setUp() will always result in verification failures */ private boolean shouldVerify; protected void setUp() throws Exception { this.shouldVerify = false; super.setUp(); ctrlConnection = MockControl.createControl(Connection.class); mockConnection = (Connection) ctrlConnection.getMock(); mockConnection.getMetaData(); ctrlConnection.setDefaultReturnValue(null); mockConnection.close(); ctrlConnection.setDefaultVoidCallable(); ctrlDataSource = MockControl.createControl(DataSource.class); mockDataSource = (DataSource) ctrlDataSource.getMock(); mockDataSource.getConnection(); ctrlDataSource.setDefaultReturnValue(mockConnection); } protected void replay() { ctrlDataSource.replay(); ctrlConnection.replay(); this.shouldVerify = true; } protected void tearDown() throws Exception { super.tearDown(); // we shouldn't verify unless the user called replay() if (shouldVerify()) { ctrlDataSource.verify(); //ctrlConnection.verify(); } } protected boolean shouldVerify() { return this.shouldVerify; } } ././@LongLink0000000000000000000000000000015000000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/beans/libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/bea0000755000175000017500000000000011623223530033306 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000016600000000000011570 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/beans/ITestBean.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/bea0000644000175000017500000000305211623223530033310 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.beans; import java.io.IOException; /** * Interface used for {@link org.springframework.beans.TestBean}. * *

Two methods are the same as on Person, but if this * extends person it breaks quite a few tests.. * * @author Rod Johnson * @author Juergen Hoeller */ public interface ITestBean { int getAge(); void setAge(int age); String getName(); void setName(String name); ITestBean getSpouse(); void setSpouse(ITestBean spouse); ITestBean[] getSpouses(); String[] getStringArray(); void setStringArray(String[] stringArray); /** * Throws a given (non-null) exception. */ void exceptional(Throwable t) throws Throwable; Object returnsThis(); INestedTestBean getDoctor(); INestedTestBean getLawyer(); IndexedTestBean getNestedIndexedBean(); /** * Increment the age by one. * @return the previous age */ int haveBirthday(); void unreliableFileOperation() throws IOException; }././@LongLink0000000000000000000000000000017400000000000011567 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/beans/INestedTestBean.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/bea0000644000175000017500000000133011623223526033312 0ustar drazzibdrazzib/* * Copyright 2002-2005 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.beans; public interface INestedTestBean { public String getCompany(); }././@LongLink0000000000000000000000000000017400000000000011567 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/beans/IndexedTestBean.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/bea0000644000175000017500000000566511623223530033324 0ustar drazzibdrazzib/* * Copyright 2002-2006 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.beans; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.SortedMap; import java.util.SortedSet; import java.util.TreeSet; /** * @author Juergen Hoeller * @since 11.11.2003 */ public class IndexedTestBean { private TestBean[] array; private Collection collection; private List list; private Set set; private SortedSet sortedSet; private Map map; private SortedMap sortedMap; public IndexedTestBean() { this(true); } public IndexedTestBean(boolean populate) { if (populate) { populate(); } } public void populate() { TestBean tb0 = new TestBean("name0", 0); TestBean tb1 = new TestBean("name1", 0); TestBean tb2 = new TestBean("name2", 0); TestBean tb3 = new TestBean("name3", 0); TestBean tb4 = new TestBean("name4", 0); TestBean tb5 = new TestBean("name5", 0); TestBean tb6 = new TestBean("name6", 0); TestBean tb7 = new TestBean("name7", 0); TestBean tbX = new TestBean("nameX", 0); TestBean tbY = new TestBean("nameY", 0); this.array = new TestBean[] {tb0, tb1}; this.list = new ArrayList(); this.list.add(tb2); this.list.add(tb3); this.set = new TreeSet(); this.set.add(tb6); this.set.add(tb7); this.map = new HashMap(); this.map.put("key1", tb4); this.map.put("key2", tb5); this.map.put("key.3", tb5); List list = new ArrayList(); list.add(tbX); list.add(tbY); this.map.put("key4", list); } public TestBean[] getArray() { return array; } public void setArray(TestBean[] array) { this.array = array; } public Collection getCollection() { return collection; } public void setCollection(Collection collection) { this.collection = collection; } public List getList() { return list; } public void setList(List list) { this.list = list; } public Set getSet() { return set; } public void setSet(Set set) { this.set = set; } public SortedSet getSortedSet() { return sortedSet; } public void setSortedSet(SortedSet sortedSet) { this.sortedSet = sortedSet; } public Map getMap() { return map; } public void setMap(Map map) { this.map = map; } public SortedMap getSortedMap() { return sortedMap; } public void setSortedMap(SortedMap sortedMap) { this.sortedMap = sortedMap; } }././@LongLink0000000000000000000000000000016300000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/beans/IOther.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/bea0000644000175000017500000000131111623223530033304 0ustar drazzibdrazzib /* * Copyright 2002-2005 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.beans; public interface IOther { void absquatulate(); }././@LongLink0000000000000000000000000000016300000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/beans/Colour.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/bea0000644000175000017500000000212511623223530033310 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.beans; import org.springframework.core.enums.ShortCodedLabeledEnum; /** * @author Rob Harrop */ public class Colour extends ShortCodedLabeledEnum { public static final Colour RED = new Colour(0, "RED"); public static final Colour BLUE = new Colour(1, "BLUE"); public static final Colour GREEN = new Colour(2, "GREEN"); public static final Colour PURPLE = new Colour(3, "PURPLE"); private Colour(int code, String label) { super(code, label); } }././@LongLink0000000000000000000000000000016500000000000011567 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/beans/TestBean.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/bea0000644000175000017500000002015511623223526033320 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.beans; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.BeanNameAware; import org.springframework.util.ObjectUtils; /** * Simple test bean used for testing bean factories, the AOP framework etc. * * @author Rod Johnson * @author Juergen Hoeller * @since 15 April 2001 */ public class TestBean implements BeanNameAware, BeanFactoryAware, ITestBean, IOther, Comparable { private String beanName; private String country; private BeanFactory beanFactory; private boolean postProcessed; private String name; private String sex; private int age; private boolean jedi; private ITestBean[] spouses; private String touchy; private String[] stringArray; private Integer[] someIntegerArray; private Date date = new Date(); private Float myFloat = new Float(0.0); private Collection friends = new LinkedList(); private Set someSet = new HashSet(); private Map someMap = new HashMap(); private List someList = new ArrayList(); private Properties someProperties = new Properties(); private INestedTestBean doctor = new NestedTestBean(); private INestedTestBean lawyer = new NestedTestBean(); private IndexedTestBean nestedIndexedBean; private boolean destroyed; private Number someNumber; private Colour favouriteColour; private Boolean someBoolean; private List otherColours; private List pets; public TestBean() { } public TestBean(String name) { this.name = name; } public TestBean(ITestBean spouse) { this.spouses = new ITestBean[] {spouse}; } public TestBean(String name, int age) { this.name = name; this.age = age; } public TestBean(ITestBean spouse, Properties someProperties) { this.spouses = new ITestBean[] {spouse}; this.someProperties = someProperties; } public TestBean(List someList) { this.someList = someList; } public TestBean(Set someSet) { this.someSet = someSet; } public TestBean(Map someMap) { this.someMap = someMap; } public TestBean(Properties someProperties) { this.someProperties = someProperties; } public void setBeanName(String beanName) { this.beanName = beanName; } public String getBeanName() { return beanName; } public void setBeanFactory(BeanFactory beanFactory) { this.beanFactory = beanFactory; } public BeanFactory getBeanFactory() { return beanFactory; } public void setPostProcessed(boolean postProcessed) { this.postProcessed = postProcessed; } public boolean isPostProcessed() { return postProcessed; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; if (this.name == null) { this.name = sex; } } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public boolean isJedi() { return jedi; } public void setJedi(boolean jedi) { this.jedi = jedi; } public ITestBean getSpouse() { return (spouses != null ? spouses[0] : null); } public void setSpouse(ITestBean spouse) { this.spouses = new ITestBean[] {spouse}; } public ITestBean[] getSpouses() { return spouses; } public String getTouchy() { return touchy; } public void setTouchy(String touchy) throws Exception { if (touchy.indexOf('.') != -1) { throw new Exception("Can't contain a ."); } if (touchy.indexOf(',') != -1) { throw new NumberFormatException("Number format exception: contains a ,"); } this.touchy = touchy; } public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } public String[] getStringArray() { return stringArray; } public void setStringArray(String[] stringArray) { this.stringArray = stringArray; } public Integer[] getSomeIntegerArray() { return someIntegerArray; } public void setSomeIntegerArray(Integer[] someIntegerArray) { this.someIntegerArray = someIntegerArray; } public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } public Float getMyFloat() { return myFloat; } public void setMyFloat(Float myFloat) { this.myFloat = myFloat; } public Collection getFriends() { return friends; } public void setFriends(Collection friends) { this.friends = friends; } public Set getSomeSet() { return someSet; } public void setSomeSet(Set someSet) { this.someSet = someSet; } public Map getSomeMap() { return someMap; } public void setSomeMap(Map someMap) { this.someMap = someMap; } public List getSomeList() { return someList; } public void setSomeList(List someList) { this.someList = someList; } public Properties getSomeProperties() { return someProperties; } public void setSomeProperties(Properties someProperties) { this.someProperties = someProperties; } public INestedTestBean getDoctor() { return doctor; } public void setDoctor(INestedTestBean doctor) { this.doctor = doctor; } public INestedTestBean getLawyer() { return lawyer; } public void setLawyer(INestedTestBean lawyer) { this.lawyer = lawyer; } public Number getSomeNumber() { return someNumber; } public void setSomeNumber(Number someNumber) { this.someNumber = someNumber; } public Colour getFavouriteColour() { return favouriteColour; } public void setFavouriteColour(Colour favouriteColour) { this.favouriteColour = favouriteColour; } public Boolean getSomeBoolean() { return someBoolean; } public void setSomeBoolean(Boolean someBoolean) { this.someBoolean = someBoolean; } public IndexedTestBean getNestedIndexedBean() { return nestedIndexedBean; } public void setNestedIndexedBean(IndexedTestBean nestedIndexedBean) { this.nestedIndexedBean = nestedIndexedBean; } public List getOtherColours() { return otherColours; } public void setOtherColours(List otherColours) { this.otherColours = otherColours; } public List getPets() { return pets; } public void setPets(List pets) { this.pets = pets; } /** * @see org.springframework.beans.ITestBean#exceptional(Throwable) */ public void exceptional(Throwable t) throws Throwable { if (t != null) { throw t; } } public void unreliableFileOperation() throws IOException { throw new IOException(); } /** * @see org.springframework.beans.ITestBean#returnsThis() */ public Object returnsThis() { return this; } /** * @see org.springframework.beans.IOther#absquatulate() */ public void absquatulate() { } public int haveBirthday() { return age++; } public void destroy() { this.destroyed = true; } public boolean wasDestroyed() { return destroyed; } public boolean equals(Object other) { if (this == other) { return true; } if (other == null || !(other instanceof TestBean)) { return false; } TestBean tb2 = (TestBean) other; return (ObjectUtils.nullSafeEquals(this.name, tb2.name) && this.age == tb2.age); } public int hashCode() { return this.age; } public int compareTo(Object other) { if (this.name != null && other instanceof TestBean) { return this.name.compareTo(((TestBean) other).getName()); } else { return 1; } } public String toString() { return this.name; } }././@LongLink0000000000000000000000000000017300000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/beans/NestedTestBean.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/src/test/java/org/springframework/bea0000644000175000017500000000267311623223526033325 0ustar drazzibdrazzib/* * Copyright 2002-2005 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.beans; /** * Simple nested test bean used for testing bean factories, AOP framework etc. * * @author Trevor D. Cook * @since 30.09.2003 */ public class NestedTestBean implements INestedTestBean { private String company = ""; public NestedTestBean() { } public NestedTestBean(String company) { setCompany(company); } public void setCompany(String company) { this.company = (company != null ? company : ""); } public String getCompany() { return company; } public boolean equals(Object obj) { if (!(obj instanceof NestedTestBean)) { return false; } NestedTestBean ntb = (NestedTestBean) obj; return this.company.equals(ntb.company); } public int hashCode() { return this.company.hashCode(); } public String toString() { return "NestedTestBean: " + this.company; } }libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/.settings/0000755000175000017500000000000011623223530026056 5ustar drazzibdrazziblibspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/.settings/org.eclipse.jdt.core.prefs0000644000175000017500000005354711623223526033063 0ustar drazzibdrazzib#Wed Jul 15 00:01:31 PDT 2009 eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve org.eclipse.jdt.core.compiler.compliance=1.6 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.source=1.6 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 org.eclipse.jdt.core.formatter.alignment_for_assignment=0 org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 org.eclipse.jdt.core.formatter.blank_lines_after_package=1 org.eclipse.jdt.core.formatter.blank_lines_before_field=0 org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 org.eclipse.jdt.core.formatter.blank_lines_before_method=1 org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 org.eclipse.jdt.core.formatter.blank_lines_before_package=0 org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false org.eclipse.jdt.core.formatter.comment.format_block_comments=false org.eclipse.jdt.core.formatter.comment.format_header=false org.eclipse.jdt.core.formatter.comment.format_html=false org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=false org.eclipse.jdt.core.formatter.comment.format_line_comments=false org.eclipse.jdt.core.formatter.comment.format_source_code=true org.eclipse.jdt.core.formatter.comment.indent_parameter_description=false org.eclipse.jdt.core.formatter.comment.indent_root_tags=false org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=do not insert org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert org.eclipse.jdt.core.formatter.comment.line_length=120 org.eclipse.jdt.core.formatter.compact_else_if=true org.eclipse.jdt.core.formatter.continuation_indentation=2 org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true org.eclipse.jdt.core.formatter.indent_empty_lines=false org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false org.eclipse.jdt.core.formatter.indentation.size=4 org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false org.eclipse.jdt.core.formatter.lineSplit=120 org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true org.eclipse.jdt.core.formatter.tabulation.char=tab org.eclipse.jdt.core.formatter.tabulation.size=4 org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true libspring-java-3.0.6.RELEASE/projects/org.springframework.jdbc/.settings/org.eclipse.jdt.ui.prefs0000644000175000017500000000016411623223530032526 0ustar drazzibdrazzib#Wed May 06 02:42:56 EDT 2009 eclipse.preferences.version=1 formatter_profile=_Spring formatter_settings_version=11 libspring-java-3.0.6.RELEASE/projects/build.versions0000644000175000017500000000017511623223530022125 0ustar drazzibdrazzib#common dependency versions aspectj.version=1.6.8.RELEASE slf4j.version=1.5.3 junit.version=4.7.0 testng.version=5.10.0 libspring-java-3.0.6.RELEASE/projects/org.springframework.core/0000755000175000017500000000000011623223530024166 5ustar drazzibdrazziblibspring-java-3.0.6.RELEASE/projects/org.springframework.core/template.mf0000644000175000017500000000153311623223526026334 0ustar drazzibdrazzibBundle-SymbolicName: org.springframework.core Bundle-Name: Spring Core Bundle-Vendor: SpringSource Bundle-ManifestVersion: 2 Import-Package: org.eclipse.core.runtime;version="0";common="split";resolution:=optional, org.jboss.virtual;version="[2.1.0.GA, 3.0.0)";resolution:=optional, org.jboss.vfs;version="[3.0.0, 4.0.0)";resolution:=optional Import-Template: javax.xml.*;version="0";resolution:=optional, org.apache.commons.logging.*;version="[1.1.1, 2.0.0)", org.springframework.asm.*;version=${spring.osgi.range};resolution:=optional, org.apache.log4j.*;version="[1.2.15, 2.0.0)";resolution:=optional, org.aspectj.*;version=${aj.osgi.range};resolution:=optional, org.xml.sax.*;version="0";resolution:=optional, org.w3c.dom.*;version="0";resolution:=optional Ignored-Existing-Headers: Bnd-LastModified, Import-Package, Export-Package, Tool libspring-java-3.0.6.RELEASE/projects/org.springframework.core/pom.xml0000644000175000017500000000420711623223530025506 0ustar drazzibdrazzib 4.0.0 org.springframework spring-core jar 3.0.6.RELEASE org.springframework spring-parent ../org.springframework.spring-parent 3.0.6.RELEASE commons-collections commons-collections 3.2 true org.springframework spring-asm ${project.version} compile commons-logging commons-logging 1.1.1 compile log4j log4j compile true org.aspectj aspectjweaver true javax.servlet servlet-api 2.5 test junit junit test org.easymock easymock test xmlunit xmlunit 1.2 test org.codehaus.woodstox wstx-asl 3.2.7 test libspring-java-3.0.6.RELEASE/projects/org.springframework.core/build.xml0000644000175000017500000000216011623223530026006 0ustar drazzibdrazzib libspring-java-3.0.6.RELEASE/projects/org.springframework.core/ivy.xml0000644000175000017500000000450711623223530025525 0ustar drazzibdrazzib libspring-java-3.0.6.RELEASE/projects/org.springframework.core/.classpath0000644000175000017500000000540411623223530026154 0ustar drazzibdrazzib libspring-java-3.0.6.RELEASE/projects/org.springframework.core/.project0000644000175000017500000000057711623223530025646 0ustar drazzibdrazzib org.springframework.core org.eclipse.jdt.core.javabuilder org.eclipse.jdt.core.javanature libspring-java-3.0.6.RELEASE/projects/org.springframework.core/core.iml0000644000175000017500000002260711623223530025630 0ustar drazzibdrazzib libspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/0000755000175000017500000000000011623223526024762 5ustar drazzibdrazziblibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/0000755000175000017500000000000011623223530025701 5ustar drazzibdrazziblibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/resources/0000755000175000017500000000000011623223530027713 5ustar drazzibdrazziblibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/resources/META-INF/0000755000175000017500000000000011623223530031053 5ustar drazzibdrazziblibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/0000755000175000017500000000000011623223526026627 5ustar drazzibdrazziblibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/overview.html0000644000175000017500000000015011623223526031357 0ustar drazzibdrazzib

Spring's core utilities, used by many other Spring modules.

libspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/0000755000175000017500000000000011623223526027416 5ustar drazzibdrazziblibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/0000755000175000017500000000000011623223526032636 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/libspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000755000175000017500000000000011623223530033335 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000017700000000000011572 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/SimpleAliasRegistry.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000001327711623223526033356 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.springframework.util.Assert; import org.springframework.util.StringUtils; import org.springframework.util.StringValueResolver; /** * Simple implementation of the {@link AliasRegistry} interface. * Serves as base class for * {@link org.springframework.beans.factory.support.BeanDefinitionRegistry} * implementations. * * @author Juergen Hoeller * @since 2.5.2 */ public class SimpleAliasRegistry implements AliasRegistry { /** Map from alias to canonical name */ private final Map aliasMap = new ConcurrentHashMap(); public void registerAlias(String name, String alias) { Assert.hasText(name, "'name' must not be empty"); Assert.hasText(alias, "'alias' must not be empty"); if (alias.equals(name)) { this.aliasMap.remove(alias); } else { if (!allowAliasOverriding()) { String registeredName = this.aliasMap.get(alias); if (registeredName != null && !registeredName.equals(name)) { throw new IllegalStateException("Cannot register alias '" + alias + "' for name '" + name + "': It is already registered for name '" + registeredName + "'."); } } checkForAliasCircle(name, alias); this.aliasMap.put(alias, name); } } /** * Return whether alias overriding is allowed. * Default is true. */ protected boolean allowAliasOverriding() { return true; } public void removeAlias(String alias) { String name = this.aliasMap.remove(alias); if (name == null) { throw new IllegalStateException("No alias '" + alias + "' registered"); } } public boolean isAlias(String name) { return this.aliasMap.containsKey(name); } public String[] getAliases(String name) { List result = new ArrayList(); synchronized (this.aliasMap) { retrieveAliases(name, result); } return StringUtils.toStringArray(result); } /** * Transitively retrieve all aliases for the given name. * @param name the target name to find aliases for * @param result the resulting aliases list */ private void retrieveAliases(String name, List result) { for (Map.Entry entry : this.aliasMap.entrySet()) { String registeredName = entry.getValue(); if (registeredName.equals(name)) { String alias = entry.getKey(); result.add(alias); retrieveAliases(alias, result); } } } /** * Resolve all alias target names and aliases registered in this * factory, applying the given StringValueResolver to them. *

The value resolver may for example resolve placeholders * in target bean names and even in alias names. * @param valueResolver the StringValueResolver to apply */ public void resolveAliases(StringValueResolver valueResolver) { Assert.notNull(valueResolver, "StringValueResolver must not be null"); synchronized (this.aliasMap) { Map aliasCopy = new HashMap(this.aliasMap); for (String alias : aliasCopy.keySet()) { String registeredName = aliasCopy.get(alias); String resolvedAlias = valueResolver.resolveStringValue(alias); String resolvedName = valueResolver.resolveStringValue(registeredName); if (resolvedAlias.equals(resolvedName)) { this.aliasMap.remove(alias); } else if (!resolvedAlias.equals(alias)) { String existingName = this.aliasMap.get(resolvedAlias); if (existingName != null && !existingName.equals(resolvedName)) { throw new IllegalStateException( "Cannot register resolved alias '" + resolvedAlias + "' (original: '" + alias + "') for name '" + resolvedName + "': It is already registered for name '" + registeredName + "'."); } checkForAliasCircle(resolvedName, resolvedAlias); this.aliasMap.remove(alias); this.aliasMap.put(resolvedAlias, resolvedName); } else if (!registeredName.equals(resolvedName)) { this.aliasMap.put(alias, resolvedName); } } } } /** * Determine the raw name, resolving aliases to canonical names. * @param name the user-specified name * @return the transformed name */ public String canonicalName(String name) { String canonicalName = name; // Handle aliasing... String resolvedName; do { resolvedName = this.aliasMap.get(canonicalName); if (resolvedName != null) { canonicalName = resolvedName; } } while (resolvedName != null); return canonicalName; } /** * Check whether the given name points back to given alias as an alias * in the other direction, catching a circular reference upfront and * throwing a corresponding IllegalStateException. * @param name the candidate name * @param alias the candidate alias * @see #registerAlias */ protected void checkForAliasCircle(String name, String alias) { if (alias.equals(canonicalName(name))) { throw new IllegalStateException("Cannot register alias '" + alias + "' for name '" + name + "': Circular reference - '" + name + "' is a direct or indirect alias for '" + alias + "' already"); } } } ././@LongLink0000000000000000000000000000016200000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/annotation/libspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000755000175000017500000000000011623223530033335 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000020300000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/annotation/package-info.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000015511623223526033345 0ustar drazzibdrazzib /** * * Core support package for Java 5 annotations. * */ package org.springframework.core.annotation; ././@LongLink0000000000000000000000000000017400000000000011567 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/annotation/Order.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000363011623223526033346 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.springframework.core.Ordered; /** * Annotation that defines ordering. The value is optional, and represents order value * as defined in the {@link Ordered} interface. Lower values have higher priority. * The default value is Ordered.LOWEST_PRECEDENCE, indicating * lowest priority (losing to any other specified order value). * *

NOTE: Annotation-based ordering is supported for specific kinds of * components only, e.g. for annotation-based AspectJ aspects. Spring container * strategies, on the other hand, are typically based on the {@link Ordered} * interface in order to allow for configurable ordering of each instance. * * @author Rod Johnson * @author Juergen Hoeller * @since 2.0 * @see org.springframework.core.Ordered * @see AnnotationAwareOrderComparator */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD}) public @interface Order { /** * The order value. Default is {@link Ordered#LOWEST_PRECEDENCE}. * @see Ordered#getOrder() */ int value() default Ordered.LOWEST_PRECEDENCE; } ././@LongLink0000000000000000000000000000020600000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/annotation/AnnotationUtils.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000004243711623223526033356 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.annotation; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.WeakHashMap; import org.springframework.core.BridgeMethodResolver; import org.springframework.util.Assert; /** * General utility methods for working with annotations, handling bridge methods (which the compiler * generates for generic declarations) as well as super methods (for optional "annotation inheritance"). * Note that none of this is provided by the JDK's introspection facilities themselves. * *

As a general rule for runtime-retained annotations (e.g. for transaction control, authorization or service * exposure), always use the lookup methods on this class (e.g., {@link #findAnnotation(Method, Class)}, {@link * #getAnnotation(Method, Class)}, and {@link #getAnnotations(Method)}) instead of the plain annotation lookup * methods in the JDK. You can still explicitly choose between lookup on the given class level only ({@link * #getAnnotation(Method, Class)}) and lookup in the entire inheritance hierarchy of the given method ({@link * #findAnnotation(Method, Class)}). * * @author Rob Harrop * @author Juergen Hoeller * @author Sam Brannen * @author Mark Fisher * @since 2.0 * @see java.lang.reflect.Method#getAnnotations() * @see java.lang.reflect.Method#getAnnotation(Class) */ public abstract class AnnotationUtils { /** The attribute name for annotations with a single element */ static final String VALUE = "value"; private static final Map annotatedInterfaceCache = new WeakHashMap(); /** * Get all {@link Annotation Annotations} from the supplied {@link Method}. *

Correctly handles bridge {@link Method Methods} generated by the compiler. * @param method the method to look for annotations on * @return the annotations found * @see org.springframework.core.BridgeMethodResolver#findBridgedMethod(Method) */ public static Annotation[] getAnnotations(Method method) { return BridgeMethodResolver.findBridgedMethod(method).getAnnotations(); } /** * Get a single {@link Annotation} of annotationType from the supplied {@link Method}. *

Correctly handles bridge {@link Method Methods} generated by the compiler. * @param method the method to look for annotations on * @param annotationType the annotation class to look for * @return the annotations found * @see org.springframework.core.BridgeMethodResolver#findBridgedMethod(Method) */ public static A getAnnotation(Method method, Class annotationType) { Method resolvedMethod = BridgeMethodResolver.findBridgedMethod(method); A ann = resolvedMethod.getAnnotation(annotationType); if (ann == null) { for (Annotation metaAnn : resolvedMethod.getAnnotations()) { ann = metaAnn.annotationType().getAnnotation(annotationType); if (ann != null) { break; } } } return ann; } /** * Get a single {@link Annotation} of annotationType from the supplied {@link Method}, * traversing its super methods if no annotation can be found on the given method itself. *

Annotations on methods are not inherited by default, so we need to handle this explicitly. * @param method the method to look for annotations on * @param annotationType the annotation class to look for * @return the annotation found, or null if none found */ public static A findAnnotation(Method method, Class annotationType) { A annotation = getAnnotation(method, annotationType); Class cl = method.getDeclaringClass(); if (annotation == null) { annotation = searchOnInterfaces(method, annotationType, cl.getInterfaces()); } while (annotation == null) { cl = cl.getSuperclass(); if (cl == null || cl == Object.class) { break; } try { Method equivalentMethod = cl.getDeclaredMethod(method.getName(), method.getParameterTypes()); annotation = getAnnotation(equivalentMethod, annotationType); if (annotation == null) { annotation = searchOnInterfaces(method, annotationType, cl.getInterfaces()); } } catch (NoSuchMethodException ex) { // We're done... } } return annotation; } private static A searchOnInterfaces(Method method, Class annotationType, Class[] ifcs) { A annotation = null; for (Class iface : ifcs) { if (isInterfaceWithAnnotatedMethods(iface)) { try { Method equivalentMethod = iface.getMethod(method.getName(), method.getParameterTypes()); annotation = getAnnotation(equivalentMethod, annotationType); } catch (NoSuchMethodException ex) { // Skip this interface - it doesn't have the method... } if (annotation != null) { break; } } } return annotation; } private static boolean isInterfaceWithAnnotatedMethods(Class iface) { synchronized (annotatedInterfaceCache) { Boolean flag = annotatedInterfaceCache.get(iface); if (flag != null) { return flag; } boolean found = false; for (Method ifcMethod : iface.getMethods()) { if (ifcMethod.getAnnotations().length > 0) { found = true; break; } } annotatedInterfaceCache.put(iface, found); return found; } } /** * Find a single {@link Annotation} of annotationType from the supplied {@link Class}, * traversing its interfaces and superclasses if no annotation can be found on the given class itself. *

This method explicitly handles class-level annotations which are not declared as * {@link java.lang.annotation.Inherited inherited} as well as annotations on interfaces. *

The algorithm operates as follows: Searches for an annotation on the given class and returns * it if found. Else searches all interfaces that the given class declares, returning the annotation * from the first matching candidate, if any. Else proceeds with introspection of the superclass * of the given class, checking the superclass itself; if no annotation found there, proceeds * with the interfaces that the superclass declares. Recursing up through the entire superclass * hierarchy if no match is found. * @param clazz the class to look for annotations on * @param annotationType the annotation class to look for * @return the annotation found, or null if none found */ public static A findAnnotation(Class clazz, Class annotationType) { Assert.notNull(clazz, "Class must not be null"); A annotation = clazz.getAnnotation(annotationType); if (annotation != null) { return annotation; } for (Class ifc : clazz.getInterfaces()) { annotation = findAnnotation(ifc, annotationType); if (annotation != null) { return annotation; } } if (!Annotation.class.isAssignableFrom(clazz)) { for (Annotation ann : clazz.getAnnotations()) { annotation = findAnnotation(ann.annotationType(), annotationType); if (annotation != null) { return annotation; } } } Class superClass = clazz.getSuperclass(); if (superClass == null || superClass == Object.class) { return null; } return findAnnotation(superClass, annotationType); } /** * Find the first {@link Class} in the inheritance hierarchy of the specified clazz * (including the specified clazz itself) which declares an annotation for the * specified annotationType, or null if not found. If the supplied * clazz is null, null will be returned. *

If the supplied clazz is an interface, only the interface itself will be checked; * the inheritance hierarchy for interfaces will not be traversed. *

The standard {@link Class} API does not provide a mechanism for determining which class * in an inheritance hierarchy actually declares an {@link Annotation}, so we need to handle * this explicitly. * @param annotationType the Class object corresponding to the annotation type * @param clazz the Class object corresponding to the class on which to check for the annotation, * or null * @return the first {@link Class} in the inheritance hierarchy of the specified clazz * which declares an annotation for the specified annotationType, or null * if not found * @see Class#isAnnotationPresent(Class) * @see Class#getDeclaredAnnotations() */ public static Class findAnnotationDeclaringClass(Class annotationType, Class clazz) { Assert.notNull(annotationType, "Annotation type must not be null"); if (clazz == null || clazz.equals(Object.class)) { return null; } return (isAnnotationDeclaredLocally(annotationType, clazz)) ? clazz : findAnnotationDeclaringClass(annotationType, clazz.getSuperclass()); } /** * Determine whether an annotation for the specified annotationType is * declared locally on the supplied clazz. The supplied {@link Class} * may represent any type. *

Note: This method does not determine if the annotation is * {@link java.lang.annotation.Inherited inherited}. For greater clarity regarding inherited * annotations, consider using {@link #isAnnotationInherited(Class, Class)} instead. * @param annotationType the Class object corresponding to the annotation type * @param clazz the Class object corresponding to the class on which to check for the annotation * @return true if an annotation for the specified annotationType * is declared locally on the supplied clazz * @see Class#getDeclaredAnnotations() * @see #isAnnotationInherited(Class, Class) */ public static boolean isAnnotationDeclaredLocally(Class annotationType, Class clazz) { Assert.notNull(annotationType, "Annotation type must not be null"); Assert.notNull(clazz, "Class must not be null"); boolean declaredLocally = false; for (Annotation annotation : Arrays.asList(clazz.getDeclaredAnnotations())) { if (annotation.annotationType().equals(annotationType)) { declaredLocally = true; break; } } return declaredLocally; } /** * Determine whether an annotation for the specified annotationType is present * on the supplied clazz and is {@link java.lang.annotation.Inherited inherited} * i.e., not declared locally for the class). *

If the supplied clazz is an interface, only the interface itself will be checked. * In accordance with standard meta-annotation semantics, the inheritance hierarchy for interfaces * will not be traversed. See the {@link java.lang.annotation.Inherited JavaDoc} for the * @Inherited meta-annotation for further details regarding annotation inheritance. * @param annotationType the Class object corresponding to the annotation type * @param clazz the Class object corresponding to the class on which to check for the annotation * @return true if an annotation for the specified annotationType is present * on the supplied clazz and is {@link java.lang.annotation.Inherited inherited} * @see Class#isAnnotationPresent(Class) * @see #isAnnotationDeclaredLocally(Class, Class) */ public static boolean isAnnotationInherited(Class annotationType, Class clazz) { Assert.notNull(annotationType, "Annotation type must not be null"); Assert.notNull(clazz, "Class must not be null"); return (clazz.isAnnotationPresent(annotationType) && !isAnnotationDeclaredLocally(annotationType, clazz)); } /** * Retrieve the given annotation's attributes as a Map, preserving all attribute types as-is. * @param annotation the annotation to retrieve the attributes for * @return the Map of annotation attributes, with attribute names as keys and * corresponding attribute values as values */ public static Map getAnnotationAttributes(Annotation annotation) { return getAnnotationAttributes(annotation, false); } /** * Retrieve the given annotation's attributes as a Map. * @param annotation the annotation to retrieve the attributes for * @param classValuesAsString whether to turn Class references into Strings (for compatibility with * {@link org.springframework.core.type.AnnotationMetadata} or to preserve them as Class references * @return the Map of annotation attributes, with attribute names as keys and * corresponding attribute values as values */ public static Map getAnnotationAttributes(Annotation annotation, boolean classValuesAsString) { Map attrs = new HashMap(); Method[] methods = annotation.annotationType().getDeclaredMethods(); for (Method method : methods) { if (method.getParameterTypes().length == 0 && method.getReturnType() != void.class) { try { Object value = method.invoke(annotation); if (classValuesAsString) { if (value instanceof Class) { value = ((Class) value).getName(); } else if (value instanceof Class[]) { Class[] clazzArray = (Class[]) value; String[] newValue = new String[clazzArray.length]; for (int i = 0; i < clazzArray.length; i++) { newValue[i] = clazzArray[i].getName(); } value = newValue; } } attrs.put(method.getName(), value); } catch (Exception ex) { throw new IllegalStateException("Could not obtain annotation attribute values", ex); } } } return attrs; } /** * Retrieve the value of the "value" attribute of a * single-element Annotation, given an annotation instance. * @param annotation the annotation instance from which to retrieve the value * @return the attribute value, or null if not found * @see #getValue(Annotation, String) */ public static Object getValue(Annotation annotation) { return getValue(annotation, VALUE); } /** * Retrieve the value of a named Annotation attribute, given an annotation instance. * @param annotation the annotation instance from which to retrieve the value * @param attributeName the name of the attribute value to retrieve * @return the attribute value, or null if not found * @see #getValue(Annotation) */ public static Object getValue(Annotation annotation, String attributeName) { try { Method method = annotation.annotationType().getDeclaredMethod(attributeName, new Class[0]); return method.invoke(annotation); } catch (Exception ex) { return null; } } /** * Retrieve the default value of the "value" attribute * of a single-element Annotation, given an annotation instance. * @param annotation the annotation instance from which to retrieve the default value * @return the default value, or null if not found * @see #getDefaultValue(Annotation, String) */ public static Object getDefaultValue(Annotation annotation) { return getDefaultValue(annotation, VALUE); } /** * Retrieve the default value of a named Annotation attribute, given an annotation instance. * @param annotation the annotation instance from which to retrieve the default value * @param attributeName the name of the attribute value to retrieve * @return the default value of the named attribute, or null if not found * @see #getDefaultValue(Class, String) */ public static Object getDefaultValue(Annotation annotation, String attributeName) { return getDefaultValue(annotation.annotationType(), attributeName); } /** * Retrieve the default value of the "value" attribute * of a single-element Annotation, given the {@link Class annotation type}. * @param annotationType the annotation type for which the default value should be retrieved * @return the default value, or null if not found * @see #getDefaultValue(Class, String) */ public static Object getDefaultValue(Class annotationType) { return getDefaultValue(annotationType, VALUE); } /** * Retrieve the default value of a named Annotation attribute, given the {@link Class annotation type}. * @param annotationType the annotation type for which the default value should be retrieved * @param attributeName the name of the attribute value to retrieve. * @return the default value of the named attribute, or null if not found * @see #getDefaultValue(Annotation, String) */ public static Object getDefaultValue(Class annotationType, String attributeName) { try { Method method = annotationType.getDeclaredMethod(attributeName, new Class[0]); return method.getDefaultValue(); } catch (Exception ex) { return null; } } } ././@LongLink0000000000000000000000000000022500000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/annotation/AnnotationAwareOrderComparator.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000276111623223530033345 0ustar drazzibdrazzib/* * Copyright 2002-2006 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.annotation; import org.springframework.core.OrderComparator; import org.springframework.core.Ordered; /** * {@link java.util.Comparator} implementation that checks * {@link org.springframework.core.Ordered} as well as the * {@link Order} annotation, with an order value provided by an * Ordered instance overriding a statically defined * annotation value (if any). * * @author Juergen Hoeller * @since 2.0.1 * @see org.springframework.core.Ordered * @see Order */ public class AnnotationAwareOrderComparator extends OrderComparator { @Override protected int getOrder(Object obj) { if (obj instanceof Ordered) { return ((Ordered) obj).getOrder(); } if (obj != null) { Order order = obj.getClass().getAnnotation(Order.class); if (order != null) { return order.value(); } } return Ordered.LOWEST_PRECEDENCE; } } ././@LongLink0000000000000000000000000000015700000000000011570 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/libspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000755000175000017500000000000011623223530033335 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000020000000000000011555 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/package-info.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000013111623223530033332 0ustar drazzibdrazzib /** * * Type conversion system API. * */ package org.springframework.core.convert; ././@LongLink0000000000000000000000000000021500000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/ConversionFailedException.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000402111623223526033341 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.convert; import org.springframework.util.ObjectUtils; /** * Exception to be thrown when an actual type conversion attempt fails. * * @author Keith Donald * @author Juergen Hoeller * @since 3.0 */ public final class ConversionFailedException extends ConversionException { private final TypeDescriptor sourceType; private final TypeDescriptor targetType; private final Object value; /** * Create a new conversion exception. * @param sourceType the value's original type * @param targetType the value's target type * @param value the value we tried to convert * @param cause the cause of the conversion failure */ public ConversionFailedException(TypeDescriptor sourceType, TypeDescriptor targetType, Object value, Throwable cause) { super("Unable to convert value \"" + ObjectUtils.nullSafeToString(value) + "\" from type '" + sourceType.getName() + "' to type '" + targetType.getName() + "'", cause); this.sourceType = sourceType; this.targetType = targetType; this.value = value; } /** * Return the source type we tried to convert the value from. */ public TypeDescriptor getSourceType() { return this.sourceType; } /** * Return the target type we tried to convert the value to. */ public TypeDescriptor getTargetType() { return this.targetType; } /** * Return the offending value. */ public Object getValue() { return this.value; } } ././@LongLink0000000000000000000000000000020700000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/ConversionException.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000240511623223530033340 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.convert; import org.springframework.core.NestedRuntimeException; /** * Base class for exceptions thrown by the conversion system. * * @author Keith Donald * @since 3.0 */ public abstract class ConversionException extends NestedRuntimeException { /** * Construct a new conversion exception. * @param message the exception message */ public ConversionException(String message) { super(message); } /** * Construct a new conversion exception. * @param message the exception message * @param cause the cause */ public ConversionException(String message, Throwable cause) { super(message, cause); } } ././@LongLink0000000000000000000000000000021600000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/ConverterNotFoundException.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000341011623223530033335 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.convert; /** * Thrown when a suitable converter could not be found in a conversion service. * * @author Keith Donald * @since 3.0 */ @SuppressWarnings("serial") public final class ConverterNotFoundException extends ConversionException { private final TypeDescriptor sourceType; private final TypeDescriptor targetType; /** * Creates a new conversion executor not found exception. * @param sourceType the source type requested to convert from * @param targetType the target type requested to convert to * @param message a descriptive message */ public ConverterNotFoundException(TypeDescriptor sourceType, TypeDescriptor targetType) { super("No converter found capable of converting from '" + sourceType.getName() + "' to '" + targetType.getName() + "'"); this.sourceType = sourceType; this.targetType = targetType; } /** * Returns the source type that was requested to convert from. */ public TypeDescriptor getSourceType() { return this.sourceType; } /** * Returns the target type that was requested to convert to. */ public TypeDescriptor getTargetType() { return this.targetType; } } ././@LongLink0000000000000000000000000000016700000000000011571 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/support/libspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000755000175000017500000000000011623223530033335 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000022400000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/support/CharacterToNumberFactory.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000374211623223526033352 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.convert.support; import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.converter.ConverterFactory; import org.springframework.util.NumberUtils; /** * Converts from a Character to any JDK-standard Number implementation. * *

Support Number classes including Byte, Short, Integer, Float, Double, Long, BigInteger, BigDecimal. This class * delegates to {@link NumberUtils#convertNumberToTargetClass(Number, Class)} to perform the conversion. * * @author Keith Donald * @since 3.0 * @see java.lang.Byte * @see java.lang.Short * @see java.lang.Integer * @see java.lang.Long * @see java.math.BigInteger * @see java.lang.Float * @see java.lang.Double * @see java.math.BigDecimal * @see NumberUtils */ final class CharacterToNumberFactory implements ConverterFactory { public Converter getConverter(Class targetType) { return new CharacterToNumber(targetType); } private static final class CharacterToNumber implements Converter { private final Class targetType; public CharacterToNumber(Class targetType) { this.targetType = targetType; } public T convert(Character source) { return NumberUtils.convertNumberToTargetClass((short) source.charValue(), this.targetType); } } } ././@LongLink0000000000000000000000000000022300000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/support/ObjectToObjectConverter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000713211623223526033347 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.convert.support; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Collections; import java.util.Set; import org.springframework.core.convert.ConversionFailedException; import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.converter.ConditionalGenericConverter; import org.springframework.util.ClassUtils; import org.springframework.util.ReflectionUtils; /** * Generic Converter that attempts to convert a source Object to a target type * by delegating to methods on the target type. * *

Calls the static valueOf(sourceType) method on the target type * to perform the conversion, if such a method exists. Else calls the target type's * Constructor that accepts a single sourceType argument, if such a Constructor exists. * Else throws a ConversionFailedException. * * @author Keith Donald * @author Juergen Hoeller * @since 3.0 */ final class ObjectToObjectConverter implements ConditionalGenericConverter { public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { Class source = sourceType.getObjectType(); Class target = targetType.getObjectType(); return (!source.equals(target) && hasValueOfMethodOrConstructor(target, source)); } public Set getConvertibleTypes() { return Collections.singleton(new ConvertiblePair(Object.class, Object.class)); } public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { Class sourceClass = sourceType.getObjectType(); Class targetClass = targetType.getObjectType(); Method method = getValueOfMethodOn(targetClass, sourceClass); try { if (method != null) { ReflectionUtils.makeAccessible(method); return method.invoke(null, source); } else { Constructor constructor = getConstructor(targetClass, sourceClass); if (constructor != null) { return constructor.newInstance(source); } } } catch (InvocationTargetException ex) { throw new ConversionFailedException(sourceType, targetType, source, ex.getTargetException()); } catch (Throwable ex) { throw new ConversionFailedException(sourceType, targetType, source, ex); } throw new IllegalStateException("No static valueOf(" + sourceClass.getName() + ") method or Constructor(" + sourceClass.getName() + ") exists on " + targetClass.getName()); } public static boolean hasValueOfMethodOrConstructor(Class targetClass, Class sourceClass) { return (getValueOfMethodOn(targetClass, sourceClass) != null || getConstructor(targetClass, sourceClass) != null); } private static Method getValueOfMethodOn(Class targetClass, Class sourceClass) { return ClassUtils.getStaticMethod(targetClass, "valueOf", sourceClass); } private static Constructor getConstructor(Class targetClass, Class sourceClass) { return ClassUtils.getConstructorIfAvailable(targetClass, sourceClass); } } ././@LongLink0000000000000000000000000000021500000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/support/MapToMapConverter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000567411623223526033360 0ustar drazzibdrazzib/* * Copyright 2002-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.convert.support; import java.util.Collections; import java.util.Map; import java.util.Set; import org.springframework.core.CollectionFactory; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.converter.ConditionalGenericConverter; /** * Converts a Map to another Map. * *

First, creates a new Map of the requested targetType with a size equal to the * size of the source Map. Then copies each element in the source map to the target map. * Will perform a conversion from the source maps's parameterized K,V types to the target * map's parameterized types K,V if necessary. * * @author Keith Donald * @since 3.0 */ final class MapToMapConverter implements ConditionalGenericConverter { private final ConversionService conversionService; public MapToMapConverter(ConversionService conversionService) { this.conversionService = conversionService; } public Set getConvertibleTypes() { return Collections.singleton(new ConvertiblePair(Map.class, Map.class)); } public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { return this.conversionService.canConvert(sourceType.getMapKeyTypeDescriptor(), targetType.getMapKeyTypeDescriptor()) && this.conversionService.canConvert(sourceType.getMapValueTypeDescriptor(), targetType.getMapValueTypeDescriptor()); } @SuppressWarnings("unchecked") public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { if (source == null) { return null; } Map sourceMap = (Map) source; Map targetMap = CollectionFactory.createMap(targetType.getType(), sourceMap.size()); for (Object entry : sourceMap.entrySet()) { Map.Entry sourceMapEntry = (Map.Entry) entry; Object sourceKey = sourceMapEntry.getKey(); Object sourceValue = sourceMapEntry.getValue(); Object targetKey = this.conversionService.convert(sourceKey, sourceType.getMapKeyTypeDescriptor(sourceKey), targetType.getMapKeyTypeDescriptor(sourceKey)); Object targetValue = this.conversionService.convert(sourceValue, sourceType.getMapValueTypeDescriptor(sourceValue), targetType.getMapValueTypeDescriptor(sourceValue)); targetMap.put(targetKey, targetValue); } return targetMap; } } ././@LongLink0000000000000000000000000000021000000000000011556 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/support/package-info.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000017311623223530033340 0ustar drazzibdrazzib /** * * Default implementation of the type conversion system. * */ package org.springframework.core.convert.support; ././@LongLink0000000000000000000000000000022600000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/support/CollectionToArrayConverter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000503011623223526033342 0ustar drazzibdrazzib/* * Copyright 2002-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.convert.support; import java.lang.reflect.Array; import java.util.Collection; import java.util.Collections; import java.util.Set; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.converter.ConditionalGenericConverter; /** * Converts a Collection to an array. * *

First, creates a new array of the requested targetType with a length equal to the * size of the source Collection. Then sets each collection element into the array. * Will perform an element conversion from the collection's parameterized type to the * array's component type if necessary. * * @author Keith Donald * @since 3.0 */ final class CollectionToArrayConverter implements ConditionalGenericConverter { private final ConversionService conversionService; public CollectionToArrayConverter(ConversionService conversionService) { this.conversionService = conversionService; } public Set getConvertibleTypes() { return Collections.singleton(new ConvertiblePair(Collection.class, Object[].class)); } public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { return ConversionUtils.canConvertElements(sourceType.getElementTypeDescriptor(), targetType.getElementTypeDescriptor(), this.conversionService); } public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { if (source == null) { return null; } Collection sourceCollection = (Collection) source; Object array = Array.newInstance(targetType.getElementType(), sourceCollection.size()); int i = 0; for (Object sourceElement : sourceCollection) { Object targetElement = this.conversionService.convert(sourceElement, sourceType.getElementTypeDescriptor(sourceElement), targetType.getElementTypeDescriptor()); Array.set(array, i++, targetElement); } return array; } } ././@LongLink0000000000000000000000000000023200000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/support/NumberToNumberConverterFactory.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000373411623223530033346 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.convert.support; import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.converter.ConverterFactory; import org.springframework.util.NumberUtils; /** * Converts from any JDK-standard Number implementation to any other JDK-standard Number implementation. * *

Support Number classes including Byte, Short, Integer, Float, Double, Long, BigInteger, BigDecimal. This class * delegates to {@link NumberUtils#convertNumberToTargetClass(Number, Class)} to perform the conversion. * * @author Keith Donald * @since 3.0 * @see java.lang.Byte * @see java.lang.Short * @see java.lang.Integer * @see java.lang.Long * @see java.math.BigInteger * @see java.lang.Float * @see java.lang.Double * @see java.math.BigDecimal * @see NumberUtils */ final class NumberToNumberConverterFactory implements ConverterFactory { public Converter getConverter(Class targetType) { return new NumberToNumber(targetType); } private final static class NumberToNumber implements Converter { private final Class targetType; public NumberToNumber(Class targetType) { this.targetType = targetType; } public T convert(Number source) { return NumberUtils.convertNumberToTargetClass(source, this.targetType); } } } ././@LongLink0000000000000000000000000000022700000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/support/StringToCollectionConverter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000445711623223530033351 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.convert.support; import java.util.Collection; import java.util.Collections; import java.util.Set; import org.springframework.core.CollectionFactory; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.converter.ConditionalGenericConverter; import org.springframework.util.StringUtils; /** * Converts a comma-delimited String to a Collection. * * @author Keith Donald * @since 3.0 */ final class StringToCollectionConverter implements ConditionalGenericConverter { private final ConversionService conversionService; public StringToCollectionConverter(ConversionService conversionService) { this.conversionService = conversionService; } public Set getConvertibleTypes() { return Collections.singleton(new ConvertiblePair(String.class, Collection.class)); } public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { return this.conversionService.canConvert(sourceType, targetType.getElementTypeDescriptor()); } @SuppressWarnings("unchecked") public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { if (source == null) { return null; } String string = (String) source; String[] fields = StringUtils.commaDelimitedListToStringArray(string); Collection target = CollectionFactory.createCollection(targetType.getType(), fields.length); for (String sourceElement : fields) { Object targetElement = this.conversionService.convert(sourceElement.trim(), sourceType, targetType.getElementTypeDescriptor(sourceElement)); target.add(targetElement); } return target; } } ././@LongLink0000000000000000000000000000022200000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/support/ObjectToArrayConverter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000412211623223530033336 0ustar drazzibdrazzib/* * Copyright 2002-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.convert.support; import java.lang.reflect.Array; import java.util.Collections; import java.util.Set; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.converter.ConditionalGenericConverter; /** * Converts an Object to a single-element Array containing the Object. * Will convert the Object to the target Array's component type if necessary. * * @author Keith Donald * @since 3.0 */ final class ObjectToArrayConverter implements ConditionalGenericConverter { private final ConversionService conversionService; public ObjectToArrayConverter(ConversionService conversionService) { this.conversionService = conversionService; } public Set getConvertibleTypes() { return Collections.singleton(new ConvertiblePair(Object.class, Object[].class)); } public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { return ConversionUtils.canConvertElements(sourceType, targetType.getElementTypeDescriptor(), this.conversionService); } public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { if (source == null) { return null; } Object target = Array.newInstance(targetType.getElementType(), 1); Object targetElement = this.conversionService.convert(source, sourceType, targetType.getElementTypeDescriptor()); Array.set(target, 0, targetElement); return target; } } ././@LongLink0000000000000000000000000000022400000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/support/StringToBooleanConverter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000326611623223530033346 0ustar drazzibdrazzib/* * Copyright 2002-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.convert.support; import java.util.HashSet; import java.util.Set; import org.springframework.core.convert.converter.Converter; /** * Converts String to a Boolean. * * @author Keith Donald * @author Juergen Hoeller * @since 3.0 */ final class StringToBooleanConverter implements Converter { private static final Set trueValues = new HashSet(4); private static final Set falseValues = new HashSet(4); static { trueValues.add("true"); trueValues.add("on"); trueValues.add("yes"); trueValues.add("1"); falseValues.add("false"); falseValues.add("off"); falseValues.add("no"); falseValues.add("0"); } public Boolean convert(String source) { String value = source.trim(); if ("".equals(value)) { return null; } value = value.toLowerCase(); if (trueValues.contains(value)) { return Boolean.TRUE; } else if (falseValues.contains(value)) { return Boolean.FALSE; } else { throw new IllegalArgumentException("Invalid boolean value '" + source + "'"); } } } ././@LongLink0000000000000000000000000000022600000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/support/ArrayToCollectionConverter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000506211623223530033342 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.convert.support; import java.lang.reflect.Array; import java.util.Collection; import java.util.Collections; import java.util.Set; import org.springframework.core.CollectionFactory; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.converter.ConditionalGenericConverter; /** * Converts an Array to a Collection. * *

First, creates a new Collection of the requested targetType. * Then adds each array element to the target collection. * Will perform an element conversion from the source component type to the collection's parameterized type if necessary. * * @author Keith Donald * @since 3.0 */ final class ArrayToCollectionConverter implements ConditionalGenericConverter { private final ConversionService conversionService; public ArrayToCollectionConverter(ConversionService conversionService) { this.conversionService = conversionService; } public Set getConvertibleTypes() { return Collections.singleton(new ConvertiblePair(Object[].class, Collection.class)); } public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { return ConversionUtils.canConvertElements(sourceType.getElementTypeDescriptor(), targetType.getElementTypeDescriptor(), this.conversionService); } @SuppressWarnings("unchecked") public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { if (source == null) { return null; } int length = Array.getLength(source); Collection target = CollectionFactory.createCollection(targetType.getType(), length); for (int i = 0; i < length; i++) { Object sourceElement = Array.get(source, i); Object targetElement = this.conversionService.convert(sourceElement, sourceType.getElementTypeDescriptor(), targetType.getElementTypeDescriptor(sourceElement)); target.add(targetElement); } return target; } } ././@LongLink0000000000000000000000000000022200000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/support/ArrayToObjectConverter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000414611623223530033344 0ustar drazzibdrazzib/* * Copyright 2002-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.convert.support; import java.lang.reflect.Array; import java.util.Collections; import java.util.Set; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.converter.ConditionalGenericConverter; /** * Converts an Array to an Object by returning the first array element after converting it to the desired targetType. * * @author Keith Donald * @since 3.0 */ final class ArrayToObjectConverter implements ConditionalGenericConverter { private final ConversionService conversionService; public ArrayToObjectConverter(ConversionService conversionService) { this.conversionService = conversionService; } public Set getConvertibleTypes() { return Collections.singleton(new ConvertiblePair(Object[].class, Object.class)); } public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { return ConversionUtils.canConvertElements(sourceType.getElementTypeDescriptor(), targetType, this.conversionService); } public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { if (source == null) { return null; } if (sourceType.isAssignableTo(targetType)) { return source; } if (Array.getLength(source) == 0) { return null; } Object firstElement = Array.get(source, 0); return this.conversionService.convert(firstElement, sourceType.getElementTypeDescriptor(firstElement), targetType); } } ././@LongLink0000000000000000000000000000023200000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/support/StringToNumberConverterFactory.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000371411623223530033344 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.convert.support; import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.converter.ConverterFactory; import org.springframework.util.NumberUtils; /** * Converts from a String any JDK-standard Number implementation. * *

Support Number classes including Byte, Short, Integer, Float, Double, Long, BigInteger, BigDecimal. This class * delegates to {@link NumberUtils#parseNumber(String, Class)} to perform the conversion. * * @author Keith Donald * @since 3.0 * @see java.lang.Byte * @see java.lang.Short * @see java.lang.Integer * @see java.lang.Long * @see java.math.BigInteger * @see java.lang.Float * @see java.lang.Double * @see java.math.BigDecimal * @see NumberUtils */ final class StringToNumberConverterFactory implements ConverterFactory { public Converter getConverter(Class targetType) { return new StringToNumber(targetType); } private static final class StringToNumber implements Converter { private final Class targetType; public StringToNumber(Class targetType) { this.targetType = targetType; } public T convert(String source) { if (source.length() == 0) { return null; } return NumberUtils.parseNumber(source, this.targetType); } } } ././@LongLink0000000000000000000000000000022400000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/support/ConversionServiceFactory.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000001115611623223530033343 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.convert.support; import java.util.Set; import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.converter.ConverterFactory; import org.springframework.core.convert.converter.ConverterRegistry; import org.springframework.core.convert.converter.GenericConverter; /** * A factory for common {@link org.springframework.core.convert.ConversionService} * configurations. * * @author Keith Donald * @author Juergen Hoeller * @since 3.0 */ public abstract class ConversionServiceFactory { /** * Create a new default ConversionService instance that can be safely modified. */ public static GenericConversionService createDefaultConversionService() { GenericConversionService conversionService = new GenericConversionService(); addDefaultConverters(conversionService); return conversionService; } /** * Populate the given ConversionService instance with all applicable default converters. */ public static void addDefaultConverters(GenericConversionService conversionService) { conversionService.addConverter(new ArrayToCollectionConverter(conversionService)); conversionService.addConverter(new CollectionToArrayConverter(conversionService)); conversionService.addConverter(new ArrayToStringConverter(conversionService)); conversionService.addConverter(new StringToArrayConverter(conversionService)); conversionService.addConverter(new ArrayToObjectConverter(conversionService)); conversionService.addConverter(new ObjectToArrayConverter(conversionService)); conversionService.addConverter(new CollectionToStringConverter(conversionService)); conversionService.addConverter(new StringToCollectionConverter(conversionService)); conversionService.addConverter(new CollectionToObjectConverter(conversionService)); conversionService.addConverter(new ObjectToCollectionConverter(conversionService)); conversionService.addConverter(new ArrayToArrayConverter(conversionService)); conversionService.addConverter(new CollectionToCollectionConverter(conversionService)); conversionService.addConverter(new MapToMapConverter(conversionService)); conversionService.addConverter(new PropertiesToStringConverter()); conversionService.addConverter(new StringToPropertiesConverter()); conversionService.addConverter(new StringToBooleanConverter()); conversionService.addConverter(new StringToCharacterConverter()); conversionService.addConverter(new StringToLocaleConverter()); conversionService.addConverterFactory(new StringToNumberConverterFactory()); conversionService.addConverterFactory(new StringToEnumConverterFactory()); conversionService.addConverter(new NumberToCharacterConverter()); conversionService.addConverterFactory(new CharacterToNumberFactory()); conversionService.addConverterFactory(new NumberToNumberConverterFactory()); conversionService.addConverter(new ObjectToStringConverter()); conversionService.addConverter(new ObjectToObjectConverter()); conversionService.addConverter(new IdToEntityConverter(conversionService)); } /** * Register the given converter objects with the given target registry. * @param converters the converter objects: implementing {@link Converter}, * {@link ConverterFactory}, or {@link GenericConverter} * @param registry the target registry to register with */ public static void registerConverters(Set converters, ConverterRegistry registry) { if (converters != null) { for (Object converter : converters) { if (converter instanceof GenericConverter) { registry.addConverter((GenericConverter) converter); } else if (converter instanceof Converter) { registry.addConverter((Converter) converter); } else if (converter instanceof ConverterFactory) { registry.addConverterFactory((ConverterFactory) converter); } else { throw new IllegalArgumentException("Each converter object must implement one of the " + "Converter, ConverterFactory, or GenericConverter interfaces"); } } } } } ././@LongLink0000000000000000000000000000022300000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/support/ObjectToStringConverter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000423011623223530033336 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.convert.support; import java.io.StringWriter; import java.util.Collections; import java.util.Set; import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.converter.ConditionalGenericConverter; /** * Simply calls {@link Object#toString()} to convert any supported Object to a String. * Supports Number, Boolean, Character, CharSequence, StringWriter, any enum, * and any class with a String constructor or valueOf(String) method. * *

Used by the default ConversionService as a fallback if there are no other explicit * to-String converters registered. * * @author Keith Donald * @author Juergen Hoeller * @since 3.0 */ final class ObjectToStringConverter implements ConditionalGenericConverter { public Set getConvertibleTypes() { return Collections.singleton(new ConvertiblePair(Object.class, String.class)); } public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { Class sourceClass = sourceType.getObjectType(); return CharSequence.class.isAssignableFrom(sourceClass) || Number.class.isAssignableFrom(sourceClass) || Boolean.class.equals(sourceClass) || Character.class.equals(sourceClass) || StringWriter.class.isAssignableFrom(sourceClass) || sourceClass.isEnum() || ObjectToObjectConverter.hasValueOfMethodOrConstructor(sourceClass, String.class); } public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { return (source != null ? source.toString() : null); } } ././@LongLink0000000000000000000000000000022200000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/support/StringToArrayConverter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000434611623223526033353 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.convert.support; import java.lang.reflect.Array; import java.util.Collections; import java.util.Set; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.converter.ConditionalGenericConverter; import org.springframework.util.StringUtils; /** * Converts a comma-delimited String to an Array. * * @author Keith Donald * @since 3.0 */ final class StringToArrayConverter implements ConditionalGenericConverter { private final ConversionService conversionService; public StringToArrayConverter(ConversionService conversionService) { this.conversionService = conversionService; } public Set getConvertibleTypes() { return Collections.singleton(new ConvertiblePair(String.class, Object[].class)); } public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { return this.conversionService.canConvert(sourceType, targetType.getElementTypeDescriptor()); } public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { if (source == null) { return null; } String string = (String) source; String[] fields = StringUtils.commaDelimitedListToStringArray(string); Object target = Array.newInstance(targetType.getElementType(), fields.length); for (int i = 0; i < fields.length; i++) { String sourceElement = fields[i]; Object targetElement = this.conversionService.convert(sourceElement.trim(), sourceType, targetType.getElementTypeDescriptor()); Array.set(target, i, targetElement); } return target; } }././@LongLink0000000000000000000000000000022700000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/support/PropertiesToStringConverter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000270311623223526033346 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.convert.support; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Properties; import org.springframework.core.convert.converter.Converter; /** * Converts from a Properties to a String by calling {@link Properties#store(java.io.OutputStream, String)}. * Decodes with the ISO-8859-1 charset before returning the String. * * @author Keith Donald * @since 3.0 */ final class PropertiesToStringConverter implements Converter { public String convert(Properties source) { try { ByteArrayOutputStream os = new ByteArrayOutputStream(); source.store(os, null); return os.toString("ISO-8859-1"); } catch (IOException ex) { // Should never happen. throw new IllegalArgumentException("Failed to store [" + source + "] into String", ex); } } } ././@LongLink0000000000000000000000000000021300000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/support/ConversionUtils.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000370711623223530033346 0ustar drazzibdrazzib/* * Copyright 2002-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.convert.support; import org.springframework.core.convert.ConversionFailedException; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.converter.GenericConverter; /** * Internal utilities for the conversion package. * * @author Keith Donald * @since 3.0 */ abstract class ConversionUtils { public static Object invokeConverter(GenericConverter converter, Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { try { return converter.convert(source, sourceType, targetType); } catch (ConversionFailedException ex) { throw ex; } catch (Exception ex) { throw new ConversionFailedException(sourceType, targetType, source, ex); } } public static boolean canConvertElements(TypeDescriptor sourceElementType, TypeDescriptor targetElementType, ConversionService conversionService) { if (targetElementType == null) { // yes return true; } if (sourceElementType == null) { // maybe return true; } if (conversionService.canConvert(sourceElementType, targetElementType)) { // yes return true; } else if (sourceElementType.getType().isAssignableFrom(targetElementType.getType())) { // maybe; return true; } else { // no; return false; } } } ././@LongLink0000000000000000000000000000022700000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/support/CollectionToObjectConverter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000430011623223526033341 0ustar drazzibdrazzib/* * Copyright 2002-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.convert.support; import java.util.Collection; import java.util.Collections; import java.util.Set; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.converter.ConditionalGenericConverter; /** * Converts a Collection to an Object by returning the first collection element after converting it to the desired targetType. * * @author Keith Donald * @since 3.0 */ final class CollectionToObjectConverter implements ConditionalGenericConverter { private final ConversionService conversionService; public CollectionToObjectConverter(ConversionService conversionService) { this.conversionService = conversionService; } public Set getConvertibleTypes() { return Collections.singleton(new ConvertiblePair(Collection.class, Object.class)); } public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { return ConversionUtils.canConvertElements(sourceType.getElementTypeDescriptor(), targetType, this.conversionService); } public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { if (source == null) { return null; } if (sourceType.isAssignableTo(targetType)) { return source; } Collection sourceCollection = (Collection) source; if (sourceCollection.size() == 0) { return null; } Object firstElement = sourceCollection.iterator().next(); return this.conversionService.convert(firstElement, sourceType.getElementTypeDescriptor(firstElement), targetType); } } ././@LongLink0000000000000000000000000000022100000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/support/ArrayToArrayConverter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000372711623223530033350 0ustar drazzibdrazzib/* * Copyright 2002-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.convert.support; import java.util.Arrays; import java.util.Collections; import java.util.Set; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.converter.ConditionalGenericConverter; import org.springframework.util.ObjectUtils; /** * Converts an Array to another Array. * First adapts the source array to a List, then delegates to {@link CollectionToArrayConverter} to perform the target array conversion. * * @author Keith Donald * @since 3.0 */ final class ArrayToArrayConverter implements ConditionalGenericConverter { private final CollectionToArrayConverter helperConverter; public ArrayToArrayConverter(ConversionService conversionService) { this.helperConverter = new CollectionToArrayConverter(conversionService); } public Set getConvertibleTypes() { return Collections.singleton(new ConvertiblePair(Object[].class, Object[].class)); } public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { return this.helperConverter.matches(sourceType, targetType); } public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { return this.helperConverter.convert(Arrays.asList(ObjectUtils.toObjectArray(source)), sourceType, targetType); } } ././@LongLink0000000000000000000000000000022700000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/support/ObjectToCollectionConverter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000456311623223530033347 0ustar drazzibdrazzib/* * Copyright 2002-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.convert.support; import java.util.Collection; import java.util.Collections; import java.util.Set; import org.springframework.core.CollectionFactory; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.converter.ConditionalGenericConverter; /** * Converts an Object to a single-element Collection containing the Object. * Will convert the Object to the target Collection's parameterized type if necessary. * * @author Keith Donald * @author Juergen Hoeller * @since 3.0 */ final class ObjectToCollectionConverter implements ConditionalGenericConverter { private final ConversionService conversionService; public ObjectToCollectionConverter(ConversionService conversionService) { this.conversionService = conversionService; } public Set getConvertibleTypes() { return Collections.singleton(new ConvertiblePair(Object.class, Collection.class)); } public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { return ConversionUtils.canConvertElements(sourceType, targetType.getElementTypeDescriptor(), this.conversionService); } @SuppressWarnings("unchecked") public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { if (source == null) { return null; } Collection target = CollectionFactory.createCollection(targetType.getType(), 1); TypeDescriptor elementType = targetType.getElementTypeDescriptor(source); // Avoid potential recursion... if (!Collection.class.isAssignableFrom(elementType.getType())) { target.add(this.conversionService.convert(source, sourceType, elementType)); } else { target.add(source); } return target; } } ././@LongLink0000000000000000000000000000023300000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/support/ConvertingPropertyEditorAdapter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000501711623223530033342 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.convert.support; import java.beans.PropertyEditorSupport; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.TypeDescriptor; import org.springframework.util.Assert; /** * Adapter that exposes a {@link java.beans.PropertyEditor} for any given * {@link org.springframework.core.convert.ConversionService} and specific target type. * * @author Juergen Hoeller * @since 3.0 */ public class ConvertingPropertyEditorAdapter extends PropertyEditorSupport { private final ConversionService conversionService; private final TypeDescriptor targetDescriptor; private final boolean canConvertToString; /** * Create a new ConvertingPropertyEditorAdapter for a given * {@link org.springframework.core.convert.ConversionService} * and the given target type. * @param conversionService the ConversionService to delegate to * @param targetDescriptor the target type to convert to */ public ConvertingPropertyEditorAdapter(ConversionService conversionService, TypeDescriptor targetDescriptor) { Assert.notNull(conversionService, "ConversionService must not be null"); Assert.notNull(targetDescriptor, "TypeDescriptor must not be null"); this.conversionService = conversionService; this.targetDescriptor = targetDescriptor; this.canConvertToString = conversionService.canConvert(this.targetDescriptor, TypeDescriptor.valueOf(String.class)); } @Override public void setAsText(String text) throws IllegalArgumentException { setValue(this.conversionService.convert(text, TypeDescriptor.valueOf(String.class), this.targetDescriptor)); } @Override public String getAsText() { if (this.canConvertToString) { return (String) this.conversionService.convert(getValue(), this.targetDescriptor, TypeDescriptor.valueOf(String.class)); } else { return null; } } } ././@LongLink0000000000000000000000000000022600000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/support/NumberToCharacterConverter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000232011623223526033341 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.convert.support; import org.springframework.core.convert.converter.Converter; /** * Converts from any JDK-standard Number implementation to a Character. * * @author Keith Donald * @since 3.0 * @see java.lang.Character * @see java.lang.Short * @see java.lang.Integer * @see java.lang.Long * @see java.math.BigInteger * @see java.lang.Float * @see java.lang.Double * @see java.math.BigDecimal */ final class NumberToCharacterConverter implements Converter { public Character convert(Number source) { return (char) source.shortValue(); } } ././@LongLink0000000000000000000000000000023300000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/support/CollectionToCollectionConverter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000524411623223526033351 0ustar drazzibdrazzib/* * Copyright 2002-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.convert.support; import java.util.Collection; import java.util.Collections; import java.util.Set; import org.springframework.core.CollectionFactory; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.converter.ConditionalGenericConverter; /** * Converts from a Collection to another Collection. * *

First, creates a new Collection of the requested targetType with a size equal to the * size of the source Collection. Then copies each element in the source collection to the * target collection. Will perform an element conversion from the source collection's * parameterized type to the target collection's parameterized type if necessary. * * @author Keith Donald * @since 3.0 */ final class CollectionToCollectionConverter implements ConditionalGenericConverter { private final ConversionService conversionService; public CollectionToCollectionConverter(ConversionService conversionService) { this.conversionService = conversionService; } public Set getConvertibleTypes() { return Collections.singleton(new ConvertiblePair(Collection.class, Collection.class)); } public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { return ConversionUtils.canConvertElements(sourceType.getElementTypeDescriptor(), targetType.getElementTypeDescriptor(), conversionService); } @SuppressWarnings("unchecked") public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { if (source == null) { return null; } Collection sourceCollection = (Collection) source; Collection target = CollectionFactory.createCollection(targetType.getType(), sourceCollection.size()); for (Object sourceElement : sourceCollection) { Object targetElement = this.conversionService.convert(sourceElement, sourceType.getElementTypeDescriptor(sourceElement), targetType.getElementTypeDescriptor(sourceElement)); target.add(targetElement); } return target; } } ././@LongLink0000000000000000000000000000022600000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/support/StringToCharacterConverter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000233411623223530033341 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.convert.support; import org.springframework.core.convert.converter.Converter; /** * Converts a String to a Character. * * @author Keith Donald * @since 3.0 */ final class StringToCharacterConverter implements Converter { public Character convert(String source) { if (source.length() == 0) { return null; } if (source.length() > 1) { throw new IllegalArgumentException( "Can only convert a [String] with length of 1 to a [Character]; string value '" + source + "' has length of " + source.length()); } return source.charAt(0); } } ././@LongLink0000000000000000000000000000022400000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/support/GenericConversionService.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000004663111623223530033351 0ustar drazzibdrazzib/* * Copyright 2002-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.convert.support; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import org.springframework.core.GenericTypeResolver; import org.springframework.core.convert.ConversionFailedException; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.ConverterNotFoundException; import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.converter.ConditionalGenericConverter; import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.converter.ConverterFactory; import org.springframework.core.convert.converter.ConverterRegistry; import org.springframework.core.convert.converter.GenericConverter; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; /** * Base {@link ConversionService} implementation suitable for use in most environments. * Implements {@link ConverterRegistry} as registration API. * * @author Keith Donald * @author Juergen Hoeller * @since 3.0 */ public class GenericConversionService implements ConversionService, ConverterRegistry { private static final GenericConverter NO_OP_CONVERTER = new GenericConverter() { public Set getConvertibleTypes() { return null; } public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { return source; } public String toString() { return "NO_OP"; } }; private static final GenericConverter NO_MATCH = new GenericConverter() { public Set getConvertibleTypes() { throw new UnsupportedOperationException(); } public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { throw new UnsupportedOperationException(); } public String toString() { return "NO_MATCH"; } }; private final Map, Map, MatchableConverters>> converters = new HashMap, Map, MatchableConverters>>(36); private final Map converterCache = new ConcurrentHashMap(); // implementing ConverterRegistry public void addConverter(Converter converter) { GenericConverter.ConvertiblePair typeInfo = getRequiredTypeInfo(converter, Converter.class); if (typeInfo == null) { throw new IllegalArgumentException("Unable to the determine sourceType and targetType which " + "your Converter converts between; declare these generic types."); } addConverter(new ConverterAdapter(typeInfo, converter)); } public void addConverterFactory(ConverterFactory converterFactory) { GenericConverter.ConvertiblePair typeInfo = getRequiredTypeInfo(converterFactory, ConverterFactory.class); if (typeInfo == null) { throw new IllegalArgumentException("Unable to the determine sourceType and targetRangeType R which " + "your ConverterFactory converts between; declare these generic types."); } addConverter(new ConverterFactoryAdapter(typeInfo, converterFactory)); } public void addConverter(GenericConverter converter) { Set convertibleTypes = converter.getConvertibleTypes(); for (GenericConverter.ConvertiblePair convertibleType : convertibleTypes) { getMatchableConverters(convertibleType.getSourceType(), convertibleType.getTargetType()).add(converter); } invalidateCache(); } public void removeConvertible(Class sourceType, Class targetType) { getSourceConverterMap(sourceType).remove(targetType); invalidateCache(); } // implementing ConversionService public boolean canConvert(Class sourceType, Class targetType) { return canConvert(TypeDescriptor.valueOf(sourceType), TypeDescriptor.valueOf(targetType)); } @SuppressWarnings("unchecked") public T convert(Object source, Class targetType) { return (T) convert(source, TypeDescriptor.forObject(source), TypeDescriptor.valueOf(targetType)); } public boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType) { assertNotNull(sourceType, targetType); if (sourceType == TypeDescriptor.NULL || targetType == TypeDescriptor.NULL) { return true; } GenericConverter converter = getConverter(sourceType, targetType); return (converter != null); } public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { assertNotNull(sourceType, targetType); if (sourceType == TypeDescriptor.NULL) { Assert.isTrue(source == null, "The value must be null if sourceType == TypeDescriptor.NULL"); return convertNullSource(sourceType, targetType); } if (targetType == TypeDescriptor.NULL) { return null; } Assert.isTrue(source == null || sourceType.getObjectType().isInstance(source)); GenericConverter converter = getConverter(sourceType, targetType); if (converter == null) { if (source == null || targetType.getObjectType().isInstance(source)) { return source; } else { throw new ConverterNotFoundException(sourceType, targetType); } } return ConversionUtils.invokeConverter(converter, source, sourceType, targetType); } public String toString() { List converterStrings = new ArrayList(); for (Map, MatchableConverters> targetConverters : this.converters.values()) { for (MatchableConverters matchable : targetConverters.values()) { converterStrings.add(matchable.toString()); } } Collections.sort(converterStrings); StringBuilder builder = new StringBuilder(); builder.append("ConversionService converters = ").append("\n"); for (String converterString : converterStrings) { builder.append("\t"); builder.append(converterString); builder.append("\n"); } return builder.toString(); } // subclassing hooks /** * Template method to convert a null source. *

Default implementation returns null. * Throws a {@link ConversionFailedException} if the targetType is a primitive type, * as null cannot be assigned to a primitive type. * Subclasses may override to return custom null objects for specific target types. * @param sourceType the sourceType to convert from * @param targetType the targetType to convert to * @return the converted null object */ protected Object convertNullSource(TypeDescriptor sourceType, TypeDescriptor targetType) { if (targetType.isPrimitive()) { throw new ConversionFailedException(sourceType, targetType, null, new IllegalArgumentException("A null value cannot be assigned to a primitive type")); } return null; } /** * Hook method to lookup the converter for a given sourceType/targetType pair. *

First queries this ConversionService's converter cache. * On a cache miss, then performs an exhaustive search for a matching converter. * If no converter matches, returns the default converter. * Subclasses may override. * @param sourceType the source type to convert from * @param targetType the target type to convert to * @return the generic converter that will perform the conversion, * or null if no suitable converter was found * @see #getDefaultConverter(TypeDescriptor, TypeDescriptor) */ protected GenericConverter getConverter(TypeDescriptor sourceType, TypeDescriptor targetType) { ConverterCacheKey key = new ConverterCacheKey(sourceType, targetType); GenericConverter converter = this.converterCache.get(key); if (converter != null) { return (converter != NO_MATCH ? converter : null); } else { converter = findConverterForClassPair(sourceType, targetType); if (converter != null) { this.converterCache.put(key, converter); return converter; } converter = getDefaultConverter(sourceType, targetType); if (converter != null) { this.converterCache.put(key, converter); return converter; } this.converterCache.put(key, NO_MATCH); return null; } } /** * Return the default converter if no converter is found for the given sourceType/targetType pair. * Returns a NO_OP Converter if the sourceType is assignable to the targetType. * Returns null otherwise, indicating no suitable converter could be found. * Subclasses may override. * @param sourceType the source type to convert from * @param targetType the target type to convert to * @return the default generic converter that will perform the conversion */ protected GenericConverter getDefaultConverter(TypeDescriptor sourceType, TypeDescriptor targetType) { return (sourceType.isAssignableTo(targetType) ? NO_OP_CONVERTER : null); } // internal helpers private GenericConverter.ConvertiblePair getRequiredTypeInfo(Object converter, Class genericIfc) { Class[] args = GenericTypeResolver.resolveTypeArguments(converter.getClass(), genericIfc); return (args != null ? new GenericConverter.ConvertiblePair(args[0], args[1]) : null); } private MatchableConverters getMatchableConverters(Class sourceType, Class targetType) { Map, MatchableConverters> sourceMap = getSourceConverterMap(sourceType); MatchableConverters matchable = sourceMap.get(targetType); if (matchable == null) { matchable = new MatchableConverters(); sourceMap.put(targetType, matchable); } return matchable; } private void invalidateCache() { this.converterCache.clear(); } private Map, MatchableConverters> getSourceConverterMap(Class sourceType) { Map, MatchableConverters> sourceMap = converters.get(sourceType); if (sourceMap == null) { sourceMap = new HashMap, MatchableConverters>(); this.converters.put(sourceType, sourceMap); } return sourceMap; } private void assertNotNull(TypeDescriptor sourceType, TypeDescriptor targetType) { Assert.notNull(sourceType, "The sourceType to convert to is required"); Assert.notNull(targetType, "The targetType to convert to is required"); } private GenericConverter findConverterForClassPair(TypeDescriptor sourceType, TypeDescriptor targetType) { Class sourceObjectType = sourceType.getObjectType(); if (sourceObjectType.isInterface()) { LinkedList> classQueue = new LinkedList>(); classQueue.addFirst(sourceObjectType); while (!classQueue.isEmpty()) { Class currentClass = classQueue.removeLast(); Map, MatchableConverters> converters = getTargetConvertersForSource(currentClass); GenericConverter converter = getMatchingConverterForTarget(sourceType, targetType, converters); if (converter != null) { return converter; } Class[] interfaces = currentClass.getInterfaces(); for (Class ifc : interfaces) { classQueue.addFirst(ifc); } } Map, MatchableConverters> objectConverters = getTargetConvertersForSource(Object.class); return getMatchingConverterForTarget(sourceType, targetType, objectConverters); } else { LinkedList> classQueue = new LinkedList>(); classQueue.addFirst(sourceObjectType); while (!classQueue.isEmpty()) { Class currentClass = classQueue.removeLast(); Map, MatchableConverters> converters = getTargetConvertersForSource(currentClass); GenericConverter converter = getMatchingConverterForTarget(sourceType, targetType, converters); if (converter != null) { return converter; } if (currentClass.isArray()) { Class componentType = ClassUtils.resolvePrimitiveIfNecessary(currentClass.getComponentType()); if (componentType.getSuperclass() != null) { classQueue.addFirst(Array.newInstance(componentType.getSuperclass(), 0).getClass()); } else if (componentType.isInterface()) { classQueue.addFirst(Object[].class); } } else { Class[] interfaces = currentClass.getInterfaces(); for (Class ifc : interfaces) { addInterfaceHierarchy(ifc, classQueue); } if (currentClass.getSuperclass() != null) { classQueue.addFirst(currentClass.getSuperclass()); } } } return null; } } private Map, MatchableConverters> getTargetConvertersForSource(Class sourceType) { Map, MatchableConverters> converters = this.converters.get(sourceType); if (converters == null) { converters = Collections.emptyMap(); } return converters; } private GenericConverter getMatchingConverterForTarget(TypeDescriptor sourceType, TypeDescriptor targetType, Map, MatchableConverters> converters) { Class targetObjectType = targetType.getObjectType(); if (targetObjectType.isInterface()) { LinkedList> classQueue = new LinkedList>(); classQueue.addFirst(targetObjectType); while (!classQueue.isEmpty()) { Class currentClass = classQueue.removeLast(); MatchableConverters matchable = converters.get(currentClass); GenericConverter converter = matchConverter(matchable, sourceType, targetType); if (converter != null) { return converter; } Class[] interfaces = currentClass.getInterfaces(); for (Class ifc : interfaces) { classQueue.addFirst(ifc); } } return matchConverter(converters.get(Object.class), sourceType, targetType); } else { LinkedList> classQueue = new LinkedList>(); classQueue.addFirst(targetObjectType); while (!classQueue.isEmpty()) { Class currentClass = classQueue.removeLast(); MatchableConverters matchable = converters.get(currentClass); GenericConverter converter = matchConverter(matchable, sourceType, targetType); if (converter != null) { return converter; } if (currentClass.isArray()) { Class componentType = ClassUtils.resolvePrimitiveIfNecessary(currentClass.getComponentType()); if (componentType.getSuperclass() != null) { classQueue.addFirst(Array.newInstance(componentType.getSuperclass(), 0).getClass()); } else if (componentType.isInterface()) { classQueue.addFirst(Object[].class); } } else { Class[] interfaces = currentClass.getInterfaces(); for (Class ifc : interfaces) { addInterfaceHierarchy(ifc, classQueue); } if (currentClass.getSuperclass() != null) { classQueue.addFirst(currentClass.getSuperclass()); } } } return null; } } private void addInterfaceHierarchy(Class ifc, LinkedList> classQueue) { classQueue.addFirst(ifc); for (Class inheritedIfc : ifc.getInterfaces()) { addInterfaceHierarchy(inheritedIfc, classQueue); } } private GenericConverter matchConverter( MatchableConverters matchable, TypeDescriptor sourceFieldType, TypeDescriptor targetFieldType) { if (matchable == null) { return null; } return matchable.matchConverter(sourceFieldType, targetFieldType); } @SuppressWarnings("unchecked") private final class ConverterAdapter implements GenericConverter { private final ConvertiblePair typeInfo; private final Converter converter; public ConverterAdapter(ConvertiblePair typeInfo, Converter converter) { this.converter = converter; this.typeInfo = typeInfo; } public Set getConvertibleTypes() { return Collections.singleton(this.typeInfo); } public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { if (source == null) { return convertNullSource(sourceType, targetType); } return this.converter.convert(source); } public String toString() { return this.typeInfo.getSourceType().getName() + " -> " + this.typeInfo.getTargetType().getName() + " : " + this.converter.toString(); } } @SuppressWarnings("unchecked") private final class ConverterFactoryAdapter implements GenericConverter { private final ConvertiblePair typeInfo; private final ConverterFactory converterFactory; public ConverterFactoryAdapter(ConvertiblePair typeInfo, ConverterFactory converterFactory) { this.converterFactory = converterFactory; this.typeInfo = typeInfo; } public Set getConvertibleTypes() { return Collections.singleton(this.typeInfo); } public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { if (source == null) { return convertNullSource(sourceType, targetType); } return this.converterFactory.getConverter(targetType.getObjectType()).convert(source); } public String toString() { return this.typeInfo.getSourceType().getName() + " -> " + this.typeInfo.getTargetType().getName() + " : " + this.converterFactory.toString(); } } private static class MatchableConverters { private LinkedList conditionalConverters; private GenericConverter defaultConverter; public void add(GenericConverter converter) { if (converter instanceof ConditionalGenericConverter) { if (this.conditionalConverters == null) { this.conditionalConverters = new LinkedList(); } this.conditionalConverters.addFirst((ConditionalGenericConverter) converter); } else { this.defaultConverter = converter; } } public GenericConverter matchConverter(TypeDescriptor sourceType, TypeDescriptor targetType) { if (this.conditionalConverters != null) { for (ConditionalGenericConverter conditional : this.conditionalConverters) { if (conditional.matches(sourceType, targetType)) { return conditional; } } } return this.defaultConverter; } public String toString() { if (this.conditionalConverters != null) { StringBuilder builder = new StringBuilder(); for (Iterator it = this.conditionalConverters.iterator(); it.hasNext();) { builder.append(it.next()); if (it.hasNext()) { builder.append(", "); } } if (this.defaultConverter != null) { builder.append(", ").append(this.defaultConverter); } return builder.toString(); } else { return this.defaultConverter.toString(); } } } private static final class ConverterCacheKey { private final TypeDescriptor sourceType; private final TypeDescriptor targetType; public ConverterCacheKey(TypeDescriptor sourceType, TypeDescriptor targetType) { this.sourceType = sourceType; this.targetType = targetType; } public boolean equals(Object other) { if (this == other) { return true; } if (!(other instanceof ConverterCacheKey)) { return false; } ConverterCacheKey otherKey = (ConverterCacheKey) other; return this.sourceType.equals(otherKey.sourceType) && this.targetType.equals(otherKey.targetType); } public int hashCode() { return this.sourceType.hashCode() * 29 + this.targetType.hashCode(); } public String toString() { return "ConverterCacheKey [sourceType = " + this.sourceType + ", targetType = " + this.targetType + "]"; } } } ././@LongLink0000000000000000000000000000022200000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/support/ArrayToStringConverter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000377011623223530033346 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.convert.support; import java.util.Arrays; import java.util.Collections; import java.util.Set; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.converter.ConditionalGenericConverter; import org.springframework.util.ObjectUtils; /** * Converts an Array to a comma-delimited String. * This implementation first adapts the source Array to a List, then delegates to {@link CollectionToStringConverter} to perform the target String conversion. * * @author Keith Donald * @since 3.0 */ final class ArrayToStringConverter implements ConditionalGenericConverter { private final CollectionToStringConverter helperConverter; public ArrayToStringConverter(ConversionService conversionService) { this.helperConverter = new CollectionToStringConverter(conversionService); } public Set getConvertibleTypes() { return Collections.singleton(new ConvertiblePair(Object[].class, String.class)); } public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { return this.helperConverter.matches(sourceType, targetType); } public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { return this.helperConverter.convert(Arrays.asList(ObjectUtils.toObjectArray(source)), sourceType, targetType); } } ././@LongLink0000000000000000000000000000023000000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/support/StringToEnumConverterFactory.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000310511623223530033336 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.convert.support; import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.converter.ConverterFactory; /** * Converts from a String to a java.lang.Enum by calling {@link Enum#valueOf(Class, String)}. * * @author Keith Donald * @since 3.0 */ @SuppressWarnings("unchecked") final class StringToEnumConverterFactory implements ConverterFactory { public Converter getConverter(Class targetType) { return new StringToEnum(targetType); } private class StringToEnum implements Converter { private final Class enumType; public StringToEnum(Class enumType) { this.enumType = enumType; } public T convert(String source) { if (source.length() == 0) { // It's an empty enum identifier: reset the enum value to null. return null; } return (T) Enum.valueOf(this.enumType, source.trim()); } } } ././@LongLink0000000000000000000000000000022200000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/support/PropertyTypeDescriptor.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000001110311623223530033333 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.convert.support; import java.beans.PropertyDescriptor; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.LinkedHashMap; import java.util.Map; import org.springframework.core.MethodParameter; import org.springframework.core.convert.TypeDescriptor; import org.springframework.util.ReflectionUtils; import org.springframework.util.StringUtils; /** * {@link TypeDescriptor} extension that exposes additional annotations * as conversion metadata: namely, annotations on other accessor methods * (getter/setter) and on the underlying field, if found. * * @author Juergen Hoeller * @since 3.0.2 */ public class PropertyTypeDescriptor extends TypeDescriptor { private final PropertyDescriptor propertyDescriptor; private Annotation[] cachedAnnotations; /** * Create a new BeanTypeDescriptor for the given bean property. * @param propertyDescriptor the corresponding JavaBean PropertyDescriptor * @param methodParameter the target method parameter */ public PropertyTypeDescriptor(PropertyDescriptor propertyDescriptor, MethodParameter methodParameter) { super(methodParameter); this.propertyDescriptor = propertyDescriptor; } /** * Create a new BeanTypeDescriptor for the given bean property. * @param propertyDescriptor the corresponding JavaBean PropertyDescriptor * @param methodParameter the target method parameter * @param type the specific type to expose (may be an array/collection element) */ public PropertyTypeDescriptor(PropertyDescriptor propertyDescriptor, MethodParameter methodParameter, Class type) { super(methodParameter, type); this.propertyDescriptor = propertyDescriptor; } /** * Return the underlying PropertyDescriptor. */ public PropertyDescriptor getPropertyDescriptor() { return this.propertyDescriptor; } public Annotation[] getAnnotations() { Annotation[] anns = this.cachedAnnotations; if (anns == null) { Map, Annotation> annMap = new LinkedHashMap, Annotation>(); String name = this.propertyDescriptor.getName(); if (StringUtils.hasLength(name)) { Class clazz = getMethodParameter().getMethod().getDeclaringClass(); Field field = ReflectionUtils.findField(clazz, name); if (field == null) { // Same lenient fallback checking as in CachedIntrospectionResults... field = ReflectionUtils.findField(clazz, name.substring(0, 1).toLowerCase() + name.substring(1)); if (field == null) { field = ReflectionUtils.findField(clazz, name.substring(0, 1).toUpperCase() + name.substring(1)); } } if (field != null) { for (Annotation ann : field.getAnnotations()) { annMap.put(ann.annotationType(), ann); } } } Method writeMethod = this.propertyDescriptor.getWriteMethod(); Method readMethod = this.propertyDescriptor.getReadMethod(); if (writeMethod != null && writeMethod != getMethodParameter().getMethod()) { for (Annotation ann : writeMethod.getAnnotations()) { annMap.put(ann.annotationType(), ann); } } if (readMethod != null && readMethod != getMethodParameter().getMethod()) { for (Annotation ann : readMethod.getAnnotations()) { annMap.put(ann.annotationType(), ann); } } for (Annotation ann : getMethodParameter().getMethodAnnotations()) { annMap.put(ann.annotationType(), ann); } for (Annotation ann : getMethodParameter().getParameterAnnotations()) { annMap.put(ann.annotationType(), ann); } anns = annMap.values().toArray(new Annotation[annMap.size()]); this.cachedAnnotations = anns; } return anns; } public TypeDescriptor forElementType(Class elementType) { if (elementType != null) { return new PropertyTypeDescriptor(this.propertyDescriptor, getMethodParameter(), elementType); } else { return super.forElementType(null); } } } ././@LongLink0000000000000000000000000000022700000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/support/StringToPropertiesConverter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000273311623223530033344 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.convert.support; import java.io.ByteArrayInputStream; import java.util.Properties; import org.springframework.core.convert.converter.Converter; /** * Converts a String to a Properties by calling Properties#load(java.io.InputStream). * Uses ISO-8559-1 encoding required by Properties. * * @author Keith Donald * @since 3.0 */ final class StringToPropertiesConverter implements Converter { public Properties convert(String source) { try { Properties props = new Properties(); // Must use the ISO-8859-1 encoding because Properties.load(stream) expects it. props.load(new ByteArrayInputStream(source.getBytes("ISO-8859-1"))); return props; } catch (Exception ex) { // Should never happen. throw new IllegalArgumentException("Failed to parse [" + source + "] into Properties", ex); } } } ././@LongLink0000000000000000000000000000021700000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/support/IdToEntityConverter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000620411623223526033346 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.convert.support; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Collections; import java.util.Set; import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.converter.ConditionalGenericConverter; import org.springframework.util.ClassUtils; import org.springframework.util.ReflectionUtils; /** * Converts an entity identifier to a entity reference by calling a static finder method * on the target entity type. * *

For this converter to match, the finder method must be public, static, have the signature * find[EntityName]([IdType]), and return an instance of the desired entity type. * * @author Keith Donald * @since 3.0 */ final class IdToEntityConverter implements ConditionalGenericConverter { private final GenericConversionService conversionService; public IdToEntityConverter(GenericConversionService conversionService) { this.conversionService = conversionService; } public Set getConvertibleTypes() { return Collections.singleton(new ConvertiblePair(Object.class, Object.class)); } public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { Method finder = getFinder(targetType.getType()); return (finder != null && this.conversionService.canConvert(sourceType, TypeDescriptor.valueOf(finder.getParameterTypes()[0]))); } public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { if (source == null) { return this.conversionService.convertNullSource(sourceType, targetType); } Method finder = getFinder(targetType.getType()); Object id = this.conversionService.convert( source, sourceType, TypeDescriptor.valueOf(finder.getParameterTypes()[0])); return ReflectionUtils.invokeMethod(finder, source, id); } private Method getFinder(Class entityClass) { String finderMethod = "find" + getEntityName(entityClass); Method[] methods = entityClass.getDeclaredMethods(); for (Method method : methods) { if (Modifier.isStatic(method.getModifiers()) && method.getParameterTypes().length == 1 && method.getReturnType().equals(entityClass)) { if (method.getName().equals(finderMethod)) { return method; } } } return null; } private String getEntityName(Class entityClass) { String shortName = ClassUtils.getShortName(entityClass); int lastDot = shortName.lastIndexOf('.'); if (lastDot != -1) { return shortName.substring(lastDot + 1); } else { return shortName; } } } ././@LongLink0000000000000000000000000000022300000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/support/StringToLocaleConverter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000204311623223530033336 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.convert.support; import java.util.Locale; import org.springframework.core.convert.converter.Converter; import org.springframework.util.StringUtils; /** * Converts a String to a Locale. * * @author Keith Donald * @since 3.0 */ final class StringToLocaleConverter implements Converter { public Locale convert(String source) { return StringUtils.parseLocaleString(source); } } ././@LongLink0000000000000000000000000000022700000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/support/CollectionToStringConverter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000441711623223530033345 0ustar drazzibdrazzib/* * Copyright 2002-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.convert.support; import java.util.Collection; import java.util.Collections; import java.util.Set; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.converter.ConditionalGenericConverter; /** * Converts a Collection to a comma-delimited String. * * @author Keith Donald * @since 3.0 */ final class CollectionToStringConverter implements ConditionalGenericConverter { private static final String DELIMITER = ","; private final ConversionService conversionService; public CollectionToStringConverter(ConversionService conversionService) { this.conversionService = conversionService; } public Set getConvertibleTypes() { return Collections.singleton(new ConvertiblePair(Collection.class, String.class)); } public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { return ConversionUtils.canConvertElements(sourceType.getElementTypeDescriptor(), targetType, this.conversionService); } public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { if (source == null) { return null; } Collection sourceCollection = (Collection) source; if (sourceCollection.size() == 0) { return ""; } StringBuilder sb = new StringBuilder(); int i = 0; for (Object sourceElement : sourceCollection) { if (i > 0) { sb.append(DELIMITER); } Object targetElement = this.conversionService.convert(sourceElement, sourceType.getElementTypeDescriptor(sourceElement), targetType); sb.append(targetElement); i++; } return sb.toString(); } } ././@LongLink0000000000000000000000000000017100000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/converter/libspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000755000175000017500000000000011623223530033335 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000021200000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/converter/package-info.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000020311623223526033337 0ustar drazzibdrazzib /** * * SPI to implement Converters for the type conversion system. * */ package org.springframework.core.convert.converter; ././@LongLink0000000000000000000000000000020700000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/converter/Converter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000232411623223530033340 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.convert.converter; /** * A converter converts a source object of type S to a target of type T. * Implementations of this interface are thread-safe and can be shared. * * @author Keith Donald * @since 3.0 */ public interface Converter { /** * Convert the source of type S to target type T. * @param source the source object to convert, which must be an instance of S * @return the converted object, which must be an instance of T * @throws IllegalArgumentException if the source could not be converted to the desired target type */ T convert(S source); } ././@LongLink0000000000000000000000000000021600000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/converter/ConverterFactory.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000255011623223530033341 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.convert.converter; /** * A factory for "ranged" converters that can convert objects from S to subtypes of R. * * @author Keith Donald * @since 3.0 * @param The source type converters created by this factory can convert from * @param The target range (or base) type converters created by this factory can convert to; * for example {@link Number} for a set of number subtypes. */ public interface ConverterFactory { /** * Get the converter to convert from S to target type T, where T is also an instance of R. * @param the target type * @param targetType the target type to convert to * @return A converter from S to T */ Converter getConverter(Class targetType); } ././@LongLink0000000000000000000000000000021700000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/converter/ConverterRegistry.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000257311623223530033346 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.convert.converter; /** * For registering converters with a type conversion system. * * @author Keith Donald * @author Juergen Hoeller * @since 3.0 */ public interface ConverterRegistry { /** * Add a plain converter to this registry. */ void addConverter(Converter converter); /** * Add a generic converter to this registry. */ void addConverter(GenericConverter converter); /** * Add a ranged converter factory to this registry. */ void addConverterFactory(ConverterFactory converterFactory); /** * Remove any converters from sourceType to targetType. * @param sourceType the source type * @param targetType the target type */ void removeConvertible(Class sourceType, Class targetType); } ././@LongLink0000000000000000000000000000021600000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/converter/GenericConverter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000704311623223530033343 0ustar drazzibdrazzib/* * Copyright 2002-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.convert.converter; import org.springframework.core.convert.TypeDescriptor; import org.springframework.util.Assert; import java.util.Set; /** * Generic converter interface for converting between two or more types. * *

This is the most flexible of the Converter SPI interfaces, but also the most complex. * It is flexible in that a GenericConverter may support converting between multiple source/target * type pairs (see {@link #getConvertibleTypes()}. In addition, GenericConverter implementations * have access to source/target {@link TypeDescriptor field context} during the type conversion process. * This allows for resolving source and target field metadata such as annotations and generics * information, which can be used influence the conversion logic. * *

This interface should generally not be used when the simpler {@link Converter} or * {@link ConverterFactory} interfaces are sufficient. * * @author Keith Donald * @author Juergen Hoeller * @since 3.0 * @see TypeDescriptor * @see Converter * @see ConverterFactory */ public interface GenericConverter { /** * Return the source and target types which this converter can convert between. *

Each entry is a convertible source-to-target type pair. */ Set getConvertibleTypes(); /** * Convert the source to the targetType described by the TypeDescriptor. * @param source the source object to convert (may be null) * @param sourceType the type descriptor of the field we are converting from * @param targetType the type descriptor of the field we are converting to * @return the converted object */ Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType); /** * Holder for a source-to-target class pair. */ public static final class ConvertiblePair { private final Class sourceType; private final Class targetType; /** * Create a new source-to-target pair. * @param sourceType the source type * @param targetType the target type */ public ConvertiblePair(Class sourceType, Class targetType) { Assert.notNull(sourceType, "Source type must not be null"); Assert.notNull(targetType, "Target type must not be null"); this.sourceType = sourceType; this.targetType = targetType; } public Class getSourceType() { return this.sourceType; } public Class getTargetType() { return this.targetType; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null || obj.getClass() != ConvertiblePair.class) { return false; } ConvertiblePair other = (ConvertiblePair) obj; return this.sourceType.equals(other.sourceType) && this.targetType.equals(other.targetType); } @Override public int hashCode() { return this.sourceType.hashCode() * 31 + this.targetType.hashCode(); } } } ././@LongLink0000000000000000000000000000023100000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/converter/ConditionalGenericConverter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000421011623223530033334 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.convert.converter; import org.springframework.core.convert.TypeDescriptor; /** * A generic converter that conditionally executes. * *

Applies a rule that determines if a converter between a set of * {@link #getConvertibleTypes() convertible types} matches given a client request to * convert between a source field of convertible type S and a target field of convertible type T. * *

Often used to selectively match custom conversion logic based on the presence of * a field or class-level characteristic, such as an annotation or method. For example, * when converting from a String field to a Date field, an implementation might return * true if the target field has also been annotated with @DateTimeFormat. * *

As another example, when converting from a String field to an Account field, * an implementation might return true if the target Account class defines a * public static findAccount(String) method. * * @author Keith Donald * @since 3.0 */ public interface ConditionalGenericConverter extends GenericConverter { /** * Should the converter from sourceType to targetType * currently under consideration be selected? * @param sourceType the type descriptor of the field we are converting from * @param targetType the type descriptor of the field we are converting to * @return true if conversion should be performed, false otherwise */ boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType); } ././@LongLink0000000000000000000000000000020500000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/ConversionService.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000606211623223526033350 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.convert; /** * A service interface for type conversion. This is the entry point into the convert system. * Call {@link #convert(Object, Class)} to perform a thread-safe type conversion using this system. * * @author Keith Donald * @since 3.0 */ public interface ConversionService { /** * Returns true if objects of sourceType can be converted to targetType. * @param sourceType the source type to convert from (required) * @param targetType the target type to convert to (required) * @return true if a conversion can be performed, false if not */ boolean canConvert(Class sourceType, Class targetType); /** * Convert the source to targetType. * @param source the source object to convert (may be null) * @param targetType the target type to convert to (required) * @return the converted object, an instance of targetType * @throws ConversionException if an exception occurred */ T convert(Object source, Class targetType); /** * Returns true if objects of sourceType can be converted to the targetType. * The TypeDescriptors provide additional context about the field locations where conversion would occur, often object property locations. * This flavor of the canConvert operation exists mainly for use by a general purpose data mapping framework, and not for use by user code. * @param sourceType context about the source type to convert from (required) * @param targetType context about the target type to convert to (required) * @return true if a conversion can be performed between the source and target types, false if not */ boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType); /** * Convert the source to targetType. * The TypeDescriptors provide additional context about the field locations where conversion will occur, often object property locations. * This flavor of the convert operation exists mainly for use by a general purpose data mapping framework, and not for use by user code. * @param source the source object to convert (may be null) * @param sourceType context about the source type converting from (required) * @param targetType context about the target type to convert to (required) * @return the converted object, an instance of {@link TypeDescriptor#getObjectType() targetType} * @throws ConversionException if an exception occurred */ Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType); } ././@LongLink0000000000000000000000000000020200000000000011557 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/convert/TypeDescriptor.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000004475711623223530033360 0ustar drazzibdrazzib/* * Copyright 2002-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.convert; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.util.Collection; import java.util.HashMap; import java.util.Map; import org.springframework.core.GenericCollectionTypeResolver; import org.springframework.core.MethodParameter; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; /** * Context about a type to convert to. * * @author Keith Donald * @author Andy Clement * @author Juergen Hoeller * @since 3.0 */ public class TypeDescriptor { /** Constant defining a TypeDescriptor for a null value */ public static final TypeDescriptor NULL = new TypeDescriptor(); /** Constant defining a TypeDescriptor for 'unknown type' */ private static final TypeDescriptor UNKNOWN = new TypeDescriptor(Object.class); private static final Map, TypeDescriptor> typeDescriptorCache = new HashMap, TypeDescriptor>(); private static final Annotation[] EMPTY_ANNOTATION_ARRAY = new Annotation[0]; static { typeDescriptorCache.put(boolean.class, new TypeDescriptor(boolean.class)); typeDescriptorCache.put(Boolean.class, new TypeDescriptor(Boolean.class)); typeDescriptorCache.put(byte.class, new TypeDescriptor(byte.class)); typeDescriptorCache.put(Byte.class, new TypeDescriptor(Byte.class)); typeDescriptorCache.put(char.class, new TypeDescriptor(char.class)); typeDescriptorCache.put(Character.class, new TypeDescriptor(Character.class)); typeDescriptorCache.put(short.class, new TypeDescriptor(short.class)); typeDescriptorCache.put(Short.class, new TypeDescriptor(Short.class)); typeDescriptorCache.put(int.class, new TypeDescriptor(int.class)); typeDescriptorCache.put(Integer.class, new TypeDescriptor(Integer.class)); typeDescriptorCache.put(long.class, new TypeDescriptor(long.class)); typeDescriptorCache.put(Long.class, new TypeDescriptor(Long.class)); typeDescriptorCache.put(float.class, new TypeDescriptor(float.class)); typeDescriptorCache.put(Float.class, new TypeDescriptor(Float.class)); typeDescriptorCache.put(double.class, new TypeDescriptor(double.class)); typeDescriptorCache.put(Double.class, new TypeDescriptor(Double.class)); typeDescriptorCache.put(String.class, new TypeDescriptor(String.class)); } private Class type; private MethodParameter methodParameter; private Field field; private int fieldNestingLevel = 1; private Object value; private volatile TypeDescriptor elementType; private volatile TypeDescriptor mapKeyType; private volatile TypeDescriptor mapValueType; private volatile Annotation[] annotations; /** * Create a new type descriptor from a method or constructor parameter. *

Use this constructor when a target conversion point originates from a method parameter, * such as a setter method argument. * @param methodParameter the MethodParameter to wrap */ public TypeDescriptor(MethodParameter methodParameter) { Assert.notNull(methodParameter, "MethodParameter must not be null"); this.methodParameter = methodParameter; } /** * Create a new type descriptor for a field. * Use this constructor when a target conversion point originates from a field. * @param field the field to wrap */ public TypeDescriptor(Field field) { Assert.notNull(field, "Field must not be null"); this.field = field; } /** * Create a new type descriptor from a method or constructor parameter. *

Use this constructor when a target conversion point originates from a method parameter, * such as a setter method argument. * @param methodParameter the MethodParameter to wrap * @param type the specific type to expose (may be an array/collection element) */ public TypeDescriptor(MethodParameter methodParameter, Class type) { Assert.notNull(methodParameter, "MethodParameter must not be null"); this.methodParameter = methodParameter; this.type = type; } /** * Create a new type descriptor for a field. * Use this constructor when a target conversion point originates from a field. * @param field the field to wrap * @param type the specific type to expose (may be an array/collection element) */ public TypeDescriptor(Field field, Class type) { Assert.notNull(field, "Field must not be null"); this.field = field; this.type = type; } /** * Create a new type descriptor for a field. * Use this constructor when a target conversion point originates from a field. * @param field the field to wrap * @param type the specific type to expose (may be an array/collection element) */ private TypeDescriptor(Field field, int nestingLevel, Class type) { Assert.notNull(field, "Field must not be null"); this.field = field; this.fieldNestingLevel = nestingLevel; this.type = type; } /** * Internal constructor for a NULL descriptor. */ private TypeDescriptor() { } /** * Create a new descriptor for the type of the given value. *

Use this constructor when a conversion point comes from a source such as a Map or * Collection, where no additional context is available but elements can be introspected. * @param value the value to determine the actual type from */ private TypeDescriptor(Object value) { Assert.notNull(value, "Value must not be null"); this.value = value; this.type = value.getClass(); } /** * Create a new descriptor for the given type. *

Use this constructor when a conversion point comes from a plain source type, * where no additional context is available. * @param type the actual type to wrap */ private TypeDescriptor(Class type) { Assert.notNull(type, "Type must not be null"); this.type = type; } /** * Return the wrapped MethodParameter, if any. *

Note: Either MethodParameter or Field is available. * @return the MethodParameter, or null if none */ public MethodParameter getMethodParameter() { return this.methodParameter; } /** * Return the wrapped Field, if any. *

Note: Either MethodParameter or Field is available. * @return the Field, or null if none */ public Field getField() { return this.field; } /** * Determine the declared (non-generic) type of the wrapped parameter/field. * @return the declared type, or null if this is {@link TypeDescriptor#NULL} */ public Class getType() { if (this.type != null) { return this.type; } else if (this.field != null) { return this.field.getType(); } else if (this.methodParameter != null) { return this.methodParameter.getParameterType(); } else { return null; } } /** * Determine the declared type of the wrapped parameter/field. * Returns the Object wrapper type if the underlying type is a primitive. */ public Class getObjectType() { Class type = getType(); return (type != null ? ClassUtils.resolvePrimitiveIfNecessary(type) : type); } /** * Returns the name of this type: the fully qualified class name. */ public String getName() { Class type = getType(); return (type != null ? ClassUtils.getQualifiedName(type) : null); } /** * Is this type a primitive type? */ public boolean isPrimitive() { Class type = getType(); return (type != null && type.isPrimitive()); } /** * Is this type an array type? */ public boolean isArray() { Class type = getType(); return (type != null && type.isArray()); } /** * Is this type a {@link Collection} type? */ public boolean isCollection() { return Collection.class.isAssignableFrom(getType()); } /** * If this type is an array type or {@link Collection} type, returns the underlying element type. * Returns null if the type is neither an array or collection. */ public Class getElementType() { return getElementTypeDescriptor().getType(); } /** * Return the element type as a type descriptor. */ public TypeDescriptor getElementTypeDescriptor() { if (this.elementType == null) { this.elementType = forElementType(resolveElementType()); } return this.elementType; } /** * Return the element type as a type descriptor. If the element type is null * (cannot be determined), the type descriptor is derived from the element argument. * @param element the element * @return the element type descriptor */ public TypeDescriptor getElementTypeDescriptor(Object element) { TypeDescriptor elementType = getElementTypeDescriptor(); return (elementType != TypeDescriptor.UNKNOWN ? elementType : forObject(element)); } /** * Is this type a {@link Map} type? */ public boolean isMap() { return Map.class.isAssignableFrom(getType()); } /** * Is this descriptor for a map where the key type and value type are known? */ public boolean isMapEntryTypeKnown() { return (isMap() && getMapKeyType() != null && getMapValueType() != null); } /** * Determine the generic key type of the wrapped Map parameter/field, if any. * @return the generic type, or null if none */ public Class getMapKeyType() { return getMapKeyTypeDescriptor().getType(); } /** * Returns map key type as a type descriptor. */ public TypeDescriptor getMapKeyTypeDescriptor() { if (this.mapKeyType == null) { this.mapKeyType = forElementType(resolveMapKeyType()); } return this.mapKeyType; } /** * Return the map key type as a type descriptor. If the key type is null * (cannot be determined), the type descriptor is derived from the key argument. * @param key the key * @return the map key type descriptor */ public TypeDescriptor getMapKeyTypeDescriptor(Object key) { TypeDescriptor keyType = getMapKeyTypeDescriptor(); return (keyType != TypeDescriptor.UNKNOWN ? keyType : TypeDescriptor.forObject(key)); } /** * Determine the generic value type of the wrapped Map parameter/field, if any. * @return the generic type, or null if none */ public Class getMapValueType() { return getMapValueTypeDescriptor().getType(); } /** * Returns map value type as a type descriptor. */ public TypeDescriptor getMapValueTypeDescriptor() { if (this.mapValueType == null) { this.mapValueType = forElementType(resolveMapValueType()); } return this.mapValueType; } /** * Return the map value type as a type descriptor. If the value type is null * (cannot be determined), the type descriptor is derived from the value argument. * @param value the value * @return the map value type descriptor */ public TypeDescriptor getMapValueTypeDescriptor(Object value) { TypeDescriptor valueType = getMapValueTypeDescriptor(); return (valueType != TypeDescriptor.UNKNOWN ? valueType : TypeDescriptor.forObject(value)); } /** * Obtain the annotations associated with the wrapped parameter/field, if any. */ public Annotation[] getAnnotations() { if (this.annotations == null) { this.annotations = resolveAnnotations(); } return this.annotations; } /** * Obtain the annotation associated with the wrapped parameter/field, if any. */ public Annotation getAnnotation(Class annotationType) { for (Annotation annotation : getAnnotations()) { if (annotation.annotationType().equals(annotationType)) { return annotation; } } return null; } /** * Returns true if an object of this type can be assigned to a reference of given targetType. * @param targetType the target type * @return true if this type is assignable to the target */ public boolean isAssignableTo(TypeDescriptor targetType) { if (this == TypeDescriptor.NULL || targetType == TypeDescriptor.NULL) { return true; } if (isCollection() && targetType.isCollection() || isArray() && targetType.isArray()) { return targetType.getType().isAssignableFrom(getType()) && getElementTypeDescriptor().isAssignableTo(targetType.getElementTypeDescriptor()); } else if (isMap() && targetType.isMap()) { return targetType.getType().isAssignableFrom(getType()) && getMapKeyTypeDescriptor().isAssignableTo(targetType.getMapKeyTypeDescriptor()) && getMapValueTypeDescriptor().isAssignableTo(targetType.getMapValueTypeDescriptor()); } else { return targetType.getObjectType().isAssignableFrom(getObjectType()); } } /** * Create a copy of this type descriptor, preserving the context information * but exposing the specified element type (e.g. an array/collection/map element). * @param elementType the desired type to expose * @return the type descriptor */ public TypeDescriptor forElementType(Class elementType) { if (elementType == null) { return TypeDescriptor.UNKNOWN; } else if (this.methodParameter != null) { MethodParameter nested = new MethodParameter(this.methodParameter); nested.increaseNestingLevel(); return new TypeDescriptor(nested, elementType); } else if (this.field != null) { return new TypeDescriptor(this.field, this.fieldNestingLevel + 1, elementType); } else { return TypeDescriptor.valueOf(elementType); } } public boolean equals(Object obj) { if (this == obj) { return true; } if (!(obj instanceof TypeDescriptor) || obj == TypeDescriptor.NULL) { return false; } TypeDescriptor other = (TypeDescriptor) obj; boolean annotatedTypeEquals = getType().equals(other.getType()) && ObjectUtils.nullSafeEquals(getAnnotations(), other.getAnnotations()); if (isCollection()) { return annotatedTypeEquals && ObjectUtils.nullSafeEquals(getElementType(), other.getElementType()); } else if (isMap()) { return annotatedTypeEquals && ObjectUtils.nullSafeEquals(getMapKeyType(), other.getMapKeyType()) && ObjectUtils.nullSafeEquals(getMapValueType(), other.getMapValueType()); } else { return annotatedTypeEquals; } } public int hashCode() { return (this == TypeDescriptor.NULL ? 0 : getType().hashCode()); } /** * A textual representation of the type descriptor (eg. Map) for use in messages. */ public String asString() { return toString(); } public String toString() { if (this == TypeDescriptor.NULL) { return "null"; } else { StringBuilder builder = new StringBuilder(); Annotation[] anns = getAnnotations(); for (Annotation ann : anns) { builder.append("@").append(ann.annotationType().getName()).append(' '); } builder.append(ClassUtils.getQualifiedName(getType())); if (isMap()) { builder.append("<").append(getMapKeyTypeDescriptor()); builder.append(", ").append(getMapValueTypeDescriptor()).append(">"); } else if (isCollection()) { builder.append("<").append(getElementTypeDescriptor()).append(">"); } return builder.toString(); } } // internal helpers private Class resolveElementType() { if (isArray()) { return getType().getComponentType(); } else if (isCollection()) { return resolveCollectionElementType(); } else { return null; } } @SuppressWarnings("unchecked") private Class resolveCollectionElementType() { if (this.field != null) { return GenericCollectionTypeResolver.getCollectionFieldType(this.field, this.fieldNestingLevel); } else if (this.methodParameter != null) { return GenericCollectionTypeResolver.getCollectionParameterType(this.methodParameter); } else if (this.value instanceof Collection) { Class elementType = CollectionUtils.findCommonElementType((Collection) this.value); if (elementType != null) { return elementType; } } else if (this.type != null) { return GenericCollectionTypeResolver.getCollectionType((Class) this.type); } return null; } @SuppressWarnings("unchecked") private Class resolveMapKeyType() { if (this.field != null) { return GenericCollectionTypeResolver.getMapKeyFieldType(this.field); } else if (this.methodParameter != null) { return GenericCollectionTypeResolver.getMapKeyParameterType(this.methodParameter); } else if (this.value instanceof Map) { Class keyType = CollectionUtils.findCommonElementType(((Map) this.value).keySet()); if (keyType != null) { return keyType; } } else if (this.type != null && isMap()) { return GenericCollectionTypeResolver.getMapKeyType((Class) this.type); } return null; } @SuppressWarnings("unchecked") private Class resolveMapValueType() { if (this.field != null) { return GenericCollectionTypeResolver.getMapValueFieldType(this.field); } else if (this.methodParameter != null) { return GenericCollectionTypeResolver.getMapValueParameterType(this.methodParameter); } else if (this.value instanceof Map) { Class valueType = CollectionUtils.findCommonElementType(((Map) this.value).values()); if (valueType != null) { return valueType; } } else if (this.type != null && isMap()) { return GenericCollectionTypeResolver.getMapValueType((Class) this.type); } return null; } private Annotation[] resolveAnnotations() { if (this.field != null) { return this.field.getAnnotations(); } else if (this.methodParameter != null) { if (this.methodParameter.getParameterIndex() < 0) { return this.methodParameter.getMethodAnnotations(); } else { return this.methodParameter.getParameterAnnotations(); } } else { return EMPTY_ANNOTATION_ARRAY; } } // static factory methods /** * Create a new type descriptor for the class of the given object. * @param object the object * @return the type descriptor */ public static TypeDescriptor forObject(Object object) { if (object == null) { return NULL; } else if (object instanceof Collection || object instanceof Map) { return new TypeDescriptor(object); } else { return valueOf(object.getClass()); } } /** * Create a new type descriptor for the given class. * @param type the class * @return the type descriptor */ public static TypeDescriptor valueOf(Class type) { if (type == null) { return TypeDescriptor.NULL; } TypeDescriptor desc = typeDescriptorCache.get(type); return (desc != null ? desc : new TypeDescriptor(type)); } } ././@LongLink0000000000000000000000000000015500000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/style/libspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000755000175000017500000000000011623223530033335 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000017600000000000011571 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/style/package-info.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000021111623223530033331 0ustar drazzibdrazzib /** * * Support for styling values as Strings, with ToStringCreator as central class. * */ package org.springframework.core.style; ././@LongLink0000000000000000000000000000020000000000000011555 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/style/ToStringStyler.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000355011623223530033342 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.style; /** * A strategy interface for pretty-printing toString() methods. * Encapsulates the print algorithms; some other object such as a builder * should provide the workflow. * * @author Keith Donald * @since 1.2.2 */ public interface ToStringStyler { /** * Style a toString()'ed object before its fields are styled. * @param buffer the buffer to print to * @param obj the object to style */ void styleStart(StringBuilder buffer, Object obj); /** * Style a toString()'ed object after it's fields are styled. * @param buffer the buffer to print to * @param obj the object to style */ void styleEnd(StringBuilder buffer, Object obj); /** * Style a field value as a string. * @param buffer the buffer to print to * @param fieldName the he name of the field * @param value the field value */ void styleField(StringBuilder buffer, String fieldName, Object value); /** * Style the given value. * @param buffer the buffer to print to * @param value the field value */ void styleValue(StringBuilder buffer, Object value); /** * Style the field separator. * @param buffer buffer to print to */ void styleFieldSeparator(StringBuilder buffer); } ././@LongLink0000000000000000000000000000017500000000000011570 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/style/ValueStyler.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000177511623223530033351 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.style; /** * Strategy that encapsulates value String styling algorithms * according to Spring conventions. * * @author Keith Donald * @since 1.2.2 */ public interface ValueStyler { /** * Style the given value, returning a String representation. * @param value the Object value to style * @return the styled String */ String style(Object value); } ././@LongLink0000000000000000000000000000017500000000000011570 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/style/StylerUtils.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000310611623223526033344 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.style; /** * Simple utility class to allow for convenient access to value * styling logic, mainly to support descriptive logging messages. * *

For more sophisticated needs, use the {@link ValueStyler} abstraction * directly. This class simply uses a shared {@link DefaultValueStyler} * instance underneath. * * @author Keith Donald * @since 1.2.2 * @see ValueStyler * @see DefaultValueStyler */ public abstract class StylerUtils { /** * Default ValueStyler instance used by the style method. * Also available for the {@link ToStringCreator} class in this package. */ static final ValueStyler DEFAULT_VALUE_STYLER = new DefaultValueStyler(); /** * Style the specified value according to default conventions. * @param value the Object value to style * @return the styled String * @see DefaultValueStyler */ public static String style(Object value) { return DEFAULT_VALUE_STYLER.style(value); } } ././@LongLink0000000000000000000000000000020400000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/style/DefaultValueStyler.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000001007311623223526033345 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.style; import java.lang.reflect.Method; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.springframework.util.ClassUtils; import org.springframework.util.ObjectUtils; /** * Converts objects to String form, generally for debugging purposes, * using Spring's toString styling conventions. * *

Uses the reflective visitor pattern underneath the hood to nicely * encapsulate styling algorithms for each type of styled object. * * @author Keith Donald * @author Juergen Hoeller * @since 1.2.2 */ public class DefaultValueStyler implements ValueStyler { private static final String EMPTY = "[empty]"; private static final String NULL = "[null]"; private static final String COLLECTION = "collection"; private static final String SET = "set"; private static final String LIST = "list"; private static final String MAP = "map"; private static final String ARRAY = "array"; public String style(Object value) { if (value == null) { return NULL; } else if (value instanceof String) { return "\'" + value + "\'"; } else if (value instanceof Class) { return ClassUtils.getShortName((Class) value); } else if (value instanceof Method) { Method method = (Method) value; return method.getName() + "@" + ClassUtils.getShortName(method.getDeclaringClass()); } else if (value instanceof Map) { return style((Map) value); } else if (value instanceof Map.Entry) { return style((Map.Entry) value); } else if (value instanceof Collection) { return style((Collection) value); } else if (value.getClass().isArray()) { return styleArray(ObjectUtils.toObjectArray(value)); } else { return String.valueOf(value); } } private String style(Map value) { StringBuilder result = new StringBuilder(value.size() * 8 + 16); result.append(MAP + "["); for (Iterator it = value.entrySet().iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry) it.next(); result.append(style(entry)); if (it.hasNext()) { result.append(',').append(' '); } } if (value.isEmpty()) { result.append(EMPTY); } result.append("]"); return result.toString(); } private String style(Map.Entry value) { return style(value.getKey()) + " -> " + style(value.getValue()); } private String style(Collection value) { StringBuilder result = new StringBuilder(value.size() * 8 + 16); result.append(getCollectionTypeString(value)).append('['); for (Iterator i = value.iterator(); i.hasNext();) { result.append(style(i.next())); if (i.hasNext()) { result.append(',').append(' '); } } if (value.isEmpty()) { result.append(EMPTY); } result.append("]"); return result.toString(); } private String getCollectionTypeString(Collection value) { if (value instanceof List) { return LIST; } else if (value instanceof Set) { return SET; } else { return COLLECTION; } } private String styleArray(Object[] array) { StringBuilder result = new StringBuilder(array.length * 8 + 16); result.append(ARRAY + "<").append(ClassUtils.getShortName(array.getClass().getComponentType())).append(">["); for (int i = 0; i < array.length - 1; i++) { result.append(style(array[i])); result.append(',').append(' '); } if (array.length > 0) { result.append(style(array[array.length - 1])); } else { result.append(EMPTY); } result.append("]"); return result.toString(); } } ././@LongLink0000000000000000000000000000020700000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/style/DefaultToStringStyler.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000530011623223530033335 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.style; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.ObjectUtils; /** * Spring's default toString() styler. * *

This class is used by {@link ToStringCreator} to style toString() * output in a consistent manner according to Spring conventions. * * @author Keith Donald * @author Juergen Hoeller * @since 1.2.2 */ public class DefaultToStringStyler implements ToStringStyler { private final ValueStyler valueStyler; /** * Create a new DefaultToStringStyler. * @param valueStyler the ValueStyler to use */ public DefaultToStringStyler(ValueStyler valueStyler) { Assert.notNull(valueStyler, "ValueStyler must not be null"); this.valueStyler = valueStyler; } /** * Return the ValueStyler used by this ToStringStyler. */ protected final ValueStyler getValueStyler() { return this.valueStyler; } public void styleStart(StringBuilder buffer, Object obj) { if (!obj.getClass().isArray()) { buffer.append('[').append(ClassUtils.getShortName(obj.getClass())); styleIdentityHashCode(buffer, obj); } else { buffer.append('['); styleIdentityHashCode(buffer, obj); buffer.append(' '); styleValue(buffer, obj); } } private void styleIdentityHashCode(StringBuilder buffer, Object obj) { buffer.append('@'); buffer.append(ObjectUtils.getIdentityHexString(obj)); } public void styleEnd(StringBuilder buffer, Object o) { buffer.append(']'); } public void styleField(StringBuilder buffer, String fieldName, Object value) { styleFieldStart(buffer, fieldName); styleValue(buffer, value); styleFieldEnd(buffer, fieldName); } protected void styleFieldStart(StringBuilder buffer, String fieldName) { buffer.append(' ').append(fieldName).append(" = "); } protected void styleFieldEnd(StringBuilder buffer, String fieldName) { } public void styleValue(StringBuilder buffer, Object value) { buffer.append(this.valueStyler.style(value)); } public void styleFieldSeparator(StringBuilder buffer) { buffer.append(','); } } ././@LongLink0000000000000000000000000000020100000000000011556 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/style/ToStringCreator.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000001271711623223530033347 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.style; import org.springframework.util.Assert; /** * Utility class that builds pretty-printing toString() methods * with pluggable styling conventions. By default, ToStringCreator adheres * to Spring's toString() styling conventions. * * @author Keith Donald * @author Juergen Hoeller * @since 1.2.2 */ public class ToStringCreator { /** * Default ToStringStyler instance used by this ToStringCreator. */ private static final ToStringStyler DEFAULT_TO_STRING_STYLER = new DefaultToStringStyler(StylerUtils.DEFAULT_VALUE_STYLER); private StringBuilder buffer = new StringBuilder(512); private ToStringStyler styler; private Object object; private boolean styledFirstField; /** * Create a ToStringCreator for the given object. * @param obj the object to be stringified */ public ToStringCreator(Object obj) { this(obj, (ToStringStyler) null); } /** * Create a ToStringCreator for the given object, using the provided style. * @param obj the object to be stringified * @param styler the ValueStyler encapsulating pretty-print instructions */ public ToStringCreator(Object obj, ValueStyler styler) { this(obj, new DefaultToStringStyler(styler != null ? styler : StylerUtils.DEFAULT_VALUE_STYLER)); } /** * Create a ToStringCreator for the given object, using the provided style. * @param obj the object to be stringified * @param styler the ToStringStyler encapsulating pretty-print instructions */ public ToStringCreator(Object obj, ToStringStyler styler) { Assert.notNull(obj, "The object to be styled must not be null"); this.object = obj; this.styler = (styler != null ? styler : DEFAULT_TO_STRING_STYLER); this.styler.styleStart(this.buffer, this.object); } /** * Append a byte field value. * @param fieldName the name of the field, usually the member variable name * @param value the field value * @return this, to support call-chaining */ public ToStringCreator append(String fieldName, byte value) { return append(fieldName, new Byte(value)); } /** * Append a short field value. * @param fieldName the name of the field, usually the member variable name * @param value the field value * @return this, to support call-chaining */ public ToStringCreator append(String fieldName, short value) { return append(fieldName, new Short(value)); } /** * Append a integer field value. * @param fieldName the name of the field, usually the member variable name * @param value the field value * @return this, to support call-chaining */ public ToStringCreator append(String fieldName, int value) { return append(fieldName, new Integer(value)); } /** * Append a long field value. * @param fieldName the name of the field, usually the member variable name * @param value the field value * @return this, to support call-chaining */ public ToStringCreator append(String fieldName, long value) { return append(fieldName, new Long(value)); } /** * Append a float field value. * @param fieldName the name of the field, usually the member variable name * @param value the field value * @return this, to support call-chaining */ public ToStringCreator append(String fieldName, float value) { return append(fieldName, new Float(value)); } /** * Append a double field value. * @param fieldName the name of the field, usually the member variable name * @param value the field value * @return this, to support call-chaining */ public ToStringCreator append(String fieldName, double value) { return append(fieldName, new Double(value)); } /** * Append a boolean field value. * @param fieldName the name of the field, usually the member variable name * @param value the field value * @return this, to support call-chaining */ public ToStringCreator append(String fieldName, boolean value) { return append(fieldName, Boolean.valueOf(value)); } /** * Append a field value. * @param fieldName the name of the field, usually the member variable name * @param value the field value * @return this, to support call-chaining */ public ToStringCreator append(String fieldName, Object value) { printFieldSeparatorIfNecessary(); this.styler.styleField(this.buffer, fieldName, value); return this; } private void printFieldSeparatorIfNecessary() { if (this.styledFirstField) { this.styler.styleFieldSeparator(this.buffer); } else { this.styledFirstField = true; } } /** * Append the provided value. * @param value The value to append * @return this, to support call-chaining. */ public ToStringCreator append(Object value) { this.styler.styleValue(this.buffer, value); return this; } /** * Return the String representation that this ToStringCreator built. */ @Override public String toString() { this.styler.styleEnd(this.buffer, this.object); return this.buffer.toString(); } } ././@LongLink0000000000000000000000000000017500000000000011570 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/NestedIOException.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000444111623223530033342 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core; import java.io.IOException; /** * Subclass of {@link IOException} that properly handles a root cause, * exposing the root cause just like NestedChecked/RuntimeException does. * *

Proper root cause handling has not been added to standard IOException before * Java 6, which is why we need to do it ourselves for Java 5 compatibility purposes. * *

The similarity between this class and the NestedChecked/RuntimeException * class is unavoidable, as this class needs to derive from IOException. * * @author Juergen Hoeller * @since 2.0 * @see #getMessage * @see #printStackTrace * @see org.springframework.core.NestedCheckedException * @see org.springframework.core.NestedRuntimeException */ public class NestedIOException extends IOException { static { // Eagerly load the NestedExceptionUtils class to avoid classloader deadlock // issues on OSGi when calling getMessage(). Reported by Don Brown; SPR-5607. NestedExceptionUtils.class.getName(); } /** * Construct a NestedIOException with the specified detail message. * @param msg the detail message */ public NestedIOException(String msg) { super(msg); } /** * Construct a NestedIOException with the specified detail message * and nested exception. * @param msg the detail message * @param cause the nested exception */ public NestedIOException(String msg, Throwable cause) { super(msg); initCause(cause); } /** * Return the detail message, including the message from the nested exception * if there is one. */ @Override public String getMessage() { return NestedExceptionUtils.buildMessage(super.getMessage(), getCause()); } } ././@LongLink0000000000000000000000000000017000000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/package-info.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000031011623223530033331 0ustar drazzibdrazzib /** * * Provides basic classes for exception handling and version detection, * and other core helpers that are not specific to any part of the framework. * */ package org.springframework.core; ././@LongLink0000000000000000000000000000015400000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/task/libspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000755000175000017500000000000011623223530033335 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000017500000000000011570 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/task/package-info.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000030511623223530033335 0ustar drazzibdrazzib /** * * This package defines Spring's core TaskExecutor abstraction, * and provides SyncTaskExecutor and SimpleAsyncTaskExecutor implementations. * */ package org.springframework.core.task; ././@LongLink0000000000000000000000000000020100000000000011556 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/task/SyncTaskExecutor.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000332111623223530033336 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.task; import java.io.Serializable; import org.springframework.util.Assert; /** * {@link TaskExecutor} implementation that executes each task synchronously * in the calling thread. * *

Mainly intended for testing scenarios. * *

Execution in the calling thread does have the advantage of participating * in it's thread context, for example the thread context class loader or the * thread's current transaction association. That said, in many cases, * asynchronous execution will be preferable: choose an asynchronous * TaskExecutor instead for such scenarios. * * @author Juergen Hoeller * @since 2.0 * @see SimpleAsyncTaskExecutor */ public class SyncTaskExecutor implements TaskExecutor, Serializable { /** * Executes the given task synchronously, through direct * invocation of it's {@link Runnable#run() run()} method. * @throws IllegalArgumentException if the given task is null */ public void execute(Runnable task) { Assert.notNull(task, "Runnable must not be null"); task.run(); } } ././@LongLink0000000000000000000000000000020600000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/task/TaskRejectedException.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000317411623223530033344 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.task; import java.util.concurrent.RejectedExecutionException; /** * Exception thrown when a {@link TaskExecutor} rejects to accept * a given task for execution. * * @author Juergen Hoeller * @since 2.0.1 * @see TaskExecutor#execute(Runnable) * @see TaskTimeoutException */ public class TaskRejectedException extends RejectedExecutionException { /** * Create a new TaskRejectedException * with the specified detail message and no root cause. * @param msg the detail message */ public TaskRejectedException(String msg) { super(msg); } /** * Create a new TaskRejectedException * with the specified detail message and the given root cause. * @param msg the detail message * @param cause the root cause (usually from using an underlying * API such as the java.util.concurrent package) * @see java.util.concurrent.RejectedExecutionException */ public TaskRejectedException(String msg, Throwable cause) { super(msg, cause); } } ././@LongLink0000000000000000000000000000020500000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/task/TaskTimeoutException.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000315311623223526033346 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.task; /** * Exception thrown when a {@link AsyncTaskExecutor} rejects to accept * a given task for execution because of the specified timeout. * * @author Juergen Hoeller * @since 2.0.3 * @see AsyncTaskExecutor#execute(Runnable, long) * @see TaskRejectedException */ public class TaskTimeoutException extends TaskRejectedException { /** * Create a new TaskTimeoutException * with the specified detail message and no root cause. * @param msg the detail message */ public TaskTimeoutException(String msg) { super(msg); } /** * Create a new TaskTimeoutException * with the specified detail message and the given root cause. * @param msg the detail message * @param cause the root cause (usually from using an underlying * API such as the java.util.concurrent package) * @see java.util.concurrent.RejectedExecutionException */ public TaskTimeoutException(String msg, Throwable cause) { super(msg, cause); } } ././@LongLink0000000000000000000000000000016400000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/task/support/libspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000755000175000017500000000000011623223530033335 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000020500000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/task/support/package-info.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000027411623223526033347 0ustar drazzibdrazzib /** * * Support classes for Spring's TaskExecutor abstraction. * Includes an adapter for the standard ExecutorService interface. * */ package org.springframework.core.task.support; ././@LongLink0000000000000000000000000000021700000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/task/support/ExecutorServiceAdapter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000610511623223526033346 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.task.support; import java.util.List; import java.util.concurrent.AbstractExecutorService; import java.util.concurrent.TimeUnit; import org.springframework.core.task.TaskExecutor; import org.springframework.util.Assert; /** * Adapter that takes a Spring {@link org.springframework.core.task.TaskExecutor}) * and exposes a full java.util.concurrent.ExecutorService for it. * *

This is primarily for adapting to client components that communicate via the * java.util.concurrent.ExecutorService API. It can also be used as * common ground between a local Spring TaskExecutor backend and a * JNDI-located ManagedExecutorService in a Java EE 6 environment. * *

NOTE: This ExecutorService adapter does not support the * lifecycle methods in the java.util.concurrent.ExecutorService API * ("shutdown()" etc), similar to a server-wide ManagedExecutorService * in a Java EE 6 environment. The lifecycle is always up to the backend pool, * with this adapter acting as an access-only proxy for that target pool. * * @author Juergen Hoeller * @since 3.0 * @see java.util.concurrent.ExecutorService */ public class ExecutorServiceAdapter extends AbstractExecutorService { private final TaskExecutor taskExecutor; /** * Create a new ExecutorServiceAdapter, using the given target executor. * @param concurrentExecutor the target executor to delegate to */ public ExecutorServiceAdapter(TaskExecutor taskExecutor) { Assert.notNull(taskExecutor, "TaskExecutor must not be null"); this.taskExecutor = taskExecutor; } public void execute(Runnable task) { this.taskExecutor.execute(task); } public void shutdown() { throw new IllegalStateException( "Manual shutdown not supported - ExecutorServiceAdapter is dependent on an external lifecycle"); } public List shutdownNow() { throw new IllegalStateException( "Manual shutdown not supported - ExecutorServiceAdapter is dependent on an external lifecycle"); } public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException { throw new IllegalStateException( "Manual shutdown not supported - ExecutorServiceAdapter is dependent on an external lifecycle"); } public boolean isShutdown() { return false; } public boolean isTerminated() { return false; } } ././@LongLink0000000000000000000000000000022200000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/task/support/ConcurrentExecutorAdapter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000350711623223526033351 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.task.support; import java.util.concurrent.Executor; import org.springframework.core.task.TaskExecutor; import org.springframework.util.Assert; /** * Adapter that exposes the {@link java.util.concurrent.Executor} interface * for any Spring {@link org.springframework.core.task.TaskExecutor}. * *

This is less useful as of Spring 3.0, since TaskExecutor itself * extends the Executor interface. The adapter is only relevant for * hiding the TaskExecutor nature of a given object now, * solely exposing the standard Executor interface to a client. * * @author Juergen Hoeller * @since 2.5 * @see java.util.concurrent.Executor * @see org.springframework.core.task.TaskExecutor */ public class ConcurrentExecutorAdapter implements Executor { private final TaskExecutor taskExecutor; /** * Create a new ConcurrentExecutorAdapter for the given Spring TaskExecutor. * @param taskExecutor the Spring TaskExecutor to wrap */ public ConcurrentExecutorAdapter(TaskExecutor taskExecutor) { Assert.notNull(taskExecutor, "TaskExecutor must not be null"); this.taskExecutor = taskExecutor; } public void execute(Runnable command) { this.taskExecutor.execute(command); } } ././@LongLink0000000000000000000000000000021400000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/task/support/TaskExecutorAdapter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000670011623223530033342 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.task.support; import java.util.concurrent.Callable; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; import java.util.concurrent.FutureTask; import java.util.concurrent.RejectedExecutionException; import org.springframework.core.task.AsyncTaskExecutor; import org.springframework.core.task.TaskRejectedException; import org.springframework.util.Assert; /** * Adapter that takes a JDK 1.5 java.util.concurrent.Executor and * exposes a Spring {@link org.springframework.core.task.TaskExecutor} for it. * Also detects an extended java.util.concurrent.ExecutorService, adapting * the {@link org.springframework.core.task.AsyncTaskExecutor} interface accordingly. * * @author Juergen Hoeller * @since 3.0 * @see java.util.concurrent.Executor * @see java.util.concurrent.ExecutorService * @see java.util.concurrent.Executors */ public class TaskExecutorAdapter implements AsyncTaskExecutor { private Executor concurrentExecutor; /** * Create a new TaskExecutorAdapter, * using the given JDK 1.5 concurrent executor. * @param concurrentExecutor the JDK 1.5 concurrent executor to delegate to */ public TaskExecutorAdapter(Executor concurrentExecutor) { Assert.notNull(concurrentExecutor, "Executor must not be null"); this.concurrentExecutor = concurrentExecutor; } /** * Delegates to the specified JDK 1.5 concurrent executor. * @see java.util.concurrent.Executor#execute(Runnable) */ public void execute(Runnable task) { try { this.concurrentExecutor.execute(task); } catch (RejectedExecutionException ex) { throw new TaskRejectedException( "Executor [" + this.concurrentExecutor + "] did not accept task: " + task, ex); } } public void execute(Runnable task, long startTimeout) { execute(task); } public Future submit(Runnable task) { try { if (this.concurrentExecutor instanceof ExecutorService) { return ((ExecutorService) this.concurrentExecutor).submit(task); } else { FutureTask future = new FutureTask(task, null); this.concurrentExecutor.execute(future); return future; } } catch (RejectedExecutionException ex) { throw new TaskRejectedException( "Executor [" + this.concurrentExecutor + "] did not accept task: " + task, ex); } } public Future submit(Callable task) { try { if (this.concurrentExecutor instanceof ExecutorService) { return ((ExecutorService) this.concurrentExecutor).submit(task); } else { FutureTask future = new FutureTask(task); this.concurrentExecutor.execute(future); return future; } } catch (RejectedExecutionException ex) { throw new TaskRejectedException( "Executor [" + this.concurrentExecutor + "] did not accept task: " + task, ex); } } } ././@LongLink0000000000000000000000000000017500000000000011570 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/task/TaskExecutor.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000345311623223530033344 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.task; import java.util.concurrent.Executor; /** * Simple task executor interface that abstracts the execution * of a {@link Runnable}. * *

Implementations can use all sorts of different execution strategies, * such as: synchronous, asynchronous, using a thread pool, and more. * *

Equivalent to JDK 1.5's {@link java.util.concurrent.Executor} * interface; extending it now in Spring 3.0, so that clients may declare * a dependency on an Executor and receive any TaskExecutor implementation. * This interface remains separate from the standard Executor interface * mainly for backwards compatibility with JDK 1.4 in Spring 2.x. * * @author Juergen Hoeller * @since 2.0 * @see java.util.concurrent.Executor */ public interface TaskExecutor extends Executor { /** * Execute the given task. *

The call might return immediately if the implementation uses * an asynchronous execution strategy, or might block in the case * of synchronous execution. * @param task the Runnable to execute (never null) * @throws TaskRejectedException if the given task was not accepted */ void execute(Runnable task); } ././@LongLink0000000000000000000000000000020200000000000011557 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/task/AsyncTaskExecutor.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000655011623223526033352 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.task; import java.util.concurrent.Callable; import java.util.concurrent.Future; /** * Extended interface for asynchronous {@link TaskExecutor} implementations, * offering an overloaded {@link #execute(Runnable, long)} variant with a start * timeout parameter as well support for {@link java.util.concurrent.Callable}. * *

Note: The {@link java.util.concurrent.Executors} class includes a set of * methods that can convert some other common closure-like objects, for example, * {@link java.security.PrivilegedAction} to {@link Callable} before executing them. * *

Implementing this interface also indicates that the {@link #execute(Runnable)} * method will not execute its Runnable in the caller's thread but rather * asynchronously in some other thread. * * @author Juergen Hoeller * @since 2.0.3 * @see SimpleAsyncTaskExecutor * @see org.springframework.scheduling.SchedulingTaskExecutor * @see java.util.concurrent.Callable * @see java.util.concurrent.Executors */ public interface AsyncTaskExecutor extends TaskExecutor { /** Constant that indicates immediate execution */ long TIMEOUT_IMMEDIATE = 0; /** Constant that indicates no time limit */ long TIMEOUT_INDEFINITE = Long.MAX_VALUE; /** * Execute the given task. * @param task the Runnable to execute (never null) * @param startTimeout the time duration (milliseconds) within which the task is * supposed to start. This is intended as a hint to the executor, allowing for * preferred handling of immediate tasks. Typical values are {@link #TIMEOUT_IMMEDIATE} * or {@link #TIMEOUT_INDEFINITE} (the default as used by {@link #execute(Runnable)}). * @throws TaskTimeoutException in case of the task being rejected because * of the timeout (i.e. it cannot be started in time) * @throws TaskRejectedException if the given task was not accepted */ void execute(Runnable task, long startTimeout); /** * Submit a Runnable task for execution, receiving a Future representing that task. * The Future will return a null result upon completion. * @param task the Runnable to execute (never null) * @return a Future representing pending completion of the task * @throws TaskRejectedException if the given task was not accepted */ Future submit(Runnable task); /** * Submit a Callable task for execution, receiving a Future representing that task. * The Future will return the Callable's result upon completion. * @param task the Callable to execute (never null) * @return a Future representing pending completion of the task * @throws TaskRejectedException if the given task was not accepted */ Future submit(Callable task); } ././@LongLink0000000000000000000000000000021000000000000011556 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/task/SimpleAsyncTaskExecutor.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000001617711623223530033353 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.task; import java.io.Serializable; import java.util.concurrent.Callable; import java.util.concurrent.Future; import java.util.concurrent.FutureTask; import java.util.concurrent.ThreadFactory; import org.springframework.util.Assert; import org.springframework.util.ConcurrencyThrottleSupport; import org.springframework.util.CustomizableThreadCreator; /** * {@link TaskExecutor} implementation that fires up a new Thread for each task, * executing it asynchronously. * *

Supports limiting concurrent threads through the "concurrencyLimit" * bean property. By default, the number of concurrent threads is unlimited. * *

NOTE: This implementation does not reuse threads! Consider a * thread-pooling TaskExecutor implementation instead, in particular for * executing a large number of short-lived tasks. * * @author Juergen Hoeller * @since 2.0 * @see #setConcurrencyLimit * @see SyncTaskExecutor * @see org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor * @see org.springframework.scheduling.commonj.WorkManagerTaskExecutor */ public class SimpleAsyncTaskExecutor extends CustomizableThreadCreator implements AsyncTaskExecutor, Serializable { /** * Permit any number of concurrent invocations: that is, don't throttle concurrency. */ public static final int UNBOUNDED_CONCURRENCY = ConcurrencyThrottleSupport.UNBOUNDED_CONCURRENCY; /** * Switch concurrency 'off': that is, don't allow any concurrent invocations. */ public static final int NO_CONCURRENCY = ConcurrencyThrottleSupport.NO_CONCURRENCY; /** Internal concurrency throttle used by this executor */ private final ConcurrencyThrottleAdapter concurrencyThrottle = new ConcurrencyThrottleAdapter(); private ThreadFactory threadFactory; /** * Create a new SimpleAsyncTaskExecutor with default thread name prefix. */ public SimpleAsyncTaskExecutor() { super(); } /** * Create a new SimpleAsyncTaskExecutor with the given thread name prefix. * @param threadNamePrefix the prefix to use for the names of newly created threads */ public SimpleAsyncTaskExecutor(String threadNamePrefix) { super(threadNamePrefix); } /** * Create a new SimpleAsyncTaskExecutor with the given external thread factory. * @param threadFactory the factory to use for creating new Threads */ public SimpleAsyncTaskExecutor(ThreadFactory threadFactory) { this.threadFactory = threadFactory; } /** * Specify an external factory to use for creating new Threads, * instead of relying on the local properties of this executor. *

You may specify an inner ThreadFactory bean or also a ThreadFactory reference * obtained from JNDI (on a Java EE 6 server) or some other lookup mechanism. * @see #setThreadNamePrefix * @see #setThreadPriority */ public void setThreadFactory(ThreadFactory threadFactory) { this.threadFactory = threadFactory; } /** * Return the external factory to use for creating new Threads, if any. */ public final ThreadFactory getThreadFactory() { return this.threadFactory; } /** * Set the maximum number of parallel accesses allowed. * -1 indicates no concurrency limit at all. *

In principle, this limit can be changed at runtime, * although it is generally designed as a config time setting. * NOTE: Do not switch between -1 and any concrete limit at runtime, * as this will lead to inconsistent concurrency counts: A limit * of -1 effectively turns off concurrency counting completely. * @see #UNBOUNDED_CONCURRENCY */ public void setConcurrencyLimit(int concurrencyLimit) { this.concurrencyThrottle.setConcurrencyLimit(concurrencyLimit); } /** * Return the maximum number of parallel accesses allowed. */ public final int getConcurrencyLimit() { return this.concurrencyThrottle.getConcurrencyLimit(); } /** * Return whether this throttle is currently active. * @return true if the concurrency limit for this instance is active * @see #getConcurrencyLimit() * @see #setConcurrencyLimit */ public final boolean isThrottleActive() { return this.concurrencyThrottle.isThrottleActive(); } /** * Executes the given task, within a concurrency throttle * if configured (through the superclass's settings). * @see #doExecute(Runnable) */ public void execute(Runnable task) { execute(task, TIMEOUT_INDEFINITE); } /** * Executes the given task, within a concurrency throttle * if configured (through the superclass's settings). *

Executes urgent tasks (with 'immediate' timeout) directly, * bypassing the concurrency throttle (if active). All other * tasks are subject to throttling. * @see #TIMEOUT_IMMEDIATE * @see #doExecute(Runnable) */ public void execute(Runnable task, long startTimeout) { Assert.notNull(task, "Runnable must not be null"); if (isThrottleActive() && startTimeout > TIMEOUT_IMMEDIATE) { this.concurrencyThrottle.beforeAccess(); doExecute(new ConcurrencyThrottlingRunnable(task)); } else { doExecute(task); } } public Future submit(Runnable task) { FutureTask future = new FutureTask(task, null); execute(future, TIMEOUT_INDEFINITE); return future; } public Future submit(Callable task) { FutureTask future = new FutureTask(task); execute(future, TIMEOUT_INDEFINITE); return future; } /** * Template method for the actual execution of a task. *

The default implementation creates a new Thread and starts it. * @param task the Runnable to execute * @see #setThreadFactory * @see #createThread * @see java.lang.Thread#start() */ protected void doExecute(Runnable task) { Thread thread = (this.threadFactory != null ? this.threadFactory.newThread(task) : createThread(task)); thread.start(); } /** * Subclass of the general ConcurrencyThrottleSupport class, * making beforeAccess() and afterAccess() * visible to the surrounding class. */ private static class ConcurrencyThrottleAdapter extends ConcurrencyThrottleSupport { @Override protected void beforeAccess() { super.beforeAccess(); } @Override protected void afterAccess() { super.afterAccess(); } } /** * This Runnable calls afterAccess() after the * target Runnable has finished its execution. */ private class ConcurrencyThrottlingRunnable implements Runnable { private final Runnable target; public ConcurrencyThrottlingRunnable(Runnable target) { this.target = target; } public void run() { try { this.target.run(); } finally { concurrencyThrottle.afterAccess(); } } } } ././@LongLink0000000000000000000000000000017100000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/ConcurrentMap.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000275211623223530033345 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core; import java.util.Map; /** * Common interface for a concurrent Map, as exposed by * {@link CollectionFactory#createConcurrentMap}. Mirrors * {@link java.util.concurrent.ConcurrentMap}, allowing to be backed by a * JDK ConcurrentHashMap as well as a backport-concurrent ConcurrentHashMap. * *

Check out the {@link java.util.concurrent.ConcurrentMap ConcurrentMap javadoc} * for details on the interface's methods. * * @author Juergen Hoeller * @since 2.5 * @deprecated as of Spring 3.0, since standard {@link java.util.concurrent.ConcurrentMap} * is available on Java 5+ anyway */ @Deprecated public interface ConcurrentMap extends Map { Object putIfAbsent(Object key, Object value); boolean remove(Object key, Object value); boolean replace(Object key, Object oldValue, Object newValue); Object replace(Object key, Object value); } ././@LongLink0000000000000000000000000000022500000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/LocalVariableTableParameterNameDiscoverer.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000002057011623223526033350 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Constructor; import java.lang.reflect.Member; import java.lang.reflect.Method; import java.util.Collections; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.asm.ClassReader; import org.springframework.asm.Label; import org.springframework.asm.MethodVisitor; import org.springframework.asm.Opcodes; import org.springframework.asm.Type; import org.springframework.asm.commons.EmptyVisitor; import org.springframework.util.ClassUtils; /** * Implementation of {@link ParameterNameDiscoverer} that uses the LocalVariableTable * information in the method attributes to discover parameter names. Returns * null if the class file was compiled without debug information. * *

Uses ObjectWeb's ASM library for analyzing class files. Each discoverer * instance caches the ASM discovered information for each introspected Class, in a * thread-safe manner. It is recommended to reuse discoverer instances * as far as possible. * * @author Adrian Colyer * @author Costin Leau * @author Juergen Hoeller * @since 2.0 */ public class LocalVariableTableParameterNameDiscoverer implements ParameterNameDiscoverer { private static Log logger = LogFactory.getLog(LocalVariableTableParameterNameDiscoverer.class); // marker object for classes that do not have any debug info private static final Map NO_DEBUG_INFO_MAP = Collections.emptyMap(); // the cache uses a nested index (value is a map) to keep the top level cache relatively small in size private final Map, Map> parameterNamesCache = new ConcurrentHashMap, Map>(); public String[] getParameterNames(Method method) { Class declaringClass = method.getDeclaringClass(); Map map = this.parameterNamesCache.get(declaringClass); if (map == null) { // initialize cache map = inspectClass(declaringClass); this.parameterNamesCache.put(declaringClass, map); } if (map != NO_DEBUG_INFO_MAP) { return map.get(method); } return null; } @SuppressWarnings("unchecked") public String[] getParameterNames(Constructor ctor) { Class declaringClass = ctor.getDeclaringClass(); Map map = this.parameterNamesCache.get(declaringClass); if (map == null) { // initialize cache map = inspectClass(declaringClass); this.parameterNamesCache.put(declaringClass, map); } if (map != NO_DEBUG_INFO_MAP) { return map.get(ctor); } return null; } /** * Inspects the target class. Exceptions will be logged and a maker map returned * to indicate the lack of debug information. */ private Map inspectClass(Class clazz) { InputStream is = clazz.getResourceAsStream(ClassUtils.getClassFileName(clazz)); if (is == null) { // We couldn't load the class file, which is not fatal as it // simply means this method of discovering parameter names won't work. if (logger.isDebugEnabled()) { logger.debug("Cannot find '.class' file for class [" + clazz + "] - unable to determine constructors/methods parameter names"); } return NO_DEBUG_INFO_MAP; } try { ClassReader classReader = new ClassReader(is); Map map = new ConcurrentHashMap(); classReader.accept(new ParameterNameDiscoveringVisitor(clazz, map), false); return map; } catch (IOException ex) { if (logger.isDebugEnabled()) { logger.debug("Exception thrown while reading '.class' file for class [" + clazz + "] - unable to determine constructors/methods parameter names", ex); } } finally { try { is.close(); } catch (IOException ex) { // ignore } } return NO_DEBUG_INFO_MAP; } /** * Helper class that inspects all methods (constructor included) and then * attempts to find the parameter names for that member. */ private static class ParameterNameDiscoveringVisitor extends EmptyVisitor { private static final String STATIC_CLASS_INIT = ""; private final Class clazz; private final Map memberMap; public ParameterNameDiscoveringVisitor(Class clazz, Map memberMap) { this.clazz = clazz; this.memberMap = memberMap; } @Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { // exclude synthetic + bridged && static class initialization if (!isSyntheticOrBridged(access) && !STATIC_CLASS_INIT.equals(name)) { return new LocalVariableTableVisitor(clazz, memberMap, name, desc, isStatic(access)); } return null; } private static boolean isSyntheticOrBridged(int access) { return (((access & Opcodes.ACC_SYNTHETIC) | (access & Opcodes.ACC_BRIDGE)) > 0); } private static boolean isStatic(int access) { return ((access & Opcodes.ACC_STATIC) > 0); } } private static class LocalVariableTableVisitor extends EmptyVisitor { private static final String CONSTRUCTOR = ""; private final Class clazz; private final Map memberMap; private final String name; private final Type[] args; private final boolean isStatic; private String[] parameterNames; private boolean hasLvtInfo = false; /* * The nth entry contains the slot index of the LVT table entry holding the * argument name for the nth parameter. */ private final int[] lvtSlotIndex; public LocalVariableTableVisitor(Class clazz, Map map, String name, String desc, boolean isStatic) { this.clazz = clazz; this.memberMap = map; this.name = name; // determine args args = Type.getArgumentTypes(desc); this.parameterNames = new String[args.length]; this.isStatic = isStatic; this.lvtSlotIndex = computeLvtSlotIndices(isStatic, args); } @Override public void visitLocalVariable(String name, String description, String signature, Label start, Label end, int index) { this.hasLvtInfo = true; for (int i = 0; i < lvtSlotIndex.length; i++) { if (lvtSlotIndex[i] == index) { this.parameterNames[i] = name; } } } @Override public void visitEnd() { if (this.hasLvtInfo || (this.isStatic && this.parameterNames.length == 0)) { // visitLocalVariable will never be called for static no args methods // which doesn't use any local variables. // This means that hasLvtInfo could be false for that kind of methods // even if the class has local variable info. memberMap.put(resolveMember(), parameterNames); } } private Member resolveMember() { ClassLoader loader = clazz.getClassLoader(); Class[] classes = new Class[args.length]; // resolve args for (int i = 0; i < args.length; i++) { classes[i] = ClassUtils.resolveClassName(args[i].getClassName(), loader); } try { if (CONSTRUCTOR.equals(name)) { return clazz.getDeclaredConstructor(classes); } return clazz.getDeclaredMethod(name, classes); } catch (NoSuchMethodException ex) { throw new IllegalStateException("Method [" + name + "] was discovered in the .class file but cannot be resolved in the class object", ex); } } private static int[] computeLvtSlotIndices(boolean isStatic, Type[] paramTypes) { int[] lvtIndex = new int[paramTypes.length]; int nextIndex = (isStatic ? 0 : 1); for (int i = 0; i < paramTypes.length; i++) { lvtIndex[i] = nextIndex; if (isWideType(paramTypes[i])) { nextIndex += 2; } else { nextIndex++; } } return lvtIndex; } private static boolean isWideType(Type aType) { // float is not a wide type return (aType == Type.LONG_TYPE || aType == Type.DOUBLE_TYPE); } } } ././@LongLink0000000000000000000000000000016600000000000011570 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/ErrorCoded.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000247211623223530033344 0ustar drazzibdrazzib/* * Copyright 2002-2005 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core; /** * Interface that can be implemented by exceptions etc that are error coded. * The error code is a String, rather than a number, so it can be given * user-readable values, such as "object.failureDescription". * *

An error code can be resolved by a MessageSource, for example. * * @author Rod Johnson * @see org.springframework.context.MessageSource */ public interface ErrorCoded { /** * Return the error code associated with this failure. * The GUI can render this any way it pleases, allowing for localization etc. * @return a String error code associated with this failure, * or null if not error-coded */ String getErrorCode(); } ././@LongLink0000000000000000000000000000020100000000000011556 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/OverridingClassLoader.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000001220411623223530033336 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core; import java.io.IOException; import java.io.InputStream; import org.springframework.util.FileCopyUtils; /** * ClassLoader that does not always delegate to the * parent loader, as normal class loaders do. This enables, for example, * instrumentation to be forced in the overriding ClassLoader, or a * "throwaway" class loading behavior, where selected classes are * temporarily loaded in the overriding ClassLoader, in order to load * an instrumented version of the class in the parent ClassLoader later on. * * @author Rod Johnson * @author Juergen Hoeller * @since 2.0.1 */ public class OverridingClassLoader extends DecoratingClassLoader { /** Packages that are excluded by default */ public static final String[] DEFAULT_EXCLUDED_PACKAGES = new String[] {"java.", "javax.", "sun.", "oracle."}; private static final String CLASS_FILE_SUFFIX = ".class"; /** * Create a new OverridingClassLoader for the given class loader. * @param parent the ClassLoader to build an overriding ClassLoader for */ public OverridingClassLoader(ClassLoader parent) { super(parent); for (String packageName : DEFAULT_EXCLUDED_PACKAGES) { excludePackage(packageName); } } @Override protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { Class result = null; if (isEligibleForOverriding(name)) { result = loadClassForOverriding(name); } if (result != null) { if (resolve) { resolveClass(result); } return result; } else { return super.loadClass(name, resolve); } } /** * Determine whether the specified class is eligible for overriding * by this class loader. * @param className the class name to check * @return whether the specified class is eligible * @see #isExcluded */ protected boolean isEligibleForOverriding(String className) { return !isExcluded(className); } /** * Load the specified class for overriding purposes in this ClassLoader. *

The default implementation delegates to {@link #findLoadedClass}, * {@link #loadBytesForClass} and {@link #defineClass}. * @param name the name of the class * @return the Class object, or null if no class defined for that name * @throws ClassNotFoundException if the class for the given name couldn't be loaded */ protected Class loadClassForOverriding(String name) throws ClassNotFoundException { Class result = findLoadedClass(name); if (result == null) { byte[] bytes = loadBytesForClass(name); if (bytes != null) { result = defineClass(name, bytes, 0, bytes.length); } } return result; } /** * Load the defining bytes for the given class, * to be turned into a Class object through a {@link #defineClass} call. *

The default implementation delegates to {@link #openStreamForClass} * and {@link #transformIfNecessary}. * @param name the name of the class * @return the byte content (with transformers already applied), * or null if no class defined for that name * @throws ClassNotFoundException if the class for the given name couldn't be loaded */ protected byte[] loadBytesForClass(String name) throws ClassNotFoundException { InputStream is = openStreamForClass(name); if (is == null) { return null; } try { // Load the raw bytes. byte[] bytes = FileCopyUtils.copyToByteArray(is); // Transform if necessary and use the potentially transformed bytes. return transformIfNecessary(name, bytes); } catch (IOException ex) { throw new ClassNotFoundException("Cannot load resource for class [" + name + "]", ex); } } /** * Open an InputStream for the specified class. *

The default implementation loads a standard class file through * the parent ClassLoader's getResourceAsStream method. * @param name the name of the class * @return the InputStream containing the byte code for the specified class */ protected InputStream openStreamForClass(String name) { String internalName = name.replace('.', '/') + CLASS_FILE_SUFFIX; return getParent().getResourceAsStream(internalName); } /** * Transformation hook to be implemented by subclasses. *

The default implementation simply returns the given bytes as-is. * @param name the fully-qualified name of the class being transformed * @param bytes the raw bytes of the class * @return the transformed bytes (never null; * same as the input bytes if the transformation produced no changes) */ protected byte[] transformIfNecessary(String name, byte[] bytes) { return bytes; } } ././@LongLink0000000000000000000000000000016300000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/Ordered.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000411311623223530033336 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core; /** * Interface that can be implemented by objects that should be * orderable, for example in a Collection. * *

The actual order can be interpreted as prioritization, with * the first object (with the lowest order value) having the highest * priority. * *

Note that there is a 'priority' marker for this interface: * {@link PriorityOrdered}. Order values expressed by PriorityOrdered * objects always apply before order values of 'plain' Ordered values. * * @author Juergen Hoeller * @since 07.04.2003 * @see OrderComparator * @see org.springframework.core.annotation.Order */ public interface Ordered { /** * Useful constant for the highest precedence value. * @see java.lang.Integer#MIN_VALUE */ int HIGHEST_PRECEDENCE = Integer.MIN_VALUE; /** * Useful constant for the lowest precedence value. * @see java.lang.Integer#MAX_VALUE */ int LOWEST_PRECEDENCE = Integer.MAX_VALUE; /** * Return the order value of this object, with a * higher value meaning greater in terms of sorting. *

Normally starting with 0, with Integer.MAX_VALUE * indicating the greatest value. Same order values will result * in arbitrary positions for the affected objects. *

Higher values can be interpreted as lower priority. As a * consequence, the object with the lowest value has highest priority * (somewhat analogous to Servlet "load-on-startup" values). * @return the order value */ int getOrder(); } ././@LongLink0000000000000000000000000000021600000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/PrioritizedParameterNameDiscoverer.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000417211623223526033350 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.Iterator; import java.util.LinkedList; import java.util.List; /** * ParameterNameDiscoverer implementation that tries several ParameterNameDiscoverers * in succession. Those added first in the addDiscoverer method have * highest priority. If one returns null, the next will be tried. * *

The default behavior is always to return null * if no discoverer matches. * * @author Rod Johnson * @author Juergen Hoeller * @since 2.0 */ public class PrioritizedParameterNameDiscoverer implements ParameterNameDiscoverer { private final List parameterNameDiscoverers = new LinkedList(); /** * Add a further ParameterNameDiscoverer to the list of discoverers * that this PrioritizedParameterNameDiscoverer checks. */ public void addDiscoverer(ParameterNameDiscoverer pnd) { this.parameterNameDiscoverers.add(pnd); } public String[] getParameterNames(Method method) { for (ParameterNameDiscoverer pnd : this.parameterNameDiscoverers) { String[] result = pnd.getParameterNames(method); if (result != null) { return result; } } return null; } public String[] getParameterNames(Constructor ctor) { for (ParameterNameDiscoverer pnd : this.parameterNameDiscoverers) { String[] result = pnd.getParameterNames(ctor); if (result != null) { return result; } } return null; } } ././@LongLink0000000000000000000000000000015500000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/enums/libspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000755000175000017500000000000011623223530033335 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000021000000000000011556 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/enums/LetterCodedLabeledEnum.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000351411623223530033342 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.enums; import org.springframework.util.Assert; /** * Implementation of LabeledEnum which uses a letter as the code type. * *

Should almost always be subclassed, but for some simple situations it may be * used directly. Note that you will not be able to use unique type-based functionality * like LabeledEnumResolver.getLabeledEnumSet(type) in this case. * * @author Keith Donald * @since 1.2.2 * @deprecated as of Spring 3.0, in favor of Java 5 enums. */ @Deprecated public class LetterCodedLabeledEnum extends AbstractGenericLabeledEnum { /** * The unique code of this enum. */ private final Character code; /** * Create a new LetterCodedLabeledEnum instance. * @param code the letter code * @param label the label (can be null) */ public LetterCodedLabeledEnum(char code, String label) { super(label); Assert.isTrue(Character.isLetter(code), "The code '" + code + "' is invalid: it must be a letter"); this.code = new Character(code); } public Comparable getCode() { return code; } /** * Return the letter code of this LabeledEnum instance. */ public char getLetterCode() { return ((Character) getCode()).charValue(); } } ././@LongLink0000000000000000000000000000017600000000000011571 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/enums/package-info.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000025711623223530033343 0ustar drazzibdrazzib /** * * Interfaces and classes for type-safe enum support on JDK >= 1.3. * This enum abstraction support codes and labels. * */ package org.springframework.core.enums; ././@LongLink0000000000000000000000000000020700000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/enums/ShortCodedLabeledEnum.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000325511623223526033351 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.enums; /** * Implementation of LabeledEnum which uses Short as the code type. * *

Should almost always be subclassed, but for some simple situations it may be * used directly. Note that you will not be able to use unique type-based functionality * like LabeledEnumResolver.getLabeledEnumSet(type) in this case. * * @author Keith Donald * @since 1.2.2 * @deprecated as of Spring 3.0, in favor of Java 5 enums. */ @Deprecated public class ShortCodedLabeledEnum extends AbstractGenericLabeledEnum { /** * The unique code of this enum. */ private final Short code; /** * Create a new ShortCodedLabeledEnum instance. * @param code the short code * @param label the label (can be null) */ public ShortCodedLabeledEnum(int code, String label) { super(label); this.code = new Short((short) code); } public Comparable getCode() { return code; } /** * Return the short code of this LabeledEnum instance. */ public short getShortCode() { return ((Short) getCode()).shortValue(); } } ././@LongLink0000000000000000000000000000020500000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/enums/AbstractLabeledEnum.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000416611623223530033346 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.enums; /** * Abstract base superclass for LabeledEnum implementations. * * @author Keith Donald * @author Juergen Hoeller * @author Sam Brannen * @since 1.2.2 * @deprecated as of Spring 3.0, in favor of Java 5 enums. */ @Deprecated public abstract class AbstractLabeledEnum implements LabeledEnum { /** * Create a new AbstractLabeledEnum instance. */ protected AbstractLabeledEnum() { } public Class getType() { // Could be coded as getClass().isAnonymousClass() on JDK 1.5 boolean isAnonymous = (getClass().getDeclaringClass() == null && getClass().getName().indexOf('$') != -1); return (isAnonymous ? getClass().getSuperclass() : getClass()); } public int compareTo(Object obj) { if (!(obj instanceof LabeledEnum)) { throw new ClassCastException("You may only compare LabeledEnums"); } LabeledEnum that = (LabeledEnum) obj; if (!this.getType().equals(that.getType())) { throw new ClassCastException("You may only compare LabeledEnums of the same type"); } return this.getCode().compareTo(that.getCode()); } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!(obj instanceof LabeledEnum)) { return false; } LabeledEnum other = (LabeledEnum) obj; return (this.getType().equals(other.getType()) && this.getCode().equals(other.getCode())); } @Override public int hashCode() { return (getType().hashCode() * 29 + getCode().hashCode()); } @Override public String toString() { return getLabel(); } } ././@LongLink0000000000000000000000000000020500000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/enums/LabeledEnumResolver.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000476411623223530033352 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.enums; import java.util.Map; import java.util.Set; /** * Interface for looking up LabeledEnum instances. * * @author Keith Donald * @author Juergen Hoeller * @since 1.2.2 * @deprecated as of Spring 3.0, in favor of Java 5 enums. */ @Deprecated public interface LabeledEnumResolver { /** * Return a set of enumerations of a particular type. Each element in the * set should be an instance of LabeledEnum. * @param type the enum type * @return a set of localized enumeration instances for the provided type * @throws IllegalArgumentException if the type is not supported */ public Set getLabeledEnumSet(Class type) throws IllegalArgumentException; /** * Return a map of enumerations of a particular type. Each element in the * map should be a key/value pair, where the key is the enum code, and the * value is the LabeledEnum instance. * @param type the enum type * @return a Map of localized enumeration instances, * with enum code as key and LabeledEnum instance as value * @throws IllegalArgumentException if the type is not supported */ public Map getLabeledEnumMap(Class type) throws IllegalArgumentException; /** * Resolve a single LabeledEnum by its identifying code. * @param type the enum type * @param code the enum code * @return the enum * @throws IllegalArgumentException if the code did not map to a valid instance */ public LabeledEnum getLabeledEnumByCode(Class type, Comparable code) throws IllegalArgumentException; /** * Resolve a single LabeledEnum by its identifying code. * @param type the enum type * @param label the enum label * @return the enum * @throws IllegalArgumentException if the label did not map to a valid instance */ public LabeledEnum getLabeledEnumByLabel(Class type, String label) throws IllegalArgumentException; } ././@LongLink0000000000000000000000000000020300000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/enums/StaticLabeledEnum.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000541711623223526033353 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.enums; /** * Base class for static type-safe labeled enum instances. * * Usage example: * *

 * public class FlowSessionStatus extends StaticLabeledEnum {
 *
 *     // public static final instances!
 *     public static FlowSessionStatus CREATED = new FlowSessionStatus(0, "Created");
 *     public static FlowSessionStatus ACTIVE = new FlowSessionStatus(1, "Active");
 *     public static FlowSessionStatus PAUSED = new FlowSessionStatus(2, "Paused");
 *     public static FlowSessionStatus SUSPENDED = new FlowSessionStatus(3, "Suspended");
 *     public static FlowSessionStatus ENDED = new FlowSessionStatus(4, "Ended");
 *     
 *     // private constructor!
 *     private FlowSessionStatus(int code, String label) {
 *         super(code, label);
 *     }
 *     
 *     // custom behavior
 * }
* * @author Keith Donald * @since 1.2.6 * @deprecated as of Spring 3.0, in favor of Java 5 enums. */ @Deprecated public abstract class StaticLabeledEnum extends AbstractLabeledEnum { /** * The unique code of the enum. */ private final Short code; /** * A descriptive label for the enum. */ private final transient String label; /** * Create a new StaticLabeledEnum instance. * @param code the short code * @param label the label (can be null) */ protected StaticLabeledEnum(int code, String label) { this.code = new Short((short) code); if (label != null) { this.label = label; } else { this.label = this.code.toString(); } } public Comparable getCode() { return code; } public String getLabel() { return label; } /** * Return the code of this LabeledEnum instance as a short. */ public short shortValue() { return ((Number) getCode()).shortValue(); } //--------------------------------------------------------------------- // Serialization support //--------------------------------------------------------------------- /** * Return the resolved type safe static enum instance. */ protected Object readResolve() { return StaticLabeledEnumResolver.instance().getLabeledEnumByCode(getType(), getCode()); } } ././@LongLink0000000000000000000000000000021300000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/enums/StaticLabeledEnumResolver.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000446511623223526033355 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.enums; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.Set; import java.util.TreeSet; import org.springframework.util.Assert; /** * {@link LabeledEnumResolver} that resolves statically defined enumerations. * Static implies all enum instances were defined within Java code, * implementing the type-safe enum pattern. * * @author Keith Donald * @author Juergen Hoeller * @since 1.2.2 * @deprecated as of Spring 3.0, in favor of Java 5 enums. */ @Deprecated public class StaticLabeledEnumResolver extends AbstractCachingLabeledEnumResolver { /** * Shared StaticLabeledEnumResolver singleton instance. */ private static final StaticLabeledEnumResolver INSTANCE = new StaticLabeledEnumResolver(); /** * Return the shared StaticLabeledEnumResolver singleton instance. * Mainly for resolving unique StaticLabeledEnum references on deserialization. * @see StaticLabeledEnum */ public static StaticLabeledEnumResolver instance() { return INSTANCE; } @Override protected Set findLabeledEnums(Class type) { Set typeEnums = new TreeSet(); for (Field field : type.getFields()) { if (Modifier.isStatic(field.getModifiers()) && Modifier.isPublic(field.getModifiers())) { if (type.isAssignableFrom(field.getType())) { try { Object value = field.get(null); Assert.isTrue(value instanceof LabeledEnum, "Field value must be a LabeledEnum instance"); typeEnums.add((LabeledEnum) value); } catch (IllegalAccessException ex) { logger.warn("Unable to access field value: " + field, ex); } } } } return typeEnums; } } ././@LongLink0000000000000000000000000000022400000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/enums/AbstractCachingLabeledEnumResolver.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000001132011623223530033334 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.enums; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.TreeSet; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.util.Assert; import org.springframework.util.CachingMapDecorator; import org.springframework.util.ClassUtils; /** * Abstract base class for {@link LabeledEnumResolver} implementations, * caching all retrieved {@link LabeledEnum} instances. * *

Subclasses need to implement the template method * {@link #findLabeledEnums(Class)}. * * @author Keith Donald * @author Juergen Hoeller * @since 1.2.2 * @see #findLabeledEnums(Class) * @deprecated as of Spring 3.0, in favor of Java 5 enums. */ @Deprecated public abstract class AbstractCachingLabeledEnumResolver implements LabeledEnumResolver { protected transient final Log logger = LogFactory.getLog(getClass()); private final LabeledEnumCache labeledEnumCache = new LabeledEnumCache(); public Set getLabeledEnumSet(Class type) throws IllegalArgumentException { return new TreeSet(getLabeledEnumMap(type).values()); } public Map getLabeledEnumMap(Class type) throws IllegalArgumentException { Assert.notNull(type, "No type specified"); return this.labeledEnumCache.get(type); } public LabeledEnum getLabeledEnumByCode(Class type, Comparable code) throws IllegalArgumentException { Assert.notNull(code, "No enum code specified"); Map typeEnums = getLabeledEnumMap(type); LabeledEnum codedEnum = typeEnums.get(code); if (codedEnum == null) { throw new IllegalArgumentException( "No enumeration with code '" + code + "'" + " of type [" + type.getName() + "] exists: this is likely a configuration error. " + "Make sure the code value matches a valid instance's code property!"); } return codedEnum; } public LabeledEnum getLabeledEnumByLabel(Class type, String label) throws IllegalArgumentException { Map typeEnums = getLabeledEnumMap(type); for (LabeledEnum value : typeEnums.values()) { if (value.getLabel().equalsIgnoreCase(label)) { return value; } } throw new IllegalArgumentException( "No enumeration with label '" + label + "' of type [" + type + "] exists: this is likely a configuration error. " + "Make sure the label string matches a valid instance's label property!"); } /** * Template method to be implemented by subclasses. * Supposed to find all LabeledEnum instances for the given type. * @param type the enum type * @return the Set of LabeledEnum instances * @see org.springframework.core.enums.LabeledEnum */ protected abstract Set findLabeledEnums(Class type); /** * Inner cache class that implements lazy building of LabeledEnum Maps. */ private class LabeledEnumCache extends CachingMapDecorator> { public LabeledEnumCache() { super(true); } @Override protected Map create(Class key) { Set typeEnums = findLabeledEnums(key); if (typeEnums == null || typeEnums.isEmpty()) { throw new IllegalArgumentException( "Unsupported labeled enumeration type '" + key + "': " + "make sure you've properly defined this enumeration! " + "If it is static, are the class and its fields public/static/final?"); } Map typeEnumMap = new HashMap(typeEnums.size()); for (LabeledEnum labeledEnum : typeEnums) { typeEnumMap.put(labeledEnum.getCode(), labeledEnum); } return Collections.unmodifiableMap(typeEnumMap); } @Override protected boolean useWeakValue(Class key, Map value) { if (!ClassUtils.isCacheSafe(key, AbstractCachingLabeledEnumResolver.this.getClass().getClassLoader())) { if (logger != null && logger.isDebugEnabled()) { logger.debug("Not strongly caching class [" + key.getName() + "] because it is not cache-safe"); } return true; } else { return false; } } } } ././@LongLink0000000000000000000000000000021000000000000011556 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/enums/StringCodedLabeledEnum.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000354211623223530033343 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.enums; import org.springframework.util.Assert; /** * Implementation of LabeledEnum which uses a String as the code type. * *

Should almost always be subclassed, but for some simple situations it may be * used directly. Note that you will not be able to use unique type-based * functionality like LabeledEnumResolver.getLabeledEnumSet(type) in this case. * * @author Keith Donald * @author Juergen Hoeller * @since 1.2.2 * @see org.springframework.core.enums.LabeledEnumResolver#getLabeledEnumSet(Class) * @deprecated as of Spring 3.0, in favor of Java 5 enums. */ @Deprecated public class StringCodedLabeledEnum extends AbstractGenericLabeledEnum { /** * The unique code of this enum. */ private final String code; /** * Create a new StringCodedLabeledEnum instance. * @param code the String code * @param label the label (can be null) */ public StringCodedLabeledEnum(String code, String label) { super(label); Assert.notNull(code, "'code' must not be null"); this.code = code; } public Comparable getCode() { return this.code; } /** * Return the String code of this LabeledEnum instance. */ public String getStringCode() { return (String) getCode(); } } ././@LongLink0000000000000000000000000000017500000000000011570 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/enums/LabeledEnum.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000547311623223530033350 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.enums; import java.io.Serializable; import java.util.Comparator; import org.springframework.util.comparator.CompoundComparator; import org.springframework.util.comparator.NullSafeComparator; /** * An interface for objects that represent a labeled enumeration. * Each such enum instance has the following characteristics: * *

    *
  • A type that identifies the enum's class. * For example: com.mycompany.util.FileFormat.
  • * *
  • A code that uniquely identifies the enum within the context of its type. * For example: "CSV". Different classes of codes are possible * (e.g., Character, Integer, String).
  • * *
  • A descriptive label. For example: "the CSV File Format".
  • *
* * @author Keith Donald * @since 1.2.2 * @deprecated as of Spring 3.0, in favor of Java 5 enums. */ @Deprecated public interface LabeledEnum extends Comparable, Serializable { /** * Return this enumeration's type. */ Class getType(); /** * Return this enumeration's code. *

Each code should be unique within enumerations of the same type. */ Comparable getCode(); /** * Return a descriptive, optional label. */ String getLabel(); // Constants for standard enum ordering (Comparator implementations) /** * Shared Comparator instance that sorts enumerations by CODE_ORDER. */ Comparator CODE_ORDER = new Comparator() { public int compare(Object o1, Object o2) { Comparable c1 = ((LabeledEnum) o1).getCode(); Comparable c2 = ((LabeledEnum) o2).getCode(); return c1.compareTo(c2); } }; /** * Shared Comparator instance that sorts enumerations by LABEL_ORDER. */ Comparator LABEL_ORDER = new Comparator() { public int compare(Object o1, Object o2) { LabeledEnum e1 = (LabeledEnum) o1; LabeledEnum e2 = (LabeledEnum) o2; Comparator comp = new NullSafeComparator(String.CASE_INSENSITIVE_ORDER, true); return comp.compare(e1.getLabel(), e2.getLabel()); } }; /** * Shared Comparator instance that sorts enumerations by LABEL_ORDER, * then CODE_ORDER. */ Comparator DEFAULT_ORDER = new CompoundComparator(new Comparator[] { LABEL_ORDER, CODE_ORDER }); } ././@LongLink0000000000000000000000000000021400000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/enums/AbstractGenericLabeledEnum.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000250711623223526033350 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.enums; /** * Base class for labeled enum instances that aren't static. * * @author Keith Donald * @since 1.2.6 * @deprecated as of Spring 3.0, in favor of Java 5 enums. */ public abstract class AbstractGenericLabeledEnum extends AbstractLabeledEnum { /** * A descriptive label for the enum. */ private final String label; /** * Create a new StaticLabeledEnum instance. * @param label the label; if null), the enum's code * will be used as label */ protected AbstractGenericLabeledEnum(String label) { this.label = label; } public String getLabel() { if (this.label != null) { return label; } else { return getCode().toString(); } } } ././@LongLink0000000000000000000000000000017400000000000011567 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/NamedThreadLocal.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000242611623223530033343 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core; import org.springframework.util.Assert; /** * {@link ThreadLocal} subclass that exposes a specified name * as {@link #toString()} result (allowing for introspection). * * @author Juergen Hoeller * @since 2.5.2 * @see NamedInheritableThreadLocal */ public class NamedThreadLocal extends ThreadLocal { private final String name; /** * Create a new NamedThreadLocal with the given name. * @param name a descriptive name for this ThreadLocal */ public NamedThreadLocal(String name) { Assert.hasText(name, "Name must not be empty"); this.name = name; } @Override public String toString() { return this.name; } } ././@LongLink0000000000000000000000000000017300000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/OrderComparator.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000607211623223530033344 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; /** * {@link Comparator} implementation for {@link Ordered} objects, * sorting by order value ascending (resp. by priority descending). * *

Non-Ordered objects are treated as greatest order * values, thus ending up at the end of the list, in arbitrary order * (just like same order values of Ordered objects). * * @author Juergen Hoeller * @since 07.04.2003 * @see Ordered * @see java.util.Collections#sort(java.util.List, java.util.Comparator) * @see java.util.Arrays#sort(Object[], java.util.Comparator) */ public class OrderComparator implements Comparator { /** * Shared default instance of OrderComparator. */ public static OrderComparator INSTANCE = new OrderComparator(); public int compare(Object o1, Object o2) { boolean p1 = (o1 instanceof PriorityOrdered); boolean p2 = (o2 instanceof PriorityOrdered); if (p1 && !p2) { return -1; } else if (p2 && !p1) { return 1; } // Direct evaluation instead of Integer.compareTo to avoid unnecessary object creation. int i1 = getOrder(o1); int i2 = getOrder(o2); return (i1 < i2) ? -1 : (i1 > i2) ? 1 : 0; } /** * Determine the order value for the given object. *

The default implementation checks against the {@link Ordered} * interface. Can be overridden in subclasses. * @param obj the object to check * @return the order value, or Ordered.LOWEST_PRECEDENCE as fallback */ protected int getOrder(Object obj) { return (obj instanceof Ordered ? ((Ordered) obj).getOrder() : Ordered.LOWEST_PRECEDENCE); } /** * Sort the given List with a default OrderComparator. *

Optimized to skip sorting for lists with size 0 or 1, * in order to avoid unnecessary array extraction. * @param list the List to sort * @see java.util.Collections#sort(java.util.List, java.util.Comparator) */ public static void sort(List list) { if (list.size() > 1) { Collections.sort(list, INSTANCE); } } /** * Sort the given array with a default OrderComparator. *

Optimized to skip sorting for lists with size 0 or 1, * in order to avoid unnecessary array extraction. * @param array the array to sort * @see java.util.Arrays#sort(Object[], java.util.Comparator) */ public static void sort(Object[] array) { if (array.length > 1) { Arrays.sort(array, INSTANCE); } } } ././@LongLink0000000000000000000000000000017500000000000011570 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/AttributeAccessor.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000427311623223526033352 0ustar drazzibdrazzib/* * Copyright 2002-2006 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core; /** * Interface defining a generic contract for attaching and accessing metadata * to/from arbitrary objects. * * @author Rob Harrop * @since 2.0 */ public interface AttributeAccessor { /** * Set the attribute defined by name to the supplied value. * If value is null, the attribute is {@link #removeAttribute removed}. *

In general, users should take care to prevent overlaps with other * metadata attributes by using fully-qualified names, perhaps using * class or package names as prefix. * @param name the unique attribute key * @param value the attribute value to be attached */ void setAttribute(String name, Object value); /** * Get the value of the attribute identified by name. * Return null if the attribute doesn't exist. * @param name the unique attribute key * @return the current value of the attribute, if any */ Object getAttribute(String name); /** * Remove the attribute identified by name and return its value. * Return null if no attribute under name is found. * @param name the unique attribute key * @return the last value of the attribute, if any */ Object removeAttribute(String name); /** * Return true if the attribute identified by name exists. * Otherwise return false. * @param name the unique attribute key */ boolean hasAttribute(String name); /** * Return the names of all attributes. */ String[] attributeNames(); } ././@LongLink0000000000000000000000000000020100000000000011556 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/DecoratingClassLoader.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000613311623223526033347 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core; import java.util.HashSet; import java.util.Set; import org.springframework.util.Assert; /** * Base class for decorating ClassLoaders such as {@link OverridingClassLoader} * and {@link org.springframework.instrument.classloading.ShadowingClassLoader}, * providing common handling of excluded packages and classes. * * @author Juergen Hoeller * @author Rod Johnson * @since 2.5.2 */ public abstract class DecoratingClassLoader extends ClassLoader { private final Set excludedPackages = new HashSet(); private final Set excludedClasses = new HashSet(); private final Object exclusionMonitor = new Object(); /** * Create a new DecoratingClassLoader with no parent ClassLoader. */ public DecoratingClassLoader() { } /** * Create a new DecoratingClassLoader using the given parent ClassLoader * for delegation. */ public DecoratingClassLoader(ClassLoader parent) { super(parent); } /** * Add a package name to exclude from decoration (e.g. overriding). *

Any class whose fully-qualified name starts with the name registered * here will be handled by the parent ClassLoader in the usual fashion. * @param packageName the package name to exclude */ public void excludePackage(String packageName) { Assert.notNull(packageName, "Package name must not be null"); synchronized (this.exclusionMonitor) { this.excludedPackages.add(packageName); } } /** * Add a class name to exclude from decoration (e.g. overriding). *

Any class name registered here will be handled by the parent * ClassLoader in the usual fashion. * @param className the class name to exclude */ public void excludeClass(String className) { Assert.notNull(className, "Class name must not be null"); synchronized (this.exclusionMonitor) { this.excludedClasses.add(className); } } /** * Determine whether the specified class is excluded from decoration * by this class loader. *

The default implementation checks against excluded packages and classes. * @param className the class name to check * @return whether the specified class is eligible * @see #excludePackage * @see #excludeClass */ protected boolean isExcluded(String className) { synchronized (this.exclusionMonitor) { if (this.excludedClasses.contains(className)) { return true; } for (String packageName : this.excludedPackages) { if (className.startsWith(packageName)) { return true; } } } return false; } } ././@LongLink0000000000000000000000000000016600000000000011570 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/JdkVersion.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000736111623223530033346 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core; /** * Internal helper class used to find the Java/JVM version * that Spring is operating on, to allow for automatically * adapting to the present platform's capabilities. * *

Note that Spring requires JVM 1.5 or higher, as of Spring 3.0. * * @author Rod Johnson * @author Juergen Hoeller * @author Rick Evans */ public abstract class JdkVersion { /** * Constant identifying the 1.3.x JVM (JDK 1.3). */ public static final int JAVA_13 = 0; /** * Constant identifying the 1.4.x JVM (J2SE 1.4). */ public static final int JAVA_14 = 1; /** * Constant identifying the 1.5 JVM (Java 5). */ public static final int JAVA_15 = 2; /** * Constant identifying the 1.6 JVM (Java 6). */ public static final int JAVA_16 = 3; /** * Constant identifying the 1.7 JVM (Java 7). */ public static final int JAVA_17 = 4; private static final String javaVersion; private static final int majorJavaVersion; static { javaVersion = System.getProperty("java.version"); // version String should look like "1.4.2_10" if (javaVersion.contains("1.7.")) { majorJavaVersion = JAVA_17; } else if (javaVersion.contains("1.6.")) { majorJavaVersion = JAVA_16; } else { // else leave 1.5 as default (it's either 1.5 or unknown) majorJavaVersion = JAVA_15; } } /** * Return the full Java version string, as returned by * System.getProperty("java.version"). * @return the full Java version string * @see System#getProperty(String) */ public static String getJavaVersion() { return javaVersion; } /** * Get the major version code. This means we can do things like * if (getMajorJavaVersion() < JAVA_14). * @return a code comparable to the JAVA_XX codes in this class * @see #JAVA_13 * @see #JAVA_14 * @see #JAVA_15 * @see #JAVA_16 * @see #JAVA_17 */ public static int getMajorJavaVersion() { return majorJavaVersion; } /** * Convenience method to determine if the current JVM is at least Java 1.4. * @return true if the current JVM is at least Java 1.4 * @deprecated as of Spring 3.0 which requires Java 1.5+ * @see #getMajorJavaVersion() * @see #JAVA_14 * @see #JAVA_15 * @see #JAVA_16 * @see #JAVA_17 */ @Deprecated public static boolean isAtLeastJava14() { return true; } /** * Convenience method to determine if the current JVM is at least * Java 1.5 (Java 5). * @return true if the current JVM is at least Java 1.5 * @deprecated as of Spring 3.0 which requires Java 1.5+ * @see #getMajorJavaVersion() * @see #JAVA_15 * @see #JAVA_16 * @see #JAVA_17 */ @Deprecated public static boolean isAtLeastJava15() { return true; } /** * Convenience method to determine if the current JVM is at least * Java 1.6 (Java 6). * @return true if the current JVM is at least Java 1.6 * @deprecated as of Spring 3.0, in favor of reflective checks for * the specific Java 1.6 classes of interest * @see #getMajorJavaVersion() * @see #JAVA_16 * @see #JAVA_17 */ @Deprecated public static boolean isAtLeastJava16() { return (majorJavaVersion >= JAVA_16); } } ././@LongLink0000000000000000000000000000016200000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/serializer/libspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000755000175000017500000000000011623223530033335 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000020300000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/serializer/package-info.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000041711623223526033346 0ustar drazzibdrazzib /** * * Root package for Spring's serializer interfaces and implementations. * Provides an abstraction over various serialization techniques. * Includes exceptions for serialization and deserialization failures. * */ package org.springframework.core.serializer; ././@LongLink0000000000000000000000000000021000000000000011556 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/serializer/DefaultSerializer.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000313511623223530033341 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.serializer; import java.io.IOException; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.io.Serializable; /** * Serializer that writes an object to an output stream using Java Serialization. * * @author Gary Russell * @author Mark Fisher * @since 3.0.5 */ public class DefaultSerializer implements Serializer { /** * Writes the source object to an output stream using Java Serialization. * The source object must implement {@link Serializable}. */ public void serialize(Object object, OutputStream outputStream) throws IOException { if (!(object instanceof Serializable)) { throw new IllegalArgumentException(getClass().getSimpleName() + " requires a Serializable payload " + "but received an object of type [" + object.getClass().getName() + "]"); } ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream); objectOutputStream.writeObject(object); objectOutputStream.flush(); } } ././@LongLink0000000000000000000000000000020300000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/serializer/Deserializer.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000251411623223530033341 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.serializer; import java.io.IOException; import java.io.InputStream; /** * A strategy interface for converting from data in an InputStream to an Object. * * @author Gary Russell * @author Mark Fisher * @since 3.0.5 */ public interface Deserializer { /** * Read (assemble) an object of type T from the given InputStream. *

Note: Implementations should not close the given InputStream * (or any decorators of that InputStream) but rather leave this up * to the caller. * @param inputStream the input stream * @return the deserialized object * @throws IOException in case of errors reading from the stream */ T deserialize(InputStream inputStream) throws IOException; } ././@LongLink0000000000000000000000000000020100000000000011556 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/serializer/Serializer.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000251011623223526033342 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.serializer; import java.io.IOException; import java.io.OutputStream; /** * A strategy interface for streaming an object to an OutputStream. * * @author Gary Russell * @author Mark Fisher * @since 3.0.5 */ public interface Serializer { /** * Write an object of type T to the given OutputStream. *

Note: Implementations should not close the given OutputStream * (or any decorators of that OutputStream) but rather leave this up * to the caller. * @param object the object to serialize * @param outputStream the output stream * @throws IOException in case of errors writing to the stream */ void serialize(T object, OutputStream outputStream) throws IOException; } ././@LongLink0000000000000000000000000000017200000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/serializer/support/libspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000755000175000017500000000000011623223530033335 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000022300000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/serializer/support/SerializingConverter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000414711623223526033352 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.serializer.support; import java.io.ByteArrayOutputStream; import org.springframework.core.convert.converter.Converter; import org.springframework.core.serializer.DefaultSerializer; import org.springframework.core.serializer.Serializer; import org.springframework.util.Assert; /** * A {@Link Converter} that delegates to a {@link org.springframework.core.serializer.Serializer} * to convert an object to a byte array. * * @author Gary Russell * @author Mark Fisher * @since 3.0.5 */ public class SerializingConverter implements Converter { private final Serializer serializer; /** * Create a default SerializingConverter that uses standard Java serialization. */ public SerializingConverter() { this.serializer = new DefaultSerializer(); } /** * Create a SerializingConverter that delegates to the provided {@link Serializer} */ public SerializingConverter(Serializer serializer) { Assert.notNull(serializer, "Serializer must not be null"); this.serializer = serializer; } /** * Serializes the source object and returns the byte array result. */ public byte[] convert(Object source) { ByteArrayOutputStream byteStream = new ByteArrayOutputStream(128); try { this.serializer.serialize(source, byteStream); return byteStream.toByteArray(); } catch (Throwable ex) { throw new SerializationFailedException("Failed to serialize object using " + this.serializer.getClass().getSimpleName(), ex); } } } ././@LongLink0000000000000000000000000000021300000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/serializer/support/package-info.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000026111623223530033336 0ustar drazzibdrazzib /** * * Support classes for Spring's serializer abstraction. * Includes adapters to the Converter SPI. * */ package org.springframework.core.serializer.support; ././@LongLink0000000000000000000000000000023300000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/serializer/support/SerializationFailedException.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000320111623223526033340 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.serializer.support; import org.springframework.core.NestedRuntimeException; /** * Wrapper for the native IOException (or similar) when a * {@link org.springframework.core.serializer.Serializer} or * {@link org.springframework.core.serializer.Deserializer} failed. * Thrown by {@link SerializingConverter} and {@link DeserializingConverter}. * * @author Gary Russell * @author Juergen Hoeller * @since 3.0.5 */ public class SerializationFailedException extends NestedRuntimeException { /** * Construct a SerializationException with the specified detail message. * @param message the detail message */ public SerializationFailedException(String message) { super(message); } /** * Construct a SerializationException with the specified detail message * and nested exception. * @param message the detail message * @param cause the nested exception */ public SerializationFailedException(String message, Throwable cause) { super(message, cause); } } ././@LongLink0000000000000000000000000000022500000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/serializer/support/DeserializingConverter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000416611623223530033346 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.serializer.support; import java.io.ByteArrayInputStream; import org.springframework.core.convert.converter.Converter; import org.springframework.core.serializer.DefaultDeserializer; import org.springframework.core.serializer.Deserializer; import org.springframework.util.Assert; /** * A {@link Converter} that delegates to a {@link org.springframework.core.serializer.Deserializer} * to convert data in a byte array to an object. * * @author Gary Russell * @author Mark Fisher * @since 3.0.5 */ public class DeserializingConverter implements Converter { private final Deserializer deserializer; /** * Create a default DeserializingConverter that uses standard Java deserialization. */ public DeserializingConverter() { this.deserializer = new DefaultDeserializer(); } /** * Create a DeserializingConverter that delegates to the provided {@link Deserializer}. */ public DeserializingConverter(Deserializer deserializer) { Assert.notNull(deserializer, "Deserializer must not be null"); this.deserializer = deserializer; } public Object convert(byte[] source) { ByteArrayInputStream byteStream = new ByteArrayInputStream(source); try { return this.deserializer.deserialize(byteStream); } catch (Throwable ex) { throw new SerializationFailedException("Failed to deserialize payload. " + "Is the byte array a result of corresponding serialization for " + this.deserializer.getClass().getSimpleName() + "?", ex); } } } ././@LongLink0000000000000000000000000000021200000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/serializer/DefaultDeserializer.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000261211623223530033340 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.serializer; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import org.springframework.core.NestedIOException; /** * Deserializer that reads an input stream using Java Serialization. * * @author Gary Russell * @author Mark Fisher * @since 3.0.5 */ public class DefaultDeserializer implements Deserializer { /** * Reads the input stream and deserializes into an object. */ public Object deserialize(InputStream inputStream) throws IOException { ObjectInputStream objectInputStream = new ObjectInputStream(inputStream); try { return objectInputStream.readObject(); } catch (ClassNotFoundException ex) { throw new NestedIOException("Failed to deserialize object type", ex); } } } ././@LongLink0000000000000000000000000000020000000000000011555 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/BridgeMethodResolver.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000002060711623223530033344 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core; import java.lang.reflect.GenericArrayType; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import org.springframework.util.ClassUtils; import org.springframework.util.ReflectionUtils; /** * Helper for resolving synthetic {@link Method#isBridge bridge Methods} to the * {@link Method} being bridged. * *

Given a synthetic {@link Method#isBridge bridge Method} returns the {@link Method} * being bridged. A bridge method may be created by the compiler when extending a * parameterized type whose methods have parameterized arguments. During runtime * invocation the bridge {@link Method} may be invoked and/or used via reflection. * When attempting to locate annotations on {@link Method Methods}, it is wise to check * for bridge {@link Method Methods} as appropriate and find the bridged {@link Method}. * *

See * The Java Language Specification for more details on the use of bridge methods. * * @author Rob Harrop * @author Juergen Hoeller * @since 2.0 */ public abstract class BridgeMethodResolver { /** * Find the original method for the supplied {@link Method bridge Method}. *

It is safe to call this method passing in a non-bridge {@link Method} instance. * In such a case, the supplied {@link Method} instance is returned directly to the caller. * Callers are not required to check for bridging before calling this method. * @param bridgeMethod the method to introspect * @return the original method (either the bridged method or the passed-in method * if no more specific one could be found) */ public static Method findBridgedMethod(Method bridgeMethod) { if (bridgeMethod == null || !bridgeMethod.isBridge()) { return bridgeMethod; } // Gather all methods with matching name and parameter size. List candidateMethods = new ArrayList(); Method[] methods = ReflectionUtils.getAllDeclaredMethods(bridgeMethod.getDeclaringClass()); for (Method candidateMethod : methods) { if (isBridgedCandidateFor(candidateMethod, bridgeMethod)) { candidateMethods.add(candidateMethod); } } // Now perform simple quick check. if (candidateMethods.size() == 1) { return candidateMethods.get(0); } // Search for candidate match. Method bridgedMethod = searchCandidates(candidateMethods, bridgeMethod); if (bridgedMethod != null) { // Bridged method found... return bridgedMethod; } else { // A bridge method was passed in but we couldn't find the bridged method. // Let's proceed with the passed-in method and hope for the best... return bridgeMethod; } } /** * Searches for the bridged method in the given candidates. * @param candidateMethods the List of candidate Methods * @param bridgeMethod the bridge method * @return the bridged method, or null if none found */ private static Method searchCandidates(List candidateMethods, Method bridgeMethod) { if (candidateMethods.isEmpty()) { return null; } Map typeParameterMap = GenericTypeResolver.getTypeVariableMap(bridgeMethod.getDeclaringClass()); Method previousMethod = null; boolean sameSig = true; for (Method candidateMethod : candidateMethods) { if (isBridgeMethodFor(bridgeMethod, candidateMethod, typeParameterMap)) { return candidateMethod; } else if (previousMethod != null) { sameSig = sameSig && Arrays.equals(candidateMethod.getGenericParameterTypes(), previousMethod.getGenericParameterTypes()); } previousMethod = candidateMethod; } return (sameSig ? candidateMethods.get(0) : null); } /** * Returns true if the supplied 'candidateMethod' can be * consider a validate candidate for the {@link Method} that is {@link Method#isBridge() bridged} * by the supplied {@link Method bridge Method}. This method performs inexpensive * checks and can be used quickly filter for a set of possible matches. */ private static boolean isBridgedCandidateFor(Method candidateMethod, Method bridgeMethod) { return (!candidateMethod.isBridge() && !candidateMethod.equals(bridgeMethod) && candidateMethod.getName().equals(bridgeMethod.getName()) && candidateMethod.getParameterTypes().length == bridgeMethod.getParameterTypes().length); } /** * Determines whether or not the bridge {@link Method} is the bridge for the * supplied candidate {@link Method}. */ static boolean isBridgeMethodFor(Method bridgeMethod, Method candidateMethod, Map typeVariableMap) { if (isResolvedTypeMatch(candidateMethod, bridgeMethod, typeVariableMap)) { return true; } Method method = findGenericDeclaration(bridgeMethod); return (method != null && isResolvedTypeMatch(method, candidateMethod, typeVariableMap)); } /** * Searches for the generic {@link Method} declaration whose erased signature * matches that of the supplied bridge method. * @throws IllegalStateException if the generic declaration cannot be found */ private static Method findGenericDeclaration(Method bridgeMethod) { // Search parent types for method that has same signature as bridge. Class superclass = bridgeMethod.getDeclaringClass().getSuperclass(); while (!Object.class.equals(superclass)) { Method method = searchForMatch(superclass, bridgeMethod); if (method != null && !method.isBridge()) { return method; } superclass = superclass.getSuperclass(); } // Search interfaces. Class[] interfaces = ClassUtils.getAllInterfacesForClass(bridgeMethod.getDeclaringClass()); for (Class ifc : interfaces) { Method method = searchForMatch(ifc, bridgeMethod); if (method != null && !method.isBridge()) { return method; } } return null; } /** * Returns true if the {@link Type} signature of both the supplied * {@link Method#getGenericParameterTypes() generic Method} and concrete {@link Method} * are equal after resolving all {@link TypeVariable TypeVariables} using the supplied * TypeVariable Map, otherwise returns false. */ private static boolean isResolvedTypeMatch( Method genericMethod, Method candidateMethod, Map typeVariableMap) { Type[] genericParameters = genericMethod.getGenericParameterTypes(); Class[] candidateParameters = candidateMethod.getParameterTypes(); if (genericParameters.length != candidateParameters.length) { return false; } for (int i = 0; i < genericParameters.length; i++) { Type genericParameter = genericParameters[i]; Class candidateParameter = candidateParameters[i]; if (candidateParameter.isArray()) { // An array type: compare the component type. Type rawType = GenericTypeResolver.getRawType(genericParameter, typeVariableMap); if (rawType instanceof GenericArrayType) { if (!candidateParameter.getComponentType().equals( GenericTypeResolver.resolveType(((GenericArrayType) rawType).getGenericComponentType(), typeVariableMap))) { return false; } break; } } // A non-array type: compare the type itself. Class resolvedParameter = GenericTypeResolver.resolveType(genericParameter, typeVariableMap); if (!candidateParameter.equals(resolvedParameter)) { return false; } } return true; } /** * If the supplied {@link Class} has a declared {@link Method} whose signature matches * that of the supplied {@link Method}, then this matching {@link Method} is returned, * otherwise null is returned. */ private static Method searchForMatch(Class type, Method bridgeMethod) { return ReflectionUtils.findMethod(type, bridgeMethod.getName(), bridgeMethod.getParameterTypes()); } } ././@LongLink0000000000000000000000000000020200000000000011557 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/NestedRuntimeException.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000001013711623223526033346 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core; /** * Handy class for wrapping runtime Exceptions with a root cause. * *

This class is abstract to force the programmer to extend * the class. getMessage will include nested exception * information; printStackTrace and other like methods will * delegate to the wrapped exception, if any. * *

The similarity between this class and the {@link NestedCheckedException} * class is unavoidable, as Java forces these two classes to have different * superclasses (ah, the inflexibility of concrete inheritance!). * * @author Rod Johnson * @author Juergen Hoeller * @see #getMessage * @see #printStackTrace * @see NestedCheckedException */ public abstract class NestedRuntimeException extends RuntimeException { /** Use serialVersionUID from Spring 1.2 for interoperability */ private static final long serialVersionUID = 5439915454935047936L; static { // Eagerly load the NestedExceptionUtils class to avoid classloader deadlock // issues on OSGi when calling getMessage(). Reported by Don Brown; SPR-5607. NestedExceptionUtils.class.getName(); } /** * Construct a NestedRuntimeException with the specified detail message. * @param msg the detail message */ public NestedRuntimeException(String msg) { super(msg); } /** * Construct a NestedRuntimeException with the specified detail message * and nested exception. * @param msg the detail message * @param cause the nested exception */ public NestedRuntimeException(String msg, Throwable cause) { super(msg, cause); } /** * Return the detail message, including the message from the nested exception * if there is one. */ @Override public String getMessage() { return NestedExceptionUtils.buildMessage(super.getMessage(), getCause()); } /** * Retrieve the innermost cause of this exception, if any. * @return the innermost exception, or null if none * @since 2.0 */ public Throwable getRootCause() { Throwable rootCause = null; Throwable cause = getCause(); while (cause != null && cause != rootCause) { rootCause = cause; cause = cause.getCause(); } return rootCause; } /** * Retrieve the most specific cause of this exception, that is, * either the innermost cause (root cause) or this exception itself. *

Differs from {@link #getRootCause()} in that it falls back * to the present exception if there is no root cause. * @return the most specific cause (never null) * @since 2.0.3 */ public Throwable getMostSpecificCause() { Throwable rootCause = getRootCause(); return (rootCause != null ? rootCause : this); } /** * Check whether this exception contains an exception of the given type: * either it is of the given class itself or it contains a nested cause * of the given type. * @param exType the exception type to look for * @return whether there is a nested exception of the specified type */ public boolean contains(Class exType) { if (exType == null) { return false; } if (exType.isInstance(this)) { return true; } Throwable cause = getCause(); if (cause == this) { return false; } if (cause instanceof NestedRuntimeException) { return ((NestedRuntimeException) cause).contains(exType); } else { while (cause != null) { if (exType.isInstance(cause)) { return true; } if (cause.getCause() == cause) { break; } cause = cause.getCause(); } return false; } } } ././@LongLink0000000000000000000000000000017600000000000011571 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/ControlFlowFactory.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000650611623223526033353 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core; import java.io.PrintWriter; import java.io.StringWriter; import org.springframework.util.Assert; /** * Static factory to conceal the automatic choice of the ControlFlow * implementation class. * *

This implementation always uses the efficient Java 1.4 StackTraceElement * mechanism for analyzing control flows. * * @author Rod Johnson * @author Juergen Hoeller * @since 02.02.2004 */ public abstract class ControlFlowFactory { /** * Return an appropriate {@link ControlFlow} instance. */ public static ControlFlow createControlFlow() { return new Jdk14ControlFlow(); } /** * Utilities for cflow-style pointcuts. Note that such pointcuts are * 5-10 times more expensive to evaluate than other pointcuts, as they require * analysis of the stack trace (through constructing a new throwable). * However, they are useful in some cases. *

This implementation uses the StackTraceElement class introduced in Java 1.4. * @see java.lang.StackTraceElement */ static class Jdk14ControlFlow implements ControlFlow { private StackTraceElement[] stack; public Jdk14ControlFlow() { this.stack = new Throwable().getStackTrace(); } /** * Searches for class name match in a StackTraceElement. */ public boolean under(Class clazz) { Assert.notNull(clazz, "Class must not be null"); String className = clazz.getName(); for (int i = 0; i < stack.length; i++) { if (this.stack[i].getClassName().equals(className)) { return true; } } return false; } /** * Searches for class name match plus method name match * in a StackTraceElement. */ public boolean under(Class clazz, String methodName) { Assert.notNull(clazz, "Class must not be null"); Assert.notNull(methodName, "Method name must not be null"); String className = clazz.getName(); for (int i = 0; i < this.stack.length; i++) { if (this.stack[i].getClassName().equals(className) && this.stack[i].getMethodName().equals(methodName)) { return true; } } return false; } /** * Leave it up to the caller to decide what matches. * Caller must understand stack trace format, so there's less abstraction. */ public boolean underToken(String token) { if (token == null) { return false; } StringWriter sw = new StringWriter(); new Throwable().printStackTrace(new PrintWriter(sw)); String stackTrace = sw.toString(); return stackTrace.indexOf(token) != -1; } @Override public String toString() { StringBuilder sb = new StringBuilder("Jdk14ControlFlow: "); for (int i = 0; i < this.stack.length; i++) { if (i > 0) { sb.append("\n\t@"); } sb.append(this.stack[i]); } return sb.toString(); } } } ././@LongLink0000000000000000000000000000017700000000000011572 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/InfrastructureProxy.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000314111623223526033343 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core; /** * Interface to be implemented by transparent resource proxies that need to be * considered as equal to the underlying resource, for example for consistent * lookup key comparisons. Note that this interface does imply such special * semantics and does not constitute a general-purpose mixin! * *

Such wrappers will automatically be unwrapped for key comparisons in * {@link org.springframework.transaction.support.TransactionSynchronizationManager}. * *

Only fully transparent proxies, e.g. for redirection or service lookups, * are supposed to implement this interface. Proxies that decorate the target * object with new behavior, such as AOP proxies, do not qualify here! * * @author Juergen Hoeller * @since 2.5.4 * @see org.springframework.transaction.support.TransactionSynchronizationManager */ public interface InfrastructureProxy { /** * Return the underlying resource (never null). */ Object getWrappedObject(); } ././@LongLink0000000000000000000000000000015400000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/type/libspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000755000175000017500000000000011623223530033335 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000017600000000000011571 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/type/ClassMetadata.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000521011623223530033335 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.type; /** * Interface that defines abstract metadata of a specific class, * in a form that does not require that class to be loaded yet. * * @author Juergen Hoeller * @since 2.5 * @see StandardClassMetadata * @see org.springframework.core.type.classreading.MetadataReader#getClassMetadata() * @see AnnotationMetadata */ public interface ClassMetadata { /** * Return the name of the underlying class. */ String getClassName(); /** * Return whether the underlying class represents an interface. */ boolean isInterface(); /** * Return whether the underlying class is marked as abstract. */ boolean isAbstract(); /** * Return whether the underlying class represents a concrete class, * i.e. neither an interface nor an abstract class. */ boolean isConcrete(); /** * Return whether the underlying class is marked as 'final'. */ boolean isFinal(); /** * Determine whether the underlying class is independent, * i.e. whether it is a top-level class or a nested class * (static inner class) that can be constructed independent * from an enclosing class. */ boolean isIndependent(); /** * Return whether the underlying class has an enclosing class * (i.e. the underlying class is an inner/nested class or * a local class within a method). *

If this method returns false, then the * underlying class is a top-level class. */ boolean hasEnclosingClass(); /** * Return the name of the enclosing class of the underlying class, * or null if the underlying class is a top-level class. */ String getEnclosingClassName(); /** * Return whether the underlying class has a super class. */ boolean hasSuperClass(); /** * Return the name of the super class of the underlying class, * or null if there is no super class defined. */ String getSuperClassName(); /** * Return the name of all interfaces that the underlying class * implements, or an empty array if there are none. */ String[] getInterfaceNames(); } ././@LongLink0000000000000000000000000000017500000000000011570 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/type/package-info.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000014711623223526033346 0ustar drazzibdrazzib /** * * Core support package for type introspection. * */ package org.springframework.core.type; ././@LongLink0000000000000000000000000000020700000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/type/StandardMethodMetadata.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000631311623223526033347 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.type; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Map; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.util.Assert; /** * {@link MethodMetadata} implementation that uses standard reflection * to introspect a given Method. * * @author Juergen Hoeller * @author Mark Pollack * @author Chris Beams * @since 3.0 */ public class StandardMethodMetadata implements MethodMetadata { private final Method introspectedMethod; /** * Create a new StandardMethodMetadata wrapper for the given Method. * @param introspectedMethod the Method to introspect */ public StandardMethodMetadata(Method introspectedMethod) { Assert.notNull(introspectedMethod, "Method must not be null"); this.introspectedMethod = introspectedMethod; } /** * Return the underlying Method. */ public final Method getIntrospectedMethod() { return this.introspectedMethod; } public String getMethodName() { return this.introspectedMethod.getName(); } public String getDeclaringClassName() { return this.introspectedMethod.getDeclaringClass().getName(); } public boolean isStatic() { return Modifier.isStatic(this.introspectedMethod.getModifiers()); } public boolean isFinal() { return Modifier.isFinal(this.introspectedMethod.getModifiers()); } public boolean isOverridable() { return (!isStatic() && !isFinal() && !Modifier.isPrivate(this.introspectedMethod.getModifiers())); } public boolean isAnnotated(String annotationType) { Annotation[] anns = this.introspectedMethod.getAnnotations(); for (Annotation ann : anns) { if (ann.annotationType().getName().equals(annotationType)) { return true; } for (Annotation metaAnn : ann.annotationType().getAnnotations()) { if (metaAnn.annotationType().getName().equals(annotationType)) { return true; } } } return false; } public Map getAnnotationAttributes(String annotationType) { Annotation[] anns = this.introspectedMethod.getAnnotations(); for (Annotation ann : anns) { if (ann.annotationType().getName().equals(annotationType)) { return AnnotationUtils.getAnnotationAttributes(ann, true); } for (Annotation metaAnn : ann.annotationType().getAnnotations()) { if (metaAnn.annotationType().getName().equals(annotationType)) { return AnnotationUtils.getAnnotationAttributes(metaAnn, true); } } } return null; } } ././@LongLink0000000000000000000000000000020600000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/type/StandardClassMetadata.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000547311623223526033355 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.type; import java.lang.reflect.Modifier; import org.springframework.util.Assert; /** * {@link ClassMetadata} implementation that uses standard reflection * to introspect a given Class. * * @author Juergen Hoeller * @since 2.5 */ public class StandardClassMetadata implements ClassMetadata { private final Class introspectedClass; /** * Create a new StandardClassMetadata wrapper for the given Class. * @param introspectedClass the Class to introspect */ public StandardClassMetadata(Class introspectedClass) { Assert.notNull(introspectedClass, "Class must not be null"); this.introspectedClass = introspectedClass; } /** * Return the underlying Class. */ public final Class getIntrospectedClass() { return this.introspectedClass; } public String getClassName() { return this.introspectedClass.getName(); } public boolean isInterface() { return this.introspectedClass.isInterface(); } public boolean isAbstract() { return Modifier.isAbstract(this.introspectedClass.getModifiers()); } public boolean isConcrete() { return !(isInterface() || isAbstract()); } public boolean isFinal() { return Modifier.isFinal(this.introspectedClass.getModifiers()); } public boolean isIndependent() { return (!hasEnclosingClass() || (this.introspectedClass.getDeclaringClass() != null && Modifier.isStatic(this.introspectedClass.getModifiers()))); } public boolean hasEnclosingClass() { return (this.introspectedClass.getEnclosingClass() != null); } public String getEnclosingClassName() { Class enclosingClass = this.introspectedClass.getEnclosingClass(); return (enclosingClass != null ? enclosingClass.getName() : null); } public boolean hasSuperClass() { return (this.introspectedClass.getSuperclass() != null); } public String getSuperClassName() { Class superClass = this.introspectedClass.getSuperclass(); return (superClass != null ? superClass.getName() : null); } public String[] getInterfaceNames() { Class[] ifcs = this.introspectedClass.getInterfaces(); String[] ifcNames = new String[ifcs.length]; for (int i = 0; i < ifcs.length; i++) { ifcNames[i] = ifcs[i].getName(); } return ifcNames; } } ././@LongLink0000000000000000000000000000020300000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/type/AnnotationMetadata.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000001110411623223526033341 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.type; import java.util.Map; import java.util.Set; /** * Interface that defines abstract access to the annotations of a specific * class, in a form that does not require that class to be loaded yet. * * @author Juergen Hoeller * @author Mark Fisher * @since 2.5 * @see StandardAnnotationMetadata * @see org.springframework.core.type.classreading.MetadataReader#getAnnotationMetadata() */ public interface AnnotationMetadata extends ClassMetadata { /** * Return the names of all annotation types defined on the underlying class. * @return the annotation type names */ Set getAnnotationTypes(); /** * Return the names of all meta-annotation types defined on the * given annotation type of the underlying class. * @param annotationType the meta-annotation type to look for * @return the meta-annotation type names */ Set getMetaAnnotationTypes(String annotationType); /** * Determine whether the underlying class has an annotation of the given * type defined. * @param annotationType the annotation type to look for * @return whether a matching annotation is defined */ boolean hasAnnotation(String annotationType); /** * Determine whether the underlying class has an annotation that * is itself annotated with the meta-annotation of the given type. * @param metaAnnotationType the meta-annotation type to look for * @return whether a matching meta-annotation is defined */ boolean hasMetaAnnotation(String metaAnnotationType); /** * Determine whether the underlying class has an annotation or * meta-annotation of the given type defined. *

This is equivalent to a "hasAnnotation || hasMetaAnnotation" * check. If this method returns true, then * {@link #getAnnotationAttributes} will return a non-null Map. * @param annotationType the annotation type to look for * @return whether a matching annotation is defined */ boolean isAnnotated(String annotationType); /** * Retrieve the attributes of the annotation of the given type, * if any (i.e. if defined on the underlying class, as direct * annotation or as meta-annotation). * @param annotationType the annotation type to look for * @return a Map of attributes, with the attribute name as key (e.g. "value") * and the defined attribute value as Map value. This return value will be * null if no matching annotation is defined. */ Map getAnnotationAttributes(String annotationType); /** * Retrieve the attributes of the annotation of the given type, * if any (i.e. if defined on the underlying class, as direct * annotation or as meta-annotation). * @param annotationType the annotation type to look for * @param classValuesAsString whether to convert class references to String * class names for exposure as values in the returned Map, instead of Class * references which might potentially have to be loaded first * @return a Map of attributes, with the attribute name as key (e.g. "value") * and the defined attribute value as Map value. This return value will be * null if no matching annotation is defined. */ Map getAnnotationAttributes(String annotationType, boolean classValuesAsString); /** * Determine whether the underlying class has any methods that are * annotated (or meta-annotated) with the given annotation type. */ boolean hasAnnotatedMethods(String annotationType); /** * Retrieve the method metadata for all methods that are annotated * (or meta-annotated) with the given annotation type. *

For any returned method, {@link MethodMetadata#isAnnotated} will * return true for the given annotation type. * @param annotationType the annotation type to look for * @return a Set of {@link MethodMetadata} for methods that have a matching * annotation. The return value will be an empty set if no methods match * the annotation type. */ Set getAnnotatedMethods(String annotationType); } ././@LongLink0000000000000000000000000000017700000000000011572 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/type/MethodMetadata.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000463111623223526033350 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.type; import java.util.Map; /** * Interface that defines abstract access to the annotations of a specific * class, in a form that does not require that class to be loaded yet. * * @author Juergen Hoeller * @author Mark Pollack * @author Chris Beams * @since 3.0 * @see StandardMethodMetadata * @see AnnotationMetadata#getAnnotatedMethods */ public interface MethodMetadata { /** * Return the name of the method. */ String getMethodName(); /** * Return the fully-qualified name of the class that declares this method. */ public String getDeclaringClassName(); /** * Return whether the underlying method is declared as 'static'. */ boolean isStatic(); /** * Return whether the underlying method is marked as 'final'. */ boolean isFinal(); /** * Return whether the underlying method is overridable, * i.e. not marked as static, final or private. */ boolean isOverridable(); /** * Determine whether the underlying method has an annotation or * meta-annotation of the given type defined. * @param annotationType the annotation type to look for * @return whether a matching annotation is defined */ boolean isAnnotated(String annotationType); /** * Retrieve the attributes of the annotation of the given type, * if any (i.e. if defined on the underlying method, as direct * annotation or as meta-annotation). * @param annotationType the annotation type to look for * @return a Map of attributes, with the attribute name as key (e.g. "value") * and the defined attribute value as Map value. This return value will be * null if no matching annotation is defined. */ Map getAnnotationAttributes(String annotationType); } ././@LongLink0000000000000000000000000000016300000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/type/filter/libspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000755000175000017500000000000011623223530033335 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000020200000000000011557 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/type/filter/TypeFilter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000311211623223530033334 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.type.filter; import java.io.IOException; import org.springframework.core.type.classreading.MetadataReader; import org.springframework.core.type.classreading.MetadataReaderFactory; /** * Base interface for type filters using a * {@link org.springframework.core.type.classreading.MetadataReader}. * * @author Costin Leau * @author Juergen Hoeller * @author Mark Fisher * @since 2.5 */ public interface TypeFilter { /** * Determine whether this filter matches for the class described by * the given metadata. * @param metadataReader the metadata reader for the target class * @param metadataReaderFactory a factory for obtaining metadata readers * for other classes (such as superclasses and interfaces) * @return whether this filter matches * @throws IOException in case of I/O failure when reading metadata */ boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException; } ././@LongLink0000000000000000000000000000020400000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/type/filter/package-info.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000021011623223526033335 0ustar drazzibdrazzib /** * * Core support package for type filtering (e.g. for classpath scanning). * */ package org.springframework.core.type.filter; ././@LongLink0000000000000000000000000000022600000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/type/filter/AbstractClassTestingTypeFilter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000323211623223530033337 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.type.filter; import java.io.IOException; import org.springframework.core.type.ClassMetadata; import org.springframework.core.type.classreading.MetadataReaderFactory; import org.springframework.core.type.classreading.MetadataReader; /** * Type filter that exposes a * {@link org.springframework.core.type.ClassMetadata} object * to subclasses, for class testing purposes. * * @author Rod Johnson * @author Costin Leau * @author Juergen Hoeller * @since 2.5 * @see #match(org.springframework.core.type.ClassMetadata) */ public abstract class AbstractClassTestingTypeFilter implements TypeFilter { public final boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException { return match(metadataReader.getClassMetadata()); } /** * Determine a match based on the given ClassMetadata object. * @param metadata the ClassMetadata object * @return whether this filter matches on the specified type */ protected abstract boolean match(ClassMetadata metadata); } ././@LongLink0000000000000000000000000000021400000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/type/filter/AssignableTypeFilter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000402111623223530033334 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.type.filter; /** * A simple filter which matches classes that are assignable to a given type. * * @author Rod Johnson * @author Mark Fisher * @author Ramnivas Laddad * @since 2.5 */ public class AssignableTypeFilter extends AbstractTypeHierarchyTraversingFilter { private final Class targetType; /** * Create a new AssignableTypeFilter for the given type. * @param targetType the type to match */ public AssignableTypeFilter(Class targetType) { super(true, true); this.targetType = targetType; } @Override protected boolean matchClassName(String className) { return this.targetType.getName().equals(className); } @Override protected Boolean matchSuperClass(String superClassName) { return matchTargetType(superClassName); } @Override protected Boolean matchInterface(String interfaceName) { return matchTargetType(interfaceName); } protected Boolean matchTargetType(String typeName) { if (this.targetType.getName().equals(typeName)) { return true; } else if (Object.class.getName().equals(typeName)) { return Boolean.FALSE; } else if (typeName.startsWith("java.")) { try { Class clazz = getClass().getClassLoader().loadClass(typeName); return Boolean.valueOf(this.targetType.isAssignableFrom(clazz)); } catch (ClassNotFoundException ex) { // Class not found - can't determine a match that way. } } return null; } } ././@LongLink0000000000000000000000000000023500000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/type/filter/AbstractTypeHierarchyTraversingFilter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000753511623223530033351 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.type.filter; import java.io.IOException; import org.springframework.core.type.ClassMetadata; import org.springframework.core.type.classreading.MetadataReaderFactory; import org.springframework.core.type.classreading.MetadataReader; /** * Type filter that is aware of traversing over hierarchy. * *

This filter is useful when matching needs to be made based on potentially the * whole class/interface hierarchy. The algorithm employed uses succeed-fast * strategy i.e. if at anytime a match is declared, no further processing is * carried out. * * @author Ramnivas Laddad * @author Mark Fisher * @since 2.5 */ public abstract class AbstractTypeHierarchyTraversingFilter implements TypeFilter { private final boolean considerInherited; private final boolean considerInterfaces; protected AbstractTypeHierarchyTraversingFilter(boolean considerInherited, boolean considerInterfaces) { this.considerInherited = considerInherited; this.considerInterfaces = considerInterfaces; } public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException { // This method optimizes avoiding unnecessary creation of ClassReaders // as well as visiting over those readers. if (matchSelf(metadataReader)) { return true; } ClassMetadata metadata = metadataReader.getClassMetadata(); if (matchClassName(metadata.getClassName())) { return true; } if (!this.considerInherited) { return false; } if (metadata.hasSuperClass()) { // Optimization to avoid creating ClassReader for super class. Boolean superClassMatch = matchSuperClass(metadata.getSuperClassName()); if (superClassMatch != null) { if (superClassMatch.booleanValue()) { return true; } } else { // Need to read super class to determine a match... if (match(metadata.getSuperClassName(), metadataReaderFactory)) { return true; } } } if (!this.considerInterfaces) { return false; } for (String ifc : metadata.getInterfaceNames()) { // Optimization to avoid creating ClassReader for super class Boolean interfaceMatch = matchInterface(ifc); if (interfaceMatch != null) { if (interfaceMatch.booleanValue()) { return true; } } else { // Need to read interface to determine a match... if (match(ifc, metadataReaderFactory)) { return true; } } } return false; } private boolean match(String className, MetadataReaderFactory metadataReaderFactory) throws IOException { return match(metadataReaderFactory.getMetadataReader(className), metadataReaderFactory); } /** * Override this to match self characteristics alone. Typically, * the implementation will use a visitor to extract information * to perform matching. */ protected boolean matchSelf(MetadataReader metadataReader) { return false; } /** * Override this to match on type name. */ protected boolean matchClassName(String className) { return false; } /** * Override this to match on super type name. */ protected Boolean matchSuperClass(String superClassName) { return null; } /** * Override this to match on interface type name. */ protected Boolean matchInterface(String interfaceNames) { return null; } } ././@LongLink0000000000000000000000000000021400000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/type/filter/AnnotationTypeFilter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000600611623223530033341 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.type.filter; import java.lang.annotation.Annotation; import java.lang.annotation.Inherited; import org.springframework.core.type.AnnotationMetadata; import org.springframework.core.type.classreading.MetadataReader; /** * A simple filter which matches classes with a given annotation, * checking inherited annotations as well. * *

The matching logic mirrors that of Class.isAnnotationPresent(). * * @author Mark Fisher * @author Ramnivas Laddad * @author Juergen Hoeller * @since 2.5 */ public class AnnotationTypeFilter extends AbstractTypeHierarchyTraversingFilter { private final Class annotationType; private final boolean considerMetaAnnotations; /** * Create a new AnnotationTypeFilter for the given annotation type. * This filter will also match meta-annotations. To disable the * meta-annotation matching, use the constructor that accepts a * 'considerMetaAnnotations' argument. * @param annotationType the annotation type to match */ public AnnotationTypeFilter(Class annotationType) { this(annotationType, true); } /** * Create a new AnnotationTypeFilter for the given annotation type. * @param annotationType the annotation type to match * @param considerMetaAnnotations whether to also match on meta-annotations */ public AnnotationTypeFilter(Class annotationType, boolean considerMetaAnnotations) { super(annotationType.isAnnotationPresent(Inherited.class), false); this.annotationType = annotationType; this.considerMetaAnnotations = considerMetaAnnotations; } @Override protected boolean matchSelf(MetadataReader metadataReader) { AnnotationMetadata metadata = metadataReader.getAnnotationMetadata(); return metadata.hasAnnotation(this.annotationType.getName()) || (this.considerMetaAnnotations && metadata.hasMetaAnnotation(this.annotationType.getName())); } @Override protected Boolean matchSuperClass(String superClassName) { if (Object.class.getName().equals(superClassName)) { return Boolean.FALSE; } else if (superClassName.startsWith("java.")) { try { Class clazz = getClass().getClassLoader().loadClass(superClassName); return (clazz.getAnnotation(this.annotationType) != null); } catch (ClassNotFoundException ex) { // Class not found - can't determine a match that way. } } return null; } } ././@LongLink0000000000000000000000000000021100000000000011557 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/type/filter/AspectJTypeFilter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000475211623223526033354 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.type.filter; import java.io.IOException; import org.aspectj.bridge.IMessageHandler; import org.aspectj.weaver.ResolvedType; import org.aspectj.weaver.World; import org.aspectj.weaver.bcel.BcelWorld; import org.aspectj.weaver.patterns.Bindings; import org.aspectj.weaver.patterns.FormalBinding; import org.aspectj.weaver.patterns.IScope; import org.aspectj.weaver.patterns.PatternParser; import org.aspectj.weaver.patterns.SimpleScope; import org.aspectj.weaver.patterns.TypePattern; import org.springframework.core.type.classreading.MetadataReaderFactory; import org.springframework.core.type.classreading.MetadataReader; /** * Type filter that uses AspectJ type pattern for matching. * *

A critical implementation details of this type filter is that it does not * load the class being examined to match with a type pattern. * * @author Ramnivas Laddad * @author Juergen Hoeller * @since 2.5 */ public class AspectJTypeFilter implements TypeFilter { private final World world; private final TypePattern typePattern; public AspectJTypeFilter(String typePatternExpression, ClassLoader classLoader) { this.world = new BcelWorld(classLoader, IMessageHandler.THROW, null); this.world.setBehaveInJava5Way(true); PatternParser patternParser = new PatternParser(typePatternExpression); TypePattern typePattern = patternParser.parseTypePattern(); typePattern.resolve(this.world); IScope scope = new SimpleScope(this.world, new FormalBinding[0]); this.typePattern = typePattern.resolveBindings(scope, Bindings.NONE, false, false); } public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException { String className = metadataReader.getClassMetadata().getClassName(); ResolvedType resolvedType = this.world.resolve(className); return this.typePattern.matchesStatically(resolvedType); } } ././@LongLink0000000000000000000000000000021600000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/type/filter/RegexPatternTypeFilter.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000247711623223526033356 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.type.filter; import java.util.regex.Pattern; import org.springframework.core.type.ClassMetadata; import org.springframework.util.Assert; /** * A simple filter for matching a fully-qualified class name with a regex {@link Pattern}. * * @author Mark Fisher * @author Juergen Hoeller * @since 2.5 */ public class RegexPatternTypeFilter extends AbstractClassTestingTypeFilter { private final Pattern pattern; public RegexPatternTypeFilter(Pattern pattern) { Assert.notNull(pattern, "Pattern must not be null"); this.pattern = pattern; } @Override protected boolean match(ClassMetadata metadata) { return this.pattern.matcher(metadata.getClassName()).matches(); } } ././@LongLink0000000000000000000000000000017100000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/type/classreading/libspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000755000175000017500000000000011623223530033335 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000024000000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/type/classreading/AnnotationAttributesReadingVisitor.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000001241311623223530033340 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.type.classreading; import java.lang.annotation.Annotation; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; import org.springframework.asm.AnnotationVisitor; import org.springframework.asm.Type; import org.springframework.asm.commons.EmptyVisitor; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.util.ObjectUtils; import org.springframework.util.ReflectionUtils; /** * ASM visitor which looks for the annotations defined on a class or method. * * @author Juergen Hoeller * @since 3.0 */ final class AnnotationAttributesReadingVisitor implements AnnotationVisitor { private final String annotationType; private final Map> attributesMap; private final Map> metaAnnotationMap; private final ClassLoader classLoader; private final Map localAttributes = new LinkedHashMap(); public AnnotationAttributesReadingVisitor( String annotationType, Map> attributesMap, Map> metaAnnotationMap, ClassLoader classLoader) { this.annotationType = annotationType; this.attributesMap = attributesMap; this.metaAnnotationMap = metaAnnotationMap; this.classLoader = classLoader; } public void visit(String name, Object value) { this.localAttributes.put(name, value); } public void visitEnum(String name, String desc, String value) { Object valueToUse = value; try { Class enumType = this.classLoader.loadClass(Type.getType(desc).getClassName()); Field enumConstant = ReflectionUtils.findField(enumType, value); if (enumConstant != null) { valueToUse = enumConstant.get(null); } } catch (Exception ex) { // Class not found - can't resolve class reference in annotation attribute. } this.localAttributes.put(name, valueToUse); } public AnnotationVisitor visitAnnotation(String name, String desc) { return new EmptyVisitor(); } public AnnotationVisitor visitArray(final String attrName) { return new AnnotationVisitor() { public void visit(String name, Object value) { Object newValue = value; Object existingValue = localAttributes.get(attrName); if (existingValue != null) { newValue = ObjectUtils.addObjectToArray((Object[]) existingValue, newValue); } else { Object[] newArray = (Object[]) Array.newInstance(newValue.getClass(), 1); newArray[0] = newValue; newValue = newArray; } localAttributes.put(attrName, newValue); } public void visitEnum(String name, String desc, String value) { } public AnnotationVisitor visitAnnotation(String name, String desc) { return new EmptyVisitor(); } public AnnotationVisitor visitArray(String name) { return new EmptyVisitor(); } public void visitEnd() { } }; } public void visitEnd() { this.attributesMap.put(this.annotationType, this.localAttributes); try { Class annotationClass = this.classLoader.loadClass(this.annotationType); // Check declared default values of attributes in the annotation type. Method[] annotationAttributes = annotationClass.getMethods(); for (Method annotationAttribute : annotationAttributes) { String attributeName = annotationAttribute.getName(); Object defaultValue = annotationAttribute.getDefaultValue(); if (defaultValue != null && !this.localAttributes.containsKey(attributeName)) { this.localAttributes.put(attributeName, defaultValue); } } // Register annotations that the annotation type is annotated with. Set metaAnnotationTypeNames = new LinkedHashSet(); for (Annotation metaAnnotation : annotationClass.getAnnotations()) { metaAnnotationTypeNames.add(metaAnnotation.annotationType().getName()); if (!this.attributesMap.containsKey(metaAnnotation.annotationType().getName())) { this.attributesMap.put(metaAnnotation.annotationType().getName(), AnnotationUtils.getAnnotationAttributes(metaAnnotation, true)); } for (Annotation metaMetaAnnotation : metaAnnotation.annotationType().getAnnotations()) { metaAnnotationTypeNames.add(metaMetaAnnotation.annotationType().getName()); } } if (this.metaAnnotationMap != null) { this.metaAnnotationMap.put(this.annotationType, metaAnnotationTypeNames); } } catch (ClassNotFoundException ex) { // Class not found - can't determine meta-annotations. } } } ././@LongLink0000000000000000000000000000023100000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/type/classreading/SimpleMetadataReaderFactory.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000532011623223526033344 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.type.classreading; import java.io.IOException; import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; import org.springframework.util.ClassUtils; /** * Simple implementation of the {@link MetadataReaderFactory} interface, * creating a new ASM {@link org.springframework.asm.ClassReader} for every request. * * @author Juergen Hoeller * @since 2.5 */ public class SimpleMetadataReaderFactory implements MetadataReaderFactory { private final ResourceLoader resourceLoader; /** * Create a new SimpleMetadataReaderFactory for the default class loader. */ public SimpleMetadataReaderFactory() { this.resourceLoader = new DefaultResourceLoader(); } /** * Create a new SimpleMetadataReaderFactory for the given resource loader. * @param resourceLoader the Spring ResourceLoader to use * (also determines the ClassLoader to use) */ public SimpleMetadataReaderFactory(ResourceLoader resourceLoader) { this.resourceLoader = (resourceLoader != null ? resourceLoader : new DefaultResourceLoader()); } /** * Create a new SimpleMetadataReaderFactory for the given class loader. * @param classLoader the ClassLoader to use */ public SimpleMetadataReaderFactory(ClassLoader classLoader) { this.resourceLoader = (classLoader != null ? new DefaultResourceLoader(classLoader) : new DefaultResourceLoader()); } /** * Return the ResourceLoader that this MetadataReaderFactory has been * constructed with. */ public final ResourceLoader getResourceLoader() { return this.resourceLoader; } public MetadataReader getMetadataReader(String className) throws IOException { String resourcePath = ResourceLoader.CLASSPATH_URL_PREFIX + ClassUtils.convertClassNameToResourcePath(className) + ClassUtils.CLASS_FILE_SUFFIX; return getMetadataReader(this.resourceLoader.getResource(resourcePath)); } public MetadataReader getMetadataReader(Resource resource) throws IOException { return new SimpleMetadataReader(resource, this.resourceLoader.getClassLoader()); } } ././@LongLink0000000000000000000000000000021200000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/type/classreading/package-info.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000021211623223530033332 0ustar drazzibdrazzib /** * * Support classes for reading annotation and class-level metadata. * */ package org.springframework.core.type.classreading; ././@LongLink0000000000000000000000000000021400000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/type/classreading/MetadataReader.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000255211623223526033350 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.type.classreading; import org.springframework.core.io.Resource; import org.springframework.core.type.AnnotationMetadata; import org.springframework.core.type.ClassMetadata; /** * Simple facade for accessing class metadata, * as read by an ASM {@link org.springframework.asm.ClassReader}. * * @author Juergen Hoeller * @since 2.5 */ public interface MetadataReader { /** * Return the resource reference for the class file. */ Resource getResource(); /** * Read basic class metadata for the underlying class. */ ClassMetadata getClassMetadata(); /** * Read full annotation metadata for the underlying class, * including metadata for annotated methods. */ AnnotationMetadata getAnnotationMetadata(); } ././@LongLink0000000000000000000000000000022200000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/type/classreading/SimpleMetadataReader.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000427111623223530033343 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.type.classreading; import java.io.IOException; import java.io.InputStream; import org.springframework.asm.ClassReader; import org.springframework.core.io.Resource; import org.springframework.core.type.AnnotationMetadata; import org.springframework.core.type.ClassMetadata; /** * {@link MetadataReader} implementation based on an ASM * {@link org.springframework.asm.ClassReader}. * *

Package-visible in order to allow for repackaging the ASM library * without effect on users of the core.type package. * * @author Juergen Hoeller * @author Costin Leau * @since 2.5 */ final class SimpleMetadataReader implements MetadataReader { private final Resource resource; private final ClassMetadata classMetadata; private final AnnotationMetadata annotationMetadata; SimpleMetadataReader(Resource resource, ClassLoader classLoader) throws IOException { InputStream is = resource.getInputStream(); ClassReader classReader = null; try { classReader = new ClassReader(is); } finally { is.close(); } AnnotationMetadataReadingVisitor visitor = new AnnotationMetadataReadingVisitor(classLoader); classReader.accept(visitor, true); this.annotationMetadata = visitor; // (since AnnotationMetadataReader extends ClassMetadataReadingVisitor) this.classMetadata = visitor; this.resource = resource; } public Resource getResource() { return this.resource; } public ClassMetadata getClassMetadata() { return this.classMetadata; } public AnnotationMetadata getAnnotationMetadata() { return this.annotationMetadata; } }././@LongLink0000000000000000000000000000023200000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/type/classreading/MethodMetadataReadingVisitor.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000602111623223530033336 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.type.classreading; import java.util.LinkedHashMap; import java.util.Map; import org.springframework.asm.AnnotationVisitor; import org.springframework.asm.MethodAdapter; import org.springframework.asm.Opcodes; import org.springframework.asm.Type; import org.springframework.asm.commons.EmptyVisitor; import org.springframework.core.type.MethodMetadata; import org.springframework.util.MultiValueMap; /** * ASM method visitor which looks for the annotations defined on the method, * exposing them through the {@link org.springframework.core.type.MethodMetadata} * interface. * * @author Juergen Hoeller * @author Mark Pollack * @author Costin Leau * @since 3.0 */ final class MethodMetadataReadingVisitor extends MethodAdapter implements MethodMetadata { private final String name; private final int access; private String declaringClassName; private final ClassLoader classLoader; private final MultiValueMap methodMetadataMap; private final Map> attributeMap = new LinkedHashMap>(2); public MethodMetadataReadingVisitor(String name, int access, String declaringClassName, ClassLoader classLoader, MultiValueMap methodMetadataMap) { super(new EmptyVisitor()); this.name = name; this.access = access; this.declaringClassName = declaringClassName; this.classLoader = classLoader; this.methodMetadataMap = methodMetadataMap; } @Override public AnnotationVisitor visitAnnotation(final String desc, boolean visible) { String className = Type.getType(desc).getClassName(); methodMetadataMap.add(className, this); return new AnnotationAttributesReadingVisitor(className, this.attributeMap, null, this.classLoader); } public String getMethodName() { return this.name; } public boolean isStatic() { return ((this.access & Opcodes.ACC_STATIC) != 0); } public boolean isFinal() { return ((this.access & Opcodes.ACC_FINAL) != 0); } public boolean isOverridable() { return (!isStatic() && !isFinal() && ((this.access & Opcodes.ACC_PRIVATE) == 0)); } public boolean isAnnotated(String annotationType) { return this.attributeMap.containsKey(annotationType); } public Map getAnnotationAttributes(String annotationType) { return this.attributeMap.get(annotationType); } public String getDeclaringClassName() { return this.declaringClassName; } }././@LongLink0000000000000000000000000000022300000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/type/classreading/MetadataReaderFactory.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000323611623223530033343 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.type.classreading; import java.io.IOException; import org.springframework.core.io.Resource; /** * Factory interface for {@link MetadataReader} instances. * Allows for caching a MetadataReader per original resource. * * @author Juergen Hoeller * @since 2.5 * @see SimpleMetadataReaderFactory * @see CachingMetadataReaderFactory */ public interface MetadataReaderFactory { /** * Obtain a MetadataReader for the given class name. * @param className the class name (to be resolved to a ".class" file) * @return a holder for the ClassReader instance (never null) * @throws IOException in case of I/O failure */ MetadataReader getMetadataReader(String className) throws IOException; /** * Obtain a MetadataReader for the given resource. * @param resource the resource (pointing to a ".class" file) * @return a holder for the ClassReader instance (never null) * @throws IOException in case of I/O failure */ MetadataReader getMetadataReader(Resource resource) throws IOException; } ././@LongLink0000000000000000000000000000023100000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/type/classreading/ClassMetadataReadingVisitor.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000001032511623223526033345 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.type.classreading; import org.springframework.asm.AnnotationVisitor; import org.springframework.asm.Attribute; import org.springframework.asm.ClassVisitor; import org.springframework.asm.FieldVisitor; import org.springframework.asm.MethodVisitor; import org.springframework.asm.Opcodes; import org.springframework.asm.commons.EmptyVisitor; import org.springframework.core.type.ClassMetadata; import org.springframework.util.ClassUtils; /** * ASM class visitor which looks only for the class name and implemented types, * exposing them through the {@link org.springframework.core.type.ClassMetadata} * interface. * * @author Rod Johnson * @author Costin Leau * @author Mark Fisher * @author Ramnivas Laddad * @since 2.5 */ class ClassMetadataReadingVisitor implements ClassVisitor, ClassMetadata { private String className; private boolean isInterface; private boolean isAbstract; private boolean isFinal; private String enclosingClassName; private boolean independentInnerClass; private String superClassName; private String[] interfaces; public void visit(int version, int access, String name, String signature, String supername, String[] interfaces) { this.className = ClassUtils.convertResourcePathToClassName(name); this.isInterface = ((access & Opcodes.ACC_INTERFACE) != 0); this.isAbstract = ((access & Opcodes.ACC_ABSTRACT) != 0); this.isFinal = ((access & Opcodes.ACC_FINAL) != 0); if (supername != null) { this.superClassName = ClassUtils.convertResourcePathToClassName(supername); } this.interfaces = new String[interfaces.length]; for (int i = 0; i < interfaces.length; i++) { this.interfaces[i] = ClassUtils.convertResourcePathToClassName(interfaces[i]); } } public void visitOuterClass(String owner, String name, String desc) { this.enclosingClassName = ClassUtils.convertResourcePathToClassName(owner); } public void visitInnerClass(String name, String outerName, String innerName, int access) { if (outerName != null && this.className.equals(ClassUtils.convertResourcePathToClassName(name))) { this.enclosingClassName = ClassUtils.convertResourcePathToClassName(outerName); this.independentInnerClass = ((access & Opcodes.ACC_STATIC) != 0); } } public void visitSource(String source, String debug) { // no-op } public AnnotationVisitor visitAnnotation(String desc, boolean visible) { // no-op return new EmptyVisitor(); } public void visitAttribute(Attribute attr) { // no-op } public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) { // no-op return new EmptyVisitor(); } public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { // no-op return new EmptyVisitor(); } public void visitEnd() { // no-op } public String getClassName() { return this.className; } public boolean isInterface() { return this.isInterface; } public boolean isAbstract() { return this.isAbstract; } public boolean isConcrete() { return !(this.isInterface || this.isAbstract); } public boolean isFinal() { return this.isFinal; } public boolean isIndependent() { return (this.enclosingClassName == null || this.independentInnerClass); } public boolean hasEnclosingClass() { return (this.enclosingClassName != null); } public String getEnclosingClassName() { return this.enclosingClassName; } public boolean hasSuperClass() { return (this.superClassName != null); } public String getSuperClassName() { return this.superClassName; } public String[] getInterfaceNames() { return this.interfaces; } } ././@LongLink0000000000000000000000000000023200000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/type/classreading/CachingMetadataReaderFactory.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000605611623223530033346 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.type.classreading; import java.io.IOException; import java.util.LinkedHashMap; import java.util.Map; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; /** * Caching implementation of the {@link MetadataReaderFactory} interface, * caching {@link MetadataReader} per Spring {@link Resource} handle * (i.e. per ".class" file). * * @author Juergen Hoeller * @author Costin Leau * @since 2.5 */ public class CachingMetadataReaderFactory extends SimpleMetadataReaderFactory { /** Default maximum number of entries for the MetadataReader cache: 256 */ public static final int DEFAULT_CACHE_LIMIT = 256; private volatile int cacheLimit = DEFAULT_CACHE_LIMIT; private final Map classReaderCache = new LinkedHashMap(DEFAULT_CACHE_LIMIT, 0.75f, true) { @Override protected boolean removeEldestEntry(Map.Entry eldest) { return size() > getCacheLimit(); } }; /** * Create a new CachingMetadataReaderFactory for the default class loader. */ public CachingMetadataReaderFactory() { super(); } /** * Create a new CachingMetadataReaderFactory for the given resource loader. * @param resourceLoader the Spring ResourceLoader to use * (also determines the ClassLoader to use) */ public CachingMetadataReaderFactory(ResourceLoader resourceLoader) { super(resourceLoader); } /** * Create a new CachingMetadataReaderFactory for the given class loader. * @param classLoader the ClassLoader to use */ public CachingMetadataReaderFactory(ClassLoader classLoader) { super(classLoader); } /** * Specify the maximum number of entries for the MetadataReader cache. * Default is 256. */ public void setCacheLimit(int cacheLimit) { this.cacheLimit = cacheLimit; } /** * Return the maximum number of entries for the MetadataReader cache. */ public int getCacheLimit() { return this.cacheLimit; } @Override public MetadataReader getMetadataReader(Resource resource) throws IOException { if (getCacheLimit() <= 0) { return super.getMetadataReader(resource); } synchronized (this.classReaderCache) { MetadataReader metadataReader = this.classReaderCache.get(resource); if (metadataReader == null) { metadataReader = super.getMetadataReader(resource); this.classReaderCache.put(resource, metadataReader); } return metadataReader; } } } ././@LongLink0000000000000000000000000000023600000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/type/classreading/AnnotationMetadataReadingVisitor.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000001226311623223530033343 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.type.classreading; import java.util.Collection; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.springframework.asm.AnnotationVisitor; import org.springframework.asm.MethodVisitor; import org.springframework.asm.Type; import org.springframework.core.type.AnnotationMetadata; import org.springframework.core.type.MethodMetadata; import org.springframework.util.CollectionUtils; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; /** * ASM class visitor which looks for the class name and implemented types as * well as for the annotations defined on the class, exposing them through * the {@link org.springframework.core.type.AnnotationMetadata} interface. * * @author Juergen Hoeller * @author Mark Fisher * @author Costin Leau * @since 2.5 */ final class AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisitor implements AnnotationMetadata { private final ClassLoader classLoader; private final Set annotationSet = new LinkedHashSet(); private final Map> metaAnnotationMap = new LinkedHashMap>(4); private final Map> attributeMap = new LinkedHashMap>(4); private final MultiValueMap methodMetadataMap = new LinkedMultiValueMap(); public AnnotationMetadataReadingVisitor(ClassLoader classLoader) { this.classLoader = classLoader; } @Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { return new MethodMetadataReadingVisitor(name, access, this.getClassName(), this.classLoader, this.methodMetadataMap); } @Override public AnnotationVisitor visitAnnotation(final String desc, boolean visible) { String className = Type.getType(desc).getClassName(); this.annotationSet.add(className); return new AnnotationAttributesReadingVisitor(className, this.attributeMap, this.metaAnnotationMap, this.classLoader); } public Set getAnnotationTypes() { return this.annotationSet; } public Set getMetaAnnotationTypes(String annotationType) { return this.metaAnnotationMap.get(annotationType); } public boolean hasAnnotation(String annotationType) { return this.annotationSet.contains(annotationType); } public boolean hasMetaAnnotation(String metaAnnotationType) { Collection> allMetaTypes = this.metaAnnotationMap.values(); for (Set metaTypes : allMetaTypes) { if (metaTypes.contains(metaAnnotationType)) { return true; } } return false; } public boolean isAnnotated(String annotationType) { return this.attributeMap.containsKey(annotationType); } public Map getAnnotationAttributes(String annotationType) { return getAnnotationAttributes(annotationType, false); } public Map getAnnotationAttributes(String annotationType, boolean classValuesAsString) { Map raw = this.attributeMap.get(annotationType); if (raw == null) { return null; } Map result = new LinkedHashMap(raw.size()); for (Map.Entry entry : raw.entrySet()) { try { Object value = entry.getValue(); if (value instanceof Type) { value = (classValuesAsString ? ((Type) value).getClassName() : this.classLoader.loadClass(((Type) value).getClassName())); } else if (value instanceof Type[]) { Type[] array = (Type[]) value; Object[] convArray = (classValuesAsString ? new String[array.length] : new Class[array.length]); for (int i = 0; i < array.length; i++) { convArray[i] = (classValuesAsString ? array[i].getClassName() : this.classLoader.loadClass(array[i].getClassName())); } value = convArray; } result.put(entry.getKey(), value); } catch (Exception ex) { // Class not found - can't resolve class reference in annotation attribute. } } return result; } public boolean hasAnnotatedMethods(String annotationType) { return this.methodMetadataMap.containsKey(annotationType); } public Set getAnnotatedMethods(String annotationType) { List list = this.methodMetadataMap.get(annotationType); if (CollectionUtils.isEmpty(list)) { return new LinkedHashSet(0); } Set annotatedMethods = new LinkedHashSet(list.size()); annotatedMethods.addAll(list); return annotatedMethods; } } ././@LongLink0000000000000000000000000000021300000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/type/StandardAnnotationMetadata.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000001267511623223530033352 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.type; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; import org.springframework.core.annotation.AnnotationUtils; /** * {@link AnnotationMetadata} implementation that uses standard reflection * to introspect a given Class. * * @author Juergen Hoeller * @author Mark Fisher * @since 2.5 */ public class StandardAnnotationMetadata extends StandardClassMetadata implements AnnotationMetadata { /** * Create a new StandardAnnotationMetadata wrapper for the given Class. * @param introspectedClass the Class to introspect */ public StandardAnnotationMetadata(Class introspectedClass) { super(introspectedClass); } public Set getAnnotationTypes() { Set types = new LinkedHashSet(); Annotation[] anns = getIntrospectedClass().getAnnotations(); for (Annotation ann : anns) { types.add(ann.annotationType().getName()); } return types; } public Set getMetaAnnotationTypes(String annotationType) { Annotation[] anns = getIntrospectedClass().getAnnotations(); for (Annotation ann : anns) { if (ann.annotationType().getName().equals(annotationType)) { Set types = new LinkedHashSet(); Annotation[] metaAnns = ann.annotationType().getAnnotations(); for (Annotation metaAnn : metaAnns) { types.add(metaAnn.annotationType().getName()); for (Annotation metaMetaAnn : metaAnn.annotationType().getAnnotations()) { types.add(metaMetaAnn.annotationType().getName()); } } return types; } } return null; } public boolean hasAnnotation(String annotationType) { Annotation[] anns = getIntrospectedClass().getAnnotations(); for (Annotation ann : anns) { if (ann.annotationType().getName().equals(annotationType)) { return true; } } return false; } public boolean hasMetaAnnotation(String annotationType) { Annotation[] anns = getIntrospectedClass().getAnnotations(); for (Annotation ann : anns) { Annotation[] metaAnns = ann.annotationType().getAnnotations(); for (Annotation metaAnn : metaAnns) { if (metaAnn.annotationType().getName().equals(annotationType)) { return true; } for (Annotation metaMetaAnn : metaAnn.annotationType().getAnnotations()) { if (metaMetaAnn.annotationType().getName().equals(annotationType)) { return true; } } } } return false; } public boolean isAnnotated(String annotationType) { Annotation[] anns = getIntrospectedClass().getAnnotations(); for (Annotation ann : anns) { if (ann.annotationType().getName().equals(annotationType)) { return true; } for (Annotation metaAnn : ann.annotationType().getAnnotations()) { if (metaAnn.annotationType().getName().equals(annotationType)) { return true; } } } return false; } public Map getAnnotationAttributes(String annotationType) { return getAnnotationAttributes(annotationType, false); } public Map getAnnotationAttributes(String annotationType, boolean classValuesAsString) { Annotation[] anns = getIntrospectedClass().getAnnotations(); for (Annotation ann : anns) { if (ann.annotationType().getName().equals(annotationType)) { return AnnotationUtils.getAnnotationAttributes(ann, classValuesAsString); } for (Annotation metaAnn : ann.annotationType().getAnnotations()) { if (metaAnn.annotationType().getName().equals(annotationType)) { return AnnotationUtils.getAnnotationAttributes(metaAnn, classValuesAsString); } } } return null; } public boolean hasAnnotatedMethods(String annotationType) { Method[] methods = getIntrospectedClass().getDeclaredMethods(); for (Method method : methods) { for (Annotation ann : method.getAnnotations()) { if (ann.annotationType().getName().equals(annotationType)) { return true; } else { for (Annotation metaAnn : ann.annotationType().getAnnotations()) { if (metaAnn.annotationType().getName().equals(annotationType)) { return true; } } } } } return false; } public Set getAnnotatedMethods(String annotationType) { Method[] methods = getIntrospectedClass().getDeclaredMethods(); Set annotatedMethods = new LinkedHashSet(); for (Method method : methods) { for (Annotation ann : method.getAnnotations()) { if (ann.annotationType().getName().equals(annotationType)) { annotatedMethods.add(new StandardMethodMetadata(method)); break; } else { for (Annotation metaAnn : ann.annotationType().getAnnotations()) { if (metaAnn.annotationType().getName().equals(annotationType)) { annotatedMethods.add(new StandardMethodMetadata(method)); break; } } } } } return annotatedMethods; } } ././@LongLink0000000000000000000000000000015200000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/io/libspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000755000175000017500000000000011623223530033335 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000017300000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/io/package-info.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000020711623223526033343 0ustar drazzibdrazzib /** * * Generic abstraction for (file-based) resources, used throughout the framework. * */ package org.springframework.core.io; ././@LongLink0000000000000000000000000000017600000000000011571 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/io/ContextResource.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000273311623223526033351 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.io; /** * Extended interface for a resource that is loaded from an enclosing * 'context', e.g. from a {@link javax.servlet.ServletContext} or a * {@link javax.portlet.PortletContext} but also from plain classpath paths * or relative file system paths (specified without an explicit prefix, * hence applying relative to the local {@link ResourceLoader}'s context). * * @author Juergen Hoeller * @since 2.5 * @see org.springframework.web.context.support.ServletContextResource * @see org.springframework.web.portlet.context.PortletContextResource */ public interface ContextResource extends Resource { /** * Return the path within the enclosing 'context'. *

This is typically path relative to a context-specific root directory, * e.g. a ServletContext root or a PortletContext root. */ String getPathWithinContext(); } ././@LongLink0000000000000000000000000000020400000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/io/DefaultResourceLoader.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000001135611623223530033345 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.io; import java.net.MalformedURLException; import java.net.URL; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.StringUtils; /** * Default implementation of the {@link ResourceLoader} interface. * Used by {@link ResourceEditor}, and serves as base class for * {@link org.springframework.context.support.AbstractApplicationContext}. * Can also be used standalone. * *

Will return a {@link UrlResource} if the location value is a URL, * and a {@link ClassPathResource} if it is a non-URL path or a * "classpath:" pseudo-URL. * * @author Juergen Hoeller * @since 10.03.2004 * @see FileSystemResourceLoader * @see org.springframework.context.support.ClassPathXmlApplicationContext */ public class DefaultResourceLoader implements ResourceLoader { private ClassLoader classLoader; /** * Create a new DefaultResourceLoader. *

ClassLoader access will happen using the thread context class loader * at the time of this ResourceLoader's initialization. * @see java.lang.Thread#getContextClassLoader() */ public DefaultResourceLoader() { this.classLoader = ClassUtils.getDefaultClassLoader(); } /** * Create a new DefaultResourceLoader. * @param classLoader the ClassLoader to load class path resources with, or null * for using the thread context class loader at the time of actual resource access */ public DefaultResourceLoader(ClassLoader classLoader) { this.classLoader = classLoader; } /** * Specify the ClassLoader to load class path resources with, or null * for using the thread context class loader at the time of actual resource access. *

The default is that ClassLoader access will happen using the thread context * class loader at the time of this ResourceLoader's initialization. */ public void setClassLoader(ClassLoader classLoader) { this.classLoader = classLoader; } /** * Return the ClassLoader to load class path resources with. *

Will get passed to ClassPathResource's constructor for all * ClassPathResource objects created by this resource loader. * @see ClassPathResource */ public ClassLoader getClassLoader() { return (this.classLoader != null ? this.classLoader : ClassUtils.getDefaultClassLoader()); } public Resource getResource(String location) { Assert.notNull(location, "Location must not be null"); if (location.startsWith(CLASSPATH_URL_PREFIX)) { return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader()); } else { try { // Try to parse the location as a URL... URL url = new URL(location); return new UrlResource(url); } catch (MalformedURLException ex) { // No URL -> resolve as resource path. return getResourceByPath(location); } } } /** * Return a Resource handle for the resource at the given path. *

The default implementation supports class path locations. This should * be appropriate for standalone implementations but can be overridden, * e.g. for implementations targeted at a Servlet container. * @param path the path to the resource * @return the corresponding Resource handle * @see ClassPathResource * @see org.springframework.context.support.FileSystemXmlApplicationContext#getResourceByPath * @see org.springframework.web.context.support.XmlWebApplicationContext#getResourceByPath */ protected Resource getResourceByPath(String path) { return new ClassPathContextResource(path, getClassLoader()); } /** * ClassPathResource that explicitly expresses a context-relative path * through implementing the ContextResource interface. */ private static class ClassPathContextResource extends ClassPathResource implements ContextResource { public ClassPathContextResource(String path, ClassLoader classLoader) { super(path, classLoader); } public String getPathWithinContext() { return getPath(); } @Override public Resource createRelative(String relativePath) { String pathToUse = StringUtils.applyRelativePath(getPath(), relativePath); return new ClassPathContextResource(pathToUse, getClassLoader()); } } } ././@LongLink0000000000000000000000000000020100000000000011556 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/io/FileSystemResource.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000001226611623223526033353 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.io; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.URI; import java.net.URL; import org.springframework.util.Assert; import org.springframework.util.StringUtils; /** * {@link Resource} implementation for java.io.File handles. * Obviously supports resolution as File, and also as URL. * * @author Juergen Hoeller * @since 28.12.2003 * @see java.io.File */ public class FileSystemResource extends AbstractResource { private final File file; private final String path; /** * Create a new FileSystemResource from a File handle. *

Note: When building relative resources via {@link #createRelative}, * the relative path will apply at the same directory level: * e.g. new File("C:/dir1"), relative path "dir2" -> "C:/dir2"! * If you prefer to have relative paths built underneath the given root * directory, use the {@link #FileSystemResource(String) constructor with a file path} * to append a trailing slash to the root path: "C:/dir1/", which * indicates this directory as root for all relative paths. * @param file a File handle */ public FileSystemResource(File file) { Assert.notNull(file, "File must not be null"); this.file = file; this.path = StringUtils.cleanPath(file.getPath()); } /** * Create a new FileSystemResource from a file path. *

Note: When building relative resources via {@link #createRelative}, * it makes a difference whether the specified resource base path here * ends with a slash or not. In the case of "C:/dir1/", relative paths * will be built underneath that root: e.g. relative path "dir2" -> * "C:/dir1/dir2". In the case of "C:/dir1", relative paths will apply * at the same directory level: relative path "dir2" -> "C:/dir2". * @param path a file path */ public FileSystemResource(String path) { Assert.notNull(path, "Path must not be null"); this.file = new File(path); this.path = StringUtils.cleanPath(path); } /** * Return the file path for this resource. */ public final String getPath() { return this.path; } /** * This implementation returns whether the underlying file exists. * @see java.io.File#exists() */ @Override public boolean exists() { return this.file.exists(); } /** * This implementation checks whether the underlying file is marked as readable * (and corresponds to an actual file with content, not to a directory). * @see java.io.File#canRead() * @see java.io.File#isDirectory() */ @Override public boolean isReadable() { return (this.file.canRead() && !this.file.isDirectory()); } /** * This implementation opens a FileInputStream for the underlying file. * @see java.io.FileInputStream */ public InputStream getInputStream() throws IOException { return new FileInputStream(this.file); } /** * This implementation returns a URL for the underlying file. * @see java.io.File#toURI() */ @Override public URL getURL() throws IOException { return this.file.toURI().toURL(); } /** * This implementation returns a URI for the underlying file. * @see java.io.File#toURI() */ @Override public URI getURI() throws IOException { return this.file.toURI(); } /** * This implementation returns the underlying File reference. */ @Override public File getFile() { return this.file; } /** * This implementation creates a FileSystemResource, applying the given path * relative to the path of the underlying file of this resource descriptor. * @see org.springframework.util.StringUtils#applyRelativePath(String, String) */ @Override public Resource createRelative(String relativePath) { String pathToUse = StringUtils.applyRelativePath(this.path, relativePath); return new FileSystemResource(pathToUse); } /** * This implementation returns the name of the file. * @see java.io.File#getName() */ @Override public String getFilename() { return this.file.getName(); } /** * This implementation returns a description that includes the absolute * path of the file. * @see java.io.File#getAbsolutePath() */ public String getDescription() { return "file [" + this.file.getAbsolutePath() + "]"; } /** * This implementation compares the underlying File references. */ @Override public boolean equals(Object obj) { return (obj == this || (obj instanceof FileSystemResource && this.path.equals(((FileSystemResource) obj).path))); } /** * This implementation returns the hash code of the underlying File reference. */ @Override public int hashCode() { return this.path.hashCode(); } } ././@LongLink0000000000000000000000000000020000000000000011555 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/io/InputStreamSource.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000413111623223530033336 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.io; import java.io.IOException; import java.io.InputStream; /** * Simple interface for objects that are sources for an {@link InputStream}. * *

This is the base interface for Spring's more extensive {@link Resource} interface. * *

For single-use streams, {@link InputStreamResource} can be used for any * given InputStream. Spring's {@link ByteArrayResource} or any * file-based Resource implementation can be used as a concrete * instance, allowing one to read the underlying content stream multiple times. * This makes this interface useful as an abstract content source for mail * attachments, for example. * * @author Juergen Hoeller * @since 20.01.2004 * @see java.io.InputStream * @see Resource * @see InputStreamResource * @see ByteArrayResource */ public interface InputStreamSource { /** * Return an {@link InputStream}. *

It is expected that each call creates a fresh stream. *

This requirement is particularly important when you consider an API such * as JavaMail, which needs to be able to read the stream multiple times when * creating mail attachments. For such a use case, it is required * that each getInputStream() call returns a fresh stream. * @throws IOException if the stream could not be opened * @see org.springframework.mail.javamail.MimeMessageHelper#addAttachment(String, InputStreamSource) */ InputStream getInputStream() throws IOException; } ././@LongLink0000000000000000000000000000017500000000000011570 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/io/ResourceLoader.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000576511623223526033361 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.io; import org.springframework.util.ResourceUtils; /** * Strategy interface for loading resources (e.. class path or file system * resources). An {@link org.springframework.context.ApplicationContext} * is required to provide this functionality, plus extended * {@link org.springframework.core.io.support.ResourcePatternResolver} support. * *

{@link DefaultResourceLoader} is a standalone implementation that is * usable outside an ApplicationContext, also used by {@link ResourceEditor}. * *

Bean properties of type Resource and Resource array can be populated * from Strings when running in an ApplicationContext, using the particular * context's resource loading strategy. * * @author Juergen Hoeller * @since 10.03.2004 * @see Resource * @see org.springframework.core.io.support.ResourcePatternResolver * @see org.springframework.context.ApplicationContext * @see org.springframework.context.ResourceLoaderAware */ public interface ResourceLoader { /** Pseudo URL prefix for loading from the class path: "classpath:" */ String CLASSPATH_URL_PREFIX = ResourceUtils.CLASSPATH_URL_PREFIX; /** * Return a Resource handle for the specified resource. * The handle should always be a reusable resource descriptor, * allowing for multiple {@link Resource#getInputStream()} calls. *

    *
  • Must support fully qualified URLs, e.g. "file:C:/test.dat". *
  • Must support classpath pseudo-URLs, e.g. "classpath:test.dat". *
  • Should support relative file paths, e.g. "WEB-INF/test.dat". * (This will be implementation-specific, typically provided by an * ApplicationContext implementation.) *
*

Note that a Resource handle does not imply an existing resource; * you need to invoke {@link Resource#exists} to check for existence. * @param location the resource location * @return a corresponding Resource handle * @see #CLASSPATH_URL_PREFIX * @see org.springframework.core.io.Resource#exists * @see org.springframework.core.io.Resource#getInputStream */ Resource getResource(String location); /** * Expose the ClassLoader used by this ResourceLoader. *

Clients which need to access the ClassLoader directly can do so * in a uniform manner with the ResourceLoader, rather than relying * on the thread context ClassLoader. * @return the ClassLoader (never null) */ ClassLoader getClassLoader(); } ././@LongLink0000000000000000000000000000020700000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/io/FileSystemResourceLoader.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000500311623223530033335 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.io; /** * {@link ResourceLoader} implementation that resolves plain paths as * file system resources rather than as class path resources * (the latter is {@link DefaultResourceLoader}'s default strategy). * *

NOTE: Plain paths will always be interpreted as relative * to the current VM working directory, even if they start with a slash. * (This is consistent with the semantics in a Servlet container.) * Use an explicit "file:" prefix to enforce an absolute file path. * *

{@link org.springframework.context.support.FileSystemXmlApplicationContext} * is a full-fledged ApplicationContext implementation that provides * the same resource path resolution strategy. * * @author Juergen Hoeller * @since 1.1.3 * @see DefaultResourceLoader * @see org.springframework.context.support.FileSystemXmlApplicationContext */ public class FileSystemResourceLoader extends DefaultResourceLoader { /** * Resolve resource paths as file system paths. *

Note: Even if a given path starts with a slash, it will get * interpreted as relative to the current VM working directory. * @param path the path to the resource * @return the corresponding Resource handle * @see FileSystemResource * @see org.springframework.web.context.support.ServletContextResourceLoader#getResourceByPath */ @Override protected Resource getResourceByPath(String path) { if (path != null && path.startsWith("/")) { path = path.substring(1); } return new FileSystemContextResource(path); } /** * FileSystemResource that explicitly expresses a context-relative path * through implementing the ContextResource interface. */ private static class FileSystemContextResource extends FileSystemResource implements ContextResource { public FileSystemContextResource(String path) { super(path); } public String getPathWithinContext() { return getPath(); } } } ././@LongLink0000000000000000000000000000016700000000000011571 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/io/VfsUtils.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000002233511623223526033351 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.io; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.URI; import java.net.URL; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.core.NestedIOException; import org.springframework.util.ReflectionUtils; /** * Utility for detecting the JBoss VFS version available in the classpath. * JBoss AS 5+ uses VFS 2.x (package org.jboss.virtual) while * JBoss AS 6+ uses VFS 3.x (package org.jboss.vfs). * *

Thanks go to Marius Bogoevici for the initial patch. * * Note: This is an internal class and should not be used outside the framework. * * @author Costin Leau * @since 3.0.3 */ public abstract class VfsUtils { private static final Log logger = LogFactory.getLog(VfsUtils.class); private static final String VFS2_PKG = "org.jboss.virtual."; private static final String VFS3_PKG = "org.jboss.vfs."; private static final String VFS_NAME = "VFS"; private static enum VFS_VER { V2, V3 } private static VFS_VER version; private static Method VFS_METHOD_GET_ROOT_URL = null; private static Method VFS_METHOD_GET_ROOT_URI = null; private static Method VIRTUAL_FILE_METHOD_EXISTS = null; private static Method VIRTUAL_FILE_METHOD_GET_SIZE; private static Method VIRTUAL_FILE_METHOD_GET_LAST_MODIFIED; private static Method VIRTUAL_FILE_METHOD_GET_CHILD; private static Method VIRTUAL_FILE_METHOD_GET_INPUT_STREAM; private static Method VIRTUAL_FILE_METHOD_TO_URL; private static Method VIRTUAL_FILE_METHOD_TO_URI; private static Method VIRTUAL_FILE_METHOD_GET_NAME; private static Method VIRTUAL_FILE_METHOD_GET_PATH_NAME; protected static Class VIRTUAL_FILE_VISITOR_INTERFACE; protected static Method VIRTUAL_FILE_METHOD_VISIT; private static Method VFS_UTILS_METHOD_IS_NESTED_FILE = null; private static Method VFS_UTILS_METHOD_GET_COMPATIBLE_URI = null; private static Field VISITOR_ATTRIBUTES_FIELD_RECURSE = null; private static Method GET_PHYSICAL_FILE = null; static { ClassLoader loader = VfsUtils.class.getClassLoader(); String pkg; Class vfsClass; // check for JBoss 6 try { vfsClass = loader.loadClass(VFS3_PKG + VFS_NAME); version = VFS_VER.V3; pkg = VFS3_PKG; if (logger.isDebugEnabled()) { logger.debug("JBoss VFS packages for JBoss AS 6 found"); } } catch (ClassNotFoundException ex) { // fallback to JBoss 5 if (logger.isDebugEnabled()) logger.debug("JBoss VFS packages for JBoss AS 6 not found; falling back to JBoss AS 5 packages"); try { vfsClass = loader.loadClass(VFS2_PKG + VFS_NAME); version = VFS_VER.V2; pkg = VFS2_PKG; if (logger.isDebugEnabled()) logger.debug("JBoss VFS packages for JBoss AS 5 found"); } catch (ClassNotFoundException ex1) { logger.error("JBoss VFS packages (for both JBoss AS 5 and 6) were not found - JBoss VFS support disabled"); throw new IllegalStateException("Cannot detect JBoss VFS packages", ex1); } } // cache reflective information try { String methodName = (VFS_VER.V3.equals(version) ? "getChild" : "getRoot"); VFS_METHOD_GET_ROOT_URL = ReflectionUtils.findMethod(vfsClass, methodName, URL.class); VFS_METHOD_GET_ROOT_URI = ReflectionUtils.findMethod(vfsClass, methodName, URI.class); Class virtualFile = loader.loadClass(pkg + "VirtualFile"); VIRTUAL_FILE_METHOD_EXISTS = ReflectionUtils.findMethod(virtualFile, "exists"); VIRTUAL_FILE_METHOD_GET_SIZE = ReflectionUtils.findMethod(virtualFile, "getSize"); VIRTUAL_FILE_METHOD_GET_INPUT_STREAM = ReflectionUtils.findMethod(virtualFile, "openStream"); VIRTUAL_FILE_METHOD_GET_LAST_MODIFIED = ReflectionUtils.findMethod(virtualFile, "getLastModified"); VIRTUAL_FILE_METHOD_TO_URI = ReflectionUtils.findMethod(virtualFile, "toURI"); VIRTUAL_FILE_METHOD_TO_URL = ReflectionUtils.findMethod(virtualFile, "toURL"); VIRTUAL_FILE_METHOD_GET_NAME = ReflectionUtils.findMethod(virtualFile, "getName"); VIRTUAL_FILE_METHOD_GET_PATH_NAME = ReflectionUtils.findMethod(virtualFile, "getPathName"); GET_PHYSICAL_FILE = ReflectionUtils.findMethod(virtualFile, "getPhysicalFile"); methodName = (VFS_VER.V3.equals(version) ? "getChild" : "findChild"); VIRTUAL_FILE_METHOD_GET_CHILD = ReflectionUtils.findMethod(virtualFile, methodName, String.class); Class utilsClass = loader.loadClass(pkg + "VFSUtils"); VFS_UTILS_METHOD_GET_COMPATIBLE_URI = ReflectionUtils.findMethod(utilsClass, "getCompatibleURI", virtualFile); VFS_UTILS_METHOD_IS_NESTED_FILE = ReflectionUtils.findMethod(utilsClass, "isNestedFile", virtualFile); VIRTUAL_FILE_VISITOR_INTERFACE = loader.loadClass(pkg + "VirtualFileVisitor"); VIRTUAL_FILE_METHOD_VISIT = ReflectionUtils.findMethod(virtualFile, "visit", VIRTUAL_FILE_VISITOR_INTERFACE); Class visitorAttributesClass = loader.loadClass(pkg + "VisitorAttributes"); VISITOR_ATTRIBUTES_FIELD_RECURSE = ReflectionUtils.findField(visitorAttributesClass, "RECURSE"); } catch (ClassNotFoundException ex) { throw new IllegalStateException("Could not detect the JBoss VFS infrastructure", ex); } } protected static Object invokeVfsMethod(Method method, Object target, Object... args) throws IOException { try { return method.invoke(target, args); } catch (InvocationTargetException ex) { Throwable targetEx = ex.getTargetException(); if (targetEx instanceof IOException) { throw (IOException) targetEx; } ReflectionUtils.handleInvocationTargetException(ex); } catch (Exception ex) { ReflectionUtils.handleReflectionException(ex); } throw new IllegalStateException("Invalid code path reached"); } static boolean exists(Object vfsResource) { try { return (Boolean) invokeVfsMethod(VIRTUAL_FILE_METHOD_EXISTS, vfsResource); } catch (IOException ex) { return false; } } static boolean isReadable(Object vfsResource) { try { return ((Long) invokeVfsMethod(VIRTUAL_FILE_METHOD_GET_SIZE, vfsResource) > 0); } catch (IOException ex) { return false; } } static long getLastModified(Object vfsResource) throws IOException { return (Long) invokeVfsMethod(VIRTUAL_FILE_METHOD_GET_LAST_MODIFIED, vfsResource); } static InputStream getInputStream(Object vfsResource) throws IOException { return (InputStream) invokeVfsMethod(VIRTUAL_FILE_METHOD_GET_INPUT_STREAM, vfsResource); } static URL getURL(Object vfsResource) throws IOException { return (URL) invokeVfsMethod(VIRTUAL_FILE_METHOD_TO_URL, vfsResource); } static URI getURI(Object vfsResource) throws IOException { return (URI) invokeVfsMethod(VIRTUAL_FILE_METHOD_TO_URI, vfsResource); } static String getName(Object vfsResource) { try { return (String) invokeVfsMethod(VIRTUAL_FILE_METHOD_GET_NAME, vfsResource); } catch (IOException ex) { throw new IllegalStateException("Cannot get resource name", ex); } } static Object getRelative(URL url) throws IOException { return invokeVfsMethod(VFS_METHOD_GET_ROOT_URL, null, url); } static Object getChild(Object vfsResource, String path) throws IOException { return invokeVfsMethod(VIRTUAL_FILE_METHOD_GET_CHILD, vfsResource, path); } static File getFile(Object vfsResource) throws IOException { if (VFS_VER.V2.equals(version)) { if ((Boolean) invokeVfsMethod(VFS_UTILS_METHOD_IS_NESTED_FILE, null, vfsResource)) { throw new IOException("File resolution not supported for nested resource: " + vfsResource); } try { return new File((URI) invokeVfsMethod(VFS_UTILS_METHOD_GET_COMPATIBLE_URI, null, vfsResource)); } catch (Exception ex) { throw new NestedIOException("Failed to obtain File reference for " + vfsResource, ex); } } else { return (File) invokeVfsMethod(GET_PHYSICAL_FILE, vfsResource); } } static Object getRoot(URI url) throws IOException { return invokeVfsMethod(VFS_METHOD_GET_ROOT_URI, null, url); } // protected methods used by the support sub-package protected static Object getRoot(URL url) throws IOException { return invokeVfsMethod(VFS_METHOD_GET_ROOT_URL, null, url); } protected static Object doGetVisitorAttribute() { return ReflectionUtils.getField(VISITOR_ATTRIBUTES_FIELD_RECURSE, null); } protected static String doGetPath(Object resource) { return (String) ReflectionUtils.invokeMethod(VIRTUAL_FILE_METHOD_GET_PATH_NAME, resource); } }././@LongLink0000000000000000000000000000020000000000000011555 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/io/ByteArrayResource.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000631611623223526033352 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.io; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Arrays; /** * {@link Resource} implementation for a given byte array. * Creates a ByteArrayInputStreams for the given byte array. * *

Useful for loading content from any given byte array, * without having to resort to a single-use {@link InputStreamResource}. * Particularly useful for creating mail attachments from local content, * where JavaMail needs to be able to read the stream multiple times. * * @author Juergen Hoeller * @since 1.2.3 * @see java.io.ByteArrayInputStream * @see InputStreamResource * @see org.springframework.mail.javamail.MimeMessageHelper#addAttachment(String, InputStreamSource) */ public class ByteArrayResource extends AbstractResource { private final byte[] byteArray; private final String description; /** * Create a new ByteArrayResource. * @param byteArray the byte array to wrap */ public ByteArrayResource(byte[] byteArray) { this(byteArray, "resource loaded from byte array"); } /** * Create a new ByteArrayResource. * @param byteArray the byte array to wrap * @param description where the byte array comes from */ public ByteArrayResource(byte[] byteArray, String description) { if (byteArray == null) { throw new IllegalArgumentException("Byte array must not be null"); } this.byteArray = byteArray; this.description = (description != null ? description : ""); } /** * Return the underlying byte array. */ public final byte[] getByteArray() { return this.byteArray; } /** * This implementation always returns true. */ @Override public boolean exists() { return true; } /** * This implementation returns a ByteArrayInputStream for the * underlying byte array. * @see java.io.ByteArrayInputStream */ public InputStream getInputStream() throws IOException { return new ByteArrayInputStream(this.byteArray); } /** * This implementation returns the passed-in description, if any. */ public String getDescription() { return this.description; } /** * This implementation compares the underlying byte array. * @see java.util.Arrays#equals(byte[], byte[]) */ @Override public boolean equals(Object obj) { return (obj == this || (obj instanceof ByteArrayResource && Arrays.equals(((ByteArrayResource) obj).byteArray, this.byteArray))); } /** * This implementation returns the hash code based on the * underlying byte array. */ @Override public int hashCode() { return (byte[].class.hashCode() * 29 * this.byteArray.length); } } ././@LongLink0000000000000000000000000000017200000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/io/VfsResource.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000574711623223526033361 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.io; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.URI; import java.net.URL; import org.springframework.core.NestedIOException; import org.springframework.util.Assert; /** * VFS based {@link Resource} implementation. * Supports the corresponding VFS API versions on JBoss AS 5.x as well as 6.x. * * @author Ales Justin * @author Juergen Hoeller * @author Costin Leau * @since 3.0 * @see org.jboss.virtual.VirtualFile * @see org.jboss.vfs.VirtualFile */ public class VfsResource extends AbstractResource { private final Object resource; public VfsResource(Object resources) { Assert.notNull(resources, "VirtualFile must not be null"); this.resource = resources; } public boolean exists() { return VfsUtils.exists(this.resource); } public boolean isReadable() { return VfsUtils.isReadable(this.resource); } public long lastModified() throws IOException { return VfsUtils.getLastModified(this.resource); } public InputStream getInputStream() throws IOException { return VfsUtils.getInputStream(this.resource); } public URL getURL() throws IOException { try { return VfsUtils.getURL(this.resource); } catch (Exception ex) { throw new NestedIOException("Failed to obtain URL for file " + this.resource, ex); } } public URI getURI() throws IOException { try { return VfsUtils.getURI(this.resource); } catch (Exception ex) { throw new NestedIOException("Failed to obtain URI for " + this.resource, ex); } } public File getFile() throws IOException { return VfsUtils.getFile(this.resource); } public Resource createRelative(String relativePath) throws IOException { if (!relativePath.startsWith(".") && relativePath.contains("/")) { try { return new VfsResource(VfsUtils.getChild(this.resource, relativePath)); } catch (IOException ex) { // fall back to getRelative } } return new VfsResource(VfsUtils.getRelative(new URL(getURL(), relativePath))); } public String getFilename() { return VfsUtils.getName(this.resource); } public String getDescription() { return this.resource.toString(); } @Override public boolean equals(Object obj) { return (obj == this || (obj instanceof VfsResource && this.resource.equals(((VfsResource) obj).resource))); } @Override public int hashCode() { return this.resource.hashCode(); } } ././@LongLink0000000000000000000000000000016200000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/io/support/libspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000755000175000017500000000000011623223530033335 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000021600000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/io/support/ResourcePatternResolver.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000633211623223530033343 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.io.support; import java.io.IOException; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; /** * Strategy interface for resolving a location pattern (for example, * an Ant-style path pattern) into Resource objects. * *

This is an extension to the {@link org.springframework.core.io.ResourceLoader} * interface. A passed-in ResourceLoader (for example, an * {@link org.springframework.context.ApplicationContext} passed in via * {@link org.springframework.context.ResourceLoaderAware} when running in a context) * can be checked whether it implements this extended interface too. * *

{@link PathMatchingResourcePatternResolver} is a standalone implementation * that is usable outside an ApplicationContext, also used by * {@link ResourceArrayPropertyEditor} for populating Resource array bean properties. * *

Can be used with any sort of location pattern (e.g. "/WEB-INF/*-context.xml"): * Input patterns have to match the strategy implementation. This interface just * specifies the conversion method rather than a specific pattern format. * *

This interface also suggests a new resource prefix "classpath*:" for all * matching resources from the class path. Note that the resource location is * expected to be a path without placeholders in this case (e.g. "/beans.xml"); * JAR files or classes directories can contain multiple files of the same name. * * @author Juergen Hoeller * @since 1.0.2 * @see org.springframework.core.io.Resource * @see org.springframework.core.io.ResourceLoader * @see org.springframework.context.ApplicationContext * @see org.springframework.context.ResourceLoaderAware */ public interface ResourcePatternResolver extends ResourceLoader { /** * Pseudo URL prefix for all matching resources from the class path: "classpath*:" * This differs from ResourceLoader's classpath URL prefix in that it * retrieves all matching resources for a given name (e.g. "/beans.xml"), * for example in the root of all deployed JAR files. * @see org.springframework.core.io.ResourceLoader#CLASSPATH_URL_PREFIX */ String CLASSPATH_ALL_URL_PREFIX = "classpath*:"; /** * Resolve the given location pattern into Resource objects. *

Overlapping resource entries that point to the same physical * resource should be avoided, as far as possible. The result should * have set semantics. * @param locationPattern the location pattern to resolve * @return the corresponding Resource objects * @throws IOException in case of I/O errors */ Resource[] getResources(String locationPattern) throws IOException; } ././@LongLink0000000000000000000000000000020300000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/io/support/package-info.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000024411623223530033337 0ustar drazzibdrazzib /** * * Support classes for Spring's resource abstraction. * Includes a ResourcePatternResolver mechanism. * */ package org.springframework.core.io.support; ././@LongLink0000000000000000000000000000023200000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/io/support/PathMatchingResourcePatternResolver.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000007034411623223530033347 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.io.support; import java.io.File; import java.io.IOException; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.net.JarURLConnection; import java.net.URISyntaxException; import java.net.URL; import java.net.URLConnection; import java.util.Collections; import java.util.Enumeration; import java.util.LinkedHashSet; import java.util.Set; import java.util.jar.JarEntry; import java.util.jar.JarFile; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.FileSystemResource; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; import org.springframework.core.io.UrlResource; import org.springframework.core.io.VfsResource; import org.springframework.util.AntPathMatcher; import org.springframework.util.Assert; import org.springframework.util.PathMatcher; import org.springframework.util.ReflectionUtils; import org.springframework.util.ResourceUtils; import org.springframework.util.StringUtils; /** * A {@link ResourcePatternResolver} implementation that is able to resolve a * specified resource location path into one or more matching Resources. * The source path may be a simple path which has a one-to-one mapping to a * target {@link org.springframework.core.io.Resource}, or alternatively * may contain the special "classpath*:" prefix and/or * internal Ant-style regular expressions (matched using Spring's * {@link org.springframework.util.AntPathMatcher} utility). * Both of the latter are effectively wildcards. * *

No Wildcards: * *

In the simple case, if the specified location path does not start with the * "classpath*:" prefix, and does not contain a PathMatcher pattern, * this resolver will simply return a single resource via a * getResource() call on the underlying ResourceLoader. * Examples are real URLs such as "file:C:/context.xml", pseudo-URLs * such as "classpath:/context.xml", and simple unprefixed paths * such as "/WEB-INF/context.xml". The latter will resolve in a * fashion specific to the underlying ResourceLoader (e.g. * ServletContextResource for a WebApplicationContext). * *

Ant-style Patterns: * *

When the path location contains an Ant-style pattern, e.g.: *

 * /WEB-INF/*-context.xml
 * com/mycompany/**/applicationContext.xml
 * file:C:/some/path/*-context.xml
 * classpath:com/mycompany/**/applicationContext.xml
* the resolver follows a more complex but defined procedure to try to resolve * the wildcard. It produces a Resource for the path up to the last * non-wildcard segment and obtains a URL from it. If this URL is * not a "jar:" URL or container-specific variant (e.g. * "zip:" in WebLogic, "wsjar" in WebSphere", etc.), * then a java.io.File is obtained from it, and used to resolve the * wildcard by walking the filesystem. In the case of a jar URL, the resolver * either gets a java.net.JarURLConnection from it, or manually parse * the jar URL, and then traverse the contents of the jar file, to resolve the * wildcards. * *

Implications on portability: * *

If the specified path is already a file URL (either explicitly, or * implicitly because the base ResourceLoader is a filesystem one, * then wildcarding is guaranteed to work in a completely portable fashion. * *

If the specified path is a classpath location, then the resolver must * obtain the last non-wildcard path segment URL via a * Classloader.getResource() call. Since this is just a * node of the path (not the file at the end) it is actually undefined * (in the ClassLoader Javadocs) exactly what sort of a URL is returned in * this case. In practice, it is usually a java.io.File representing * the directory, where the classpath resource resolves to a filesystem * location, or a jar URL of some sort, where the classpath resource resolves * to a jar location. Still, there is a portability concern on this operation. * *

If a jar URL is obtained for the last non-wildcard segment, the resolver * must be able to get a java.net.JarURLConnection from it, or * manually parse the jar URL, to be able to walk the contents of the jar, * and resolve the wildcard. This will work in most environments, but will * fail in others, and it is strongly recommended that the wildcard * resolution of resources coming from jars be thoroughly tested in your * specific environment before you rely on it. * *

classpath*: Prefix: * *

There is special support for retrieving multiple class path resources with * the same name, via the "classpath*:" prefix. For example, * "classpath*:META-INF/beans.xml" will find all "beans.xml" * files in the class path, be it in "classes" directories or in JAR files. * This is particularly useful for autodetecting config files of the same name * at the same location within each jar file. Internally, this happens via a * ClassLoader.getResources() call, and is completely portable. * *

The "classpath*:" prefix can also be combined with a PathMatcher pattern in * the rest of the location path, for example "classpath*:META-INF/*-beans.xml". * In this case, the resolution strategy is fairly simple: a * ClassLoader.getResources() call is used on the last non-wildcard * path segment to get all the matching resources in the class loader hierarchy, * and then off each resource the same PathMatcher resolution strategy described * above is used for the wildcard subpath. * *

Other notes: * *

WARNING: Note that "classpath*:" when combined with * Ant-style patterns will only work reliably with at least one root directory * before the pattern starts, unless the actual target files reside in the file * system. This means that a pattern like "classpath*:*.xml" will * not retrieve files from the root of jar files but rather only from the * root of expanded directories. This originates from a limitation in the JDK's * ClassLoader.getResources() method which only returns file system * locations for a passed-in empty String (indicating potential roots to search). * *

WARNING: Ant-style patterns with "classpath:" resources are not * guaranteed to find matching resources if the root package to search is available * in multiple class path locations. This is because a resource such as

 *     com/mycompany/package1/service-context.xml
 * 
may be in only one location, but when a path such as
 *     classpath:com/mycompany/**/service-context.xml
 * 
is used to try to resolve it, the resolver will work off the (first) URL * returned by getResource("com/mycompany");. If this base package * node exists in multiple classloader locations, the actual end resource may * not be underneath. Therefore, preferably, use "classpath*:" with the same * Ant-style pattern in such a case, which will search all class path * locations that contain the root package. * * @author Juergen Hoeller * @author Colin Sampaleanu * @author Marius Bogoevici * @author Costin Leau * @since 1.0.2 * @see #CLASSPATH_ALL_URL_PREFIX * @see org.springframework.util.AntPathMatcher * @see org.springframework.core.io.ResourceLoader#getResource(String) * @see java.lang.ClassLoader#getResources(String) */ public class PathMatchingResourcePatternResolver implements ResourcePatternResolver { private static final Log logger = LogFactory.getLog(PathMatchingResourcePatternResolver.class); private static Method equinoxResolveMethod; static { // Detect Equinox OSGi (e.g. on WebSphere 6.1) try { Class fileLocatorClass = PathMatchingResourcePatternResolver.class.getClassLoader().loadClass( "org.eclipse.core.runtime.FileLocator"); equinoxResolveMethod = fileLocatorClass.getMethod("resolve", URL.class); logger.debug("Found Equinox FileLocator for OSGi bundle URL resolution"); } catch (Throwable ex) { equinoxResolveMethod = null; } } private final ResourceLoader resourceLoader; private PathMatcher pathMatcher = new AntPathMatcher(); /** * Create a new PathMatchingResourcePatternResolver with a DefaultResourceLoader. *

ClassLoader access will happen via the thread context class loader. * @see org.springframework.core.io.DefaultResourceLoader */ public PathMatchingResourcePatternResolver() { this.resourceLoader = new DefaultResourceLoader(); } /** * Create a new PathMatchingResourcePatternResolver with a DefaultResourceLoader. * @param classLoader the ClassLoader to load classpath resources with, * or null for using the thread context class loader * at the time of actual resource access * @see org.springframework.core.io.DefaultResourceLoader */ public PathMatchingResourcePatternResolver(ClassLoader classLoader) { this.resourceLoader = new DefaultResourceLoader(classLoader); } /** * Create a new PathMatchingResourcePatternResolver. *

ClassLoader access will happen via the thread context class loader. * @param resourceLoader the ResourceLoader to load root directories and * actual resources with */ public PathMatchingResourcePatternResolver(ResourceLoader resourceLoader) { Assert.notNull(resourceLoader, "ResourceLoader must not be null"); this.resourceLoader = resourceLoader; } /** * Return the ResourceLoader that this pattern resolver works with. */ public ResourceLoader getResourceLoader() { return this.resourceLoader; } /** * Return the ClassLoader that this pattern resolver works with * (never null). */ public ClassLoader getClassLoader() { return getResourceLoader().getClassLoader(); } /** * Set the PathMatcher implementation to use for this * resource pattern resolver. Default is AntPathMatcher. * @see org.springframework.util.AntPathMatcher */ public void setPathMatcher(PathMatcher pathMatcher) { Assert.notNull(pathMatcher, "PathMatcher must not be null"); this.pathMatcher = pathMatcher; } /** * Return the PathMatcher that this resource pattern resolver uses. */ public PathMatcher getPathMatcher() { return this.pathMatcher; } public Resource getResource(String location) { return getResourceLoader().getResource(location); } public Resource[] getResources(String locationPattern) throws IOException { Assert.notNull(locationPattern, "Location pattern must not be null"); if (locationPattern.startsWith(CLASSPATH_ALL_URL_PREFIX)) { // a class path resource (multiple resources for same name possible) if (getPathMatcher().isPattern(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()))) { // a class path resource pattern return findPathMatchingResources(locationPattern); } else { // all class path resources with the given name return findAllClassPathResources(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length())); } } else { // Only look for a pattern after a prefix here // (to not get fooled by a pattern symbol in a strange prefix). int prefixEnd = locationPattern.indexOf(":") + 1; if (getPathMatcher().isPattern(locationPattern.substring(prefixEnd))) { // a file pattern return findPathMatchingResources(locationPattern); } else { // a single resource with the given name return new Resource[] {getResourceLoader().getResource(locationPattern)}; } } } /** * Find all class location resources with the given location via the ClassLoader. * @param location the absolute path within the classpath * @return the result as Resource array * @throws IOException in case of I/O errors * @see java.lang.ClassLoader#getResources * @see #convertClassLoaderURL */ protected Resource[] findAllClassPathResources(String location) throws IOException { String path = location; if (path.startsWith("/")) { path = path.substring(1); } Enumeration resourceUrls = getClassLoader().getResources(path); Set result = new LinkedHashSet(16); while (resourceUrls.hasMoreElements()) { URL url = (URL) resourceUrls.nextElement(); result.add(convertClassLoaderURL(url)); } return result.toArray(new Resource[result.size()]); } /** * Convert the given URL as returned from the ClassLoader into a Resource object. *

The default implementation simply creates a UrlResource instance. * @param url a URL as returned from the ClassLoader * @return the corresponding Resource object * @see java.lang.ClassLoader#getResources * @see org.springframework.core.io.Resource */ protected Resource convertClassLoaderURL(URL url) { return new UrlResource(url); } /** * Find all resources that match the given location pattern via the * Ant-style PathMatcher. Supports resources in jar files and zip files * and in the file system. * @param locationPattern the location pattern to match * @return the result as Resource array * @throws IOException in case of I/O errors * @see #doFindPathMatchingJarResources * @see #doFindPathMatchingFileResources * @see org.springframework.util.PathMatcher */ protected Resource[] findPathMatchingResources(String locationPattern) throws IOException { String rootDirPath = determineRootDir(locationPattern); String subPattern = locationPattern.substring(rootDirPath.length()); Resource[] rootDirResources = getResources(rootDirPath); Set result = new LinkedHashSet(16); for (Resource rootDirResource : rootDirResources) { rootDirResource = resolveRootDirResource(rootDirResource); if (isJarResource(rootDirResource)) { result.addAll(doFindPathMatchingJarResources(rootDirResource, subPattern)); } else if (rootDirResource.getURL().getProtocol().startsWith(ResourceUtils.URL_PROTOCOL_VFS)) { result.addAll(VfsResourceMatchingDelegate.findMatchingResources(rootDirResource, subPattern, getPathMatcher())); } else { result.addAll(doFindPathMatchingFileResources(rootDirResource, subPattern)); } } if (logger.isDebugEnabled()) { logger.debug("Resolved location pattern [" + locationPattern + "] to resources " + result); } return result.toArray(new Resource[result.size()]); } /** * Determine the root directory for the given location. *

Used for determining the starting point for file matching, * resolving the root directory location to a java.io.File * and passing it into retrieveMatchingFiles, with the * remainder of the location as pattern. *

Will return "/WEB-INF/" for the pattern "/WEB-INF/*.xml", * for example. * @param location the location to check * @return the part of the location that denotes the root directory * @see #retrieveMatchingFiles */ protected String determineRootDir(String location) { int prefixEnd = location.indexOf(":") + 1; int rootDirEnd = location.length(); while (rootDirEnd > prefixEnd && getPathMatcher().isPattern(location.substring(prefixEnd, rootDirEnd))) { rootDirEnd = location.lastIndexOf('/', rootDirEnd - 2) + 1; } if (rootDirEnd == 0) { rootDirEnd = prefixEnd; } return location.substring(0, rootDirEnd); } /** * Resolve the specified resource for path matching. *

The default implementation detects an Equinox OSGi "bundleresource:" * / "bundleentry:" URL and resolves it into a standard jar file URL that * can be traversed using Spring's standard jar file traversal algorithm. * @param original the resource to resolfe * @return the resolved resource (may be identical to the passed-in resource) * @throws IOException in case of resolution failure */ protected Resource resolveRootDirResource(Resource original) throws IOException { if (equinoxResolveMethod != null) { URL url = original.getURL(); if (url.getProtocol().startsWith("bundle")) { return new UrlResource((URL) ReflectionUtils.invokeMethod(equinoxResolveMethod, null, url)); } } return original; } /** * Return whether the given resource handle indicates a jar resource * that the doFindPathMatchingJarResources method can handle. *

The default implementation checks against the URL protocols * "jar", "zip" and "wsjar" (the latter are used by BEA WebLogic Server * and IBM WebSphere, respectively, but can be treated like jar files). * @param resource the resource handle to check * (usually the root directory to start path matching from) * @see #doFindPathMatchingJarResources * @see org.springframework.util.ResourceUtils#isJarURL */ protected boolean isJarResource(Resource resource) throws IOException { return ResourceUtils.isJarURL(resource.getURL()); } /** * Find all resources in jar files that match the given location pattern * via the Ant-style PathMatcher. * @param rootDirResource the root directory as Resource * @param subPattern the sub pattern to match (below the root directory) * @return the Set of matching Resource instances * @throws IOException in case of I/O errors * @see java.net.JarURLConnection * @see org.springframework.util.PathMatcher */ protected Set doFindPathMatchingJarResources(Resource rootDirResource, String subPattern) throws IOException { URLConnection con = rootDirResource.getURL().openConnection(); JarFile jarFile; String jarFileUrl; String rootEntryPath; boolean newJarFile = false; if (con instanceof JarURLConnection) { // Should usually be the case for traditional JAR files. JarURLConnection jarCon = (JarURLConnection) con; jarCon.setUseCaches(false); jarFile = jarCon.getJarFile(); jarFileUrl = jarCon.getJarFileURL().toExternalForm(); JarEntry jarEntry = jarCon.getJarEntry(); rootEntryPath = (jarEntry != null ? jarEntry.getName() : ""); } else { // No JarURLConnection -> need to resort to URL file parsing. // We'll assume URLs of the format "jar:path!/entry", with the protocol // being arbitrary as long as following the entry format. // We'll also handle paths with and without leading "file:" prefix. String urlFile = rootDirResource.getURL().getFile(); int separatorIndex = urlFile.indexOf(ResourceUtils.JAR_URL_SEPARATOR); if (separatorIndex != -1) { jarFileUrl = urlFile.substring(0, separatorIndex); rootEntryPath = urlFile.substring(separatorIndex + ResourceUtils.JAR_URL_SEPARATOR.length()); jarFile = getJarFile(jarFileUrl); } else { jarFile = new JarFile(urlFile); jarFileUrl = urlFile; rootEntryPath = ""; } newJarFile = true; } try { if (logger.isDebugEnabled()) { logger.debug("Looking for matching resources in jar file [" + jarFileUrl + "]"); } if (!"".equals(rootEntryPath) && !rootEntryPath.endsWith("/")) { // Root entry path must end with slash to allow for proper matching. // The Sun JRE does not return a slash here, but BEA JRockit does. rootEntryPath = rootEntryPath + "/"; } Set result = new LinkedHashSet(8); for (Enumeration entries = jarFile.entries(); entries.hasMoreElements();) { JarEntry entry = (JarEntry) entries.nextElement(); String entryPath = entry.getName(); if (entryPath.startsWith(rootEntryPath)) { String relativePath = entryPath.substring(rootEntryPath.length()); if (getPathMatcher().match(subPattern, relativePath)) { result.add(rootDirResource.createRelative(relativePath)); } } } return result; } finally { // Close jar file, but only if freshly obtained - // not from JarURLConnection, which might cache the file reference. if (newJarFile) { jarFile.close(); } } } /** * Resolve the given jar file URL into a JarFile object. */ protected JarFile getJarFile(String jarFileUrl) throws IOException { if (jarFileUrl.startsWith(ResourceUtils.FILE_URL_PREFIX)) { try { return new JarFile(ResourceUtils.toURI(jarFileUrl).getSchemeSpecificPart()); } catch (URISyntaxException ex) { // Fallback for URLs that are not valid URIs (should hardly ever happen). return new JarFile(jarFileUrl.substring(ResourceUtils.FILE_URL_PREFIX.length())); } } else { return new JarFile(jarFileUrl); } } /** * Find all resources in the file system that match the given location pattern * via the Ant-style PathMatcher. * @param rootDirResource the root directory as Resource * @param subPattern the sub pattern to match (below the root directory) * @return the Set of matching Resource instances * @throws IOException in case of I/O errors * @see #retrieveMatchingFiles * @see org.springframework.util.PathMatcher */ protected Set doFindPathMatchingFileResources(Resource rootDirResource, String subPattern) throws IOException { File rootDir; try { rootDir = rootDirResource.getFile().getAbsoluteFile(); } catch (IOException ex) { if (logger.isWarnEnabled()) { logger.warn("Cannot search for matching files underneath " + rootDirResource + " because it does not correspond to a directory in the file system", ex); } return Collections.emptySet(); } return doFindMatchingFileSystemResources(rootDir, subPattern); } /** * Find all resources in the file system that match the given location pattern * via the Ant-style PathMatcher. * @param rootDir the root directory in the file system * @param subPattern the sub pattern to match (below the root directory) * @return the Set of matching Resource instances * @throws IOException in case of I/O errors * @see #retrieveMatchingFiles * @see org.springframework.util.PathMatcher */ protected Set doFindMatchingFileSystemResources(File rootDir, String subPattern) throws IOException { if (logger.isDebugEnabled()) { logger.debug("Looking for matching resources in directory tree [" + rootDir.getPath() + "]"); } Set matchingFiles = retrieveMatchingFiles(rootDir, subPattern); Set result = new LinkedHashSet(matchingFiles.size()); for (File file : matchingFiles) { result.add(new FileSystemResource(file)); } return result; } /** * Retrieve files that match the given path pattern, * checking the given directory and its subdirectories. * @param rootDir the directory to start from * @param pattern the pattern to match against, * relative to the root directory * @return the Set of matching File instances * @throws IOException if directory contents could not be retrieved */ protected Set retrieveMatchingFiles(File rootDir, String pattern) throws IOException { if (!rootDir.exists()) { // Silently skip non-existing directories. if (logger.isDebugEnabled()) { logger.debug("Skipping [" + rootDir.getAbsolutePath() + "] because it does not exist"); } return Collections.emptySet(); } if (!rootDir.isDirectory()) { // Complain louder if it exists but is no directory. if (logger.isWarnEnabled()) { logger.warn("Skipping [" + rootDir.getAbsolutePath() + "] because it does not denote a directory"); } return Collections.emptySet(); } if (!rootDir.canRead()) { if (logger.isWarnEnabled()) { logger.warn("Cannot search for matching files underneath directory [" + rootDir.getAbsolutePath() + "] because the application is not allowed to read the directory"); } return Collections.emptySet(); } String fullPattern = StringUtils.replace(rootDir.getAbsolutePath(), File.separator, "/"); if (!pattern.startsWith("/")) { fullPattern += "/"; } fullPattern = fullPattern + StringUtils.replace(pattern, File.separator, "/"); Set result = new LinkedHashSet(8); doRetrieveMatchingFiles(fullPattern, rootDir, result); return result; } /** * Recursively retrieve files that match the given pattern, * adding them to the given result list. * @param fullPattern the pattern to match against, * with preprended root directory path * @param dir the current directory * @param result the Set of matching File instances to add to * @throws IOException if directory contents could not be retrieved */ protected void doRetrieveMatchingFiles(String fullPattern, File dir, Set result) throws IOException { if (logger.isDebugEnabled()) { logger.debug("Searching directory [" + dir.getAbsolutePath() + "] for files matching pattern [" + fullPattern + "]"); } File[] dirContents = dir.listFiles(); if (dirContents == null) { if (logger.isWarnEnabled()) { logger.warn("Could not retrieve contents of directory [" + dir.getAbsolutePath() + "]"); } return; } for (File content : dirContents) { String currPath = StringUtils.replace(content.getAbsolutePath(), File.separator, "/"); if (content.isDirectory() && getPathMatcher().matchStart(fullPattern, currPath + "/")) { if (!content.canRead()) { if (logger.isDebugEnabled()) { logger.debug("Skipping subdirectory [" + dir.getAbsolutePath() + "] because the application is not allowed to read the directory"); } } else { doRetrieveMatchingFiles(fullPattern, content, result); } } if (getPathMatcher().match(fullPattern, currPath)) { result.add(content); } } } /** * Inner delegate class, avoiding a hard JBoss VFS API dependency at runtime. */ private static class VfsResourceMatchingDelegate { public static Set findMatchingResources( Resource rootResource, String locationPattern, PathMatcher pathMatcher) throws IOException { Object root = VfsPatternUtils.findRoot(rootResource.getURL()); PatternVirtualFileVisitor visitor = new PatternVirtualFileVisitor(VfsPatternUtils.getPath(root), locationPattern, pathMatcher); VfsPatternUtils.visit(root, visitor); return visitor.getResources(); } } /** * VFS visitor for path matching purposes. */ private static class PatternVirtualFileVisitor implements InvocationHandler { private final String subPattern; private final PathMatcher pathMatcher; private final String rootPath; private final Set resources = new LinkedHashSet(); public PatternVirtualFileVisitor(String rootPath, String subPattern, PathMatcher pathMatcher) { this.subPattern = subPattern; this.pathMatcher = pathMatcher; this.rootPath = (rootPath.length() == 0 || rootPath.endsWith("/") ? rootPath : rootPath + "/"); } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String methodName = method.getName(); if (Object.class.equals(method.getDeclaringClass())) { if (methodName.equals("equals")) { // Only consider equal when proxies are identical. return (proxy == args[0]); } else if (methodName.equals("hashCode")) { return System.identityHashCode(proxy); } } else if ("getAttributes".equals(methodName)) { return getAttributes(); } else if ("visit".equals(methodName)) { visit(args[0]); return null; } else if ("toString".equals(methodName)) { return toString(); } throw new IllegalStateException("Unexpected method invocation: " + method); } public void visit(Object vfsResource) { if (this.pathMatcher.match(this.subPattern, VfsPatternUtils.getPath(vfsResource).substring(this.rootPath.length()))) { this.resources.add(new VfsResource(vfsResource)); } } public Object getAttributes() { return VfsPatternUtils.getVisitorAttribute(); } public Set getResources() { return this.resources; } public int size() { return this.resources.size(); } public String toString() { StringBuilder sb = new StringBuilder(); sb.append("sub-pattern: ").append(this.subPattern); sb.append(", resources: ").append(this.resources); return sb.toString(); } } } ././@LongLink0000000000000000000000000000021600000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/io/support/LocalizedResourceHelper.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000001037711623223526033354 0ustar drazzibdrazzib/* * Copyright 2002-2006 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.io.support; import java.util.Locale; import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; import org.springframework.util.Assert; /** * Helper class for loading a localized resource, * specified through name, extension and current locale. * * @author Juergen Hoeller * @since 1.2.5 */ public class LocalizedResourceHelper { /** The default separator to use inbetween file name parts: an underscore */ public static final String DEFAULT_SEPARATOR = "_"; private final ResourceLoader resourceLoader; private String separator = DEFAULT_SEPARATOR; /** * Create a new LocalizedResourceHelper with a DefaultResourceLoader. * @see org.springframework.core.io.DefaultResourceLoader */ public LocalizedResourceHelper() { this.resourceLoader = new DefaultResourceLoader(); } /** * Create a new LocalizedResourceHelper with the given ResourceLoader. * @param resourceLoader the ResourceLoader to use */ public LocalizedResourceHelper(ResourceLoader resourceLoader) { Assert.notNull(resourceLoader, "ResourceLoader must not be null"); this.resourceLoader = resourceLoader; } /** * Set the separator to use inbetween file name parts. * Default is an underscore ("_"). */ public void setSeparator(String separator) { this.separator = (separator != null ? separator : DEFAULT_SEPARATOR); } /** * Find the most specific localized resource for the given name, * extension and locale: *

The file will be searched with locations in the following order, * similar to java.util.ResourceBundle's search order: *

    *
  • [name]_[language]_[country]_[variant][extension] *
  • [name]_[language]_[country][extension] *
  • [name]_[language][extension] *
  • [name][extension] *
*

If none of the specific files can be found, a resource * descriptor for the default location will be returned. * @param name the name of the file, without localization part nor extension * @param extension the file extension (e.g. ".xls") * @param locale the current locale (may be null) * @return the most specific localized resource found * @see java.util.ResourceBundle */ public Resource findLocalizedResource(String name, String extension, Locale locale) { Assert.notNull(name, "Name must not be null"); Assert.notNull(extension, "Extension must not be null"); Resource resource = null; if (locale != null) { String lang = locale.getLanguage(); String country = locale.getCountry(); String variant = locale.getVariant(); // Check for file with language, country and variant localization. if (variant.length() > 0) { String location = name + this.separator + lang + this.separator + country + this.separator + variant + extension; resource = this.resourceLoader.getResource(location); } // Check for file with language and country localization. if ((resource == null || !resource.exists()) && country.length() > 0) { String location = name + this.separator + lang + this.separator + country + extension; resource = this.resourceLoader.getResource(location); } // Check for document with language localization. if ((resource == null || !resource.exists()) && lang.length() > 0) { String location = name + this.separator + lang + extension; resource = this.resourceLoader.getResource(location); } } // Check for document without localization. if (resource == null || !resource.exists()) { String location = name + extension; resource = this.resourceLoader.getResource(location); } return resource; } } ././@LongLink0000000000000000000000000000021600000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/io/support/PropertiesLoaderSupport.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000001470711623223530033350 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.io.support; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.Properties; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.core.io.Resource; import org.springframework.util.CollectionUtils; import org.springframework.util.DefaultPropertiesPersister; import org.springframework.util.PropertiesPersister; /** * Base class for JavaBean-style components that need to load properties * from one or more resources. Supports local properties as well, with * configurable overriding. * * @author Juergen Hoeller * @since 1.2.2 */ public abstract class PropertiesLoaderSupport { public static final String XML_FILE_EXTENSION = ".xml"; /** Logger available to subclasses */ protected final Log logger = LogFactory.getLog(getClass()); private Properties[] localProperties; private Resource[] locations; private boolean localOverride = false; private boolean ignoreResourceNotFound = false; private String fileEncoding; private PropertiesPersister propertiesPersister = new DefaultPropertiesPersister(); /** * Set local properties, e.g. via the "props" tag in XML bean definitions. * These can be considered defaults, to be overridden by properties * loaded from files. */ public void setProperties(Properties properties) { this.localProperties = new Properties[] {properties}; } /** * Set local properties, e.g. via the "props" tag in XML bean definitions, * allowing for merging multiple properties sets into one. */ public void setPropertiesArray(Properties[] propertiesArray) { this.localProperties = propertiesArray; } /** * Set a location of a properties file to be loaded. *

Can point to a classic properties file or to an XML file * that follows JDK 1.5's properties XML format. */ public void setLocation(Resource location) { this.locations = new Resource[] {location}; } /** * Set locations of properties files to be loaded. *

Can point to classic properties files or to XML files * that follow JDK 1.5's properties XML format. *

Note: Properties defined in later files will override * properties defined earlier files, in case of overlapping keys. * Hence, make sure that the most specific files are the last * ones in the given list of locations. */ public void setLocations(Resource[] locations) { this.locations = locations; } /** * Set whether local properties override properties from files. *

Default is "false": Properties from files override local defaults. * Can be switched to "true" to let local properties override defaults * from files. */ public void setLocalOverride(boolean localOverride) { this.localOverride = localOverride; } /** * Set if failure to find the property resource should be ignored. *

"true" is appropriate if the properties file is completely optional. * Default is "false". */ public void setIgnoreResourceNotFound(boolean ignoreResourceNotFound) { this.ignoreResourceNotFound = ignoreResourceNotFound; } /** * Set the encoding to use for parsing properties files. *

Default is none, using the java.util.Properties * default encoding. *

Only applies to classic properties files, not to XML files. * @see org.springframework.util.PropertiesPersister#load */ public void setFileEncoding(String encoding) { this.fileEncoding = encoding; } /** * Set the PropertiesPersister to use for parsing properties files. * The default is DefaultPropertiesPersister. * @see org.springframework.util.DefaultPropertiesPersister */ public void setPropertiesPersister(PropertiesPersister propertiesPersister) { this.propertiesPersister = (propertiesPersister != null ? propertiesPersister : new DefaultPropertiesPersister()); } /** * Return a merged Properties instance containing both the * loaded properties and properties set on this FactoryBean. */ protected Properties mergeProperties() throws IOException { Properties result = new Properties(); if (this.localOverride) { // Load properties from file upfront, to let local properties override. loadProperties(result); } if (this.localProperties != null) { for (Properties localProp : this.localProperties) { CollectionUtils.mergePropertiesIntoMap(localProp, result); } } if (!this.localOverride) { // Load properties from file afterwards, to let those properties override. loadProperties(result); } return result; } /** * Load properties into the given instance. * @param props the Properties instance to load into * @throws java.io.IOException in case of I/O errors * @see #setLocations */ protected void loadProperties(Properties props) throws IOException { if (this.locations != null) { for (Resource location : this.locations) { if (logger.isInfoEnabled()) { logger.info("Loading properties file from " + location); } InputStream is = null; try { is = location.getInputStream(); String filename = null; try { filename = location.getFilename(); } catch (IllegalStateException ex) { // resource is not file-based. See SPR-7552. } if (filename != null && filename.endsWith(XML_FILE_EXTENSION)) { this.propertiesPersister.loadFromXml(props, is); } else { if (this.fileEncoding != null) { this.propertiesPersister.load(props, new InputStreamReader(is, this.fileEncoding)); } else { this.propertiesPersister.load(props, is); } } } catch (IOException ex) { if (this.ignoreResourceNotFound) { if (logger.isWarnEnabled()) { logger.warn("Could not load properties from " + location + ": " + ex.getMessage()); } } else { throw ex; } } finally { if (is != null) { is.close(); } } } } } } ././@LongLink0000000000000000000000000000022200000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/io/support/ResourceArrayPropertyEditor.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000001404211623223530033340 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.io.support; import java.beans.PropertyEditorSupport; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.core.io.Resource; import org.springframework.util.SystemPropertyUtils; /** * Editor for {@link org.springframework.core.io.Resource} arrays, to * automatically convert String location patterns * (e.g. "file:C:/my*.txt" or "classpath*:myfile.txt") * to Resource array properties. Can also translate a collection * or array of location patterns into a merged Resource array. * *

The path may contain ${...} placeholders, * to be resolved as system properties: e.g. ${user.dir}. * Unresolvable placeholder are ignored by default. * *

Delegates to a {@link ResourcePatternResolver}, * by default using a {@link PathMatchingResourcePatternResolver}. * * @author Juergen Hoeller * @since 1.1.2 * @see org.springframework.core.io.Resource * @see ResourcePatternResolver * @see PathMatchingResourcePatternResolver * @see org.springframework.util.SystemPropertyUtils#resolvePlaceholders * @see System#getProperty(String) */ public class ResourceArrayPropertyEditor extends PropertyEditorSupport { private static final Log logger = LogFactory.getLog(ResourceArrayPropertyEditor.class); private final ResourcePatternResolver resourcePatternResolver; private final boolean ignoreUnresolvablePlaceholders; /** * Create a new ResourceArrayPropertyEditor with a default * PathMatchingResourcePatternResolver. * @see PathMatchingResourcePatternResolver */ public ResourceArrayPropertyEditor() { this(new PathMatchingResourcePatternResolver()); } /** * Create a new ResourceArrayPropertyEditor with the given ResourcePatternResolver. * @param resourcePatternResolver the ResourcePatternResolver to use */ public ResourceArrayPropertyEditor(ResourcePatternResolver resourcePatternResolver) { this(resourcePatternResolver, true); } /** * Create a new ResourceArrayPropertyEditor with the given ResourcePatternResolver. * @param resourcePatternResolver the ResourcePatternResolver to use * @param ignoreUnresolvablePlaceholders whether to ignore unresolvable placeholders * if no corresponding system property could be found */ public ResourceArrayPropertyEditor(ResourcePatternResolver resourcePatternResolver, boolean ignoreUnresolvablePlaceholders) { this.resourcePatternResolver = resourcePatternResolver; this.ignoreUnresolvablePlaceholders = ignoreUnresolvablePlaceholders; } /** * Treat the given text as location pattern and convert it to a Resource array. */ @Override public void setAsText(String text) { String pattern = resolvePath(text).trim(); try { setValue(this.resourcePatternResolver.getResources(pattern)); } catch (IOException ex) { throw new IllegalArgumentException( "Could not resolve resource location pattern [" + pattern + "]: " + ex.getMessage()); } } /** * Treat the given value as collection or array and convert it to a Resource array. * Considers String elements as location patterns, and takes Resource elements as-is. */ @Override public void setValue(Object value) throws IllegalArgumentException { if (value instanceof Collection || (value instanceof Object[] && !(value instanceof Resource[]))) { Collection input = (value instanceof Collection ? (Collection) value : Arrays.asList((Object[]) value)); List merged = new ArrayList(); for (Object element : input) { if (element instanceof String) { // A location pattern: resolve it into a Resource array. // Might point to a single resource or to multiple resources. String pattern = resolvePath((String) element).trim(); try { Resource[] resources = this.resourcePatternResolver.getResources(pattern); for (Resource resource : resources) { if (!merged.contains(resource)) { merged.add(resource); } } } catch (IOException ex) { // ignore - might be an unresolved placeholder or non-existing base directory if (logger.isDebugEnabled()) { logger.debug("Could not retrieve resources for pattern '" + pattern + "': " + ex); } } } else if (element instanceof Resource) { // A Resource object: add it to the result. Resource resource = (Resource) element; if (!merged.contains(resource)) { merged.add(resource); } } else { throw new IllegalArgumentException("Cannot convert element [" + element + "] to [" + Resource.class.getName() + "]: only location String and Resource object supported"); } } super.setValue(merged.toArray(new Resource[merged.size()])); } else { // An arbitrary value: probably a String or a Resource array. // setAsText will be called for a String; a Resource array will be used as-is. super.setValue(value); } } /** * Resolve the given path, replacing placeholders with * corresponding system property values if necessary. * @param path the original file path * @return the resolved file path * @see org.springframework.util.SystemPropertyUtils#resolvePlaceholders */ protected String resolvePath(String path) { return SystemPropertyUtils.resolvePlaceholders(path, this.ignoreUnresolvablePlaceholders); } } ././@LongLink0000000000000000000000000000021300000000000011561 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/io/support/ResourcePatternUtils.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000542711623223526033354 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.io.support; import org.springframework.core.io.ResourceLoader; import org.springframework.util.Assert; import org.springframework.util.ResourceUtils; /** * Utility class for determining whether a given URL is a resource * location that can be loaded via a ResourcePatternResolver. * *

Callers will usually assume that a location is a relative path * if the {@link #isUrl(String)} method returns false. * * @author Juergen Hoeller * @since 1.2.3 */ public abstract class ResourcePatternUtils { /** * Return whether the given resource location is a URL: either a * special "classpath" or "classpath*" pseudo URL or a standard URL. * @param resourceLocation the location String to check * @return whether the location qualifies as a URL * @see ResourcePatternResolver#CLASSPATH_ALL_URL_PREFIX * @see org.springframework.util.ResourceUtils#CLASSPATH_URL_PREFIX * @see org.springframework.util.ResourceUtils#isUrl(String) * @see java.net.URL */ public static boolean isUrl(String resourceLocation) { return (resourceLocation != null && (resourceLocation.startsWith(ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX) || ResourceUtils.isUrl(resourceLocation))); } /** * Return a default ResourcePatternResolver for the given ResourceLoader. *

This might be the ResourceLoader itself, if it implements the * ResourcePatternResolver extension, or a PathMatchingResourcePatternResolver * built on the given ResourceLoader. * @param resourceLoader the ResourceLoader to build a pattern resolver for * (may be null to indicate a default ResourceLoader) * @return the ResourcePatternResolver * @see PathMatchingResourcePatternResolver */ public static ResourcePatternResolver getResourcePatternResolver(ResourceLoader resourceLoader) { Assert.notNull(resourceLoader, "ResourceLoader must not be null"); if (resourceLoader instanceof ResourcePatternResolver) { return (ResourcePatternResolver) resourceLoader; } else if (resourceLoader != null) { return new PathMatchingResourcePatternResolver(resourceLoader); } else { return new PathMatchingResourcePatternResolver(); } } } ././@LongLink0000000000000000000000000000021400000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/io/support/PropertiesLoaderUtils.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000742211623223526033351 0ustar drazzibdrazzib/* * Copyright 2002-2006 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.io.support; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.net.URLConnection; import java.util.Enumeration; import java.util.Properties; import org.springframework.core.io.Resource; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; /** * Convenient utility methods for loading of java.util.Properties, * performing standard handling of input streams. * *

For more configurable properties loading, including the option of a * customized encoding, consider using the PropertiesLoaderSupport class. * * @author Juergen Hoeller * @author Rob Harrop * @since 2.0 * @see PropertiesLoaderSupport */ public abstract class PropertiesLoaderUtils { /** * Load properties from the given resource. * @param resource the resource to load from * @return the populated Properties instance * @throws IOException if loading failed */ public static Properties loadProperties(Resource resource) throws IOException { Properties props = new Properties(); fillProperties(props, resource); return props; } /** * Fill the given properties from the given resource. * @param props the Properties instance to fill * @param resource the resource to load from * @throws IOException if loading failed */ public static void fillProperties(Properties props, Resource resource) throws IOException { InputStream is = resource.getInputStream(); try { props.load(is); } finally { is.close(); } } /** * Load all properties from the given class path resource, * using the default class loader. *

Merges properties if more than one resource of the same name * found in the class path. * @param resourceName the name of the class path resource * @return the populated Properties instance * @throws IOException if loading failed */ public static Properties loadAllProperties(String resourceName) throws IOException { return loadAllProperties(resourceName, null); } /** * Load all properties from the given class path resource, * using the given class loader. *

Merges properties if more than one resource of the same name * found in the class path. * @param resourceName the name of the class path resource * @param classLoader the ClassLoader to use for loading * (or null to use the default class loader) * @return the populated Properties instance * @throws IOException if loading failed */ public static Properties loadAllProperties(String resourceName, ClassLoader classLoader) throws IOException { Assert.notNull(resourceName, "Resource name must not be null"); ClassLoader clToUse = classLoader; if (clToUse == null) { clToUse = ClassUtils.getDefaultClassLoader(); } Properties properties = new Properties(); Enumeration urls = clToUse.getResources(resourceName); while (urls.hasMoreElements()) { URL url = (URL) urls.nextElement(); InputStream is = null; try { URLConnection con = url.openConnection(); con.setUseCaches(false); is = con.getInputStream(); properties.load(is); } finally { if (is != null) { is.close(); } } } return properties; } } ././@LongLink0000000000000000000000000000020600000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/io/support/EncodedResource.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000612111623223526033344 0ustar drazzibdrazzib/* * Copyright 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.io.support; import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; import org.springframework.core.io.Resource; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; /** * Holder that combines a {@link org.springframework.core.io.Resource} * with a specific encoding to be used for reading from the resource. * *

Used as argument for operations that support to read content with * a specific encoding (usually through a java.io.Reader. * * @author Juergen Hoeller * @since 1.2.6 * @see java.io.Reader */ public class EncodedResource { private final Resource resource; private final String encoding; /** * Create a new EncodedResource for the given Resource, * not specifying a specific encoding. * @param resource the Resource to hold */ public EncodedResource(Resource resource) { this(resource, null); } /** * Create a new EncodedResource for the given Resource, * using the specified encoding. * @param resource the Resource to hold * @param encoding the encoding to use for reading from the resource */ public EncodedResource(Resource resource, String encoding) { Assert.notNull(resource, "Resource must not be null"); this.resource = resource; this.encoding = encoding; } /** * Return the Resource held. */ public final Resource getResource() { return this.resource; } /** * Return the encoding to use for reading from the resource, * or null if none specified. */ public final String getEncoding() { return this.encoding; } /** * Open a java.io.Reader for the specified resource, * using the specified encoding (if any). * @throws IOException if opening the Reader failed */ public Reader getReader() throws IOException { if (this.encoding != null) { return new InputStreamReader(this.resource.getInputStream(), this.encoding); } else { return new InputStreamReader(this.resource.getInputStream()); } } @Override public boolean equals(Object obj) { if (obj == this) { return true; } if (obj instanceof EncodedResource) { EncodedResource otherRes = (EncodedResource) obj; return (this.resource.equals(otherRes.resource) && ObjectUtils.nullSafeEquals(this.encoding, otherRes.encoding)); } return false; } @Override public int hashCode() { return this.resource.hashCode(); } @Override public String toString() { return this.resource.toString(); } } ././@LongLink0000000000000000000000000000020600000000000011563 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/io/support/VfsPatternUtils.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000317711623223530033347 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.io.support; import java.io.IOException; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; import java.net.URL; import org.springframework.core.io.VfsUtils; /** * Artificial class used for accessing the {@link VfsUtils} methods * without exposing them to the entire world. * * @author Costin Leau * @since 3.0.3 */ abstract class VfsPatternUtils extends VfsUtils { static Object getVisitorAttribute() { return doGetVisitorAttribute(); } static String getPath(Object resource) { return doGetPath(resource); } static Object findRoot(URL url) throws IOException { return getRoot(url); } static void visit(Object resource, InvocationHandler visitor) throws IOException { Object visitorProxy = Proxy.newProxyInstance(VIRTUAL_FILE_VISITOR_INTERFACE.getClassLoader(), new Class[] { VIRTUAL_FILE_VISITOR_INTERFACE }, visitor); invokeVfsMethod(VIRTUAL_FILE_METHOD_VISIT, resource, visitorProxy); } } ././@LongLink0000000000000000000000000000020200000000000011557 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/io/DescriptiveResource.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000424511623223530033344 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.io; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; /** * Simple {@link Resource} implementation that holds a resource description * but does not point to an actually readable resource. * *

To be used as placeholder if a Resource argument is * expected by an API but not necessarily used for actual reading. * * @author Juergen Hoeller * @since 1.2.6 */ public class DescriptiveResource extends AbstractResource { private final String description; /** * Create a new DescriptiveResource. * @param description the resource description */ public DescriptiveResource(String description) { this.description = (description != null ? description : ""); } @Override public boolean exists() { return false; } @Override public boolean isReadable() { return false; } public InputStream getInputStream() throws IOException { throw new FileNotFoundException( getDescription() + " cannot be opened because it does not point to a readable resource"); } public String getDescription() { return this.description; } /** * This implementation compares the underlying description String. */ @Override public boolean equals(Object obj) { return (obj == this || (obj instanceof DescriptiveResource && ((DescriptiveResource) obj).description.equals(this.description))); } /** * This implementation returns the hash code of the underlying description String. */ @Override public int hashCode() { return this.description.hashCode(); } } ././@LongLink0000000000000000000000000000021400000000000011562 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/io/AbstractFileResolvingResource.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000001320311623223530033336 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.io; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URI; import java.net.URL; import java.net.URLConnection; import org.springframework.util.ResourceUtils; /** * Abstract base class for resources which resolve URLs into File references, * such as {@link UrlResource} or {@link ClassPathResource}. * *

Detects the "file" protocol as well as the JBoss "vfs" protocol in URLs, * resolving file system references accordingly. * * @author Juergen Hoeller * @since 3.0 */ public abstract class AbstractFileResolvingResource extends AbstractResource { /** * This implementation returns a File reference for the underlying class path * resource, provided that it refers to a file in the file system. * @see org.springframework.util.ResourceUtils#getFile(java.net.URL, String) */ @Override public File getFile() throws IOException { URL url = getURL(); if (url.getProtocol().startsWith(ResourceUtils.URL_PROTOCOL_VFS)) { return VfsResourceDelegate.getResource(url).getFile(); } return ResourceUtils.getFile(url, getDescription()); } /** * This implementation determines the underlying File * (or jar file, in case of a resource in a jar/zip). */ @Override protected File getFileForLastModifiedCheck() throws IOException { URL url = getURL(); if (ResourceUtils.isJarURL(url)) { URL actualUrl = ResourceUtils.extractJarFileURL(url); if (actualUrl.getProtocol().startsWith(ResourceUtils.URL_PROTOCOL_VFS)) { return VfsResourceDelegate.getResource(actualUrl).getFile(); } return ResourceUtils.getFile(actualUrl, "Jar URL"); } else { return getFile(); } } /** * This implementation returns a File reference for the underlying class path * resource, provided that it refers to a file in the file system. * @see org.springframework.util.ResourceUtils#getFile(java.net.URI, String) */ protected File getFile(URI uri) throws IOException { if (uri.getScheme().startsWith(ResourceUtils.URL_PROTOCOL_VFS)) { return VfsResourceDelegate.getResource(uri).getFile(); } return ResourceUtils.getFile(uri, getDescription()); } @Override public boolean exists() { try { URL url = getURL(); if (ResourceUtils.isFileURL(url)) { // Proceed with file system resolution... return getFile().exists(); } else { // Try a URL connection content-length header... URLConnection con = url.openConnection(); con.setUseCaches(false); HttpURLConnection httpCon = (con instanceof HttpURLConnection ? (HttpURLConnection) con : null); if (httpCon != null) { httpCon.setRequestMethod("HEAD"); if (httpCon.getResponseCode() == HttpURLConnection.HTTP_OK) { return true; } } if (con.getContentLength() >= 0) { return true; } if (httpCon != null) { // no HTTP OK status, and no content-length header: give up httpCon.disconnect(); return false; } else { // Fall back to stream existence: can we open the stream? InputStream is = getInputStream(); is.close(); return true; } } } catch (IOException ex) { return false; } } @Override public boolean isReadable() { try { URL url = getURL(); if (ResourceUtils.isFileURL(url)) { // Proceed with file system resolution... File file = getFile(); return (file.canRead() && !file.isDirectory()); } else { return true; } } catch (IOException ex) { return false; } } @Override public long contentLength() throws IOException { URL url = getURL(); if (ResourceUtils.isFileURL(url)) { // Proceed with file system resolution... return super.contentLength(); } else { // Try a URL connection content-length header... URLConnection con = url.openConnection(); con.setUseCaches(false); if (con instanceof HttpURLConnection) { ((HttpURLConnection) con).setRequestMethod("HEAD"); } return con.getContentLength(); } } @Override public long lastModified() throws IOException { URL url = getURL(); if (ResourceUtils.isFileURL(url) || ResourceUtils.isJarURL(url)) { // Proceed with file system resolution... return super.lastModified(); } else { // Try a URL connection last-modified header... URLConnection con = url.openConnection(); con.setUseCaches(false); if (con instanceof HttpURLConnection) { ((HttpURLConnection) con).setRequestMethod("HEAD"); } return con.getLastModified(); } } /** * Inner delegate class, avoiding a hard JBoss VFS API dependency at runtime. */ private static class VfsResourceDelegate { public static Resource getResource(URL url) throws IOException { return new VfsResource(VfsUtils.getRoot(url)); } public static Resource getResource(URI uri) throws IOException { return new VfsResource(VfsUtils.getRoot(uri)); } } } ././@LongLink0000000000000000000000000000017700000000000011572 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/io/AbstractResource.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000001234111623223526033345 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.io; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import org.springframework.core.NestedIOException; import org.springframework.util.ResourceUtils; /** * Convenience base class for {@link Resource} implementations, * pre-implementing typical behavior. * *

The "exists" method will check whether a File or InputStream can * be opened; "isOpen" will always return false; "getURL" and "getFile" * throw an exception; and "toString" will return the description. * * @author Juergen Hoeller * @since 28.12.2003 */ public abstract class AbstractResource implements Resource { /** * This implementation checks whether a File can be opened, * falling back to whether an InputStream can be opened. * This will cover both directories and content resources. */ public boolean exists() { // Try file existence: can we find the file in the file system? try { return getFile().exists(); } catch (IOException ex) { // Fall back to stream existence: can we open the stream? try { InputStream is = getInputStream(); is.close(); return true; } catch (Throwable isEx) { return false; } } } /** * This implementation always returns true. */ public boolean isReadable() { return true; } /** * This implementation always returns false. */ public boolean isOpen() { return false; } /** * This implementation throws a FileNotFoundException, assuming * that the resource cannot be resolved to a URL. */ public URL getURL() throws IOException { throw new FileNotFoundException(getDescription() + " cannot be resolved to URL"); } /** * This implementation builds a URI based on the URL returned * by {@link #getURL()}. */ public URI getURI() throws IOException { URL url = getURL(); try { return ResourceUtils.toURI(url); } catch (URISyntaxException ex) { throw new NestedIOException("Invalid URI [" + url + "]", ex); } } /** * This implementation throws a FileNotFoundException, assuming * that the resource cannot be resolved to an absolute file path. */ public File getFile() throws IOException { throw new FileNotFoundException(getDescription() + " cannot be resolved to absolute file path"); } /** * This implementation checks the timestamp of the underlying File, * if available. * @see #getFile() */ public long contentLength() throws IOException { return getFile().length(); } /** * This implementation checks the timestamp of the underlying File, * if available. * @see #getFileForLastModifiedCheck() */ public long lastModified() throws IOException { long lastModified = getFileForLastModifiedCheck().lastModified(); if (lastModified == 0L) { throw new FileNotFoundException(getDescription() + " cannot be resolved in the file system for resolving its last-modified timestamp"); } return lastModified; } /** * Determine the File to use for timestamp checking. *

The default implementation delegates to {@link #getFile()}. * @return the File to use for timestamp checking (never null) * @throws IOException if the resource cannot be resolved as absolute * file path, i.e. if the resource is not available in a file system */ protected File getFileForLastModifiedCheck() throws IOException { return getFile(); } /** * This implementation throws a FileNotFoundException, assuming * that relative resources cannot be created for this resource. */ public Resource createRelative(String relativePath) throws IOException { throw new FileNotFoundException("Cannot create a relative resource for " + getDescription()); } /** * This implementation always throws IllegalStateException, * assuming that the resource does not have a filename. */ public String getFilename() throws IllegalStateException { throw new IllegalStateException(getDescription() + " does not have a filename"); } /** * This implementation returns the description of this resource. * @see #getDescription() */ @Override public String toString() { return getDescription(); } /** * This implementation compares description strings. * @see #getDescription() */ @Override public boolean equals(Object obj) { return (obj == this || (obj instanceof Resource && ((Resource) obj).getDescription().equals(getDescription()))); } /** * This implementation returns the description's hash code. * @see #getDescription() */ @Override public int hashCode() { return getDescription().hashCode(); } } ././@LongLink0000000000000000000000000000017500000000000011570 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/io/ResourceEditor.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000764311623223526033356 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.io; import java.beans.PropertyEditorSupport; import java.io.IOException; import org.springframework.util.Assert; import org.springframework.util.StringUtils; import org.springframework.util.SystemPropertyUtils; /** * {@link java.beans.PropertyEditor Editor} for {@link Resource} * descriptors, to automatically convert String locations * e.g. "file:C:/myfile.txt" or * "classpath:myfile.txt") to Resource * properties instead of using a String location property. * *

The path may contain ${...} placeholders, * to be resolved as system properties: e.g. ${user.dir}. * Unresolvable placeholder are ignored by default. * *

Delegates to a {@link ResourceLoader} to do the heavy lifting, * by default using a {@link DefaultResourceLoader}. * * @author Juergen Hoeller * @author Dave Syer * @since 28.12.2003 * @see Resource * @see ResourceLoader * @see DefaultResourceLoader * @see org.springframework.util.SystemPropertyUtils#resolvePlaceholders * @see System#getProperty(String) */ public class ResourceEditor extends PropertyEditorSupport { private final ResourceLoader resourceLoader; private final boolean ignoreUnresolvablePlaceholders; /** * Create a new instance of the {@link ResourceEditor} class * using a {@link DefaultResourceLoader}. */ public ResourceEditor() { this(new DefaultResourceLoader()); } /** * Create a new instance of the {@link ResourceEditor} class * using the given {@link ResourceLoader}. * @param resourceLoader the ResourceLoader to use */ public ResourceEditor(ResourceLoader resourceLoader) { this(resourceLoader, true); } /** * Create a new instance of the {@link ResourceEditor} class * using the given {@link ResourceLoader}. * @param resourceLoader the ResourceLoader to use * @param ignoreUnresolvablePlaceholders whether to ignore unresolvable placeholders * if no corresponding system property could be found */ public ResourceEditor(ResourceLoader resourceLoader, boolean ignoreUnresolvablePlaceholders) { Assert.notNull(resourceLoader, "ResourceLoader must not be null"); this.resourceLoader = resourceLoader; this.ignoreUnresolvablePlaceholders = ignoreUnresolvablePlaceholders; } @Override public void setAsText(String text) { if (StringUtils.hasText(text)) { String locationToUse = resolvePath(text).trim(); setValue(this.resourceLoader.getResource(locationToUse)); } else { setValue(null); } } /** * Resolve the given path, replacing placeholders with * corresponding system property values if necessary. * @param path the original file path * @return the resolved file path * @see org.springframework.util.SystemPropertyUtils#resolvePlaceholders */ protected String resolvePath(String path) { return SystemPropertyUtils.resolvePlaceholders(path, this.ignoreUnresolvablePlaceholders); } @Override public String getAsText() { Resource value = (Resource) getValue(); try { // Try to determine URL for resource. return (value != null ? value.getURL().toExternalForm() : ""); } catch (IOException ex) { // Couldn't determine resource URL - return null to indicate // that there is no appropriate text representation. return null; } } } ././@LongLink0000000000000000000000000000016700000000000011571 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/io/Resource.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000001040211623223526033341 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.io; import java.io.File; import java.io.IOException; import java.net.URI; import java.net.URL; /** * Interface for a resource descriptor that abstracts from the actual * type of underlying resource, such as a file or class path resource. * *

An InputStream can be opened for every resource if it exists in * physical form, but a URL or File handle can just be returned for * certain resources. The actual behavior is implementation-specific. * * @author Juergen Hoeller * @since 28.12.2003 * @see #getInputStream() * @see #getURL() * @see #getURI() * @see #getFile() * @see FileSystemResource * @see ClassPathResource * @see UrlResource * @see ByteArrayResource * @see InputStreamResource * @see org.springframework.web.context.support.ServletContextResource */ public interface Resource extends InputStreamSource { /** * Return whether this resource actually exists in physical form. *

This method performs a definitive existence check, whereas the * existence of a Resource handle only guarantees a * valid descriptor handle. */ boolean exists(); /** * Return whether the contents of this resource can be read, * e.g. via {@link #getInputStream()} or {@link #getFile()}. *

Will be true for typical resource descriptors; * note that actual content reading may still fail when attempted. * However, a value of false is a definitive indication * that the resource content cannot be read. */ boolean isReadable(); /** * Return whether this resource represents a handle with an open * stream. If true, the InputStream cannot be read multiple times, * and must be read and closed to avoid resource leaks. *

Will be false for typical resource descriptors. */ boolean isOpen(); /** * Return a URL handle for this resource. * @throws IOException if the resource cannot be resolved as URL, * i.e. if the resource is not available as descriptor */ URL getURL() throws IOException; /** * Return a URI handle for this resource. * @throws IOException if the resource cannot be resolved as URI, * i.e. if the resource is not available as descriptor */ URI getURI() throws IOException; /** * Return a File handle for this resource. * @throws IOException if the resource cannot be resolved as absolute * file path, i.e. if the resource is not available in a file system */ File getFile() throws IOException; /** * Determine the content length for this resource. * @throws IOException if the resource cannot be resolved * (in the file system or as some other known physical resource type) */ long contentLength() throws IOException; /** * Determine the last-modified timestamp for this resource. * @throws IOException if the resource cannot be resolved * (in the file system or as some other known physical resource type) */ long lastModified() throws IOException; /** * Create a resource relative to this resource. * @param relativePath the relative path (relative to this resource) * @return the resource handle for the relative resource * @throws IOException if the relative resource cannot be determined */ Resource createRelative(String relativePath) throws IOException; /** * Return a filename for this resource, i.e. typically the last * part of the path: for example, "myfile.txt". */ String getFilename(); /** * Return a description for this resource, * to be used for error output when working with the resource. *

Implementations are also encouraged to return this value * from their toString method. * @see java.lang.Object#toString() */ String getDescription(); } ././@LongLink0000000000000000000000000000020200000000000011557 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/io/InputStreamResource.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000666411623223526033360 0ustar drazzibdrazzib/* * Copyright 2002-2006 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.io; import java.io.IOException; import java.io.InputStream; /** * {@link Resource} implementation for a given InputStream. Should only * be used if no specific Resource implementation is applicable. * In particular, prefer {@link ByteArrayResource} or any of the * file-based Resource implementations where possible. * *

In contrast to other Resource implementations, this is a descriptor * for an already opened resource - therefore returning "true" from * isOpen(). Do not use it if you need to keep the resource * descriptor somewhere, or if you need to read a stream multiple times. * * @author Juergen Hoeller * @since 28.12.2003 * @see ByteArrayResource * @see ClassPathResource * @see FileSystemResource * @see UrlResource */ public class InputStreamResource extends AbstractResource { private final InputStream inputStream; private final String description; private boolean read = false; /** * Create a new InputStreamResource. * @param inputStream the InputStream to use */ public InputStreamResource(InputStream inputStream) { this(inputStream, "resource loaded through InputStream"); } /** * Create a new InputStreamResource. * @param inputStream the InputStream to use * @param description where the InputStream comes from */ public InputStreamResource(InputStream inputStream, String description) { if (inputStream == null) { throw new IllegalArgumentException("InputStream must not be null"); } this.inputStream = inputStream; this.description = (description != null ? description : ""); } /** * This implementation always returns true. */ @Override public boolean exists() { return true; } /** * This implementation always returns true. */ @Override public boolean isOpen() { return true; } /** * This implementation throws IllegalStateException if attempting to * read the underlying stream multiple times. */ public InputStream getInputStream() throws IOException, IllegalStateException { if (this.read) { throw new IllegalStateException("InputStream has already been read - " + "do not use InputStreamResource if a stream needs to be read multiple times"); } this.read = true; return this.inputStream; } /** * This implementation returns the passed-in description, if any. */ public String getDescription() { return this.description; } /** * This implementation compares the underlying InputStream. */ @Override public boolean equals(Object obj) { return (obj == this || (obj instanceof InputStreamResource && ((InputStreamResource) obj).inputStream.equals(this.inputStream))); } /** * This implementation returns the hash code of the underlying InputStream. */ @Override public int hashCode() { return this.inputStream.hashCode(); } } ././@LongLink0000000000000000000000000000021200000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/io/ClassRelativeResourceLoader.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000441211623223526033345 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.io; import org.springframework.util.Assert; import org.springframework.util.StringUtils; /** * {@link ResourceLoader} implementation that interprets plain resource paths * as relative to a given java.lang.Class. * * @author Juergen Hoeller * @since 3.0 * @see java.lang.Class#getResource(String) * @see ClassPathResource#ClassPathResource(String, Class) */ public class ClassRelativeResourceLoader extends DefaultResourceLoader { private final Class clazz; /** * Create a new ClassRelativeResourceLoader for the given class. * @param clazz the class to load resources through */ public ClassRelativeResourceLoader(Class clazz) { Assert.notNull(clazz, "Class must not be null"); this.clazz = clazz; setClassLoader(clazz.getClassLoader()); } protected Resource getResourceByPath(String path) { return new ClassRelativeContextResource(path, this.clazz); } /** * ClassPathResource that explicitly expresses a context-relative path * through implementing the ContextResource interface. */ private static class ClassRelativeContextResource extends ClassPathResource implements ContextResource { private final Class clazz; public ClassRelativeContextResource(String path, Class clazz) { super(path, clazz); this.clazz = clazz; } public String getPathWithinContext() { return getPath(); } @Override public Resource createRelative(String relativePath) { String pathToUse = StringUtils.applyRelativePath(getPath(), relativePath); return new ClassRelativeContextResource(pathToUse, this.clazz); } } } ././@LongLink0000000000000000000000000000020000000000000011555 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/io/ClassPathResource.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000001661511623223530033350 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.io; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.net.URL; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; /** * {@link Resource} implementation for class path resources. * Uses either a given ClassLoader or a given Class for loading resources. * *

Supports resolution as java.io.File if the class path * resource resides in the file system, but not for resources in a JAR. * Always supports resolution as URL. * * @author Juergen Hoeller * @since 28.12.2003 * @see java.lang.ClassLoader#getResourceAsStream(String) * @see java.lang.Class#getResourceAsStream(String) */ public class ClassPathResource extends AbstractFileResolvingResource { private final String path; private ClassLoader classLoader; private Class clazz; /** * Create a new ClassPathResource for ClassLoader usage. * A leading slash will be removed, as the ClassLoader * resource access methods will not accept it. *

The thread context class loader will be used for * loading the resource. * @param path the absolute path within the class path * @see java.lang.ClassLoader#getResourceAsStream(String) * @see org.springframework.util.ClassUtils#getDefaultClassLoader() */ public ClassPathResource(String path) { this(path, (ClassLoader) null); } /** * Create a new ClassPathResource for ClassLoader usage. * A leading slash will be removed, as the ClassLoader * resource access methods will not accept it. * @param path the absolute path within the classpath * @param classLoader the class loader to load the resource with, * or null for the thread context class loader * @see java.lang.ClassLoader#getResourceAsStream(String) */ public ClassPathResource(String path, ClassLoader classLoader) { Assert.notNull(path, "Path must not be null"); String pathToUse = StringUtils.cleanPath(path); if (pathToUse.startsWith("/")) { pathToUse = pathToUse.substring(1); } this.path = pathToUse; this.classLoader = (classLoader != null ? classLoader : ClassUtils.getDefaultClassLoader()); } /** * Create a new ClassPathResource for Class usage. * The path can be relative to the given class, * or absolute within the classpath via a leading slash. * @param path relative or absolute path within the class path * @param clazz the class to load resources with * @see java.lang.Class#getResourceAsStream */ public ClassPathResource(String path, Class clazz) { Assert.notNull(path, "Path must not be null"); this.path = StringUtils.cleanPath(path); this.clazz = clazz; } /** * Create a new ClassPathResource with optional ClassLoader and Class. * Only for internal usage. * @param path relative or absolute path within the classpath * @param classLoader the class loader to load the resource with, if any * @param clazz the class to load resources with, if any */ protected ClassPathResource(String path, ClassLoader classLoader, Class clazz) { this.path = StringUtils.cleanPath(path); this.classLoader = classLoader; this.clazz = clazz; } /** * Return the path for this resource (as resource path within the class path). */ public final String getPath() { return this.path; } /** * Return the ClassLoader that this resource will be obtained from. */ public final ClassLoader getClassLoader() { return (this.classLoader != null ? this.classLoader : this.clazz.getClassLoader()); } /** * This implementation checks for the resolution of a resource URL. * @see java.lang.ClassLoader#getResource(String) * @see java.lang.Class#getResource(String) */ @Override public boolean exists() { URL url; if (this.clazz != null) { url = this.clazz.getResource(this.path); } else { url = this.classLoader.getResource(this.path); } return (url != null); } /** * This implementation opens an InputStream for the given class path resource. * @see java.lang.ClassLoader#getResourceAsStream(String) * @see java.lang.Class#getResourceAsStream(String) */ public InputStream getInputStream() throws IOException { InputStream is; if (this.clazz != null) { is = this.clazz.getResourceAsStream(this.path); } else { is = this.classLoader.getResourceAsStream(this.path); } if (is == null) { throw new FileNotFoundException( getDescription() + " cannot be opened because it does not exist"); } return is; } /** * This implementation returns a URL for the underlying class path resource. * @see java.lang.ClassLoader#getResource(String) * @see java.lang.Class#getResource(String) */ @Override public URL getURL() throws IOException { URL url; if (this.clazz != null) { url = this.clazz.getResource(this.path); } else { url = this.classLoader.getResource(this.path); } if (url == null) { throw new FileNotFoundException( getDescription() + " cannot be resolved to URL because it does not exist"); } return url; } /** * This implementation creates a ClassPathResource, applying the given path * relative to the path of the underlying resource of this descriptor. * @see org.springframework.util.StringUtils#applyRelativePath(String, String) */ @Override public Resource createRelative(String relativePath) { String pathToUse = StringUtils.applyRelativePath(this.path, relativePath); return new ClassPathResource(pathToUse, this.classLoader, this.clazz); } /** * This implementation returns the name of the file that this class path * resource refers to. * @see org.springframework.util.StringUtils#getFilename(String) */ @Override public String getFilename() { return StringUtils.getFilename(this.path); } /** * This implementation returns a description that includes the class path location. */ public String getDescription() { StringBuilder builder = new StringBuilder("class path resource ["); if (this.clazz != null) { builder.append(ClassUtils.classPackageAsResourcePath(this.clazz)); builder.append('/'); } builder.append(this.path); builder.append(']'); return builder.toString(); } /** * This implementation compares the underlying class path locations. */ @Override public boolean equals(Object obj) { if (obj == this) { return true; } if (obj instanceof ClassPathResource) { ClassPathResource otherRes = (ClassPathResource) obj; return (this.path.equals(otherRes.path) && ObjectUtils.nullSafeEquals(this.classLoader, otherRes.classLoader) && ObjectUtils.nullSafeEquals(this.clazz, otherRes.clazz)); } return false; } /** * This implementation returns the hash code of the underlying * class path location. */ @Override public int hashCode() { return this.path.hashCode(); } } ././@LongLink0000000000000000000000000000017200000000000011565 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/io/UrlResource.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000001315611623223526033352 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core.io; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URI; import java.net.URL; import java.net.URLConnection; import org.springframework.util.Assert; import org.springframework.util.StringUtils; /** * {@link Resource} implementation for java.net.URL locators. * Obviously supports resolution as URL, and also as File in case of * the "file:" protocol. * * @author Juergen Hoeller * @since 28.12.2003 * @see java.net.URL */ public class UrlResource extends AbstractFileResolvingResource { /** * Original URL, used for actual access. */ private final URL url; /** * Cleaned URL (with normalized path), used for comparisons. */ private final URL cleanedUrl; /** * Original URI, if available; used for URI and File access. */ private final URI uri; /** * Create a new UrlResource. * @param url a URL */ public UrlResource(URL url) { Assert.notNull(url, "URL must not be null"); this.url = url; this.cleanedUrl = getCleanedUrl(this.url, url.toString()); this.uri = null; } /** * Create a new UrlResource. * @param uri a URI * @throws MalformedURLException if the given URL path is not valid */ public UrlResource(URI uri) throws MalformedURLException { Assert.notNull(uri, "URI must not be null"); this.url = uri.toURL(); this.cleanedUrl = getCleanedUrl(this.url, uri.toString()); this.uri = uri; } /** * Create a new UrlResource. * @param path a URL path * @throws MalformedURLException if the given URL path is not valid */ public UrlResource(String path) throws MalformedURLException { Assert.notNull(path, "Path must not be null"); this.url = new URL(path); this.cleanedUrl = getCleanedUrl(this.url, path); this.uri = null; } /** * Determine a cleaned URL for the given original URL. * @param originalUrl the original URL * @param originalPath the original URL path * @return the cleaned URL * @see org.springframework.util.StringUtils#cleanPath */ private URL getCleanedUrl(URL originalUrl, String originalPath) { try { return new URL(StringUtils.cleanPath(originalPath)); } catch (MalformedURLException ex) { // Cleaned URL path cannot be converted to URL // -> take original URL. return originalUrl; } } /** * This implementation opens an InputStream for the given URL. * It sets the "UseCaches" flag to false, * mainly to avoid jar file locking on Windows. * @see java.net.URL#openConnection() * @see java.net.URLConnection#setUseCaches(boolean) * @see java.net.URLConnection#getInputStream() */ public InputStream getInputStream() throws IOException { URLConnection con = this.url.openConnection(); con.setUseCaches(false); try { return con.getInputStream(); } catch (IOException ex) { // Close the HTTP connection (if applicable). if (con instanceof HttpURLConnection) { ((HttpURLConnection) con).disconnect(); } throw ex; } } /** * This implementation returns the underlying URL reference. */ @Override public URL getURL() throws IOException { return this.url; } /** * This implementation returns the underlying URI directly, * if possible. */ @Override public URI getURI() throws IOException { if (this.uri != null) { return this.uri; } else { return super.getURI(); } } /** * This implementation returns a File reference for the underlying URL/URI, * provided that it refers to a file in the file system. * @see org.springframework.util.ResourceUtils#getFile(java.net.URL, String) */ @Override public File getFile() throws IOException { if (this.uri != null) { return super.getFile(this.uri); } else { return super.getFile(); } } /** * This implementation creates a UrlResource, applying the given path * relative to the path of the underlying URL of this resource descriptor. * @see java.net.URL#URL(java.net.URL, String) */ @Override public Resource createRelative(String relativePath) throws MalformedURLException { if (relativePath.startsWith("/")) { relativePath = relativePath.substring(1); } return new UrlResource(new URL(this.url, relativePath)); } /** * This implementation returns the name of the file that this URL refers to. * @see java.net.URL#getFile() * @see java.io.File#getName() */ @Override public String getFilename() { return new File(this.url.getFile()).getName(); } /** * This implementation returns a description that includes the URL. */ public String getDescription() { return "URL [" + this.url + "]"; } /** * This implementation compares the underlying URL references. */ @Override public boolean equals(Object obj) { return (obj == this || (obj instanceof UrlResource && this.cleanedUrl.equals(((UrlResource) obj).cleanedUrl))); } /** * This implementation returns the hash code of the underlying URL reference. */ @Override public int hashCode() { return this.cleanedUrl.hashCode(); } } ././@LongLink0000000000000000000000000000017300000000000011566 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/PriorityOrdered.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000327211623223530033343 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core; /** * Extension of the {@link Ordered} interface, expressing a 'priority' * ordering: Order values expressed by PriorityOrdered objects always * apply before order values of 'plain' Ordered values. * *

This is primarily a special-purpose interface, used for objects * where it is particularly important to determine 'prioritized' * objects first, without even obtaining the remaining objects. * A typical example: Prioritized post-processors in a Spring * {@link org.springframework.context.ApplicationContext}. * *

Note: PriorityOrdered post-processor beans are initialized in * a special phase, ahead of other post-processor beans. This subtly * affects their autowiring behavior: They will only be autowired against * beans which do not require eager initialization for type matching. * * @author Juergen Hoeller * @since 2.5 * @see org.springframework.beans.factory.config.PropertyOverrideConfigurer * @see org.springframework.beans.factory.config.PropertyPlaceholderConfigurer */ public interface PriorityOrdered extends Ordered { } ././@LongLink0000000000000000000000000000020200000000000011557 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/NestedCheckedException.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000001011111623223526033336 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core; /** * Handy class for wrapping checked Exceptions with a root cause. * *

This class is abstract to force the programmer to extend * the class. getMessage will include nested exception * information; printStackTrace and other like methods will * delegate to the wrapped exception, if any. * *

The similarity between this class and the {@link NestedRuntimeException} * class is unavoidable, as Java forces these two classes to have different * superclasses (ah, the inflexibility of concrete inheritance!). * * @author Rod Johnson * @author Juergen Hoeller * @see #getMessage * @see #printStackTrace * @see NestedRuntimeException */ public abstract class NestedCheckedException extends Exception { /** Use serialVersionUID from Spring 1.2 for interoperability */ private static final long serialVersionUID = 7100714597678207546L; static { // Eagerly load the NestedExceptionUtils class to avoid classloader deadlock // issues on OSGi when calling getMessage(). Reported by Don Brown; SPR-5607. NestedExceptionUtils.class.getName(); } /** * Construct a NestedCheckedException with the specified detail message. * @param msg the detail message */ public NestedCheckedException(String msg) { super(msg); } /** * Construct a NestedCheckedException with the specified detail message * and nested exception. * @param msg the detail message * @param cause the nested exception */ public NestedCheckedException(String msg, Throwable cause) { super(msg, cause); } /** * Return the detail message, including the message from the nested exception * if there is one. */ @Override public String getMessage() { return NestedExceptionUtils.buildMessage(super.getMessage(), getCause()); } /** * Retrieve the innermost cause of this exception, if any. * @return the innermost exception, or null if none */ public Throwable getRootCause() { Throwable rootCause = null; Throwable cause = getCause(); while (cause != null && cause != rootCause) { rootCause = cause; cause = cause.getCause(); } return rootCause; } /** * Retrieve the most specific cause of this exception, that is, * either the innermost cause (root cause) or this exception itself. *

Differs from {@link #getRootCause()} in that it falls back * to the present exception if there is no root cause. * @return the most specific cause (never null) * @since 2.0.3 */ public Throwable getMostSpecificCause() { Throwable rootCause = getRootCause(); return (rootCause != null ? rootCause : this); } /** * Check whether this exception contains an exception of the given type: * either it is of the given class itself or it contains a nested cause * of the given type. * @param exType the exception type to look for * @return whether there is a nested exception of the specified type */ public boolean contains(Class exType) { if (exType == null) { return false; } if (exType.isInstance(this)) { return true; } Throwable cause = getCause(); if (cause == this) { return false; } if (cause instanceof NestedCheckedException) { return ((NestedCheckedException) cause).contains(exType); } else { while (cause != null) { if (exType.isInstance(cause)) { return true; } if (cause.getCause() == cause) { break; } cause = cause.getCause(); } return false; } } } ././@LongLink0000000000000000000000000000020300000000000011560 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/ParameterNameDiscoverer.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000347511623223530033350 0ustar drazzibdrazzib/* * Copyright 2002-2006 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core; import java.lang.reflect.Constructor; import java.lang.reflect.Method; /** * Interface to discover parameter names for methods and constructors. * *

Parameter name discovery is not always possible, but various strategies are * available to try, such as looking for debug information that may have been * emitted at compile time, and looking for argname annotation values optionally * accompanying AspectJ annotated methods. * * @author Rod Johnson * @author Adrian Colyer * @since 2.0 */ public interface ParameterNameDiscoverer { /** * Return parameter names for this method, * or null if they cannot be determined. * @param method method to find parameter names for * @return an array of parameter names if the names can be resolved, * or null if they cannot */ String[] getParameterNames(Method method); /** * Return parameter names for this constructor, * or null if they cannot be determined. * @param ctor constructor to find parameter names for * @return an array of parameter names if the names can be resolved, * or null if they cannot */ String[] getParameterNames(Constructor ctor); } ././@LongLink0000000000000000000000000000016700000000000011571 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/Conventions.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000002505011623223526033346 0ustar drazzibdrazzib/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core; import java.io.Externalizable; import java.io.Serializable; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; /** * Provides methods to support various naming and other conventions used * throughout the framework. Mainly for internal use within the framework. * * @author Rob Harrop * @author Juergen Hoeller * @since 2.0 */ public abstract class Conventions { /** * Suffix added to names when using arrays. */ private static final String PLURAL_SUFFIX = "List"; /** * Set of interfaces that are supposed to be ignored * when searching for the 'primary' interface of a proxy. */ private static final Set ignoredInterfaces = new HashSet(); static { ignoredInterfaces.add(Serializable.class); ignoredInterfaces.add(Externalizable.class); ignoredInterfaces.add(Cloneable.class); ignoredInterfaces.add(Comparable.class); } /** * Determine the conventional variable name for the supplied * Object based on its concrete type. The convention * used is to return the uncapitalized short name of the Class, * according to JavaBeans property naming rules: So, * com.myapp.Product becomes product; * com.myapp.MyProduct becomes myProduct; * com.myapp.UKProduct becomes UKProduct. *

For arrays, we use the pluralized version of the array component type. * For Collections we attempt to 'peek ahead' in the * Collection to determine the component type and * return the pluralized version of that component type. * @param value the value to generate a variable name for * @return the generated variable name */ public static String getVariableName(Object value) { Assert.notNull(value, "Value must not be null"); Class valueClass; boolean pluralize = false; if (value.getClass().isArray()) { valueClass = value.getClass().getComponentType(); pluralize = true; } else if (value instanceof Collection) { Collection collection = (Collection) value; if (collection.isEmpty()) { throw new IllegalArgumentException("Cannot generate variable name for an empty Collection"); } Object valueToCheck = peekAhead(collection); valueClass = getClassForValue(valueToCheck); pluralize = true; } else { valueClass = getClassForValue(value); } String name = ClassUtils.getShortNameAsProperty(valueClass); return (pluralize ? pluralize(name) : name); } /** * Determine the conventional variable name for the supplied parameter, * taking the generic collection type (if any) into account. * @param parameter the method or constructor parameter to generate a variable name for * @return the generated variable name */ public static String getVariableNameForParameter(MethodParameter parameter) { Assert.notNull(parameter, "MethodParameter must not be null"); Class valueClass; boolean pluralize = false; if (parameter.getParameterType().isArray()) { valueClass = parameter.getParameterType().getComponentType(); pluralize = true; } else if (Collection.class.isAssignableFrom(parameter.getParameterType())) { valueClass = GenericCollectionTypeResolver.getCollectionParameterType(parameter); if (valueClass == null) { throw new IllegalArgumentException( "Cannot generate variable name for non-typed Collection parameter type"); } pluralize = true; } else { valueClass = parameter.getParameterType(); } String name = ClassUtils.getShortNameAsProperty(valueClass); return (pluralize ? pluralize(name) : name); } /** * Determine the conventional variable name for the return type of the supplied method, * taking the generic collection type (if any) into account. * @param method the method to generate a variable name for * @return the generated variable name */ public static String getVariableNameForReturnType(Method method) { return getVariableNameForReturnType(method, method.getReturnType(), null); } /** * Determine the conventional variable name for the return type of the supplied method, * taking the generic collection type (if any) into account, falling back to the * given return value if the method declaration is not specific enough (i.e. in case of * the return type being declared as Object or as untyped collection). * @param method the method to generate a variable name for * @param value the return value (may be null if not available) * @return the generated variable name */ public static String getVariableNameForReturnType(Method method, Object value) { return getVariableNameForReturnType(method, method.getReturnType(), value); } /** * Determine the conventional variable name for the return type of the supplied method, * taking the generic collection type (if any) into account, falling back to the * given return value if the method declaration is not specific enough (i.e. in case of * the return type being declared as Object or as untyped collection). * @param method the method to generate a variable name for * @param resolvedType the resolved return type of the method * @param value the return value (may be null if not available) * @return the generated variable name */ public static String getVariableNameForReturnType(Method method, Class resolvedType, Object value) { Assert.notNull(method, "Method must not be null"); if (Object.class.equals(resolvedType)) { if (value == null) { throw new IllegalArgumentException("Cannot generate variable name for an Object return type with null value"); } return getVariableName(value); } Class valueClass; boolean pluralize = false; if (resolvedType.isArray()) { valueClass = resolvedType.getComponentType(); pluralize = true; } else if (Collection.class.isAssignableFrom(resolvedType)) { valueClass = GenericCollectionTypeResolver.getCollectionReturnType(method); if (valueClass == null) { if (!(value instanceof Collection)) { throw new IllegalArgumentException( "Cannot generate variable name for non-typed Collection return type and a non-Collection value"); } Collection collection = (Collection) value; if (collection.isEmpty()) { throw new IllegalArgumentException( "Cannot generate variable name for non-typed Collection return type and an empty Collection value"); } Object valueToCheck = peekAhead(collection); valueClass = getClassForValue(valueToCheck); } pluralize = true; } else { valueClass = resolvedType; } String name = ClassUtils.getShortNameAsProperty(valueClass); return (pluralize ? pluralize(name) : name); } /** * Convert Strings in attribute name format (lowercase, hyphens separating words) * into property name format (camel-cased). For example, transaction-manager is * converted into transactionManager. */ public static String attributeNameToPropertyName(String attributeName) { Assert.notNull(attributeName, "'attributeName' must not be null"); if (!attributeName.contains("-")) { return attributeName; } char[] chars = attributeName.toCharArray(); char[] result = new char[chars.length -1]; // not completely accurate but good guess int currPos = 0; boolean upperCaseNext = false; for (char c : chars) { if (c == '-') { upperCaseNext = true; } else if (upperCaseNext) { result[currPos++] = Character.toUpperCase(c); upperCaseNext = false; } else { result[currPos++] = c; } } return new String(result, 0, currPos); } /** * Return an attribute name qualified by the supplied enclosing {@link Class}. For example, * the attribute name 'foo' qualified by {@link Class} 'com.myapp.SomeClass' * would be 'com.myapp.SomeClass.foo' */ public static String getQualifiedAttributeName(Class enclosingClass, String attributeName) { Assert.notNull(enclosingClass, "'enclosingClass' must not be null"); Assert.notNull(attributeName, "'attributeName' must not be null"); return enclosingClass.getName() + "." + attributeName; } /** * Determines the class to use for naming a variable that contains * the given value. *

Will return the class of the given value, except when * encountering a JDK proxy, in which case it will determine * the 'primary' interface implemented by that proxy. * @param value the value to check * @return the class to use for naming a variable */ private static Class getClassForValue(Object value) { Class valueClass = value.getClass(); if (Proxy.isProxyClass(valueClass)) { Class[] ifcs = valueClass.getInterfaces(); for (Class ifc : ifcs) { if (!ignoredInterfaces.contains(ifc)) { return ifc; } } } else if (valueClass.getName().lastIndexOf('$') != -1 && valueClass.getDeclaringClass() == null) { // '$' in the class name but no inner class - // assuming it's a special subclass (e.g. by OpenJPA) valueClass = valueClass.getSuperclass(); } return valueClass; } /** * Pluralize the given name. */ private static String pluralize(String name) { return name + PLURAL_SUFFIX; } /** * Retrieves the Class of an element in the Collection. * The exact element for which the Class is retreived will depend * on the concrete Collection implementation. */ private static Object peekAhead(Collection collection) { Iterator it = collection.iterator(); if (!it.hasNext()) { throw new IllegalStateException( "Unable to peek ahead in non-empty collection - no element found"); } Object value = it.next(); if (value == null) { throw new IllegalStateException( "Unable to peek ahead in non-empty collection - only null element found"); } return value; } } ././@LongLink0000000000000000000000000000016700000000000011571 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/ControlFlow.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000273411623223526033352 0ustar drazzibdrazzib/* * Copyright 2002-2005 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core; /** * Interface to be implemented by objects that can return information about * the current call stack. Useful in AOP (as in AspectJ cflow concept) * but not AOP-specific. * * @author Rod Johnson * @since 02.02.2004 */ public interface ControlFlow { /** * Detect whether we're under the given class, * according to the current stack trace. * @param clazz the clazz to look for */ boolean under(Class clazz); /** * Detect whether we're under the given class and method, * according to the current stack trace. * @param clazz the clazz to look for * @param methodName the name of the method to look for */ boolean under(Class clazz, String methodName); /** * Detect whether the current stack trace contains the given token. * @param token the token to look for */ boolean underToken(String token); } ././@LongLink0000000000000000000000000000016500000000000011567 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/Constants.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000002710111623223530033340 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core; import java.lang.reflect.Field; import java.util.HashMap; import java.util.HashSet; import java.util.Locale; import java.util.Map; import java.util.Set; import org.springframework.util.Assert; import org.springframework.util.ReflectionUtils; /** * This class can be used to parse other classes containing constant definitions * in public static final members. The asXXXX methods of this class * allow these constant values to be accessed via their string names. * *

Consider class Foo containing public final static int CONSTANT1 = 66; * An instance of this class wrapping Foo.class will return the constant value * of 66 from its asNumber method given the argument "CONSTANT1". * *

This class is ideal for use in PropertyEditors, enabling them to * recognize the same names as the constants themselves, and freeing them * from maintaining their own mapping. * * @author Rod Johnson * @author Juergen Hoeller * @since 16.03.2003 */ public class Constants { /** The name of the introspected class */ private final String className; /** Map from String field name to object value */ private final Map fieldCache = new HashMap(); /** * Create a new Constants converter class wrapping the given class. *

All public static final variables will be exposed, whatever their type. * @param clazz the class to analyze * @throws IllegalArgumentException if the supplied clazz is null */ public Constants(Class clazz) { Assert.notNull(clazz); this.className = clazz.getName(); Field[] fields = clazz.getFields(); for (Field field : fields) { if (ReflectionUtils.isPublicStaticFinal(field)) { String name = field.getName(); try { Object value = field.get(null); this.fieldCache.put(name, value); } catch (IllegalAccessException ex) { // just leave this field and continue } } } } /** * Return the name of the analyzed class. */ public final String getClassName() { return this.className; } /** * Return the number of constants exposed. */ public final int getSize() { return this.fieldCache.size(); } /** * Exposes the field cache to subclasses: * a Map from String field name to object value. */ protected final Map getFieldCache() { return this.fieldCache; } /** * Return a constant value cast to a Number. * @param code the name of the field (never null) * @return the Number value * @see #asObject * @throws ConstantException if the field name wasn't found * or if the type wasn't compatible with Number */ public Number asNumber(String code) throws ConstantException { Object obj = asObject(code); if (!(obj instanceof Number)) { throw new ConstantException(this.className, code, "not a Number"); } return (Number) obj; } /** * Return a constant value as a String. * @param code the name of the field (never null) * @return the String value * Works even if it's not a string (invokes toString()). * @see #asObject * @throws ConstantException if the field name wasn't found */ public String asString(String code) throws ConstantException { return asObject(code).toString(); } /** * Parse the given String (upper or lower case accepted) and return * the appropriate value if it's the name of a constant field in the * class that we're analysing. * @param code the name of the field (never null) * @return the Object value * @throws ConstantException if there's no such field */ public Object asObject(String code) throws ConstantException { Assert.notNull(code, "Code must not be null"); String codeToUse = code.toUpperCase(Locale.ENGLISH); Object val = this.fieldCache.get(codeToUse); if (val == null) { throw new ConstantException(this.className, codeToUse, "not found"); } return val; } /** * Return all names of the given group of constants. *

Note that this method assumes that constants are named * in accordance with the standard Java convention for constant * values (i.e. all uppercase). The supplied namePrefix * will be uppercased (in a locale-insensitive fashion) prior to * the main logic of this method kicking in. * @param namePrefix prefix of the constant names to search (may be null) * @return the set of constant names */ public Set getNames(String namePrefix) { String prefixToUse = (namePrefix != null ? namePrefix.trim().toUpperCase(Locale.ENGLISH) : ""); Set names = new HashSet(); for (String code : this.fieldCache.keySet()) { if (code.startsWith(prefixToUse)) { names.add(code); } } return names; } /** * Return all names of the group of constants for the * given bean property name. * @param propertyName the name of the bean property * @return the set of values * @see #propertyToConstantNamePrefix */ public Set getNamesForProperty(String propertyName) { return getNames(propertyToConstantNamePrefix(propertyName)); } /** * Return all names of the given group of constants. *

Note that this method assumes that constants are named * in accordance with the standard Java convention for constant * values (i.e. all uppercase). The supplied nameSuffix * will be uppercased (in a locale-insensitive fashion) prior to * the main logic of this method kicking in. * @param nameSuffix suffix of the constant names to search (may be null) * @return the set of constant names */ public Set getNamesForSuffix(String nameSuffix) { String suffixToUse = (nameSuffix != null ? nameSuffix.trim().toUpperCase(Locale.ENGLISH) : ""); Set names = new HashSet(); for (String code : this.fieldCache.keySet()) { if (code.endsWith(suffixToUse)) { names.add(code); } } return names; } /** * Return all values of the given group of constants. *

Note that this method assumes that constants are named * in accordance with the standard Java convention for constant * values (i.e. all uppercase). The supplied namePrefix * will be uppercased (in a locale-insensitive fashion) prior to * the main logic of this method kicking in. * @param namePrefix prefix of the constant names to search (may be null) * @return the set of values */ public Set getValues(String namePrefix) { String prefixToUse = (namePrefix != null ? namePrefix.trim().toUpperCase(Locale.ENGLISH) : ""); Set values = new HashSet(); for (String code : this.fieldCache.keySet()) { if (code.startsWith(prefixToUse)) { values.add(this.fieldCache.get(code)); } } return values; } /** * Return all values of the group of constants for the * given bean property name. * @param propertyName the name of the bean property * @return the set of values * @see #propertyToConstantNamePrefix */ public Set getValuesForProperty(String propertyName) { return getValues(propertyToConstantNamePrefix(propertyName)); } /** * Return all values of the given group of constants. *

Note that this method assumes that constants are named * in accordance with the standard Java convention for constant * values (i.e. all uppercase). The supplied nameSuffix * will be uppercased (in a locale-insensitive fashion) prior to * the main logic of this method kicking in. * @param nameSuffix suffix of the constant names to search (may be null) * @return the set of values */ public Set getValuesForSuffix(String nameSuffix) { String suffixToUse = (nameSuffix != null ? nameSuffix.trim().toUpperCase(Locale.ENGLISH) : ""); Set values = new HashSet(); for (String code : this.fieldCache.keySet()) { if (code.endsWith(suffixToUse)) { values.add(this.fieldCache.get(code)); } } return values; } /** * Look up the given value within the given group of constants. *

Will return the first match. * @param value constant value to look up * @param namePrefix prefix of the constant names to search (may be null) * @return the name of the constant field * @throws ConstantException if the value wasn't found */ public String toCode(Object value, String namePrefix) throws ConstantException { String prefixToUse = (namePrefix != null ? namePrefix.trim().toUpperCase(Locale.ENGLISH) : null); for (Map.Entry entry : this.fieldCache.entrySet()) { if (entry.getKey().startsWith(prefixToUse) && entry.getValue().equals(value)) { return entry.getKey(); } } throw new ConstantException(this.className, prefixToUse, value); } /** * Look up the given value within the group of constants for * the given bean property name. Will return the first match. * @param value constant value to look up * @param propertyName the name of the bean property * @return the name of the constant field * @throws ConstantException if the value wasn't found * @see #propertyToConstantNamePrefix */ public String toCodeForProperty(Object value, String propertyName) throws ConstantException { return toCode(value, propertyToConstantNamePrefix(propertyName)); } /** * Look up the given value within the given group of constants. *

Will return the first match. * @param value constant value to look up * @param nameSuffix suffix of the constant names to search (may be null) * @return the name of the constant field * @throws ConstantException if the value wasn't found */ public String toCodeForSuffix(Object value, String nameSuffix) throws ConstantException { String suffixToUse = (nameSuffix != null ? nameSuffix.trim().toUpperCase(Locale.ENGLISH) : null); for (Map.Entry entry : this.fieldCache.entrySet()) { if (entry.getKey().endsWith(suffixToUse) && entry.getValue().equals(value)) { return entry.getKey(); } } throw new ConstantException(this.className, suffixToUse, value); } /** * Convert the given bean property name to a constant name prefix. *

Uses a common naming idiom: turning all lower case characters to * upper case, and prepending upper case characters with an underscore. *

Example: "imageSize" -> "IMAGE_SIZE"
* Example: "imagesize" -> "IMAGESIZE".
* Example: "ImageSize" -> "_IMAGE_SIZE".
* Example: "IMAGESIZE" -> "_I_M_A_G_E_S_I_Z_E" * @param propertyName the name of the bean property * @return the corresponding constant name prefix * @see #getValuesForProperty * @see #toCodeForProperty */ public String propertyToConstantNamePrefix(String propertyName) { StringBuilder parsedPrefix = new StringBuilder(); for(int i = 0; i < propertyName.length(); i++) { char c = propertyName.charAt(i); if (Character.isUpperCase(c)) { parsedPrefix.append("_"); parsedPrefix.append(c); } else { parsedPrefix.append(Character.toUpperCase(c)); } } return parsedPrefix.toString(); } } ././@LongLink0000000000000000000000000000020700000000000011564 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/NamedInheritableThreadLocal.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000000250111623223526033342 0ustar drazzibdrazzib/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core; import org.springframework.util.Assert; /** * {@link InheritableThreadLocal} subclass that exposes a specified name * as {@link #toString()} result (allowing for introspection). * * @author Juergen Hoeller * @since 2.5.2 * @see NamedThreadLocal */ public class NamedInheritableThreadLocal extends InheritableThreadLocal { private final String name; /** * Create a new NamedInheritableThreadLocal with the given name. * @param name a descriptive name for this ThreadLocal */ public NamedInheritableThreadLocal(String name) { Assert.hasText(name, "Name must not be empty"); this.name = name; } @Override public String toString() { return this.name; } }././@LongLink0000000000000000000000000000017700000000000011572 Lustar rootrootlibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/core/GenericTypeResolver.javalibspring-java-3.0.6.RELEASE/projects/org.springframework.core/src/main/java/org/springframework/cor0000644000175000017500000003256111623223526033353 0ustar drazzibdrazzib/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core; import java.lang.ref.Reference; import java.lang.ref.WeakReference; import java.lang.reflect.Array; import java.lang.reflect.GenericArrayType; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.WeakHashMap; import org.springframework.util.Assert; /** * Helper class for resolving generic types against type variables. * *

Mainly intended for usage within the framework, resolving method * parameter types even when they are declared generically. * * @author Juergen Hoeller * @author Rob Harrop * @since 2.5.2 * @see GenericCollectionTypeResolver * @see JdkVersion */ public abstract class GenericTypeResolver { /** Cache from Class to TypeVariable Map */ private static final Map>> typeVariableCache = Collections.synchronizedMap(new WeakHashMap>>()); /** * Determine the target type for the given parameter specification. * @param methodParam the method parameter specification * @return the corresponding generic parameter type */ public static Type getTargetType(MethodParameter methodParam) { Assert.notNull(methodParam, "MethodParameter must not be null"); if (methodParam.getConstructor() != null) { return methodParam.getConstructor().getGenericParameterTypes()[methodParam.getParameterIndex()]; } else { if (methodParam.getParameterIndex() >= 0) { return methodParam.getMethod().getGenericParameterTypes()[methodParam.getParameterIndex()]; } else { return methodParam.getMethod().getGenericReturnType(); } } } /** * Determine the target type for the given generic parameter type. * @param methodParam the method parameter specification * @param clazz the class to resolve type variables against * @return the corresponding generic parameter or return type */ public static Class resolveParameterType(MethodParameter methodParam, Class clazz) { Type genericType = getTargetType(methodParam); Assert.notNull(clazz, "Class must not be null"); Map typeVariableMap = getTypeVariableMap(clazz); Type rawType = getRawType(genericType, typeVariableMap); Class result = (rawType instanceof Class ? (Class) rawType : methodParam.getParameterType()); methodParam.setParameterType(result); methodParam.typeVariableMap = typeVariableMap; return result; } /** * Determine the target type for the generic return type of the given method. * @param method the method to introspect * @param clazz the class to resolve type variables against * @return the corresponding generic parameter or return type */ public static Class resolveReturnType(Method method, Class clazz) { Assert.notNull(method, "Method must not be null"); Type genericType = method.getGenericReturnType(); Assert.notNull(clazz, "Class must not be null"); Map typeVariableMap = getTypeVariableMap(clazz); Type rawType = getRawType(genericType, typeVariableMap); return (rawType instanceof Class ? (Class) rawType : method.getReturnType()); } /** * Resolve the single type argument of the given generic interface against * the given target class which is assumed to implement the generic interface * and possibly declare a concrete type for its type variable. * @param clazz the target class to check against * @param genericIfc the generic interface or superclass to resolve the type argument from * @return the resolved type of the argument, or null if not resolvable */ public static Class resolveTypeArgument(Class clazz, Class genericIfc) { Class[] typeArgs = resolveTypeArguments(clazz, genericIfc); if (typeArgs == null) { return null; } if (typeArgs.length != 1) { throw new IllegalArgumentException("Expected 1 type argument on generic interface [" + genericIfc.getName() + "] but found " + typeArgs.length); } return typeArgs[0]; } /** * Resolve the type arguments of the given generic interface against the given * target class which is assumed to implement the generic interface and possibly * declare concrete types for its type variables. * @param clazz the target class to check against * @param genericIfc the generic interface or superclass to resolve the type argument from * @return the resolved type of each argument, with the array size matching the * number of actual type arguments, or null if not resolvable */ public static Class[] resolveTypeArguments(Class clazz, Class genericIfc) { return doResolveTypeArguments(clazz, clazz, genericIfc); } private static Class[] doResolveTypeArguments(Class ownerClass, Class classToIntrospect, Class genericIfc) { while (classToIntrospect != null) { if (genericIfc.isInterface()) { Type[] ifcs = classToIntrospect.getGenericInterfaces(); for (Type ifc : ifcs) { Class[] result = doResolveTypeArguments(ownerClass, ifc, genericIfc); if (result != null) { return result; } } } else { Class[] result = doResolveTypeArguments( ownerClass, classToIntrospect.getGenericSuperclass(), genericIfc); if (result != null) { return result; } } classToIntrospect = classToIntrospect.getSuperclass(); } return null; } private static Class[] doResolveTypeArguments(Class ownerClass, Type ifc, Class genericIfc) { if (ifc instanceof ParameterizedType) { ParameterizedType paramIfc = (ParameterizedType) ifc; Type rawType = paramIfc.getRawType(); if (genericIfc.equals(rawType)) { Type[] typeArgs = paramIfc.getActualTypeArguments(); Class[] result = new Class[typeArgs.length]; for (int i = 0; i < typeArgs.length; i++) { Type arg = typeArgs[i]; result[i] = extractClass(ownerClass, arg); } return result; } else if (genericIfc.isAssignableFrom((Class) rawType)) { return doResolveTypeArguments(ownerClass, (Class) rawType, genericIfc); } } else if (genericIfc.isAssignableFrom((Class) ifc)) { return doResolveTypeArguments(ownerClass, (Class) ifc, genericIfc); } return null; } /** * Extract a class instance from given Type. */ private static Class extractClass(Class ownerClass, Type arg) { if (arg instanceof ParameterizedType) { return extractClass(ownerClass, ((ParameterizedType) arg).getRawType()); } else if (arg instanceof GenericArrayType) { GenericArrayType gat = (GenericArrayType) arg; Type gt = gat.getGenericComponentType(); Class componentClass = extractClass(ownerClass, gt); return Array.newInstance(componentClass, 0).getClass(); } else if (arg instanceof TypeVariable) { TypeVariable tv = (TypeVariable) arg; arg = getTypeVariableMap(ownerClass).get(tv); if (arg == null) { arg = extractBoundForTypeVariable(tv); } else { arg = extractClass(ownerClass, arg); } } return (arg instanceof Class ? (Class) arg : Object.class); } /** * Resolve the specified generic type against the given TypeVariable map. * @param genericType the generic type to resolve * @param typeVariableMap the TypeVariable Map to resolved against * @return the type if it resolves to a Class, or Object.class otherwise */ static Class resolveType(Type genericType, Map typeVariableMap) { Type rawType = getRawType(genericType, typeVariableMap); return (rawType instanceof Class ? (Class) rawType : Object.class); } /** * Determine the raw type for the given generic parameter type. * @param genericType the generic type to resolve * @param typeVariableMap the TypeVariable Map to resolved against * @return the resolved raw type */ static Type getRawType(Type genericType, Map typeVariableMap) { Type resolvedType = genericType; if (genericType instanceof TypeVariable) { TypeVariable tv = (TypeVariable) genericType; resolvedType = typeVariableMap.get(tv); if (resolvedType == null) { resolvedType = extractBoundForTypeVariable(tv); } } if (resolvedType instanceof ParameterizedType) { return ((ParameterizedType) resolvedType).getRawType(); } else { return resolvedType; } } /** * Build a mapping of {@link TypeVariable#getName TypeVariable names} to concrete * {@link Class} for the specified {@link Class}. Searches all super types, * enclosing types and interfaces. */ static Map getTypeVariableMap(Class clazz) { Reference> ref = typeVariableCache.get(clazz); Map typeVariableMap = (ref != null ? ref.get() : null); if (typeVariableMap == null) { typeVariableMap = new HashMap(); // interfaces extractTypeVariablesFromGenericInterfaces(clazz.getGenericInterfaces(), typeVariableMap); // super class Type genericType = clazz.getGenericSuperclass(); Class type = clazz.getSuperclass(); while (type != null && !Object.class.equals(type)) { if (genericType instanceof ParameterizedType) { ParameterizedType pt = (ParameterizedType) genericType; populateTypeMapFromParameterizedType(pt, typeVariableMap); } extractTypeVariablesFromGenericInterfaces(type.getGenericInterfaces(), typeVariableMap); genericType = type.getGenericSuperclass(); type = type.getSuperclass(); } // enclosing class type = clazz; while (type.isMemberClass()) { genericType = type.getGenericSuperclass(); if (genericType instanceof ParameterizedType) { ParameterizedType pt = (ParameterizedType) genericType; populateTypeMapFromParameterizedType(pt, typeVariableMap); } type = type.getEnclosingClass(); } typeVariableCache.put(clazz, new WeakReference>(typeVariableMap)); } return typeVariableMap; } /** * Extracts the bound Type for a given {@link TypeVariable}. */ static Type extractBoundForTypeVariable(TypeVariable typeVariable) { Type[] bounds = typeVariable.getBounds(); if (bounds.length == 0) { return Object.class; } Type bound = bounds[0]; if (bound instanceof TypeVariable) { bound = extractBoundForTypeVariable((TypeVariable) bound); } return bound; } private static void extractTypeVariablesFromGenericInterfaces(Type[] genericInterfaces, Map typeVariableMap) { for (Type genericInterface : genericInterfaces) { if (genericInterface instanceof ParameterizedType) { ParameterizedType pt = (ParameterizedType) genericInterface; populateTypeMapFromParameterizedType(pt, typeVariableMap); if (pt.getRawType() instanceof Class) { extractTypeVariablesFromGenericInterfaces( ((Class) pt.getRawType()).getGenericInterfaces(), typeVariableMap); } } else if (genericInterface instanceof Class) { extractTypeVariablesFromGenericInterfaces( ((Class) genericInterface).getGenericInterfaces(), typeVariableMap); } } } /** * Read the {@link TypeVariable TypeVariables} from the supplied {@link ParameterizedType} * and add mappings corresponding to the {@link TypeVariable#getName TypeVariable name} -> * concrete type to the supplied {@link Map}. *

Consider this case: *