alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Spring Framework example source code file (CciTemplate.java)

This example Spring Framework source code file (CciTemplate.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Spring Framework tags/keywords

cci, ccitemplate, creation, dataaccessexception, dataaccessexception, jdbc, notsupportedexception, object, object, record, record, recordcreator, recordfactory, resourceexception, resourceexception, sql

The Spring Framework CciTemplate.java source code

/*
 * 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.jca.cci.core;

import java.sql.SQLException;

import javax.resource.NotSupportedException;
import javax.resource.ResourceException;
import javax.resource.cci.Connection;
import javax.resource.cci.ConnectionFactory;
import javax.resource.cci.ConnectionSpec;
import javax.resource.cci.IndexedRecord;
import javax.resource.cci.Interaction;
import javax.resource.cci.InteractionSpec;
import javax.resource.cci.MappedRecord;
import javax.resource.cci.Record;
import javax.resource.cci.RecordFactory;
import javax.resource.cci.ResultSet;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.jca.cci.CannotCreateRecordException;
import org.springframework.jca.cci.CciOperationNotSupportedException;
import org.springframework.jca.cci.InvalidResultSetAccessException;
import org.springframework.jca.cci.RecordTypeNotSupportedException;
import org.springframework.jca.cci.connection.ConnectionFactoryUtils;
import org.springframework.jca.cci.connection.NotSupportedRecordFactory;
import org.springframework.util.Assert;

/**
 * <b>This is the central class in the CCI core package.
 * It simplifies the use of CCI and helps to avoid common errors.
 * It executes core CCI workflow, leaving application code to provide parameters
 * to CCI and extract results. This class executes EIS queries or updates,
 * catching ResourceExceptions and translating them to the generic exception
 * hierarchy defined in the <code>org.springframework.dao package.
 *
 * <p>Code using this class can pass in and receive {@link javax.resource.cci.Record}
 * instances, or alternatively implement callback interfaces for creating input
 * Records and extracting result objects from output Records (or CCI ResultSets).
 *
 * <p>Can be used within a service implementation via direct instantiation
 * with a ConnectionFactory reference, or get prepared in an application context
 * and given to services as bean reference. Note: The ConnectionFactory 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.
 *
 * @author Thierry Templier
 * @author Juergen Hoeller
 * @since 1.2
 * @see RecordCreator
 * @see RecordExtractor
 */
public class CciTemplate implements CciOperations {

	private final Log logger = LogFactory.getLog(getClass());

	private ConnectionFactory connectionFactory;

	private ConnectionSpec connectionSpec;

	private RecordCreator outputRecordCreator;


	/**
	 * Construct a new CciTemplate for bean usage.
	 * <p>Note: The ConnectionFactory has to be set before using the instance.
	 * @see #setConnectionFactory
	 */
	public CciTemplate() {
	}

	/**
	 * Construct a new CciTemplate, given a ConnectionFactory to obtain Connections from.
	 * Note: This will trigger eager initialization of the exception translator.
	 * @param connectionFactory JCA ConnectionFactory to obtain Connections from
	 */
	public CciTemplate(ConnectionFactory connectionFactory) {
		setConnectionFactory(connectionFactory);
		afterPropertiesSet();
	}

	/**
	 * Construct a new CciTemplate, given a ConnectionFactory to obtain Connections from.
	 * Note: This will trigger eager initialization of the exception translator.
	 * @param connectionFactory JCA ConnectionFactory to obtain Connections from
	 * @param connectionSpec the CCI ConnectionSpec to obtain Connections for
	 * (may be <code>null)
	 */
	public CciTemplate(ConnectionFactory connectionFactory, ConnectionSpec connectionSpec) {
		setConnectionFactory(connectionFactory);
		setConnectionSpec(connectionSpec);
		afterPropertiesSet();
	}


	/**
	 * Set the CCI ConnectionFactory to obtain Connections from.
	 */
	public void setConnectionFactory(ConnectionFactory connectionFactory) {
		this.connectionFactory = connectionFactory;
	}

	/**
	 * Return the CCI ConnectionFactory used by this template.
	 */
	public ConnectionFactory getConnectionFactory() {
		return this.connectionFactory;
	}

	/**
	 * Set the CCI ConnectionSpec that this template instance is
	 * supposed to obtain Connections for.
	 */
	public void setConnectionSpec(ConnectionSpec connectionSpec) {
		this.connectionSpec = connectionSpec;
	}

	/**
	 * Return the CCI ConnectionSpec used by this template, if any.
	 */
	public ConnectionSpec getConnectionSpec() {
		return this.connectionSpec;
	}

	/**
	 * Set a RecordCreator that should be used for creating default output Records.
	 * <p>Default is none: When no explicit output Record gets passed into an
	 * <code>execute method, CCI's Interaction.execute variant
	 * that returns an output Record will be called.
	 * <p>Specify a RecordCreator here if you always need to call CCI's
	 * <code>Interaction.execute variant with a passed-in output Record.
	 * Unless there is an explicitly specified output Record, CciTemplate will
	 * then invoke this RecordCreator to create a default output Record instance.
	 * @see javax.resource.cci.Interaction#execute(javax.resource.cci.InteractionSpec, Record)
	 * @see javax.resource.cci.Interaction#execute(javax.resource.cci.InteractionSpec, Record, Record)
	 */
	public void setOutputRecordCreator(RecordCreator creator) {
		this.outputRecordCreator = creator;
	}

	/**
	 * Return a RecordCreator that should be used for creating default output Records.
	 */
	public RecordCreator getOutputRecordCreator() {
		return this.outputRecordCreator;
	}

	public void afterPropertiesSet() {
		if (getConnectionFactory() == null) {
			throw new IllegalArgumentException("Property 'connectionFactory' is required");
		}
	}


	/**
	 * Create a template derived from this template instance,
	 * inheriting the ConnectionFactory and other settings but
	 * overriding the ConnectionSpec used for obtaining Connections.
	 * @param connectionSpec the CCI ConnectionSpec that the derived template
	 * instance is supposed to obtain Connections for
	 * @return the derived template instance
	 * @see #setConnectionSpec
	 */
	public CciTemplate getDerivedTemplate(ConnectionSpec connectionSpec) {
		CciTemplate derived = new CciTemplate();
		derived.setConnectionFactory(getConnectionFactory());
		derived.setConnectionSpec(connectionSpec);
		derived.setOutputRecordCreator(getOutputRecordCreator());
		return derived;
	}


	public Object execute(ConnectionCallback action) throws DataAccessException {
		Assert.notNull(action, "Callback object must not be null");

		Connection con = ConnectionFactoryUtils.getConnection(getConnectionFactory(), getConnectionSpec());
		try {
			return action.doInConnection(con, getConnectionFactory());
		}
		catch (NotSupportedException ex) {
			throw new CciOperationNotSupportedException("CCI operation not supported by connector", ex);
		}
		catch (ResourceException ex) {
			throw new DataAccessResourceFailureException("CCI operation failed", ex);
		}
		catch (SQLException ex) {
			throw new InvalidResultSetAccessException("Parsing of CCI ResultSet failed", ex);
		}
		finally {
			ConnectionFactoryUtils.releaseConnection(con, getConnectionFactory());
		}
	}

	public Object execute(final InteractionCallback action) throws DataAccessException {
		Assert.notNull(action, "Callback object must not be null");

		return execute(new ConnectionCallback() {
			public Object doInConnection(Connection connection, ConnectionFactory connectionFactory)
					throws ResourceException, SQLException, DataAccessException {

				Interaction interaction = connection.createInteraction();
				try {
					return action.doInInteraction(interaction, connectionFactory);
				}
				finally {
					closeInteraction(interaction);
				}
			}
		});
	}

	public Record execute(InteractionSpec spec, Record inputRecord) throws DataAccessException {
		return (Record) doExecute(spec, inputRecord, null, null);
	}

	public void execute(InteractionSpec spec, Record inputRecord, Record outputRecord) throws DataAccessException {
		doExecute(spec, inputRecord, outputRecord, null);
	}

	public Record execute(InteractionSpec spec, RecordCreator inputCreator) throws DataAccessException {
		return (Record) doExecute(spec, createRecord(inputCreator), null, null);
	}

	public Object execute(InteractionSpec spec, Record inputRecord, RecordExtractor outputExtractor)
			throws DataAccessException {

		return doExecute(spec, inputRecord, null, outputExtractor);
	}

	public Object execute(InteractionSpec spec, RecordCreator inputCreator, RecordExtractor outputExtractor)
			throws DataAccessException {

		return doExecute(spec, createRecord(inputCreator), null, outputExtractor);
	}

	/**
	 * Execute the specified interaction on an EIS with CCI.
	 * All other interaction execution methods go through this.
	 * @param spec the CCI InteractionSpec instance that defines
	 * the interaction (connector-specific)
	 * @param inputRecord the input record
	 * @param outputRecord output record (can be <code>null)
	 * @param outputExtractor object to convert the output record to a result object
	 * @return the output data extracted with the RecordExtractor object
	 * @throws DataAccessException if there is any problem
	 */
	protected Object doExecute(
			final InteractionSpec spec, final Record inputRecord, final Record outputRecord,
			final RecordExtractor outputExtractor) throws DataAccessException {

		return execute(new InteractionCallback() {
			public Object doInInteraction(Interaction interaction, ConnectionFactory connectionFactory)
					throws ResourceException, SQLException, DataAccessException {

				Record outputRecordToUse = outputRecord;
				try {
					if (outputRecord != null || getOutputRecordCreator() != null) {
						// Use the CCI execute method with output record as parameter.
						if (outputRecord == null) {
							RecordFactory recordFactory = getRecordFactory(connectionFactory);
							outputRecordToUse = getOutputRecordCreator().createRecord(recordFactory);
						}
						interaction.execute(spec, inputRecord, outputRecordToUse);
					}
					else {
						outputRecordToUse = interaction.execute(spec, inputRecord);
					}
					if (outputExtractor != null) {
						return outputExtractor.extractData(outputRecordToUse);
					}
					else {
						return outputRecordToUse;
					}
				}
				finally {
					if (outputRecordToUse instanceof ResultSet) {
						closeResultSet((ResultSet) outputRecordToUse);
					}
				}
			}
		});
	}


	/**
	 * Create an indexed Record through the ConnectionFactory's RecordFactory.
	 * @param name the name of the record
	 * @return the Record
	 * @throws DataAccessException if creation of the Record failed
	 * @see #getRecordFactory(javax.resource.cci.ConnectionFactory)
	 * @see javax.resource.cci.RecordFactory#createIndexedRecord(String)
	 */
	public IndexedRecord createIndexedRecord(String name) throws DataAccessException {
		try {
			RecordFactory recordFactory = getRecordFactory(getConnectionFactory());
			return recordFactory.createIndexedRecord(name);
		}
		catch (NotSupportedException ex) {
			throw new RecordTypeNotSupportedException("Creation of indexed Record not supported by connector", ex);
		}
		catch (ResourceException ex) {
			throw new CannotCreateRecordException("Creation of indexed Record failed", ex);
		}
	}

	/**
	 * Create a mapped Record from the ConnectionFactory's RecordFactory.
	 * @param name record name
	 * @return the Record
	 * @throws DataAccessException if creation of the Record failed
	 * @see #getRecordFactory(javax.resource.cci.ConnectionFactory)
	 * @see javax.resource.cci.RecordFactory#createMappedRecord(String)
	 */
	public MappedRecord createMappedRecord(String name) throws DataAccessException {
		try {
			RecordFactory recordFactory = getRecordFactory(getConnectionFactory());
			return recordFactory.createMappedRecord(name);
		}
		catch (NotSupportedException ex) {
			throw new RecordTypeNotSupportedException("Creation of mapped Record not supported by connector", ex);
		}
		catch (ResourceException ex) {
			throw new CannotCreateRecordException("Creation of mapped Record failed", ex);
		}
	}

	/**
	 * Invoke the given RecordCreator, converting JCA ResourceExceptions
	 * to Spring's DataAccessException hierarchy.
	 * @param recordCreator the RecordCreator to invoke
	 * @return the created Record
	 * @throws DataAccessException if creation of the Record failed
	 * @see #getRecordFactory(javax.resource.cci.ConnectionFactory)
	 * @see RecordCreator#createRecord(javax.resource.cci.RecordFactory)
	 */
	protected Record createRecord(RecordCreator recordCreator) throws DataAccessException {
		try {
			RecordFactory recordFactory = getRecordFactory(getConnectionFactory());
			return recordCreator.createRecord(recordFactory);
		}
		catch (NotSupportedException ex) {
			throw new RecordTypeNotSupportedException(
					"Creation of the desired Record type not supported by connector", ex);
		}
		catch (ResourceException ex) {
			throw new CannotCreateRecordException("Creation of the desired Record failed", ex);
		}
	}

	/**
	 * Return a RecordFactory for the given ConnectionFactory.
	 * <p>Default implementation returns the connector's RecordFactory if
	 * available, falling back to a NotSupportedRecordFactory placeholder.
	 * This allows to invoke a RecordCreator callback with a non-null
	 * RecordFactory reference in any case.
	 * @param connectionFactory the CCI ConnectionFactory
	 * @return the CCI RecordFactory for the ConnectionFactory
	 * @throws ResourceException if thrown by CCI methods
	 * @see org.springframework.jca.cci.connection.NotSupportedRecordFactory
	 */
	protected RecordFactory getRecordFactory(ConnectionFactory connectionFactory) throws ResourceException {
		try {
			return getConnectionFactory().getRecordFactory();
		}
		catch (NotSupportedException ex) {
			return new NotSupportedRecordFactory();
		}
	}


	/**
	 * Close the given CCI Interaction and ignore any thrown exception.
	 * This is useful for typical finally blocks in manual CCI code.
	 * @param interaction the CCI Interaction to close
	 * @see javax.resource.cci.Interaction#close()
	 */
	private void closeInteraction(Interaction interaction) {
		if (interaction != null) {
			try {
				interaction.close();
			}
			catch (ResourceException ex) {
				logger.debug("Could not close CCI Interaction", ex);
			}
			catch (Throwable ex) {
				// We don't trust the CCI driver: It might throw RuntimeException or Error.
				logger.debug("Unexpected exception on closing CCI Interaction", ex);
			}
		}
	}

	/**
	 * Close the given CCI ResultSet and ignore any thrown exception.
	 * This is useful for typical finally blocks in manual CCI code.
	 * @param resultSet the CCI ResultSet to close
	 * @see javax.resource.cci.ResultSet#close()
	 */
	private void closeResultSet(ResultSet resultSet) {
		if (resultSet != null) {
			try {
				resultSet.close();
			}
			catch (SQLException ex) {
				logger.debug("Could not close CCI ResultSet", ex);
			}
			catch (Throwable ex) {
				// We don't trust the CCI driver: It might throw RuntimeException or Error.
				logger.debug("Unexpected exception on closing CCI ResultSet", ex);
			}
		}
	}

}

Other Spring Framework examples (source code examples)

Here is a short list of links related to this Spring Framework CciTemplate.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.