Source Code Cross Referenced for AbstractJpaTests.java in  » J2EE » spring-framework-2.0.6 » org » springframework » test » jpa » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » J2EE » spring framework 2.0.6 » org.springframework.test.jpa 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2002-2006 the original author or authors.
003:         *
004:         * Licensed under the Apache License, Version 2.0 (the "License");
005:         * you may not use this file except in compliance with the License.
006:         * You may obtain a copy of the License at
007:         *
008:         *      http://www.apache.org/licenses/LICENSE-2.0
009:         *
010:         * Unless required by applicable law or agreed to in writing, software
011:         * distributed under the License is distributed on an "AS IS" BASIS,
012:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013:         * See the License for the specific language governing permissions and
014:         * limitations under the License.
015:         */
016:
017:        package org.springframework.test.jpa;
018:
019:        import java.lang.instrument.ClassFileTransformer;
020:        import java.lang.reflect.Constructor;
021:        import java.lang.reflect.Field;
022:        import java.lang.reflect.InvocationTargetException;
023:        import java.lang.reflect.Method;
024:        import java.util.HashMap;
025:        import java.util.Map;
026:
027:        import javax.persistence.EntityManager;
028:        import javax.persistence.EntityManagerFactory;
029:
030:        import junit.framework.TestCase;
031:
032:        import org.springframework.beans.BeanUtils;
033:        import org.springframework.beans.BeansException;
034:        import org.springframework.beans.factory.config.BeanPostProcessor;
035:        import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
036:        import org.springframework.beans.factory.support.BeanDefinitionRegistry;
037:        import org.springframework.beans.factory.support.DefaultListableBeanFactory;
038:        import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
039:        import org.springframework.context.ConfigurableApplicationContext;
040:        import org.springframework.context.support.GenericApplicationContext;
041:        import org.springframework.instrument.classloading.LoadTimeWeaver;
042:        import org.springframework.instrument.classloading.ResourceOverridingShadowingClassLoader;
043:        import org.springframework.instrument.classloading.ShadowingClassLoader;
044:        import org.springframework.orm.jpa.ExtendedEntityManagerCreator;
045:        import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
046:        import org.springframework.orm.jpa.SharedEntityManagerCreator;
047:        import org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager;
048:        import org.springframework.test.annotation.AbstractAnnotationAwareTransactionalTests;
049:        import org.springframework.util.StringUtils;
050:
051:        /**
052:         * Convenient support class for JPA-related tests. Offers the same contract as
053:         * AbstractTransactionalDataSourceSpringContextTests and equally good performance,
054:         * even when performing the instrumentation required by the JPA specification.
055:         *
056:         * <p>Exposes an EntityManagerFactory and a shared EntityManager.
057:         * Requires an EntityManagerFactory to be injected, plus the DataSource and
058:         * JpaTransactionManager through the superclass.
059:         * 
060:         * <p>When using Xerces, make sure a post 2.0.2 version is available on the classpath
061:         * to avoid a critical 
062:         * <a href="http://nagoya.apache.org/bugzilla/show_bug.cgi?id=16014"/>bug</a> 
063:         * that leads to StackOverflow. Maven users are likely to encounter this problem since
064:         * 2.0.2 is used by default.
065:         * <p/>
066:         * A workaround is to explicitly specify the Xerces version inside the Maven pom: 
067:         * <pre>
068:         * &lt;dependency&gt;
069:         *   &lt;groupId&gt;xerces&lt;/groupId&gt;
070:         *     &lt;artifactId&gt;xercesImpl&lt;/artifactId&gt;
071:         *   &lt;version&gt;2.8.1&lt;/version&gt;
072:         * &lt;/dependency&gt;
073:         * </pre>
074:         *
075:         * @author Rod Johnson
076:         * @author Rob Harrop
077:         * @since 2.0
078:         */
079:        public abstract class AbstractJpaTests extends
080:                AbstractAnnotationAwareTransactionalTests {
081:
082:            private static final String DEFAULT_ORM_XML_LOCATION = "META-INF/orm.xml";
083:
084:            /**
085:             * Map from String defining unique combination of config locations, to ApplicationContext.
086:             * Values are intentionally not strongly typed, to avoid potential class cast exceptions
087:             * through use between different class loaders.
088:             */
089:            private static Map<String, Object> contextCache = new HashMap<String, Object>();
090:
091:            private static Map<String, ClassLoader> classLoaderCache = new HashMap<String, ClassLoader>();
092:
093:            protected EntityManagerFactory entityManagerFactory;
094:
095:            /**
096:             * If this instance is in a shadow loader, this variable
097:             * will contain the parent instance of the subclass.
098:             * The class will not be the same as the class of the
099:             * shadow instance, as it was loaded by a different class loader,
100:             * but it can be invoked reflectively. The shadowParent
101:             * and the shadow loader can communicate reflectively
102:             * but not through direct invocation.
103:             */
104:            private Object shadowParent;
105:
106:            /**
107:             * Subclasses can use this in test cases.
108:             * It will participate in any current transaction.
109:             */
110:            protected EntityManager sharedEntityManager;
111:
112:            public void setEntityManagerFactory(
113:                    EntityManagerFactory entityManagerFactory) {
114:                this .entityManagerFactory = entityManagerFactory;
115:                this .sharedEntityManager = SharedEntityManagerCreator
116:                        .createSharedEntityManager(this .entityManagerFactory);
117:            }
118:
119:            /**
120:             * Create an EntityManager that will always automatically enlist itself in current
121:             * transactions, in contrast to an EntityManager returned by
122:             * <code>EntityManagerFactory.createEntityManager()</code>
123:             * (which requires an explicit <code>joinTransaction()</code> call).
124:             */
125:            protected EntityManager createContainerManagedEntityManager() {
126:                return ExtendedEntityManagerCreator
127:                        .createContainerManagedEntityManager(this .entityManagerFactory);
128:            }
129:
130:            /**
131:             * Subclasses should override this method if they wish
132:             * to disable shadow class loading. Do this only
133:             * if instrumentation is not required in your
134:             * JPA implementation. 
135:             * @return whether to disable shadow loading functionality
136:             */
137:            protected boolean shouldUseShadowLoader() {
138:                return true;
139:            }
140:
141:            @Override
142:            public void setDirty() {
143:                super .setDirty();
144:                contextCache.remove(cacheKeys());
145:                classLoaderCache.remove(cacheKeys());
146:
147:                // If we are a shadow loader, we need to invoke
148:                // the shadow parent to set it dirty, as 
149:                // it is the shadow parent that maintains the cache state,
150:                // not the child
151:                if (this .shadowParent != null) {
152:                    try {
153:                        Method m = shadowParent.getClass().getMethod(
154:                                "setDirty", (Class[]) null);
155:                        m.invoke(shadowParent, (Object[]) null);
156:                    } catch (Exception ex) {
157:                        throw new RuntimeException(ex);
158:                    }
159:                }
160:            }
161:
162:            @Override
163:            public void runBare() throws Throwable {
164:                if (!shouldUseShadowLoader()) {
165:                    super .runBare();
166:                    return;
167:                }
168:
169:                String combinationOfContextLocationsForThisTestClass = cacheKeys();
170:                ClassLoader classLoaderForThisTestClass = getClass()
171:                        .getClassLoader();
172:                // save the TCCL
173:                ClassLoader initialClassLoader = Thread.currentThread()
174:                        .getContextClassLoader();
175:
176:                if (this .shadowParent != null) {
177:                    Thread.currentThread().setContextClassLoader(
178:                            classLoaderForThisTestClass);
179:                    super .runBare();
180:                } else {
181:                    ShadowingClassLoader shadowingClassLoader = (ShadowingClassLoader) classLoaderCache
182:                            .get(combinationOfContextLocationsForThisTestClass);
183:
184:                    if (shadowingClassLoader == null) {
185:                        shadowingClassLoader = (ShadowingClassLoader) createShadowingClassLoader(classLoaderForThisTestClass);
186:                        classLoaderCache.put(
187:                                combinationOfContextLocationsForThisTestClass,
188:                                shadowingClassLoader);
189:                    }
190:                    try {
191:                        Thread.currentThread().setContextClassLoader(
192:                                shadowingClassLoader);
193:                        String[] configLocations = getConfigLocations();
194:
195:                        // Do not strongly type, to avoid ClassCastException.
196:                        Object cachedContext = contextCache
197:                                .get(combinationOfContextLocationsForThisTestClass);
198:
199:                        if (cachedContext == null) {
200:
201:                            // Create the LoadTimeWeaver.
202:                            Class shadowingLoadTimeWeaverClass = shadowingClassLoader
203:                                    .loadClass(ShadowingLoadTimeWeaver.class
204:                                            .getName());
205:                            Constructor constructor = shadowingLoadTimeWeaverClass
206:                                    .getConstructor(ClassLoader.class);
207:                            constructor.setAccessible(true);
208:                            Object ltw = constructor
209:                                    .newInstance(shadowingClassLoader);
210:
211:                            // Create the BeanFactory.
212:                            Class beanFactoryClass = shadowingClassLoader
213:                                    .loadClass(DefaultListableBeanFactory.class
214:                                            .getName());
215:                            Object beanFactory = BeanUtils
216:                                    .instantiateClass(beanFactoryClass);
217:
218:                            // Create the BeanDefinitionReader.
219:                            Class beanDefinitionReaderClass = shadowingClassLoader
220:                                    .loadClass(XmlBeanDefinitionReader.class
221:                                            .getName());
222:                            Class beanDefinitionRegistryClass = shadowingClassLoader
223:                                    .loadClass(BeanDefinitionRegistry.class
224:                                            .getName());
225:                            Object reader = beanDefinitionReaderClass
226:                                    .getConstructor(beanDefinitionRegistryClass)
227:                                    .newInstance(beanFactory);
228:
229:                            // Load the bean definitions into the BeanFactory.
230:                            Method loadBeanDefinitions = beanDefinitionReaderClass
231:                                    .getMethod("loadBeanDefinitions",
232:                                            String[].class);
233:                            loadBeanDefinitions.invoke(reader,
234:                                    new Object[] { configLocations });
235:
236:                            // Create LoadTimeWeaver-injecting BeanPostProcessor.
237:                            Class loadTimeWeaverInjectingBeanPostProcessorClass = shadowingClassLoader
238:                                    .loadClass(LoadTimeWeaverInjectingBeanPostProcessor.class
239:                                            .getName());
240:                            Class loadTimeWeaverClass = shadowingClassLoader
241:                                    .loadClass(LoadTimeWeaver.class.getName());
242:                            Constructor bppConstructor = loadTimeWeaverInjectingBeanPostProcessorClass
243:                                    .getConstructor(loadTimeWeaverClass);
244:                            bppConstructor.setAccessible(true);
245:                            Object beanPostProcessor = bppConstructor
246:                                    .newInstance(ltw);
247:
248:                            // Add LoadTimeWeaver-injecting BeanPostProcessor.
249:                            Class beanPostProcessorClass = shadowingClassLoader
250:                                    .loadClass(BeanPostProcessor.class
251:                                            .getName());
252:                            Method addBeanPostProcessor = beanFactoryClass
253:                                    .getMethod("addBeanPostProcessor",
254:                                            beanPostProcessorClass);
255:                            addBeanPostProcessor.invoke(beanFactory,
256:                                    beanPostProcessor);
257:
258:                            // Create the GenericApplicationContext.
259:                            Class genericApplicationContextClass = shadowingClassLoader
260:                                    .loadClass(GenericApplicationContext.class
261:                                            .getName());
262:                            Class defaultListableBeanFactoryClass = shadowingClassLoader
263:                                    .loadClass(DefaultListableBeanFactory.class
264:                                            .getName());
265:                            cachedContext = genericApplicationContextClass
266:                                    .getConstructor(
267:                                            defaultListableBeanFactoryClass)
268:                                    .newInstance(beanFactory);
269:
270:                            // Invoke the context's "refresh" method.
271:                            genericApplicationContextClass.getMethod("refresh")
272:                                    .invoke(cachedContext);
273:
274:                            // Store the context reference in the cache.
275:                            contextCache
276:                                    .put(
277:                                            combinationOfContextLocationsForThisTestClass,
278:                                            cachedContext);
279:                        }
280:                        // create the shadowed test
281:                        Class shadowedTestClass = shadowingClassLoader
282:                                .loadClass(getClass().getName());
283:
284:                        // So long as JUnit is excluded from shadowing we
285:                        // can minimize reflective invocation here
286:                        TestCase shadowedTestCase = (TestCase) BeanUtils
287:                                .instantiateClass(shadowedTestClass);
288:
289:                        /* shadowParent = this */
290:                        Class this ShadowedClass = shadowingClassLoader
291:                                .loadClass(AbstractJpaTests.class.getName());
292:                        Field shadowed = this ShadowedClass
293:                                .getDeclaredField("shadowParent");
294:                        shadowed.setAccessible(true);
295:                        shadowed.set(shadowedTestCase, this );
296:
297:                        /* AbstractSpringContextTests.addContext(Object, ApplicationContext) */
298:                        Class applicationContextClass = shadowingClassLoader
299:                                .loadClass(ConfigurableApplicationContext.class
300:                                        .getName());
301:                        Method addContextMethod = shadowedTestClass.getMethod(
302:                                "addContext", Object.class,
303:                                applicationContextClass);
304:                        addContextMethod.invoke(shadowedTestCase,
305:                                configLocations, cachedContext);
306:
307:                        // Invoke tests on shadowed test case
308:                        shadowedTestCase.setName(getName());
309:                        shadowedTestCase.runBare();
310:                    } catch (InvocationTargetException ex) {
311:                        // Unwrap this for better exception reporting
312:                        // when running tests
313:                        throw ex.getTargetException();
314:                    } finally {
315:                        Thread.currentThread().setContextClassLoader(
316:                                initialClassLoader);
317:                    }
318:                }
319:            }
320:
321:            protected String cacheKeys() {
322:                return StringUtils
323:                        .arrayToCommaDelimitedString(getConfigLocations());
324:            }
325:
326:            /**
327:             * NB: This method must <b>not</b> have a return type of ShadowingClassLoader as that would cause that
328:             * class to be loaded eagerly when this test case loads, creating verify errors at runtime.
329:             */
330:            protected ClassLoader createShadowingClassLoader(
331:                    ClassLoader classLoader) {
332:                OrmXmlOverridingShadowingClassLoader orxl = new OrmXmlOverridingShadowingClassLoader(
333:                        classLoader, getActualOrmXmlLocation());
334:                customizeResourceOverridingShadowingClassLoader(orxl);
335:                return orxl;
336:            }
337:
338:            /**
339:             * Customize the shadowing class loader.
340:             * @param shadowingClassLoader this parameter is actually of type
341:             * ResourceOverridingShadowingClassLoader, and can safely to be cast to
342:             * that type. However, the signature must not be of that type as that
343:             * would cause the present class loader to load that type.
344:             */
345:            protected void customizeResourceOverridingShadowingClassLoader(
346:                    ClassLoader shadowingClassLoader) {
347:                // empty
348:            }
349:
350:            /**
351:             * Subclasses can override this to return the real location path for
352:             * orm.xml or null if they do not wish to find any orm.xml
353:             * @return orm.xml path or null to hide any such file
354:             */
355:            protected String getActualOrmXmlLocation() {
356:                return DEFAULT_ORM_XML_LOCATION;
357:            }
358:
359:            private static class LoadTimeWeaverInjectingBeanPostProcessor
360:                    extends InstantiationAwareBeanPostProcessorAdapter {
361:
362:                private final LoadTimeWeaver ltw;
363:
364:                public LoadTimeWeaverInjectingBeanPostProcessor(
365:                        LoadTimeWeaver ltw) {
366:                    this .ltw = ltw;
367:                }
368:
369:                public Object postProcessBeforeInitialization(Object bean,
370:                        String beanName) throws BeansException {
371:                    if (bean instanceof  LocalContainerEntityManagerFactoryBean) {
372:                        ((LocalContainerEntityManagerFactoryBean) bean)
373:                                .setLoadTimeWeaver(this .ltw);
374:                    }
375:                    if (bean instanceof  DefaultPersistenceUnitManager) {
376:                        ((DefaultPersistenceUnitManager) bean)
377:                                .setLoadTimeWeaver(this .ltw);
378:                    }
379:                    return bean;
380:                }
381:            }
382:
383:            private static class ShadowingLoadTimeWeaver implements 
384:                    LoadTimeWeaver {
385:
386:                private final ClassLoader shadowingClassLoader;
387:
388:                private final Class shadowingClassLoaderClass;
389:
390:                public ShadowingLoadTimeWeaver(ClassLoader shadowingClassLoader) {
391:                    this .shadowingClassLoader = shadowingClassLoader;
392:                    this .shadowingClassLoaderClass = shadowingClassLoader
393:                            .getClass();
394:                }
395:
396:                public ClassLoader getInstrumentableClassLoader() {
397:                    return (ClassLoader) this .shadowingClassLoader;
398:                }
399:
400:                public ClassLoader getThrowawayClassLoader() {
401:                    // Be sure to copy the same resource overrides
402:                    // and same class file transformers:
403:                    // We want the throwaway class loader to behave
404:                    // like the instrumentable class loader
405:                    ResourceOverridingShadowingClassLoader roscl = new ResourceOverridingShadowingClassLoader(
406:                            getClass().getClassLoader());
407:                    if (shadowingClassLoader instanceof  ResourceOverridingShadowingClassLoader) {
408:                        roscl
409:                                .copyOverrides((ResourceOverridingShadowingClassLoader) shadowingClassLoader);
410:                    }
411:                    if (shadowingClassLoader instanceof  ShadowingClassLoader) {
412:                        roscl
413:                                .copyTransformers((ShadowingClassLoader) shadowingClassLoader);
414:                    }
415:                    return roscl;
416:                }
417:
418:                public void addTransformer(ClassFileTransformer transformer) {
419:                    try {
420:                        Method addClassFileTransformer = this .shadowingClassLoaderClass
421:                                .getMethod("addTransformer",
422:                                        ClassFileTransformer.class);
423:                        addClassFileTransformer.setAccessible(true);
424:                        addClassFileTransformer.invoke(
425:                                this .shadowingClassLoader, transformer);
426:                    } catch (Exception ex) {
427:                        throw new RuntimeException(ex);
428:                    }
429:                }
430:            }
431:
432:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.