Save This Page
Home » spring-framework-2.5.6-with-dependencies » org.springframework » dao » support » [javadoc | source]
    1   /*
    2    * Copyright 2002-2007 the original author or authors.
    3    *
    4    * Licensed under the Apache License, Version 2.0 (the "License");
    5    * you may not use this file except in compliance with the License.
    6    * You may obtain a copy of the License at
    7    *
    8    *      http://www.apache.org/licenses/LICENSE-2.0
    9    *
   10    * Unless required by applicable law or agreed to in writing, software
   11    * distributed under the License is distributed on an "AS IS" BASIS,
   12    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   13    * See the License for the specific language governing permissions and
   14    * limitations under the License.
   15    */
   16   
   17   package org.springframework.dao.support;
   18   
   19   import java.util.Iterator;
   20   import java.util.Map;
   21   
   22   import org.aopalliance.intercept.MethodInterceptor;
   23   import org.aopalliance.intercept.MethodInvocation;
   24   
   25   import org.springframework.beans.BeansException;
   26   import org.springframework.beans.factory.BeanFactory;
   27   import org.springframework.beans.factory.BeanFactoryAware;
   28   import org.springframework.beans.factory.BeanFactoryUtils;
   29   import org.springframework.beans.factory.InitializingBean;
   30   import org.springframework.beans.factory.ListableBeanFactory;
   31   import org.springframework.util.Assert;
   32   import org.springframework.util.ReflectionUtils;
   33   
   34   /**
   35    * AOP Alliance MethodInterceptor that provides persistence exception translation
   36    * based on a given PersistenceExceptionTranslator.
   37    *
   38    * <p>Delegates to the given {@link PersistenceExceptionTranslator} to translate
   39    * a RuntimeException thrown into Spring's DataAccessException hierarchy
   40    * (if appropriate). If the RuntimeException in question is declared on the
   41    * target method, it is always propagated as-is (with no translation applied).
   42    *
   43    * @author Rod Johnson
   44    * @author Juergen Hoeller
   45    * @since 2.0
   46    * @see PersistenceExceptionTranslator
   47    */
   48   public class PersistenceExceptionTranslationInterceptor
   49   		implements MethodInterceptor, BeanFactoryAware, InitializingBean {
   50   
   51   	private PersistenceExceptionTranslator persistenceExceptionTranslator;
   52   
   53   
   54   	/**
   55   	 * Create a new PersistenceExceptionTranslationInterceptor.
   56   	 * Needs to be configured with a PersistenceExceptionTranslator afterwards.
   57   	 * @see #setPersistenceExceptionTranslator
   58   	 */
   59   	public PersistenceExceptionTranslationInterceptor() {
   60   	}
   61   
   62   	/**
   63   	 * Create a new PersistenceExceptionTranslationInterceptor
   64   	 * for the given PersistenceExceptionTranslator.
   65   	 * @param persistenceExceptionTranslator the PersistenceExceptionTranslator to use
   66   	 */
   67   	public PersistenceExceptionTranslationInterceptor(PersistenceExceptionTranslator persistenceExceptionTranslator) {
   68   		setPersistenceExceptionTranslator(persistenceExceptionTranslator);
   69   	}
   70   
   71   	/**
   72   	 * Create a new PersistenceExceptionTranslationInterceptor, autodetecting
   73   	 * PersistenceExceptionTranslators in the given BeanFactory.
   74   	 * @param beanFactory the ListableBeanFactory to obtaining all
   75   	 * PersistenceExceptionTranslators from
   76   	 */
   77   	public PersistenceExceptionTranslationInterceptor(ListableBeanFactory beanFactory) {
   78   		this.persistenceExceptionTranslator = detectPersistenceExceptionTranslators(beanFactory);
   79   	}
   80   
   81   
   82   	/**
   83   	 * Specify the PersistenceExceptionTranslator to use.
   84   	 * <p>Default is to autodetect all PersistenceExceptionTranslators
   85   	 * in the containing BeanFactory, using them in a chain.
   86   	 * @see #detectPersistenceExceptionTranslators
   87   	 */
   88   	public void setPersistenceExceptionTranslator(PersistenceExceptionTranslator pet) {
   89   		Assert.notNull(pet, "PersistenceExceptionTranslator must not be null");
   90   		this.persistenceExceptionTranslator = pet;
   91   	}
   92   
   93   	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
   94   		if (this.persistenceExceptionTranslator == null) {
   95   			// No explicit exception translator specified - perform autodetection.
   96   			if (!(beanFactory instanceof ListableBeanFactory)) {
   97   				throw new IllegalArgumentException(
   98   						"Cannot use PersistenceExceptionTranslator autodetection without ListableBeanFactory");
   99   			}
  100   			this.persistenceExceptionTranslator =
  101   					detectPersistenceExceptionTranslators((ListableBeanFactory) beanFactory);
  102   		}
  103   	}
  104   
  105   	public void afterPropertiesSet() {
  106   		if (this.persistenceExceptionTranslator == null) {
  107   			throw new IllegalArgumentException("Property 'persistenceExceptionTranslator' is required");
  108   		}
  109   	}
  110   
  111   
  112   	/**
  113   	 * Detect all PersistenceExceptionTranslators in the given BeanFactory.
  114   	 * @param beanFactory the ListableBeanFactory to obtaining all
  115   	 * PersistenceExceptionTranslators from
  116   	 * @return a chained PersistenceExceptionTranslator, combining all
  117   	 * PersistenceExceptionTranslators found in the factory
  118   	 * @see ChainedPersistenceExceptionTranslator
  119   	 */
  120   	protected PersistenceExceptionTranslator detectPersistenceExceptionTranslators(ListableBeanFactory beanFactory) {
  121   		// Find all translators, being careful not to activate FactoryBeans.
  122   		Map pets = BeanFactoryUtils.beansOfTypeIncludingAncestors(
  123   				beanFactory, PersistenceExceptionTranslator.class, false, false);
  124   		if (pets.isEmpty()) {
  125   			throw new IllegalStateException(
  126   					"No persistence exception translators found in bean factory. Cannot perform exception translation.");
  127   		}
  128   		ChainedPersistenceExceptionTranslator cpet = new ChainedPersistenceExceptionTranslator();
  129   		for (Iterator it = pets.values().iterator(); it.hasNext();) {
  130   			cpet.addDelegate((PersistenceExceptionTranslator) it.next());
  131   		}
  132   		return cpet;
  133   	}
  134   
  135   
  136   	public Object invoke(MethodInvocation mi) throws Throwable {
  137   		try {
  138   			return mi.proceed();
  139   		}
  140   		catch (RuntimeException ex) {
  141   			// Let it throw raw if the type of the exception is on the throws clause of the method.
  142   			if (ReflectionUtils.declaresException(mi.getMethod(), ex.getClass())) {
  143   				throw ex;
  144   			}
  145   			else {
  146   				throw DataAccessUtils.translateIfNecessary(ex, this.persistenceExceptionTranslator);
  147   			}
  148   		}
  149   	}
  150   
  151   }

Save This Page
Home » spring-framework-2.5.6-with-dependencies » org.springframework » dao » support » [javadoc | source]