Source Code Cross Referenced for JpaGpsDevice.java in  » Search-Engine » compass-2.0 » org » compass » gps » device » 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 » Search Engine » compass 2.0 » org.compass.gps.device.jpa 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2004-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.compass.gps.device.jpa;
018:
019:        import java.util.HashMap;
020:        import java.util.Map;
021:        import javax.persistence.EntityManagerFactory;
022:
023:        import org.compass.core.util.Assert;
024:        import org.compass.gps.CompassGpsException;
025:        import org.compass.gps.PassiveMirrorGpsDevice;
026:        import org.compass.gps.device.jpa.entities.EntityInformation;
027:        import org.compass.gps.device.jpa.entities.JpaEntitiesLocator;
028:        import org.compass.gps.device.jpa.entities.JpaEntitiesLocatorDetector;
029:        import org.compass.gps.device.jpa.indexer.JpaIndexEntitiesIndexer;
030:        import org.compass.gps.device.jpa.indexer.JpaIndexEntitiesIndexerDetector;
031:        import org.compass.gps.device.jpa.lifecycle.JpaEntityLifecycleInjector;
032:        import org.compass.gps.device.jpa.lifecycle.JpaEntityLifecycleInjectorDetector;
033:        import org.compass.gps.device.jpa.queryprovider.DefaultJpaQueryProvider;
034:        import org.compass.gps.device.jpa.queryprovider.JpaQueryProvider;
035:        import org.compass.gps.device.jpa.support.NativeJpaHelper;
036:        import org.compass.gps.device.support.parallel.AbstractParallelGpsDevice;
037:        import org.compass.gps.device.support.parallel.IndexEntitiesIndexer;
038:        import org.compass.gps.device.support.parallel.IndexEntity;
039:
040:        /**
041:         * <p>A Java Persistence API Gps Device (EJB3 Persistence).
042:         *
043:         * <p>The jpa device provides support for using jpa to index a database. The path can
044:         * be viewed as: Database <-> EntityManager(JPA) <-> Objects <-> Compass::Gps
045:         * <-> Compass::Core (Search Engine). What it means is that for every object that has both
046:         * jpa and compass mappings, you will be able to index it's data, as well as real time mirroring of
047:         * data changes.
048:         *
049:         * <p>When creating the object, an <code>EntityManagerFactory</code> must be provided to the Device.
050:         *
051:         * <p>Indexing uses {@link JpaEntitiesLocator} to locate all the entities that can be
052:         * indexed (i.e. entities that have both Compass and JPA mappings). Most of the time
053:         * the {@link org.compass.gps.device.jpa.entities.DefaultJpaEntitiesLocator} is enough, but
054:         * special JPA implementation one can be provided. If none is provided, the device will use the {@link
055:         * JpaEntitiesLocatorDetector} to auto detect the correct locator (which defaults to the ({@link
056:         * org.compass.gps.device.jpa.entities.DefaultJpaEntitiesLocator}).
057:         *
058:         * <p>The indexing process itself is done through an implementation of
059:         * {@link org.compass.gps.device.jpa.indexer.JpaIndexEntitiesIndexer}. There are several implemenations
060:         * for it including a default one that uses plain JPA APIs. Specific implementations (such as Hibernate
061:         * and OpenJPA) are used for better performance.
062:         *
063:         * <p>Mirroring can be done in two ways. The first one is using JPA official API, implemeting
064:         * an Entity Lifecycle listener and specifing it for each entity class via annotations. Compass
065:         * comes with helper base clases for it, {@link AbstractCompassJpaEntityListener} and
066:         * {@link AbstractDeviceJpaEntityListener}. As far as integrating Compass with JPA for mirroring,
067:         * this is the less preferable way. The second option for mirroring is to use the
068:         * {@link JpaEntityLifecycleInjector}, which will use the internal JPA implementation to
069:         * inject global lifecycle event listerens (sadly, there is no option to do that with the
070:         * <code>EntityManagerFactory</code> API). If the {@link #setInjectEntityLifecycleListener(boolean)} is
071:         * set to <code>true</code> (defaults to <code>false</code>), the device will try to use the injector to
072:         * inject global event listeners. If no {@link JpaEntityLifecycleInjector} is defined, the device will
073:         * try to autodetect the injector based on the current support for specific JPA implementations using
074:         * the {@link JpaEntityLifecycleInjectorDetector}. See its javadoc for a list of the current JPA
075:         * implementations supported.
076:         *
077:         * <p>Mirroring can be turned off using the {@link #setMirrorDataChanges(boolean)} to <code>false</code>.
078:         * It defaults to <code>true<code>.
079:         *
080:         * <p>The device allows for {@link NativeJpaExtractor} to be set, for applications
081:         * that use a framework or by themself wrap the actual <code>EntityManagerFactory</code> implementation.
082:         *
083:         * <p>For advance usage, the device allows for {@link EntityManagerWrapper} to be set,
084:         * allowing to control the creation of <code>EntityManager</code>s, and transactions.
085:         * The {@link DefaultEntityManagerWrapper} should suffice for most cases.
086:         *
087:         * <p>The device extends the parallel device provinding supprot for parallel indexing.
088:         *
089:         * @author kimchy
090:         */
091:        public class JpaGpsDevice extends AbstractParallelGpsDevice implements 
092:                PassiveMirrorGpsDevice {
093:
094:            /**
095:             * Creates a new JpaGpsDevice. Note that its name ({@link #setName(String)}  and
096:             * entity manager factory ({@link #setEntityManagerFactory(javax.persistence.EntityManagerFactory)}
097:             * must be set.
098:             */
099:            public JpaGpsDevice() {
100:
101:            }
102:
103:            /**
104:             * Creates a new device with a specific name and an entity manager factory.
105:             */
106:            public JpaGpsDevice(String name,
107:                    EntityManagerFactory entityManagerFactory) {
108:                setName(name);
109:                setEntityManagerFactory(entityManagerFactory);
110:            }
111:
112:            private boolean mirrorDataChanges = true;
113:
114:            private int fetchCount = 200;
115:
116:            private EntityManagerFactory entityManagerFactory;
117:
118:            private EntityManagerWrapper entityManagerWrapper;
119:
120:            private JpaEntityLifecycleInjector lifecycleInjector;
121:
122:            private boolean injectEntityLifecycleListener;
123:
124:            private NativeJpaExtractor nativeJpaExtractor;
125:
126:            private EntityManagerFactory nativeEntityManagerFactory;
127:
128:            private JpaEntitiesLocator entitiesLocator;
129:
130:            private Map<Class<?>, JpaQueryProvider> queryProviderByClass = new HashMap<Class<?>, JpaQueryProvider>();
131:
132:            private Map<String, JpaQueryProvider> queryProviderByName = new HashMap<String, JpaQueryProvider>();
133:
134:            private JpaIndexEntitiesIndexer entitiesIndexer;
135:
136:            protected void doStart() throws CompassGpsException {
137:                Assert.notNull(entityManagerFactory,
138:                        buildMessage("Must set JPA EntityManagerFactory"));
139:                if (entityManagerWrapper == null) {
140:                    entityManagerWrapper = new DefaultEntityManagerWrapper();
141:                }
142:                entityManagerWrapper.setUp(entityManagerFactory);
143:
144:                nativeEntityManagerFactory = entityManagerFactory;
145:                if (nativeJpaExtractor != null) {
146:                    nativeEntityManagerFactory = nativeJpaExtractor
147:                            .extractNative(nativeEntityManagerFactory);
148:                    if (nativeEntityManagerFactory == null) {
149:                        throw new JpaGpsDeviceException(
150:                                buildMessage("Native EntityManager extractor returned null"));
151:                    }
152:                    if (log.isDebugEnabled()) {
153:                        log
154:                                .debug(buildMessage("Using native EntityManagerFactory ["
155:                                        + nativeEntityManagerFactory.getClass()
156:                                                .getName()
157:                                        + "] extracted by ["
158:                                        + nativeJpaExtractor.getClass()
159:                                                .getName() + "]"));
160:                    }
161:                } else {
162:                    nativeEntityManagerFactory = NativeJpaHelper
163:                            .extractNativeJpa(entityManagerFactory, compassGps
164:                                    .getMirrorCompass().getSettings());
165:                    if (log.isDebugEnabled()) {
166:                        log
167:                                .debug(buildMessage("Using native EntityManagerFactory ["
168:                                        + nativeEntityManagerFactory.getClass()
169:                                                .getName()
170:                                        + "] using default extractor"));
171:                    }
172:                }
173:
174:                if (entitiesLocator == null) {
175:                    entitiesLocator = JpaEntitiesLocatorDetector.detectLocator(
176:                            nativeEntityManagerFactory, compassGps
177:                                    .getMirrorCompass().getSettings());
178:                    if (log.isDebugEnabled()) {
179:                        log.debug(buildMessage("Using index entityLocator ["
180:                                + entitiesLocator.getClass().getName() + "]"));
181:                    }
182:                }
183:
184:                if (injectEntityLifecycleListener && mirrorDataChanges) {
185:                    if (lifecycleInjector == null) {
186:                        lifecycleInjector = JpaEntityLifecycleInjectorDetector
187:                                .detectInjector(nativeEntityManagerFactory,
188:                                        compassGps.getMirrorCompass()
189:                                                .getSettings());
190:                    }
191:                    if (lifecycleInjector == null) {
192:                        throw new JpaGpsDeviceException(
193:                                buildMessage("Failed to locate lifecycleInjector"));
194:                    }
195:                    if (log.isDebugEnabled()) {
196:                        log
197:                                .debug(buildMessage("Using lifecycleInjector ["
198:                                        + lifecycleInjector.getClass()
199:                                                .getName() + "]"));
200:                    }
201:                    lifecycleInjector.injectLifecycle(
202:                            nativeEntityManagerFactory, this );
203:                }
204:
205:                if (entitiesIndexer == null) {
206:                    entitiesIndexer = JpaIndexEntitiesIndexerDetector
207:                            .detectEntitiesIndexer(nativeEntityManagerFactory,
208:                                    compassGps.getMirrorCompass().getSettings());
209:                }
210:                if (log.isDebugEnabled()) {
211:                    log.debug(buildMessage("Using entities indexer ["
212:                            + entitiesIndexer.getClass().getName() + "]"));
213:                }
214:                entitiesIndexer.setJpaGpsDevice(this );
215:            }
216:
217:            protected void doStop() throws CompassGpsException {
218:                if (injectEntityLifecycleListener && mirrorDataChanges) {
219:                    lifecycleInjector.removeLifecycle(
220:                            nativeEntityManagerFactory, this );
221:                }
222:            }
223:
224:            protected IndexEntity[] doGetIndexEntities()
225:                    throws CompassGpsException {
226:                EntityInformation[] entitiesInformation = entitiesLocator
227:                        .locate(nativeEntityManagerFactory, this );
228:                // apply specific select statements
229:                for (EntityInformation entityInformation : entitiesInformation) {
230:                    if (queryProviderByClass.get(entityInformation
231:                            .getEntityClass()) != null) {
232:                        entityInformation.setQueryProvider(queryProviderByClass
233:                                .get(entityInformation.getEntityClass()));
234:                    }
235:                    if (queryProviderByName.get(entityInformation.getName()) != null) {
236:                        entityInformation.setQueryProvider(queryProviderByName
237:                                .get(entityInformation.getName()));
238:                    }
239:                }
240:                return entitiesInformation;
241:            }
242:
243:            protected IndexEntitiesIndexer doGetIndexEntitiesIndexer() {
244:                return entitiesIndexer;
245:            }
246:
247:            public EntityManagerFactory getEntityManagerFactory() {
248:                return this .entityManagerFactory;
249:            }
250:
251:            public EntityManagerFactory getNativeEntityManagerFactory() {
252:                return this .nativeEntityManagerFactory;
253:            }
254:
255:            /**
256:             * @see org.compass.gps.MirrorDataChangesGpsDevice#isMirrorDataChanges()
257:             */
258:            public boolean isMirrorDataChanges() {
259:                return mirrorDataChanges;
260:            }
261:
262:            /**
263:             * @see org.compass.gps.MirrorDataChangesGpsDevice#setMirrorDataChanges(boolean)
264:             */
265:            public void setMirrorDataChanges(boolean mirrorDataChanges) {
266:                this .mirrorDataChanges = mirrorDataChanges;
267:            }
268:
269:            /**
270:             * Sets the Jpa <code>EntityManagerFactory</code>. This is manadatory for the Jpa device.
271:             *
272:             * @param entityManagerFactory The entity manager factory the device will use.
273:             */
274:            public void setEntityManagerFactory(
275:                    EntityManagerFactory entityManagerFactory) {
276:                this .entityManagerFactory = entityManagerFactory;
277:            }
278:
279:            /**
280:             * Sets the Entity Manager factory wrapper to control the entity manager operations. This is optional since the
281:             * device has sensible defaults for it.
282:             *
283:             * @param entityManagerWrapper The entity manager wrapper to control the manager operations.
284:             */
285:            public void setEntityManagerWrapper(
286:                    EntityManagerWrapper entityManagerWrapper) {
287:                this .entityManagerWrapper = entityManagerWrapper;
288:            }
289:
290:            /**
291:             * Returns the Entity Manager factory wrapper to control the entity manager operations.
292:             */
293:            public EntityManagerWrapper getEntityManagerWrapper() {
294:                return entityManagerWrapper;
295:            }
296:
297:            /**
298:             * <p>Sets a specialized native entity manager factory extractor.
299:             * For applications that use a framework or by themself wrap the actual
300:             * <code>EntityManagerFactory</code> implementation.
301:             *
302:             * The native extractor is mainly used for specialized {@link JpaEntityLifecycleInjector}
303:             * and {@link JpaEntitiesLocator}.
304:             */
305:            public void setNativeExtractor(NativeJpaExtractor nativeJpaExtractor) {
306:                this .nativeJpaExtractor = nativeJpaExtractor;
307:            }
308:
309:            /**
310:             * Returns the native extractor.
311:             */
312:            public NativeJpaExtractor getNativeJpaExtractor() {
313:                return nativeJpaExtractor;
314:            }
315:
316:            /**
317:             * Sets if the device should try and automatically inject global entity lifecycle
318:             * listeners using either the provided {@link JpaEntityLifecycleInjector}, or if not
319:             * set, using the {@link JpaEntityLifecycleInjectorDetector}. Defaults to <code>false</code>.
320:             */
321:            public void setInjectEntityLifecycleListener(
322:                    boolean injectEntityLifecycleListener) {
323:                this .injectEntityLifecycleListener = injectEntityLifecycleListener;
324:            }
325:
326:            /**
327:             * If the {@link #setLifecycleInjector(org.compass.gps.device.jpa.lifecycle.JpaEntityLifecycleInjector)} is
328:             * set to <code>true</code>, the global lifecycle injector that will be used to inject global lifecycle
329:             * event listerens to the underlying implementation of the <code>EntityManagerFactory</code>. If not set,
330:             * the {@link JpaEntitiesLocatorDetector} will be used to auto-detect it.
331:             */
332:            public void setLifecycleInjector(
333:                    JpaEntityLifecycleInjector lifecycleInjector) {
334:                this .lifecycleInjector = lifecycleInjector;
335:            }
336:
337:            /**
338:             * Sets a specific enteties locator, which is responsible for locating enteties
339:             * that need to be indexed. Not a required parameter, since will use the
340:             * {@link JpaEntitiesLocatorDetector} to auto detect that correct one.
341:             */
342:            public void setEntitiesLocator(JpaEntitiesLocator entitiesLocator) {
343:                this .entitiesLocator = entitiesLocator;
344:            }
345:
346:            /**
347:             * Sets the fetch count for the indexing process. A large number will perform the indexing faster,
348:             * but will consume more memory. Defaults to <code>200</code>.
349:             */
350:            public void setFetchCount(int fetchCount) {
351:                this .fetchCount = fetchCount;
352:            }
353:
354:            /**
355:             * Returns the fetch count for the indexing process. A large number will perform the indexing faster,
356:             * but will consume more memory. Default to <code>200</code>.
357:             */
358:            public int getFetchCount() {
359:                return this .fetchCount;
360:            }
361:
362:            /**
363:             * <p>Sets a specific select statement for the index process of the given
364:             * entity class. The same as {@link #setIndexQueryProvider(Class,JpaQueryProvider)}
365:             * using {@link org.compass.gps.device.jpa.queryprovider.DefaultJpaQueryProvider}.
366:             *
367:             * <p>Certain JPA implementations have specific query providers with possible
368:             * enhanced functionality in regards to indexing. When using this method
369:             * instead of providing their specific implementation might mean less functionality
370:             * from the indexer.
371:             *
372:             * <p>Note, this information is used when the device starts.
373:             *
374:             * @param entityClass The Entity class to associate the select query with
375:             * @param selectQuery The select query to execute when indexing the given entity
376:             */
377:            public void setIndexSelectQuery(Class<?> entityClass,
378:                    String selectQuery) {
379:                setIndexQueryProvider(entityClass, new DefaultJpaQueryProvider(
380:                        selectQuery));
381:            }
382:
383:            /**
384:             * Sets a specific select statement for the index process of the given
385:             * entity name. The same as {@link #setIndexQueryProvider(String,JpaQueryProvider)}
386:             * using {@link org.compass.gps.device.jpa.queryprovider.DefaultJpaQueryProvider}.
387:             *
388:             * <p>Certain JPA implementations have specific query providers with possible
389:             * enhanced functionality in regards to indexing. When using this method
390:             * instead of providing their specific implementation might mean less functionality
391:             * from the indexer.
392:             *
393:             * <p>Note, this information is used when the device starts.
394:             *
395:             * @param entityName  The entity name to associate the select query with
396:             * @param selectQuery The select query to execute when indexing the given entity
397:             */
398:            public void setIndexSelectQuery(String entityName,
399:                    String selectQuery) {
400:                setIndexQueryProvider(entityName, new DefaultJpaQueryProvider(
401:                        selectQuery));
402:            }
403:
404:            /**
405:             * <p>Sets a specific query provider for the index process of the given entity class.
406:             * <p>Note, this information is used when the device starts.
407:             *
408:             * @param entityClass   The Entity class to associate the query provider with
409:             * @param queryProvider The query provider to execute when indexing the given entity
410:             */
411:            public void setIndexQueryProvider(Class<?> entityClass,
412:                    JpaQueryProvider queryProvider) {
413:                queryProviderByClass.put(entityClass, queryProvider);
414:            }
415:
416:            /**
417:             * <p>Sets a specific query provider for the index process of the given entity name.
418:             * <p>Note, this information is used when the device starts.
419:             *
420:             * @param entityName    The Entity name to associate the query provider with
421:             * @param queryProvider The query provider to execute when indexing the given entity
422:             */
423:            public void setIndexQueryProvider(String entityName,
424:                    JpaQueryProvider queryProvider) {
425:                queryProviderByName.put(entityName, queryProvider);
426:            }
427:
428:            /**
429:             * Sets a custom entities indexer that will be used to index the data. By default will
430:             * be detected automatically based on the actual implemenation of JPA used and will try
431:             * to use it.
432:             */
433:            public void setEntitiesIndexer(
434:                    JpaIndexEntitiesIndexer entitiesIndexer) {
435:                this.entitiesIndexer = entitiesIndexer;
436:            }
437:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.