View Javadoc

1   /*
2    * EL4J, the Extension Library for the J2EE, adds incremental enhancements to
3    * the spring framework, http://el4j.sf.net
4    * Copyright (C) 2010 by ELCA Informatique SA, Av. de la Harpe 22-24,
5    * 1000 Lausanne, Switzerland, http://www.elca.ch
6    *
7    * EL4J is published under the GNU Lesser General Public License (LGPL)
8    * Version 2.1. See http://www.gnu.org/licenses/
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13   * GNU Lesser General Public License for more details.
14   *
15   * For alternative licensing, please contact info@elca.ch
16   */
17  package ch.elca.el4j.services.persistence.jpa.dao;
18  
19  import java.lang.reflect.Method;
20  
21  import javax.persistence.EntityManagerFactory;
22  
23  import org.slf4j.Logger;
24  import org.slf4j.LoggerFactory;
25  import org.springframework.beans.BeansException;
26  import org.springframework.beans.factory.config.BeanPostProcessor;
27  import org.springframework.context.ApplicationContext;
28  import org.springframework.context.ApplicationContextAware;
29  import org.springframework.core.Ordered;
30  import org.springframework.core.PriorityOrdered;
31  
32  import ch.elca.el4j.services.persistence.generic.dao.GenericDao;
33  import ch.elca.el4j.services.persistence.jpa.dao.extentstrategies.ExtentFetcher;
34  import ch.elca.el4j.util.codingsupport.Reject;
35  
36  /**
37   * Inject the ExtentFetcher in GenericDaos.
38   * It gets the extentFetcher from the spring context
39   * by using the default name {@link EXTENT_FETCHER_BEAN_DEFAULT_NAME}.
40   *
41   * @svnLink $Revision: 4253 $;$Date: 2010-12-21 11:08:04 +0100 (Di, 21. Dez 2010) $;$Author: swismer $;$URL: https://el4j.svn.sourceforge.net/svnroot/el4j/branches/el4j_3_1/el4j/framework/modules/hibernate/src/main/java/ch/elca/el4j/services/persistence/jpa/dao/JpaExtentFetcherInjectorBeanPostProcessor.java $
42   *
43   * @author Simon Stelling (SST)
44   */
45  public class JpaExtentFetcherInjectorBeanPostProcessor
46  		implements BeanPostProcessor, PriorityOrdered, ApplicationContextAware {
47  
48  	/**
49  	 * The default name for the property of the session factory.
50  	 */
51  	public static final String EXTENT_FETCHER_BEAN_DEFAULT_NAME = "extentFetcher";
52  	
53  	/**
54  	 * private logger.
55  	 */
56  	private static final Logger s_logger = LoggerFactory.getLogger(JpaExtentFetcherInjectorBeanPostProcessor.class);
57  	
58  	/**
59  	 * Caches the 'extentFetcher' bean from the application context. 
60  	 */
61  	protected ExtentFetcher extentFetcher;
62  	
63  	/**
64  	 * the order of this BeanPostProcessor.
65  	 */
66  	private int order = Ordered.LOWEST_PRECEDENCE;
67  
68  	/**
69  	 * The ApplicationContext from which the extentFetcher bean is obtained.
70  	 */
71  	private ApplicationContext m_applicationContext;
72  	
73  	/**
74  	 * Initiates the real work.
75  	 * @param bean the bean to postprocess
76  	 * @param beanName the name of the bean
77  	 * @return the bean
78  	 * @throws BeansException
79  	 */
80  	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
81  		s_logger.debug("Treating bean with name:" + beanName);
82  		if (GenericJpaDao.class.isAssignableFrom(bean.getClass())) {
83  			s_logger.debug("init dao with name:" + beanName);
84  			initDao((GenericJpaDao<?, ?>) bean);
85  		}
86  		return bean;
87  	}
88  
89  	/** {@inheritDoc} */
90  	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
91  		return bean;
92  	}
93  
94  
95  	/**
96  	 * Try to inject the extentFetcher into the given dao.
97  	 * @param dao the dao to inject the extentFetcher
98  	 */
99  	protected void initDao(GenericJpaDao<?, ?> dao) {
100 		if (getExtentFetcher() != null) {
101 			try {
102 				Method setter = dao.getClass().getMethod(
103 					"setExtentFetcher", ExtentFetcher.class);
104 				setter.invoke(dao, getExtentFetcher());
105 				s_logger.debug("value set in dao");
106 				
107 			} catch (Exception e) {
108 				// ignore problems
109 				s_logger.error("problem when auto-setting extentFetcher", e);
110 
111 			}
112 		} else {
113 			s_logger.error("no extentFetcher available -- cannot use extent-based fetch methods");
114 		}
115 	}
116 
117 	/**
118 	 * Gets the session factory (from spring context if needed).
119 	 * @return the extentFetcher
120 	 */
121 	public ExtentFetcher getExtentFetcher() {
122 		if ((extentFetcher == null) && (m_applicationContext != null)) {
123 			// try to locate the session factory
124 			if (m_applicationContext.containsBean(EXTENT_FETCHER_BEAN_DEFAULT_NAME)) {
125 				extentFetcher = (ExtentFetcher)
126 					m_applicationContext.getBean(EXTENT_FETCHER_BEAN_DEFAULT_NAME);
127 			} else {
128 				s_logger.error("failed to obtain extentFetcher from application context "
129 					+ "-- cannot use Extent-based fetching");
130 			}
131 		}
132 		return extentFetcher;
133 	}
134 
135 	/**
136 	 * If you do not set the extent fetcher explicitly,
137 	 * it will be obtained from the application's context.
138 	 * @param extentFetcher the fetcher to use
139 	 */
140 	public void setExtentFetcher(ExtentFetcher extentFetcher) {
141 		this.extentFetcher = extentFetcher;
142 	}
143 
144 	/** {@inheritDoc} */
145 	public void setOrder(int order) {
146 		this.order = order;
147 	}
148 
149 	/** {@inheritDoc} */
150 	public int getOrder() {
151 		return this.order;
152 	}
153 
154 	/** {@inheritDoc} */
155 	public void setApplicationContext(ApplicationContext applicationContext)
156 		throws BeansException {
157 		
158 		m_applicationContext = applicationContext;
159 	}
160 }