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