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

Spring Framework example source code file (AbstractSessionFactory.java)

This example Spring Framework source code file (AbstractSessionFactory.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

creating, illegalstateexception, invocationhandler, managedclientinvocationhandler, managedclientinvocationhandler, object, object, reflection, session, session, sessionfactory, toplink, toplinkexception, toplinkexception, transactionawareinvocationhandler

The Spring Framework AbstractSessionFactory.java source code

/*
 * 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.orm.toplink;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import oracle.toplink.exceptions.TopLinkException;
import oracle.toplink.sessions.Session;
import oracle.toplink.sessions.UnitOfWork;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * Abstract SessionFactory implementation that creates proxies for
 * "managed" client Sessions and transaction-aware Session references.
 *
 * <p>Delegates to two template methods:
 *
 * @author Juergen Hoeller
 * @since 1.2.6
 * @see #getMasterSession()
 * @see #createClientSession()
 */
public abstract class AbstractSessionFactory implements SessionFactory {

	/** Logger available to subclasses */
	protected final Log logger = LogFactory.getLog(getClass());


	/**
	 * Create a plain client Session for this factory's master Session.
	 * @see #createClientSession()
	 */
	public Session createSession() throws TopLinkException {
		logger.debug("Creating TopLink client Session");
		return createClientSession();
	}

	/**
	 * Create a "managed" client Session reference for an underlying
	 * client Session created for this factory.
	 * @see #createClientSession()
	 */
	public Session createManagedClientSession() throws TopLinkException {
		logger.debug("Creating managed TopLink client Session");
		return (Session) Proxy.newProxyInstance(
				getClass().getClassLoader(), new Class[] {Session.class},
				new ManagedClientInvocationHandler(createClientSession()));
	}

	/**
	 * Create a transaction-aware Session reference for this factory's master Session,
	 * expecting transactions to be registered for this SessionFactory.
	 * @see #getMasterSession()
	 * @see oracle.toplink.sessions.Session#getActiveSession()
	 * @see oracle.toplink.sessions.Session#getActiveUnitOfWork()
	 */
	public Session createTransactionAwareSession() throws TopLinkException {
		logger.debug("Creating transaction-aware TopLink Session");
		return createTransactionAwareSession(this);
	}

	/**
	 * Create a transaction-aware Session reference for this factory's master Session,
	 * expecting transactions to be registered for the given SessionFactory.
	 * <p>This method is public to allow custom SessionFactory facades to access
	 * it directly, if necessary.
	 * @param sessionFactory the SessionFactory that transactions
	 * are expected to be registered for
	 * @see #getMasterSession()
	 * @see oracle.toplink.sessions.Session#getActiveSession()
	 * @see oracle.toplink.sessions.Session#getActiveUnitOfWork()
	 */
	public Session createTransactionAwareSession(SessionFactory sessionFactory) throws TopLinkException {
		return (Session) Proxy.newProxyInstance(
				getClass().getClassLoader(), new Class[] {Session.class},
				new TransactionAwareInvocationHandler(sessionFactory, getMasterSession()));
	}


	/**
	 * Return this factory's "master" Session.
	 * For example, a TopLink ServerSession.
	 * <p>Used for creating transaction-aware Session reference.
	 */
	protected abstract Session getMasterSession();

	/**
	 * Create a new client Session for this factory's master Session.
	 * For example, a TopLink ClientSession.
	 * <p>Used for creating plain Sessions and "managed" client Sessions.
	 * @throws TopLinkException if creation of a client Session failed
	 */
	protected abstract Session createClientSession() throws TopLinkException;


	/**
	 * Invocation handler that decorates a client Session with an "active"
	 * UnitOfWork. For use in situations where Spring's TopLinkTransactionManager
	 * requires a "managed" thread-safe TopLink Session.
	 */
	private static class ManagedClientInvocationHandler implements InvocationHandler {

		private final Session target;

		private final UnitOfWork uow;

		public ManagedClientInvocationHandler(Session target) {
			this.target = target;
			this.uow = this.target.acquireUnitOfWork();
		}

		public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
			if (method.getName().equals("getActiveSession")) {
				return this.target;
			}
			else if (method.getName().equals("getActiveUnitOfWork")) {
				return this.uow;
			}
			else if (method.getName().equals("release")) {
				this.uow.release();
				this.target.release();
			}
			else if (method.getName().equals("equals")) {
				// Only consider equal when proxies are identical.
				return (proxy == args[0] ? Boolean.TRUE : Boolean.FALSE);
			}
			else if (method.getName().equals("hashCode")) {
				// Use hashCode of SessionFactory proxy.
				return new Integer(hashCode());
			}

			// Invoke method on target Session.
			try {
				return method.invoke(this.target, args);
			}
			catch (InvocationTargetException ex) {
				throw ex.getTargetException();
			}
		}
	}


	/**
	 * Invocation handler that delegates <code>getActiveSession calls
	 * to SessionFactoryUtils, for being aware of thread-bound transactions.
	 */
	private static class TransactionAwareInvocationHandler implements InvocationHandler {

		private final SessionFactory sessionFactory;

		private final Session target;

		public TransactionAwareInvocationHandler(SessionFactory sessionFactory, Session target) {
			this.sessionFactory = sessionFactory;
			this.target = target;
		}

		public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
			// Invocation on Session interface coming in...

			if (method.getName().equals("getActiveSession")) {
				// Handle getActiveSession method: return transactional Session, if any.
				try {
					return SessionFactoryUtils.doGetSession(this.sessionFactory, false);
				}
				catch (IllegalStateException ex) {
					// getActiveSession is supposed to return the Session itself if no active one found.
					return this.target;
				}
			}
			else if (method.getName().equals("getActiveUnitOfWork")) {
				// Handle getActiveUnitOfWork method: return transactional UnitOfWork, if any.
				try {
					return SessionFactoryUtils.doGetSession(this.sessionFactory, false).getActiveUnitOfWork();
				}
				catch (IllegalStateException ex) {
					// getActiveUnitOfWork is supposed to return null if no active one found.
					return null;
				}
			}
			else if (method.getName().equals("equals")) {
				// Only consider equal when proxies are identical.
				return (proxy == args[0] ? Boolean.TRUE : Boolean.FALSE);
			}
			else if (method.getName().equals("hashCode")) {
				// Use hashCode of SessionFactory proxy.
				return new Integer(hashCode());
			}

			// Invoke method on target Session.
			try {
				return method.invoke(this.target, args);
			}
			catch (InvocationTargetException ex) {
				throw ex.getTargetException();
			}
		}
	}

}

Other Spring Framework examples (source code examples)

Here is a short list of links related to this Spring Framework AbstractSessionFactory.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.