import org.wamblee.reflection.AnnotationUtils;
/**
- * This class represents an injection binding. It provides injection of a defined object (typically mock or stub)
- * into other objects. The binding is defined by the required annotation that must be on the field, the field type,
- * and the object to be injected.
+ * This class represents an injection binding. It provides injection of a
+ * defined object (typically mock or stub) into other objects. The binding is
+ * defined by the required annotation that must be on the field, the field type,
+ * and the object to be injected.
*
* @author Erik Brakkee
- *
+ *
* @param <T>
*/
public class Binding<T> {
private Map<Class, List<Accessor>> accessorCache;
/**
- * Constructs the binding.
- * @param aClass Required type of the field injected into.
- * @param aAnnotation Annotation that must be present on the field.
- * @param aValue Value of the annotation.
+ * Constructs the binding.
+ *
+ * @param aClass
+ * Required type of the field injected into.
+ * @param aAnnotation
+ * Annotation that must be present on the field.
+ * @param aValue
+ * Value of the annotation.
*/
public Binding(Class<T> aClass, Class<? extends Annotation> aAnnotation,
Object aValue) {
* </p>
*
* <p>
- * It works by first delegating to the default injector (typically CDI). Afterwards it traverses the
- * object graph of the injected object and performs custom injection of test objects as specified by the
- * {@link Binding} class. This approach makes sure that test dependencies also find their way into
- * objects that were created by the injection framework.
+ * It works by first delegating to the default injector (typically CDI).
+ * Afterwards it traverses the object graph of the injected object and performs
+ * custom injection of test objects as specified by the {@link Binding} class.
+ * This approach makes sure that test dependencies also find their way into
+ * objects that were created by the injection framework.
* </p>
*
* @author Erik Brakkee
private class InjectionVisitor implements ObjectVisitor {
@Override
public boolean mustVisit(Class aClass) {
- if (EntityManager.class.isAssignableFrom(aClass)) {
+ if (EntityManager.class.isAssignableFrom(aClass)) {
return false;
}
return true;
}
+
@Override
public boolean mustVisit(Field aField) {
// just process any field with annotations
- return aField.getAnnotations().length > 0;
+ return aField.getAnnotations().length > 0;
}
+
@Override
public boolean mustVisit(Method aMethod) {
return false;
}
+
@Override
public boolean visitArray(Object aArray) {
return true;
}
+
@Override
public boolean visitList(List aObject) {
return true;
}
+
@Override
public boolean visitMap(Map aObject) {
return true;
}
+
@Override
public boolean visitPlainObject(Object aObject) {
performTestInjections(aObject);
return true;
}
+
@Override
public boolean visitSet(Set aSet) {
return true;
public void inject(Object aComponent) {
// basic injection
delegate.inject(aComponent);
-
+
// Now perform test injections.
ObjectTraversal traversal = new ObjectTraversal(new InjectionVisitor());
traversal.accept(aComponent);
/**
* <p>
- * The test injector factory provides dependency injection of a contextual entity manager
- * using the support/inject mini framework. It supports dependency injection of fields
- * annoted with <code>@PersistenceContext</code>. It only supports one persistence context
- * at the moment. This injector can be easily used together with {@link JpaBuilder#getContextualEntityManager()}
- * for obtaining an entity manager in unit test.
+ * The test injector factory provides dependency injection of a contextual
+ * entity manager using the support/inject mini framework. It supports
+ * dependency injection of fields annoted with
+ * <code>@PersistenceContext</code>. It only supports one persistence
+ * context at the moment. This injector can be easily used together with
+ * {@link JpaBuilder#getContextualEntityManager()} for obtaining an entity
+ * manager in unit test.
* </p>
*
* <p>
- * The reason it is needed is because standard injection mechanisms (such as weld CDI) do not support
- * entity manager injection in a Java SE environment out of the box.
+ * The reason it is needed is because standard injection mechanisms (such as
+ * weld CDI) do not support entity manager injection in a Java SE environment
+ * out of the box.
* </p>
- *
+ *
* <p>
- * To use it, construct the factory using one of the available constructors and set
- * <code>InjectorBuilder.setInjectorFactory(InjectorFactory)</code>.
+ * To use it, construct the factory using one of the available constructors and
+ * set <code>InjectorBuilder.setInjectorFactory(InjectorFactory)</code>.
* </p>
*
* @author Erik Brakkee
- *
+ *
*/
public class JavaEETestInjectorFactory implements InjectorFactory {
private List<Binding> bindings;
private InjectorFactory delegate;
-
+
/**
- * Constructs the factory.
- * @param aInjectorFactory Injector factory to delegate to.
+ * Constructs the factory.
+ *
+ * @param aInjectorFactory
+ * Injector factory to delegate to.
*/
public JavaEETestInjectorFactory(InjectorFactory aInjectorFactory) {
- bindings = new ArrayList<Binding>();
+ bindings = new ArrayList<Binding>();
delegate = aInjectorFactory;
}
/**
- * Adds default entity manager binding. Any field annotated with @PersistenceContext and of type
- * entity manager will get injected.
- * @param aEntityManager Entitymanager object to inject.
+ * Adds default entity manager binding. Any field annotated with @PersistenceContext
+ * and of type entity manager will get injected.
+ *
+ * @param aEntityManager
+ * Entitymanager object to inject.
* @return Factory to allow chaining.
*/
- public JavaEETestInjectorFactory addEntityManagerBinding(EntityManager aEntityManager) {
- Binding em = new Binding(EntityManager.class, PersistenceContext.class, aEntityManager);
+ public JavaEETestInjectorFactory addEntityManagerBinding(
+ EntityManager aEntityManager) {
+ Binding em = new Binding(EntityManager.class, PersistenceContext.class,
+ aEntityManager);
addBinding(em);
return this;
}
-
+
/**
- * Adds another custom injection binding.
- * @param aBinding Injection binding to use.
+ * Adds another custom injection binding.
+ *
+ * @param aBinding
+ * Injection binding to use.
* @return the factoryto allow chaining.
*/
- public JavaEETestInjectorFactory addBinding(Binding aBinding) {
+ public JavaEETestInjectorFactory addBinding(Binding aBinding) {
bindings.add(aBinding);
- return this;
+ return this;
}
/**
- * Constructs the factory with the default injector factory obtained from
- * {@link InjectorBuilder#getInjector()}.
+ * Constructs the factory with the default injector factory obtained from
+ * {@link InjectorBuilder#getInjector()}.
*/
public JavaEETestInjectorFactory() {
this(getDefaultInjectorFactory());
@Override
public Injector create(Class aClass) {
- return new JavaEETestInjector(aClass, bindings, delegate
- .create(aClass));
+ return new JavaEETestInjector(aClass, bindings, delegate.create(aClass));
}
}
import javax.naming.NamingException;
/**
- * Initial context implementation.
+ * Initial context implementation.
*
* @author Erik Brakkee
*/
public void bind(String aName, Object aObj) throws NamingException {
bindings.put(aName, aObj);
}
-
+
@Override
public void unbind(String aName) throws NamingException {
bindings.remove(aName);
}
return value;
}
-
+
@Override
public void bind(Name aName, Object aObj) throws NamingException {
bind(aName.toString(), aObj);
}
-
+
@Override
public void unbind(Name aName) throws NamingException {
unbind(aName.toString());
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- */
+ */
package org.wamblee.test.jndi;
import java.util.Hashtable;
*
* See {@link #bind(String, Object)} to resp. register the initial context.
*
- * To start mocking the JNDI tree, call {@link #register()}.
+ * To start mocking the JNDI tree, call {@link #register()}.
+ *
+ * To bind objects in the JNDI tree simply use the standard JNDI api:
*
- * To bind objects in the JNDI tree simply use the standard JNDI api:
* <pre>
* InitialContext context = new InitialContext();
* MyClass myObj = ...;
- * context.bind("a/b", myObj);
+ * context.bind("a/b", myObj);
* </pre>
*
- * When finished with a test case, call {@link #unregister()} to unregister the
- * JNDI tree again.
+ * When finished with a test case, call {@link #unregister()} to unregister the
+ * JNDI tree again.
*/
public class StubInitialContextFactory implements InitialContextFactory {
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- */
+ */
/**
* This package provides utilities for JNDI testing.
*
import org.apache.commons.pool.impl.GenericObjectPool;
/**
- * Abstract database class providing the creation of the datasource,
- * preventing duplicate starts of the same database, and checking
- * for connection leaks when the database is stopped.
+ * Abstract database class providing the creation of the datasource, preventing
+ * duplicate starts of the same database, and checking for connection leaks when
+ * the database is stopped.
*
* @author Erik Brakkee
- *
+ *
*/
public abstract class AbstractDatabase implements Database {
private boolean started;
/**
- * Constructs the database.
+ * Constructs the database.
*/
protected AbstractDatabase() {
started = false;
}
/**
- * To be implemented by subclasses to start the database.
+ * To be implemented by subclasses to start the database.
*/
protected abstract void doStart();
/**
- * To be implemented by subclasses to stop the database.
+ * To be implemented by subclasses to stop the database.
*/
protected abstract void doStop();
// / BELOW THIS LINE IS NOT OF INTEREST TO SUBCLASSES.
/**
- * Starts the database.
+ * Starts the database.
*/
public final DataSource start() {
if (started) {
}
/**
- * Stops the database and tests for connection leaks.
- * In cast the system property with the name given by {@link #IGNORE_CONNECTION_LEAK_PROPERTY}
- * is set then the connection leaks are not checked.
+ * Stops the database and tests for connection leaks. In cast the system
+ * property with the name given by {@link #IGNORE_CONNECTION_LEAK_PROPERTY}
+ * is set then the connection leaks are not checked.
*/
public final void stop() {
if (!started) {
String msg = "JDBC connection pool still has " +
connectionPool.getNumActive() +
" active connection(s), this is a potential resource leak in the code\n";
- // backdoor to ignore connection leaks. Use this system property only if you
- // can safely ignore the connection leaks.
+ // backdoor to ignore connection leaks. Use this system property
+ // only if you
+ // can safely ignore the connection leaks.
if (System.getProperty(IGNORE_CONNECTION_LEAK_PROPERTY) == null) {
Assert.fail(msg);
}
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- */
+ */
package org.wamblee.test.persistence;
import java.util.List;
+
/**
- * Base class for database providers.
+ * Base class for database providers.
*
* @author Erik Brakkee
*/
public abstract class AbstractDatabaseProvider implements DatabaseProvider {
/**
- * @return List of database capabilities.
+ * @return List of database capabilities.
*/
protected abstract List<String> getCapabilities();
/**
- * Standard implementation of the capabalities check.
+ * Standard implementation of the capabalities check.
*/
public final boolean supportsCapabilities(String[] aCapabilities) {
for (String capability : aCapabilities) {
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- */
+ */
package org.wamblee.test.persistence;
import java.util.List;
import org.dbunit.dataset.filter.ITableFilterSimple;
/**
- * Composite JPA customizer that applies the customizations from several
- * JPA customizers.
+ * Composite JPA customizer that applies the customizations from several JPA
+ * customizers.
*
* @author Erik Brakkee
*/
private CompositeJpaTables tables;
/**
- * Construcst the customizer.
- * @param aCustomizers List of customizers.
+ * Construcst the customizer.
+ *
+ * @param aCustomizers
+ * List of customizers.
*/
public CompositeJpaCustomizer(List<JpaCustomizer> aCustomizers) {
customizers = aCustomizers;
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- */
+ */
package org.wamblee.test.persistence;
import java.util.ArrayList;
import org.dbunit.dataset.filter.ITableFilterSimple;
/**
- * Composite JPA tables. Implements the logical or of several table filters.
+ * Composite JPA tables. Implements the logical or of several table filters.
*
* @author Erik Brakkee
*/
private List<ITableFilterSimple> tables;
/**
- * Construcst the tables.
+ * Construcst the tables.
*/
public CompositeJpaTables() {
tables = new ArrayList<ITableFilterSimple>();
}
/**
- * Adds a table filter.
- * @param aFilter filter.
+ * Adds a table filter.
+ *
+ * @param aFilter
+ * filter.
*/
public void add(ITableFilterSimple aFilter) {
tables.add(aFilter);
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- */
+ */
package org.wamblee.test.persistence;
import javax.sql.DataSource;
* database has been started.
*/
DataSource start();
-
+
/**
- * Gets the number of active connections from the pool. This is useful for
- * determining resource leaks.
- * @return Active connections.
+ * Gets the number of active connections from the pool. This is useful for
+ * determining resource leaks.
+ *
+ * @return Active connections.
*/
- int getActiveConnections();
+ int getActiveConnections();
/**
* Gets the Jdbc Url to connect to this database.
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- */
+ */
package org.wamblee.test.persistence;
import java.util.ArrayList;
*/
public static final String DB_CAPABILITIES_PROP = "TEST_DB_CAPABILITIES";
- private static ServiceLoader<DatabaseProvider> LOADER =
- ServiceLoader.load(DatabaseProvider.class);
+ private static ServiceLoader<DatabaseProvider> LOADER = ServiceLoader
+ .load(DatabaseProvider.class);
/**
- * Constructs the database builder.
+ * Constructs the database builder.
*/
private DatabaseBuilder() {
// Empty.
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- */
+ */
package org.wamblee.test.persistence;
/**
for (int i = 0; i < itsCapabilities.length; i++) {
res.append(itsCapabilities[i]);
if (i < itsCapabilities.length - 1) {
- res.append(", ");
+ res.append(", ");
}
}
return res.toString();
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- */
+ */
package org.wamblee.test.persistence;
/**
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- */
+ */
package org.wamblee.test.persistence;
/**
/**
* Represents a set of tables.
- *
+ *
* @author Erik Brakkee
*/
public static interface TableSet {
* Represents a unit of work (transaction).
*
* @author Erik Brakkee
- *
- * @param <T> Type of return value.
+ *
+ * @param <T>
+ * Type of return value.
*/
public static interface JdbcUnitOfWork<T> {
/**
- * Executes statement within a transaction.
- * @param aConnection Connection.
- * @return Result of the work.
+ * Executes statement within a transaction.
+ *
+ * @param aConnection
+ * Connection.
+ * @return Result of the work.
* @throws Exception
*/
T execute(Connection aConnection) throws Exception;
}
/**
- * Operation to be executed on a set of tables for each table
- * individually.
+ * Operation to be executed on a set of tables for each table individually.
*
* @author Erik Brakkee
*/
public static interface TableSetOperation {
/**
- * Executes on a table.
- * @param aTable Table name.
+ * Executes on a table.
+ *
+ * @param aTable
+ * Table name.
* @throws Exception
*/
void execute(String aTable) throws Exception;
private IDatabaseTester dbtester;
/**
- * List of connections that were created for dbtesters.
- * This list will be closed in the {@link #stop()} method.
+ * List of connections that were created for dbtesters. This list will be
+ * closed in the {@link #stop()} method.
*/
- private List<IDatabaseConnection> connections;
-
+ private List<IDatabaseConnection> connections;
+
/**
- * Constructs the database utils.
- * Before use, {@link #start()} must be called.
- * @param aDataSource Datasource.
+ * Constructs the database utils. Before use, {@link #start()} must be
+ * called.
+ *
+ * @param aDataSource
+ * Datasource.
*/
public DatabaseUtils(DataSource aDataSource) {
dataSource = aDataSource;
dbtester = new DataSourceDatabaseTester(dataSource);
- connections = new ArrayList<IDatabaseConnection>();
+ connections = new ArrayList<IDatabaseConnection>();
}
/**
- * Starts the database utils.
+ * Starts the database utils.
*/
- public void start() {
- // Empty. No operation currently.
+ public void start() {
+ // Empty. No operation currently.
}
/**
* Stops the database utils, closing any JDBC connections that were created
- * by this utility. Note that connections obtained from the datasource directly
- * must still be closed by the user. The involved connections are only those that
- * are created by this utility.
+ * by this utility. Note that connections obtained from the datasource
+ * directly must still be closed by the user. The involved connections are
+ * only those that are created by this utility.
*/
public void stop() {
- for (IDatabaseConnection connection: connections) {
+ for (IDatabaseConnection connection : connections) {
try {
connection.close();
} catch (SQLException e) {
}
/**
- * Creates database tester.
- * @param aTables Tables to create the tester for.
- * @return Database tester.
+ * Creates database tester.
+ *
+ * @param aTables
+ * Tables to create the tester for.
+ * @return Database tester.
* @throws Exception
*/
- public IDatabaseTester createDbTester(ITableFilterSimple aTables) throws Exception {
+ public IDatabaseTester createDbTester(ITableFilterSimple aTables)
+ throws Exception {
return createDbTester(getTableNames(aTables));
}
-
+
/**
- * Creates database tester.
- * @param aTables Tables to create the tester for.
- * @return Database tester.
+ * Creates database tester.
+ *
+ * @param aTables
+ * Tables to create the tester for.
+ * @return Database tester.
* @throws Exception
*/
public IDatabaseTester createDbTester(String[] aTables) throws Exception {
}
/**
- * Executes an operation on a set of tables.
- * @param aTables Tables.
- * @param aOperation Operation.
+ * Executes an operation on a set of tables.
+ *
+ * @param aTables
+ * Tables.
+ * @param aOperation
+ * Operation.
* @throws Exception
*/
public void executeOnTables(ITableFilterSimple aTables,
}
/**
- * Cleans a number of database tables. This means deleting the content not dropping the tables.
- * This may fail in case of cyclic dependencies between the tables (current limitation).
- * @param aSelection Tables.
+ * Cleans a number of database tables. This means deleting the content not
+ * dropping the tables. This may fail in case of cyclic dependencies between
+ * the tables (current limitation).
+ *
+ * @param aSelection
+ * Tables.
* @throws Exception
*/
public void cleanDatabase(ITableFilterSimple aSelection) throws Exception {
}
/**
- * Executes a unit of work within a transaction.
- * @param <T> Result type of th ework.
- * @param aWork Unit of work.
+ * Executes a unit of work within a transaction.
+ *
+ * @param <T>
+ * Result type of th ework.
+ * @param aWork
+ * Unit of work.
* @return
* @throws Exception
*/
- public <T> T executeInTransaction(JdbcUnitOfWork<T> aWork)
- throws Exception {
+ public <T> T executeInTransaction(JdbcUnitOfWork<T> aWork) throws Exception {
Connection connection = dataSource.getConnection();
connection.setAutoCommit(false);
try {
connection.close();
}
}
-
+
/**
- * Returns table names based on a table filter.
- * @param aSelection Table filter.
- * @return Table names.
+ * Returns table names based on a table filter.
+ *
+ * @param aSelection
+ * Table filter.
+ * @return Table names.
* @throws Exception
*/
public String[] getTableNames(ITableFilterSimple aSelection)
}
/**
- * Use {@link #cleanDatabase(ITableFilterSimple)} instead.
+ * Use {@link #cleanDatabase(ITableFilterSimple)} instead.
*/
@Deprecated
public void emptyTables(final ITableFilterSimple aSelection)
}
/**
- * User {@link #cleanDatabase(ITableFilterSimple)} instead.
+ * User {@link #cleanDatabase(ITableFilterSimple)} instead.
*/
@Deprecated
public void emptyTable(String aTable) throws Exception {
}
/**
- * Drops tables. This only works if there are no cyclic dependencies between the tables.
- * @param aTables Tables to drop.
+ * Drops tables. This only works if there are no cyclic dependencies between
+ * the tables.
+ *
+ * @param aTables
+ * Tables to drop.
* @throws Exception
*/
public void dropTables(ITableFilterSimple aTables) throws Exception {
}
/**
- * Drops a table.
- * @param aTable Table to drop.
+ * Drops a table.
+ *
+ * @param aTable
+ * Table to drop.
* @throws Exception
*/
public void dropTable(final String aTable) throws Exception {
}
/**
- * Executes an update.
- * @param aConnection Connection to use.
- * @param aSql SQL update to use.
- * @param aArgs Arguments to the update.
- * @return Number of rows updated.
+ * Executes an update.
+ *
+ * @param aConnection
+ * Connection to use.
+ * @param aSql
+ * SQL update to use.
+ * @param aArgs
+ * Arguments to the update.
+ * @return Number of rows updated.
*/
public int executeUpdate(Connection aConnection, final String aSql,
final Object... aArgs) {
}
/**
- * Gets the table size.
- * @param aTable Table.
- * @return Table size.
+ * Gets the table size.
+ *
+ * @param aTable
+ * Table.
+ * @return Table size.
* @throws SQLException
*/
public int getTableSize(final String aTable) throws Exception {
}
/**
- * Counts the results in a result set.
- * @param aResultSet Resultset.
- * @return Number of rows in the set.
+ * Counts the results in a result set.
+ *
+ * @param aResultSet
+ * Resultset.
+ * @return Number of rows in the set.
* @throws SQLException
*/
public int countResultSet(ResultSet aResultSet) throws SQLException {
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- */
+ */
package org.wamblee.test.persistence;
import java.util.Arrays;
import java.util.List;
/**
- * Derby database provider.
+ * Derby database provider.
*
* @author Erik Brakkee
*/
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- */
+ */
package org.wamblee.test.persistence;
-
/**
* Database that encapsulates connection to an external database. Database
* connection details can be configured through system properties and
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- */
+ */
package org.wamblee.test.persistence;
import java.util.Arrays;
import java.util.List;
/**
- * Database provider for an external database.
+ * Database provider for an external database.
*
* @author Erik Brakkee
*/
*
* This method requires the transaction to succeed. Otherwise the test will
* fail. See {@link #execute(JpaUnitOfWork, TransactionResultCallback)} and
- * {@link RequireTransactionStatus} for more possibilities.
+ * {@link RequireTransactionStatus} for more possibilities.
*
* @param aWork
* Work to execute.
* @return The return value of the execute method of the unit of work.
*/
public <T> T execute(JpaUnitOfWork<T> aWork) throws Exception {
- return execute(aWork, new RequireTransactionStatus(TransactionResult.COMMIT));
+ return execute(aWork, new RequireTransactionStatus(
+ TransactionResult.COMMIT));
}
-
+
/**
* Executes a unit of work. This creates an entitymanager and runs the
* {@link JpaUnitOfWork#execute(EntityManager)} within a transaction,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- */
+ */
package org.wamblee.test.persistence;
import java.util.Map;
public interface JpaCustomizer {
/**
- * Customizes the persistence unit through properties.
- * @param aPersistenceUnit Persistence unit.
- * @param aJpaProperties Current properties.
+ * Customizes the persistence unit through properties.
+ *
+ * @param aPersistenceUnit
+ * Persistence unit.
+ * @param aJpaProperties
+ * Current properties.
*/
void customize(PersistenceUnitDescription aPersistenceUnit,
Map<String, String> aJpaProperties);
/**
- * Gets the tables specific to the JPA provider.
- * @return Tables.
+ * Gets the tables specific to the JPA provider.
+ *
+ * @return Tables.
*/
ITableFilterSimple getJpaTables();
}
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- */
+ */
package org.wamblee.test.persistence;
import java.util.ArrayList;
import java.util.ServiceLoader;
/**
- * JPA customizer builder implements the {@link ServiceLoader} based mechanism for looking up
- * JPA customizers.
+ * JPA customizer builder implements the {@link ServiceLoader} based mechanism
+ * for looking up JPA customizers.
*/
public class JpaCustomizerBuilder {
.load(JpaCustomizer.class);
/**
- * Gets the customizer to use. This is a composite customizer that combines all customizers that
- * were found.
- * @return JPA customizer.
+ * Gets the customizer to use. This is a composite customizer that combines
+ * all customizers that were found.
+ *
+ * @return JPA customizer.
*/
public static JpaCustomizer getCustomizer() {
List<JpaCustomizer> customizers = new ArrayList<JpaCustomizer>();
private DataSource dataSource;
private DatabaseUtils dbUtils;
private JpaBuilder jpaBuilder;
-
+
/**
* Constructs the tester.
*
public void start() throws Exception {
db = DatabaseBuilder.getDatabase();
dataSource = db.start();
-
- // NOTE: adding datasource to JNDI is no longer needed for
- // JPA testing, but is nice to have available for other uses.
+
+ // NOTE: adding datasource to JNDI is no longer needed for
+ // JPA testing, but is nice to have available for other uses.
StubInitialContextFactory.register();
try {
InitialContext ctx = new InitialContext();
dbUtils.start();
dbUtils.dropTables(JpaCustomizerBuilder.getCustomizer().getJpaTables());
- jpaBuilder = new JpaBuilder(db.getJdbcUrl(), db.getUsername(), db.getPassword(), persistenceUnit);
+ jpaBuilder = new JpaBuilder(db.getJdbcUrl(), db.getUsername(), db
+ .getPassword(), persistenceUnit);
jpaBuilder.start();
}
}
/**
- * Gets the database.
- * @return Database.
+ * Gets the database.
+ *
+ * @return Database.
*/
public Database getDb() {
return db;
}
/**
- * Gets the datasource.
- * @return Datasource.
+ * Gets the datasource.
+ *
+ * @return Datasource.
*/
public DataSource getDataSource() {
return dataSource;
}
/**
- * Gets the database utilities.
- * @return Database utilities.
+ * Gets the database utilities.
+ *
+ * @return Database utilities.
*/
public DatabaseUtils getDbUtils() {
return dbUtils;
}
/**
- * Gets the jpa builder.
- * @return JPA builder.
+ * Gets the jpa builder.
+ *
+ * @return JPA builder.
*/
public JpaBuilder getJpaBuilder() {
return jpaBuilder;
}
/**
- * Gets the persistence unit.
- * @return Persistence unit.
+ * Gets the persistence unit.
+ *
+ * @return Persistence unit.
*/
public PersistenceUnitDescription getPersistenceUnit() {
return persistenceUnit;
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- */
+ */
package org.wamblee.test.persistence;
import java.util.logging.Level;
/**
* Logging the result of a transaction.
+ *
* @author Erik Brakkee
- *
+ *
*/
public class LoggingTransactionResultCallback implements
TransactionResultCallback {
-
- private static final Logger LOGGER = Logger.getLogger(LoggingTransactionResultCallback.class.getName());
-
- private Level level;
-
- public LoggingTransactionResultCallback(Level aLevel) {
- level = aLevel;
+
+ private static final Logger LOGGER = Logger
+ .getLogger(LoggingTransactionResultCallback.class.getName());
+
+ private Level level;
+
+ public LoggingTransactionResultCallback(Level aLevel) {
+ level = aLevel;
}
@Override
public void status(TransactionResult aResult) {
- LOGGER.log(level, "Transaction result " + aResult);
+ LOGGER.log(level, "Transaction result " + aResult);
}
}
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- */
+ */
package org.wamblee.test.persistence;
-
/**
- * Describes a persistence unit.
+ * Describes a persistence unit.
*
* @author Erik Brakkee
*/
private String unitName;
/**
- * Constructs the description.
- * @param aJndiName Jndi name.
- * @param aUnitName Persistence unit name.
+ * Constructs the description.
+ *
+ * @param aJndiName
+ * Jndi name.
+ * @param aUnitName
+ * Persistence unit name.
*/
public PersistenceUnitDescription(String aJndiName, String aUnitName) {
jndiName = aJndiName;
}
/**
- * @return JNDI name.
+ * @return JNDI name.
*/
public String getJndiName() {
return jndiName;
}
/**
- * Persistence unit name.
+ * Persistence unit name.
*/
public String getUnitName() {
return unitName;
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- */
+ */
package org.wamblee.test.persistence;
import org.wamblee.test.transactions.TransactionResult;
import static junit.framework.Assert.*;
/**
- * Specific transaction result callback to require a specific transaction result.
+ * Specific transaction result callback to require a specific transaction
+ * result.
+ *
* @author Erik Brakkee
- *
+ *
*/
public class RequireTransactionStatus implements TransactionResultCallback {
- private TransactionResult result;
-
+ private TransactionResult result;
+
/**
- * Constructs the callback.
- * @param aResult Required result.
+ * Constructs the callback.
+ *
+ * @param aResult
+ * Required result.
*/
- public RequireTransactionStatus(TransactionResult aResult) {
+ public RequireTransactionStatus(TransactionResult aResult) {
result = aResult;
}
-
+
@Override
public void status(TransactionResult aResult) {
- if (!result.equals(aResult)) {
- fail("Required transaction result was " + result + " but actual result was " + aResult);
+ if (!result.equals(aResult)) {
+ fail("Required transaction result was " + result +
+ " but actual result was " + aResult);
}
}
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- */
+ */
package org.wamblee.test.persistence;
import org.wamblee.test.transactions.TransactionResult;
*/
public interface TransactionResultCallback {
/**
- * Result notification.
- * @param aResult Transaction result.
+ * Result notification.
+ *
+ * @param aResult
+ * Transaction result.
*/
void status(TransactionResult aResult);
}
\ No newline at end of file
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- */
+ */
/**
* <p>
* This package provides test library for database testing in general and JPA testing
*/
package org.wamblee.test.persistence;
-
import javax.transaction.UserTransaction;
/**
- * Transaction factory implementation that creates {@link SimpleUserTransaction} objects.
+ * Transaction factory implementation that creates {@link SimpleUserTransaction}
+ * objects.
*
* @author Erik Brakkee
- *
+ *
*/
public class DefaultUserTransactionFactory implements UserTransactionFactory {
/**
- * Constructs the factory.
+ * Constructs the factory.
*/
- public DefaultUserTransactionFactory() {
- // Empty.
+ public DefaultUserTransactionFactory() {
+ // Empty.
}
-
+
@Override
public UserTransaction create(UserTransactionCallback aCallback,
List<TransactionResource> aResources) {
- return new SimpleUserTransaction(aCallback, aResources.toArray(new TransactionResource[0]));
+ return new SimpleUserTransaction(aCallback, aResources
+ .toArray(new TransactionResource[0]));
}
}
transactionFInishedCallback = new UserTransactionCallback() {
@Override
public void transactionFinished() {
- transaction.set(factory.create(this, resources));
+ transaction.set(factory.create(this, resources));
}
};
transaction = new ThreadSpecificProxyFactory<UserTransaction>(
public UserTransaction getTransaction() {
return transaction.getProxy();
}
-
+
/**
* Gets the thread-specific transaction object.
*
@Override
public void rollback() throws IllegalStateException, SecurityException,
SystemException {
- if ( status == Status.STATUS_NO_TRANSACTION) {
- throw new IllegalStateException("Rollback while not in a transaction");
+ if (status == Status.STATUS_NO_TRANSACTION) {
+ throw new IllegalStateException(
+ "Rollback while not in a transaction");
}
try {
for (int i = 0; i < resources.length; i++) {
resources[i].rollback(txStates[i]);
}
} catch (Exception e) {
- committing = false;
+ committing = false;
}
}
-
- if (!committing) {
+
+ if (!committing) {
throw new HeuristicMixedException("Commit failed");
}
} finally {
@Override
public void setRollbackOnly() throws IllegalStateException, SystemException {
- if ( status == Status.STATUS_NO_TRANSACTION) {
- throw new IllegalStateException("setRollbackOnly() while not in a transaction");
+ if (status == Status.STATUS_NO_TRANSACTION) {
+ throw new IllegalStateException(
+ "setRollbackOnly() while not in a transaction");
}
status = Status.STATUS_MARKED_ROLLBACK;
}
*/
package org.wamblee.test.transactions;
-
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* This utility makes sure that each invocation on a certain interface is
- * carried out within a JPA unit of work. Note that this is equivalent
- * to the sementics of a requiresNew transaction attribute.
+ * carried out within a JPA unit of work. Note that this is equivalent to the
+ * sementics of a requiresNew transaction attribute.
*
* Use {@link #getTransactionScopedEntityManager()} to get the transaction
* scoped entity manager to pass to services.
*
*
- * For example:
+ * For example:
+ *
* <pre>
* JpaBuilder builder = ...
* TransactionProxyFactory<Service> factory = new TransactionProxyFactory<Service>(
* builder, Service.class);
* Service service = new JpaService(factory.getTransactionScopedEntityManager());
* Service proxy = factory.getProxy(service);
- * proxy.executeMethod(...);
+ * proxy.executeMethod(...);
* </pre>
- * The above example executes the executeMethod() call on the service object within an active transaction.
- * In the constructor of the service a transaction scoped entity manager is passed.
+ *
+ * The above example executes the executeMethod() call on the service object
+ * within an active transaction. In the constructor of the service a transaction
+ * scoped entity manager is passed.
*
* @param T
* Type of interface to proxy.
public class TransactionProxyFactory<T> {
/**
- * Executes the call on the service within a new transaction.
+ * Executes the call on the service within a new transaction.
*
* @author Erik Brakkee
- *
- * @param <T> Type of the service interface.
+ *
+ * @param <T>
+ * Type of the service interface.
*/
private class UnitOfWorkInvocationHandler<T> implements InvocationHandler {
@Override
public Object invoke(Object aProxy, final Method aMethod,
final Object[] aArgs) throws Throwable {
- return TransactionProxyFactory.this.jpaBuilder
- .execute(new JpaUnitOfWork<Object>() {
+ return TransactionProxyFactory.this.jpaBuilder.execute(
+ new JpaUnitOfWork<Object>() {
@Override
public Object execute(EntityManager aEm) throws Exception {
- EntityManager oldEm = ENTITY_MANAGER.get();
+ EntityManager oldEm = ENTITY_MANAGER.get();
try {
ENTITY_MANAGER.set(aEm);
return aMethod.invoke(service, aArgs);
*/
package org.wamblee.test.transactions;
-
/**
- * Interfaces to be implemented by resources that want to participate in transactions
- * managed through {@link SimpleTransactionManager}.
+ * Interfaces to be implemented by resources that want to participate in
+ * transactions managed through {@link SimpleTransactionManager}.
*
* @author Erik Brakkee
- *
+ *
* @param <T>
*/
public interface TransactionResource<T> {
-
+
/**
- * Begins a transaction.
+ * Begins a transaction.
+ *
* @return Object that manages the transaction for the resource.
*/
- T begin();
-
+ T begin();
+
/**
* Rolls back a transaction.
- * @param aT Object that manages the transaction for the resource.
+ *
+ * @param aT
+ * Object that manages the transaction for the resource.
*/
- TransactionResult rollback(T aT);
-
+ TransactionResult rollback(T aT);
+
/**
- * Commits the transaction.
- * @param aT Object that manages the transaction for the resource.
+ * Commits the transaction.
+ *
+ * @param aT
+ * Object that manages the transaction for the resource.
*/
TransactionResult commit(T aT);
-
+
}
package org.wamblee.test.transactions;
/**
- * Transaction result.
+ * Transaction result.
*
* @author Erik Brakkee
*/
-public enum TransactionResult {
+public enum TransactionResult {
/**
- * Nothing was done. The transaction was committed or rolled back by the application.
- * Most likely an exception occurred and the transaction was rolled back.
+ * Nothing was done. The transaction was committed or rolled back by the
+ * application. Most likely an exception occurred and the transaction was
+ * rolled back.
*/
- UNKNOWN,
-
+ UNKNOWN,
+
/**
- * Transaction was committed.
+ * Transaction was committed.
*/
COMMIT,
-
+
/**
* Tranasction was rolled back.
*/
*/
package org.wamblee.test.transactions;
-public interface UserTransactionCallback {
- void transactionFinished();
+public interface UserTransactionCallback {
+ void transactionFinished();
}
\ No newline at end of file
import javax.transaction.UserTransaction;
/**
- * Factory used to create transactions.
+ * Factory used to create transactions.
*
* @author Erik Brakkee
- *
+ *
*/
public interface UserTransactionFactory {
- UserTransaction create(UserTransactionCallback aCallback, List<TransactionResource> aResources);
+ UserTransaction create(UserTransactionCallback aCallback,
+ List<TransactionResource> aResources);
}
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- */
+ */
/**
* <p>
* This package provides basic support utilities for testing with transactions.
@Test
public void testXyz() {
EntityManager em = mock(EntityManager.class);
- InjectorBuilder.setInjectorFactory(new JavaEETestInjectorFactory().addEntityManagerBinding(em));
+ InjectorBuilder.setInjectorFactory(new JavaEETestInjectorFactory()
+ .addEntityManagerBinding(em));
X x = new X();
public static class Y {
@PersistenceContext
- Integer wrongType;
+ private Integer wrongType;
}
@Test
public void testWrongType() {
EntityManager em = mock(EntityManager.class);
- InjectorBuilder.setInjectorFactory(new JavaEETestInjectorFactory().addEntityManagerBinding(em));
+ InjectorBuilder.setInjectorFactory(new JavaEETestInjectorFactory()
+ .addEntityManagerBinding(em));
Y y = new Y();
InjectorBuilder.getInjector().inject(y);
assertNull(y.wrongType);
public static @interface MyAnnotation {
}
-
+
public static class Z {
@MyAnnotation
private int x;
-
+
// any annotation will force traversal.
@Mock
- private Z z;
+ private Z z;
}
assertEquals(100, z.x);
assertEquals(100, z.z.x);
}
-
-
+
}
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- */
+ */
package org.wamblee.test.jndi;
import static junit.framework.Assert.*;
InitialContext ctx = new InitialContext();
ctx.bind(JNDI_NAME, "hallo");
}
-
+
// String based lookups.
@Test
assertEquals("hallo", obj);
}
-
+
@Test(expected = NameNotFoundException.class)
- public void testUnbind() throws Exception {
- testLookup();
- InitialContext ctx = new InitialContext();
+ public void testUnbind() throws Exception {
+ testLookup();
+ InitialContext ctx = new InitialContext();
ctx.unbind(JNDI_NAME);
ctx = new InitialContext();
ctx.lookup(JNDI_NAME);
-
+
}
@Test(expected = NameNotFoundException.class)
StubInitialContextFactory.register();
InitialContext ctx = new InitialContext();
- Object obj = ctx.lookup(JNDI_NAME);
+ ctx.lookup(JNDI_NAME);
}
-
+
// Name based lookups
-
+
@Test
public void testLookupName() throws Exception {
StubInitialContextFactory.register();
assertEquals("hallo", obj);
}
-
+
@Test(expected = NameNotFoundException.class)
- public void testUnbindName() throws Exception {
- testLookup();
- InitialContext ctx = new InitialContext();
+ public void testUnbindName() throws Exception {
+ testLookup();
+ InitialContext ctx = new InitialContext();
ctx.unbind(new CompositeName(JNDI_NAME));
ctx = new InitialContext();
ctx.lookup(new CompositeName(JNDI_NAME));
StubInitialContextFactory.register();
InitialContext ctx = new InitialContext();
- Object obj = ctx.lookup(JNDI_NAME);
+ ctx.lookup(JNDI_NAME);
}
}
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- */
+ */
package org.wamblee.test.persistence;
import org.junit.Test;
System.out.println(description);
}
}
-
+
@Test
- public void testConnectionLeak() {
+ public void testConnectionLeak() {
Database db = DatabaseBuilder.getDatabase();
db.start();
assertEquals(0, db.getActiveConnections());
public class DatabaseUtilsLeakTest {
private Database db;
- private DatabaseUtils dbutils;
-
+ private DatabaseUtils dbutils;
+
@Before
- public void setUp() {
+ public void setUp() {
db = DatabaseBuilder.getDatabase();
- DataSource ds = db.start();
-
+ DataSource ds = db.start();
+
dbutils = new DatabaseUtils(ds);
}
-
+
@After
- public void tearDown() {
- db.stop();
+ public void tearDown() {
+ db.stop();
}
-
+
@Test
public void testLeak() throws Exception {
- assertEquals(0, db.getActiveConnections());
+ assertEquals(0, db.getActiveConnections());
dbutils.dropTables(new MyTables());
assertEquals(0, db.getActiveConnections());
}
-
-
+
}
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- */
+ */
package org.wamblee.test.persistence;
import static junit.framework.Assert.assertEquals;
dbutils.dropTables(new MyTables());
dbutils.dropTables(JpaCustomizerBuilder.getCustomizer().getJpaTables());
- builder = new JpaBuilder(db.getJdbcUrl(), db.getUsername(), db.getPassword(), persistenceUnit);
+ builder = new JpaBuilder(db.getJdbcUrl(), db.getUsername(), db
+ .getPassword(), persistenceUnit);
builder.start();
assertEquals(0, db.getActiveConnections());
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- */
+ */
package org.wamblee.test.persistence;
import java.sql.Connection;
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- */
+ */
package org.wamblee.test.persistence;
import java.sql.Connection;
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- */
+ */
package org.wamblee.test.persistence;
import javax.persistence.Entity;
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- */
+ */
package org.wamblee.test.persistence;
import org.wamblee.test.persistence.PersistenceUnitDescription;
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- */
+ */
package org.wamblee.test.persistence;
import org.dbunit.dataset.DataSetException;
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- */
+ */
package org.wamblee.test.persistence;
import junit.framework.AssertionFailedError;
public class RequireTransactionStatusTest {
@Test
- public void testResultOk() {
- RequireTransactionStatus callback = new RequireTransactionStatus(TransactionResult.ROLLBACK);
+ public void testResultOk() {
+ RequireTransactionStatus callback = new RequireTransactionStatus(
+ TransactionResult.ROLLBACK);
callback.status(TransactionResult.ROLLBACK);
- // if we get here everything is ok.
+ // if we get here everything is ok.
}
-
+
@Test(expected = AssertionFailedError.class)
- public void testResultWrong() {
- RequireTransactionStatus callback = new RequireTransactionStatus(TransactionResult.COMMIT);
+ public void testResultWrong() {
+ RequireTransactionStatus callback = new RequireTransactionStatus(
+ TransactionResult.COMMIT);
callback.status(TransactionResult.ROLLBACK);
}
}
public class SimpleTransactionManagerIntegrationTest {
-
private TransactionResource resource1;
private TransactionResource resource2;
private Object tx1;
private Object tx2;
- private SimpleTransactionManager manager;
-
+ private SimpleTransactionManager manager;
+
@Before
public void setUp() {
- UserTransactionFactory factory = new DefaultUserTransactionFactory();
- manager = new SimpleTransactionManager(factory);
+ UserTransactionFactory factory = new DefaultUserTransactionFactory();
+ manager = new SimpleTransactionManager(factory);
resource1 = mock(TransactionResource.class);
resource2 = mock(TransactionResource.class);
tx1 = mock(Object.class);
}
@Test
- public void testTwoTransactions() throws Exception {
+ public void testTwoTransactions() throws Exception {
UserTransaction transaction = manager.getTransaction();
transaction.begin();
transaction.commit();
-
+
transaction.begin();
- transaction.commit();
+ transaction.commit();
}
-
+
}
public void testTransactionLifeCycle() throws Exception {
manager.getTransaction().getStatus();
UserTransaction transaction = manager.getThreadSpecificTransaction();
-
+
assertNotNull(transaction);
assertEquals(1, callbacks.size());
callbacks.get(0).transactionFinished();
@Test
public void testEntityManagerIsPassed() throws Exception {
-
-
+
final TransactionProxyFactory<Service> factory = new TransactionProxyFactory<Service>(
jpaTester.getJpaBuilder(), Service.class);
- Service service = new Service() {
- private EntityManager em = factory.getTransactionScopedEntityManager();
-
+ Service service = new Service() {
+ private EntityManager em = factory
+ .getTransactionScopedEntityManager();
+
@Override
public int execute(int aValue) throws Exception {
assertNotNull(em);
return 0;
}
};
-
+
final Service proxy = factory.getProxy(service);
jpaTester.getJpaBuilder().execute(new JpaUnitOfWork<Void>() {
@Override
public Void execute(EntityManager aEm) throws Exception {
- assert(aEm != null);
+ assert (aEm != null);
proxy.execute(10);
- return null;
+ return null;
}
});
}