Package org.springmodules.orm.ojb

Source Code of org.springmodules.orm.ojb.OjbFactoryUtils

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

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ojb.broker.OJBRuntimeException;
import org.apache.ojb.broker.PBKey;
import org.apache.ojb.broker.PersistenceBroker;
import org.apache.ojb.broker.PersistenceBrokerFactory;

import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
import org.springframework.transaction.support.TransactionSynchronizationManager;

/**
* Helper class featuring methods for OJB PersistenceBroker handling,
* allowing for reuse of PersistenceBroker instances within transactions.
*
* <p>Used by PersistenceBrokerTemplate and PersistenceBrokerTransactionManager.
* Can also be used directly in application code.
*
* @author Juergen Hoeller
* @since 1.1
* @see PersistenceBrokerTemplate
* @see PersistenceBrokerTransactionManager
* @see org.springframework.transaction.jta.JtaTransactionManager
*/
public abstract class OjbFactoryUtils {

  /**
   * Order value for TransactionSynchronization objects that clean up OJB
   * PersistenceBrokers. Return DataSourceUtils.CONNECTION_SYNCHRONIZATION_ORDER - 100
   * to execute PersistenceBroker cleanup before JDBC Connection cleanup, if any.
   * @see org.springframework.jdbc.datasource.DataSourceUtils#CONNECTION_SYNCHRONIZATION_ORDER
   */
  public static final int PERSISTENCE_BROKER_SYNCHRONIZATION_ORDER =
      DataSourceUtils.CONNECTION_SYNCHRONIZATION_ORDER - 100;

  private static final Log logger = LogFactory.getLog(OjbFactoryUtils.class);


  /**
   * Get an OJB PersistenceBroker for the given PBKey. Is aware of a
   * corresponding PersistenceBroker bound to the current thread, for
   * example when using PersistenceBrokerTransactionManager. Will
   * create a new PersistenceBroker else, if allowCreate is true.
   * @param pbKey PBKey to create the PersistenceBroker for
   * @param allowCreate if a non-transactional PersistenceBroker should be created
   * when no transactional PersistenceBroker can be found for the current thread
   * @return the PersistenceBroker
   * @throws DataAccessResourceFailureException if the PersistenceBroker couldn't be created
   * @throws IllegalStateException if no thread-bound PersistenceBroker found and allowCreate false
   */
  public static PersistenceBroker getPersistenceBroker(PBKey pbKey, boolean allowCreate)
      throws DataAccessResourceFailureException, IllegalStateException {

    PersistenceBrokerHolder pbHolder =
        (PersistenceBrokerHolder) TransactionSynchronizationManager.getResource(pbKey);
    if (pbHolder != null) {
      return pbHolder.getPersistenceBroker();
    }

    if (!allowCreate && !TransactionSynchronizationManager.isSynchronizationActive()) {
      throw new IllegalStateException("No OJB PersistenceBroker bound to thread, " +
          "and configuration does not allow creation of non-transactional one here");
    }

    try {
      logger.debug("Opening OJB PersistenceBroker");
      PersistenceBroker pb = PersistenceBrokerFactory.createPersistenceBroker(pbKey);

      if (TransactionSynchronizationManager.isSynchronizationActive()) {
        logger.debug("Registering transaction synchronization for OJB PersistenceBroker");
        // Use same PersistenceBroker for further OJB actions within the transaction.
        // Thread object will get removed by synchronization at transaction completion.
        pbHolder = new PersistenceBrokerHolder(pb);
        pbHolder.setSynchronizedWithTransaction(true);
        TransactionSynchronizationManager.registerSynchronization(
            new PersistenceBrokerSynchronization(pbHolder, pbKey));
        TransactionSynchronizationManager.bindResource(pbKey, pbHolder);
      }

      return pb;
    }
    catch (OJBRuntimeException ex) {
      throw new DataAccessResourceFailureException("Could not open OJB PersistenceBroker", ex);
    }
  }

  /**
   * Close the given PersistenceBroker, created for the given PBKey,
   * if it is not managed externally (i.e. not bound to the thread).
   * @param pb PersistenceBroker to close
   * @param pbKey PBKey that the PersistenceBroker was created with
   */
  public static void releasePersistenceBroker(PersistenceBroker pb, PBKey pbKey) {
    if (pb == null) {
      return;
    }

    PersistenceBrokerHolder pbHolder =
        (PersistenceBrokerHolder) TransactionSynchronizationManager.getResource(pbKey);
    if (pbHolder != null && pb == pbHolder.getPersistenceBroker()) {
      // It's the transactional PersistenceBroker: Don't close it.
      return;
    }

    logger.debug("Closing OJB PersistenceBroker");
    pb.close();
  }


  /**
   * Callback for resource cleanup at the end of a non-OJB transaction
   * (e.g. when participating in a JtaTransactionManager transaction).
   * @see org.springframework.transaction.jta.JtaTransactionManager
   */
  private static class PersistenceBrokerSynchronization extends TransactionSynchronizationAdapter {

    private final PersistenceBrokerHolder persistenceBrokerHolder;

    private final PBKey pbKey;

    private boolean holderActive = true;

    private PersistenceBrokerSynchronization(PersistenceBrokerHolder pbHolder, PBKey pbKey) {
      this.persistenceBrokerHolder = pbHolder;
      this.pbKey = pbKey;
    }

    public int getOrder() {
      return PERSISTENCE_BROKER_SYNCHRONIZATION_ORDER;
    }

    public void suspend() {
      if (this.holderActive) {
        TransactionSynchronizationManager.unbindResource(this.pbKey);
      }
    }

    public void resume() {
      if (this.holderActive) {
        TransactionSynchronizationManager.bindResource(this.pbKey, this.persistenceBrokerHolder);
      }
    }

    public void beforeCompletion() {
      TransactionSynchronizationManager.unbindResource(this.pbKey);
      this.holderActive = false;
      releasePersistenceBroker(this.persistenceBrokerHolder.getPersistenceBroker(), this.pbKey);
    }
  }

}
TOP

Related Classes of org.springmodules.orm.ojb.OjbFactoryUtils

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.