Source Code Cross Referenced for DefaultPersistenceUnitManager.java in  » J2EE » spring-framework-2.5 » org » springframework » orm » jpa » persistenceunit » 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.5 » org.springframework.orm.jpa.persistenceunit 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2002-2007 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.orm.jpa.persistenceunit;
018:
019:        import java.io.IOException;
020:        import java.net.URL;
021:        import java.util.HashMap;
022:        import java.util.HashSet;
023:        import java.util.Map;
024:        import java.util.Set;
025:
026:        import javax.persistence.PersistenceException;
027:        import javax.persistence.spi.PersistenceUnitInfo;
028:        import javax.sql.DataSource;
029:
030:        import org.springframework.beans.factory.InitializingBean;
031:        import org.springframework.context.ResourceLoaderAware;
032:        import org.springframework.context.weaving.LoadTimeWeaverAware;
033:        import org.springframework.core.io.Resource;
034:        import org.springframework.core.io.ResourceLoader;
035:        import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
036:        import org.springframework.core.io.support.ResourcePatternResolver;
037:        import org.springframework.core.io.support.ResourcePatternUtils;
038:        import org.springframework.instrument.InstrumentationSavingAgent;
039:        import org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver;
040:        import org.springframework.instrument.classloading.LoadTimeWeaver;
041:        import org.springframework.jdbc.datasource.lookup.DataSourceLookup;
042:        import org.springframework.jdbc.datasource.lookup.JndiDataSourceLookup;
043:        import org.springframework.jdbc.datasource.lookup.MapDataSourceLookup;
044:        import org.springframework.util.ObjectUtils;
045:
046:        /**
047:         * Default implementation of the {@link PersistenceUnitManager} interface.
048:         * Used as internal default by
049:         * {@link org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean}.
050:         *
051:         * <p>Supports standard JPA scanning for <code>persistence.xml</code> files,
052:         * with configurable file locations, JDBC DataSource lookup and load-time weaving.
053:         *
054:         * <p>The default XML file location is <code>classpath:META-INF/persistence.xml</code>,
055:         * scanning for all matching files in the class path (as defined in the JPA specification).
056:         * DataSource names are by default interpreted as JNDI names, and no load time weaving
057:         * is available (which requires weaving to be turned off in the persistence provider).
058:         *
059:         * @author Juergen Hoeller
060:         * @since 2.0
061:         * @see #setPersistenceXmlLocations
062:         * @see #setDataSourceLookup
063:         * @see #setLoadTimeWeaver
064:         * @see org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean#setPersistenceUnitManager
065:         */
066:        public class DefaultPersistenceUnitManager implements 
067:                PersistenceUnitManager, ResourceLoaderAware,
068:                LoadTimeWeaverAware, InitializingBean {
069:
070:            /**
071:             * Default location of the <code>persistence.xml</code> file:
072:             * "classpath*:META-INF/persistence.xml".
073:             */
074:            public final static String DEFAULT_PERSISTENCE_XML_LOCATION = "classpath*:META-INF/persistence.xml";
075:
076:            /**
077:             * Default location for the persistence unit root URL:
078:             * "classpath:", indicating the root of the class path.
079:             */
080:            public final static String ORIGINAL_DEFAULT_PERSISTENCE_UNIT_ROOT_LOCATION = "classpath:";
081:
082:            /** Location of persistence.xml file(s) */
083:            private String[] persistenceXmlLocations = new String[] { DEFAULT_PERSISTENCE_XML_LOCATION };
084:
085:            private String defaultPersistenceUnitRootLocation = ORIGINAL_DEFAULT_PERSISTENCE_UNIT_ROOT_LOCATION;
086:
087:            private DataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
088:
089:            private DataSource defaultDataSource;
090:
091:            private PersistenceUnitPostProcessor[] persistenceUnitPostProcessors;
092:
093:            private LoadTimeWeaver loadTimeWeaver;
094:
095:            private ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
096:
097:            private final Set<String> persistenceUnitInfoNames = new HashSet<String>();
098:
099:            private final Map<String, MutablePersistenceUnitInfo> persistenceUnitInfos = new HashMap<String, MutablePersistenceUnitInfo>();
100:
101:            /**
102:             * Set the locations of the <code>persistence.xml</code> files to load.
103:             * These can be specified as Spring resource locations and/or location patterns.
104:             * <p>Default is "classpath*:META-INF/persistence.xml".
105:             * @param persistenceXmlLocations an array of Spring resource Strings
106:             * identifying the location of the <code>persistence.xml</code> files to read
107:             */
108:            public void setPersistenceXmlLocations(
109:                    String[] persistenceXmlLocations) {
110:                this .persistenceXmlLocations = persistenceXmlLocations;
111:            }
112:
113:            /**
114:             * Set the default persistence unit root location, to be applied
115:             * if no unit-specific persistence unit root could be determined.
116:             * <p>Default is "classpath:", that is, the root of the current class path
117:             * (nearest root directory). To be overridden if unit-specific resolution
118:             * does not work and the class path root is not appropriate either.
119:             */
120:            public void setDefaultPersistenceUnitRootLocation(
121:                    String defaultPersistenceUnitRootLocation) {
122:                this .defaultPersistenceUnitRootLocation = defaultPersistenceUnitRootLocation;
123:            }
124:
125:            /**
126:             * Specify the JDBC DataSources that the JPA persistence provider is supposed
127:             * to use for accessing the database, resolving data source names in
128:             * <code>persistence.xml</code> against Spring-managed DataSources.
129:             * <p>The specified Map needs to define data source names for specific DataSource
130:             * objects, matching the data source names used in <code>persistence.xml</code>.
131:             * If not specified, data source names will be resolved as JNDI names instead
132:             * (as defined by standard JPA).
133:             * @see org.springframework.jdbc.datasource.lookup.MapDataSourceLookup
134:             */
135:            public void setDataSources(Map<String, DataSource> dataSources) {
136:                this .dataSourceLookup = new MapDataSourceLookup(dataSources);
137:            }
138:
139:            /**
140:             * Specify the JDBC DataSourceLookup that provides DataSources for the
141:             * persistence provider, resolving data source names in <code>persistence.xml</code>
142:             * against Spring-managed DataSource instances.
143:             * <p>Default is JndiDataSourceLookup, which resolves DataSource names as
144:             * JNDI names (as defined by standard JPA). Specify a BeanFactoryDataSourceLookup
145:             * instance if you want DataSource names to be resolved against Spring bean names.
146:             * <p>Alternatively, consider passing in a map from names to DataSource instances
147:             * via the "dataSources" property. If the <code>persistence.xml</code> file
148:             * does not define DataSource names at all, specify a default DataSource
149:             * via the "defaultDataSource" property.
150:             * @see org.springframework.jdbc.datasource.lookup.JndiDataSourceLookup
151:             * @see org.springframework.jdbc.datasource.lookup.BeanFactoryDataSourceLookup
152:             * @see #setDataSources
153:             * @see #setDefaultDataSource
154:             */
155:            public void setDataSourceLookup(DataSourceLookup dataSourceLookup) {
156:                this .dataSourceLookup = (dataSourceLookup != null ? dataSourceLookup
157:                        : new JndiDataSourceLookup());
158:            }
159:
160:            /**
161:             * Return the JDBC DataSourceLookup that provides DataSources for the
162:             * persistence provider, resolving data source names in <code>persistence.xml</code>
163:             * against Spring-managed DataSource instances.
164:             */
165:            public DataSourceLookup getDataSourceLookup() {
166:                return this .dataSourceLookup;
167:            }
168:
169:            /**
170:             * Specify the JDBC DataSource that the JPA persistence provider is supposed
171:             * to use for accessing the database if none has been specified in
172:             * <code>persistence.xml</code>.
173:             * <p>In JPA speak, a DataSource passed in here will be uses as "nonJtaDataSource"
174:             * on the PersistenceUnitInfo passed to the PersistenceProvider, provided that
175:             * none has been registered before.
176:             * @see javax.persistence.spi.PersistenceUnitInfo#getNonJtaDataSource()
177:             */
178:            public void setDefaultDataSource(DataSource defaultDataSource) {
179:                this .defaultDataSource = defaultDataSource;
180:            }
181:
182:            /**
183:             * Return the JDBC DataSource that the JPA persistence provider is supposed
184:             * to use for accessing the database if none has been specified in
185:             * <code>persistence.xml</code>.
186:             */
187:            public DataSource getDefaultDataSource() {
188:                return this .defaultDataSource;
189:            }
190:
191:            /**
192:             * Set the PersistenceUnitPostProcessors to be applied to each
193:             * PersistenceUnitInfo that has been parsed by this manager.
194:             * <p>Such post-processors can, for example, register further entity
195:             * classes and jar files, in addition to the metadata read in from
196:             * <code>persistence.xml</code>.
197:             */
198:            public void setPersistenceUnitPostProcessors(
199:                    PersistenceUnitPostProcessor[] postProcessors) {
200:                this .persistenceUnitPostProcessors = postProcessors;
201:            }
202:
203:            /**
204:             * Return the PersistenceUnitPostProcessors to be applied to each
205:             * PersistenceUnitInfo that has been parsed by this manager.
206:             */
207:            public PersistenceUnitPostProcessor[] getPersistenceUnitPostProcessors() {
208:                return this .persistenceUnitPostProcessors;
209:            }
210:
211:            /**
212:             * Specify the Spring LoadTimeWeaver to use for class instrumentation according
213:             * to the JPA class transformer contract.
214:             * <p>It is not required to specify a LoadTimeWeaver: Most providers will be
215:             * able to provide a subset of their functionality without class instrumentation
216:             * as well, or operate with their VM agent specified on JVM startup.
217:             * <p>In terms of Spring-provided weaving options, the most important ones are
218:             * InstrumentationLoadTimeWeaver, which requires a Spring-specific (but very general)
219:             * VM agent specified on JVM startup, and ReflectiveLoadTimeWeaver, which interacts
220:             * with an underlying ClassLoader based on specific extended methods being available
221:             * on it (for example, interacting with Spring's TomcatInstrumentableClassLoader).
222:             * <p><b>NOTE:</b> As of Spring 2.5, the context's default LoadTimeWeaver (defined
223:             * as bean with name "loadTimeWeaver") will be picked up automatically, if available,
224:             * removing the need for LoadTimeWeaver configuration on each affected target bean.</b>
225:             * Consider using the <code>context:load-time-weaver</code> XML tag for creating
226:             * such a shared LoadTimeWeaver (autodetecting the environment by default).
227:             * @see org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver
228:             * @see org.springframework.instrument.classloading.ReflectiveLoadTimeWeaver
229:             * @see org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader
230:             */
231:            public void setLoadTimeWeaver(LoadTimeWeaver loadTimeWeaver) {
232:                this .loadTimeWeaver = loadTimeWeaver;
233:            }
234:
235:            /**
236:             * Return the Spring LoadTimeWeaver to use for class instrumentation according
237:             * to the JPA class transformer contract.
238:             */
239:            public LoadTimeWeaver getLoadTimeWeaver() {
240:                return this .loadTimeWeaver;
241:            }
242:
243:            public void setResourceLoader(ResourceLoader resourceLoader) {
244:                this .resourcePatternResolver = (resourceLoader != null ? ResourcePatternUtils
245:                        .getResourcePatternResolver(resourceLoader)
246:                        : new PathMatchingResourcePatternResolver());
247:            }
248:
249:            public void afterPropertiesSet() {
250:                if (this .loadTimeWeaver == null
251:                        && InstrumentationSavingAgent.getInstrumentation() != null) {
252:                    this .loadTimeWeaver = new InstrumentationLoadTimeWeaver();
253:                }
254:                preparePersistenceUnitInfos();
255:            }
256:
257:            /**
258:             * Prepare the PersistenceUnitInfos according to the configuration
259:             * of this manager: scanning for <code>persistence.xml</code> files,
260:             * parsing all matching files, configurating and post-processing them.
261:             * <p>PersistenceUnitInfos cannot be obtained before this preparation
262:             * method has been invoked.
263:             * @see #obtainDefaultPersistenceUnitInfo()
264:             * @see #obtainPersistenceUnitInfo(String)
265:             */
266:            public void preparePersistenceUnitInfos() {
267:                this .persistenceUnitInfoNames.clear();
268:                this .persistenceUnitInfos.clear();
269:                SpringPersistenceUnitInfo[] puis = readPersistenceUnitInfos();
270:                for (int i = 0; i < puis.length; i++) {
271:                    SpringPersistenceUnitInfo pui = puis[i];
272:                    if (pui.getPersistenceUnitRootUrl() == null) {
273:                        pui
274:                                .setPersistenceUnitRootUrl(determineDefaultPersistenceUnitRootUrl());
275:                    }
276:                    if (pui.getNonJtaDataSource() == null) {
277:                        pui.setNonJtaDataSource(this .defaultDataSource);
278:                    }
279:                    if (this .loadTimeWeaver != null) {
280:                        pui.init(this .loadTimeWeaver);
281:                    } else {
282:                        pui.init(this .resourcePatternResolver.getClassLoader());
283:                    }
284:                    postProcessPersistenceUnitInfo(pui);
285:                    String name = pui.getPersistenceUnitName();
286:                    this .persistenceUnitInfoNames.add(name);
287:                    this .persistenceUnitInfos.put(name, pui);
288:                }
289:            }
290:
291:            /**
292:             * Read all persistence unit infos from <code>persistence.xml</code>,
293:             * as defined in the JPA specification.
294:             */
295:            private SpringPersistenceUnitInfo[] readPersistenceUnitInfos() {
296:                PersistenceUnitReader reader = new PersistenceUnitReader(
297:                        this .resourcePatternResolver, this .dataSourceLookup);
298:                return reader
299:                        .readPersistenceUnitInfos(this .persistenceXmlLocations);
300:            }
301:
302:            /**
303:             * Try to determine the persistence unit root URL based on the given
304:             * "defaultPersistenceUnitRootLocation".
305:             * @return the persistence unit root URL to pass to the JPA PersistenceProvider
306:             * @see #setDefaultPersistenceUnitRootLocation
307:             */
308:            private URL determineDefaultPersistenceUnitRootUrl() {
309:                if (this .defaultPersistenceUnitRootLocation == null) {
310:                    return null;
311:                }
312:                try {
313:                    Resource res = this .resourcePatternResolver
314:                            .getResource(this .defaultPersistenceUnitRootLocation);
315:                    return res.getURL();
316:                } catch (IOException ex) {
317:                    throw new PersistenceException(
318:                            "Unable to resolve persistence unit root URL", ex);
319:                }
320:            }
321:
322:            /**
323:             * Return the specified PersistenceUnitInfo from this manager's cache
324:             * of processed persistence units, keeping it in the cache (i.e. not
325:             * 'obtaining' it for use but rather just accessing it for post-processing).
326:             * <p>This can be used in {@link #postProcessPersistenceUnitInfo} implementations,
327:             * detecting existing persistence units of the same name and potentially merging them.
328:             * @param persistenceUnitName the name of the desired persistence unit
329:             * @return the PersistenceUnitInfo in mutable form,
330:             * or <code>null</code> if not available
331:             */
332:            protected final MutablePersistenceUnitInfo getPersistenceUnitInfo(
333:                    String persistenceUnitName) {
334:                return this .persistenceUnitInfos.get(persistenceUnitName);
335:            }
336:
337:            /**
338:             * Hook method allowing subclasses to customize each PersistenceUnitInfo.
339:             * <p>Default implementation delegates to all registered PersistenceUnitPostProcessors.
340:             * It is usually preferable to register further entity classes, jar files etc there
341:             * rather than in a subclass of this manager, to be able to reuse the post-processors.
342:             * @param pui the chosen PersistenceUnitInfo, as read from <code>persistence.xml</code>.
343:             * Passed in as MutablePersistenceUnitInfo.
344:             * @see #setPersistenceUnitPostProcessors
345:             */
346:            protected void postProcessPersistenceUnitInfo(
347:                    MutablePersistenceUnitInfo pui) {
348:                PersistenceUnitPostProcessor[] postProcessors = getPersistenceUnitPostProcessors();
349:                if (postProcessors != null) {
350:                    for (int i = 0; i < postProcessors.length; i++) {
351:                        postProcessors[i].postProcessPersistenceUnitInfo(pui);
352:                    }
353:                }
354:            }
355:
356:            public PersistenceUnitInfo obtainDefaultPersistenceUnitInfo() {
357:                if (this .persistenceUnitInfoNames.isEmpty()) {
358:                    throw new IllegalStateException(
359:                            "No persistence units parsed from "
360:                                    + ObjectUtils
361:                                            .nullSafeToString(this .persistenceXmlLocations));
362:                }
363:                if (this .persistenceUnitInfos.isEmpty()) {
364:                    throw new IllegalStateException(
365:                            "All persistence units from "
366:                                    + ObjectUtils
367:                                            .nullSafeToString(this .persistenceXmlLocations)
368:                                    + " already obtained");
369:                }
370:                if (this .persistenceUnitInfos.size() > 1) {
371:                    throw new IllegalStateException(
372:                            "No single default persistence unit defined in "
373:                                    + ObjectUtils
374:                                            .nullSafeToString(this .persistenceXmlLocations));
375:                }
376:                PersistenceUnitInfo pui = this .persistenceUnitInfos.values()
377:                        .iterator().next();
378:                this .persistenceUnitInfos.clear();
379:                return pui;
380:            }
381:
382:            public PersistenceUnitInfo obtainPersistenceUnitInfo(
383:                    String persistenceUnitName) {
384:                PersistenceUnitInfo pui = this .persistenceUnitInfos
385:                        .remove(persistenceUnitName);
386:                if (pui == null) {
387:                    if (!this .persistenceUnitInfoNames
388:                            .contains(persistenceUnitName)) {
389:                        throw new IllegalArgumentException(
390:                                "No persistence unit with name '"
391:                                        + persistenceUnitName + "' found");
392:                    } else {
393:                        throw new IllegalStateException(
394:                                "Persistence unit with name '"
395:                                        + persistenceUnitName
396:                                        + "' already obtained");
397:                    }
398:                }
399:                return pui;
400:            }
401:
402:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.