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.lifecycle;
018:
019: import java.util.Collection;
020: import javax.persistence.EntityManagerFactory;
021:
022: import org.apache.openjpa.event.DeleteListener;
023: import org.apache.openjpa.event.LifecycleEvent;
024: import org.apache.openjpa.event.PersistListener;
025: import org.apache.openjpa.event.StoreListener;
026: import org.apache.openjpa.meta.ClassMetaData;
027: import org.apache.openjpa.persistence.EntityManagerFactoryImpl;
028: import org.apache.openjpa.persistence.OpenJPAPersistence;
029: import org.compass.core.mapping.CascadeMapping;
030: import org.compass.gps.device.jpa.AbstractDeviceJpaEntityListener;
031: import org.compass.gps.device.jpa.JpaGpsDevice;
032: import org.compass.gps.device.jpa.JpaGpsDeviceException;
033: import org.compass.gps.spi.CompassGpsInterfaceDevice;
034:
035: /**
036: * Injects lifecycle listeners directly into OpenJPA for mirroring operations.
037: *
038: * @author kimchy
039: */
040: public class OpenJPAJpaEntityLifecycleInjector implements
041: JpaEntityLifecycleInjector {
042:
043: private class OpenJPAEventListener extends
044: AbstractDeviceJpaEntityListener implements DeleteListener,
045: PersistListener, StoreListener {
046:
047: private JpaGpsDevice device;
048:
049: public OpenJPAEventListener(JpaGpsDevice device) {
050: this .device = device;
051: }
052:
053: @Override
054: protected JpaGpsDevice getDevice() {
055: return this .device;
056: }
057:
058: public void beforeDelete(LifecycleEvent lifecycleEvent) {
059: }
060:
061: public void afterDelete(LifecycleEvent lifecycleEvent) {
062: postRemove(lifecycleEvent.getSource());
063: }
064:
065: public void beforePersist(LifecycleEvent lifecycleEvent) {
066: }
067:
068: public void afterPersist(LifecycleEvent lifecycleEvent) {
069: postPersist(lifecycleEvent.getSource());
070: }
071:
072: public void beforeStore(LifecycleEvent lifecycleEvent) {
073: }
074:
075: public void afterStore(LifecycleEvent lifecycleEvent) {
076: postUpdate(lifecycleEvent.getSource());
077: }
078: }
079:
080: private boolean useSpecificClassEvents = true;
081:
082: private ClassLoader classLoader;
083:
084: private Object eventListener;
085:
086: public void setUseSpecificClassEvents(boolean useSpecificClassEvents) {
087: this .useSpecificClassEvents = useSpecificClassEvents;
088: }
089:
090: public void setClassLoader(ClassLoader classLoader) {
091: this .classLoader = classLoader;
092: }
093:
094: /**
095: * Allows to directly inject the event listener that will be used with Open JPA. Will
096: * not use Compass default one ({@link org.compass.gps.device.jpa.lifecycle.OpenJPAJpaEntityLifecycleInjector.OpenJPAEventListener}.
097: */
098: public void setEventListener(Object eventListener) {
099: this .eventListener = eventListener;
100: }
101:
102: public void injectLifecycle(
103: EntityManagerFactory entityManagerFactory,
104: JpaGpsDevice device) throws JpaGpsDeviceException {
105:
106: CompassGpsInterfaceDevice gps = (CompassGpsInterfaceDevice) device
107: .getGps();
108:
109: // TODO this should use OpenJPAEnitiyManagerFactorySPI, here for backward compatability with pre 1.0
110: EntityManagerFactoryImpl emf = (EntityManagerFactoryImpl) OpenJPAPersistence
111: .cast(entityManagerFactory);
112:
113: if (eventListener == null) {
114: eventListener = new OpenJPAEventListener(device);
115: }
116:
117: if (useSpecificClassEvents) {
118: Collection<Class> classes = emf.getConfiguration()
119: .getMetaDataRepositoryInstance()
120: .loadPersistentTypes(true, classLoader);
121: for (Class clazz : classes) {
122: ClassMetaData classMetaData = emf.getConfiguration()
123: .getMetaDataRepositoryInstance().getMetaData(
124: clazz, classLoader, true);
125: Class mappedClass = classMetaData.getDescribedType();
126: if (gps.hasMappingForEntityForMirror(mappedClass,
127: CascadeMapping.Cascade.ALL)) {
128: emf
129: .addLifecycleListener(eventListener,
130: mappedClass);
131: }
132: }
133: } else {
134: emf.addLifecycleListener(eventListener);
135: }
136: }
137:
138: public void removeLifecycle(
139: EntityManagerFactory entityManagerFactory,
140: JpaGpsDevice device) throws JpaGpsDeviceException {
141: // TODO this should use OpenJPAEnitiyManagerFactorySPI, here for backward compatability with pre 1.0
142: EntityManagerFactoryImpl emf = (EntityManagerFactoryImpl) OpenJPAPersistence
143: .cast(entityManagerFactory);
144: eventListener = new OpenJPAEventListener(device);
145: emf.removeLifecycleListener(eventListener);
146: }
147: }
|