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.ArrayList;
020: import javax.persistence.EntityManagerFactory;
021:
022: import org.compass.gps.device.jpa.AbstractDeviceJpaEntityListener;
023: import org.compass.gps.device.jpa.JpaGpsDevice;
024: import org.compass.gps.device.jpa.JpaGpsDeviceException;
025: import org.hibernate.ejb.HibernateEntityManagerFactory;
026: import org.hibernate.event.EventListeners;
027: import org.hibernate.event.PostDeleteEvent;
028: import org.hibernate.event.PostDeleteEventListener;
029: import org.hibernate.event.PostInsertEvent;
030: import org.hibernate.event.PostInsertEventListener;
031: import org.hibernate.event.PostUpdateEvent;
032: import org.hibernate.event.PostUpdateEventListener;
033: import org.hibernate.impl.SessionFactoryImpl;
034:
035: /**
036: * Injects lifecycle listeners directly into Hibernate for mirroring operations.
037: *
038: * <p>By default, registers with plain insert/update/delete listeners, which will be triggered
039: * by Hibernate before committing (and up to Hibernate flushing logic). Also allows to be created
040: * with setting the <code>registerPostCommitListeneres</code> to <code>true</code> which will cause
041: * the insert/update/delete listeneres to be registered as post commit events.
042: *
043: * @author kimchy
044: */
045: public class HibernateJpaEntityLifecycleInjector implements
046: JpaEntityLifecycleInjector {
047:
048: private class HibernateEventListener extends
049: AbstractDeviceJpaEntityListener implements
050: PostInsertEventListener, PostUpdateEventListener,
051: PostDeleteEventListener {
052:
053: private JpaGpsDevice device;
054:
055: public HibernateEventListener(JpaGpsDevice device) {
056: this .device = device;
057: }
058:
059: protected JpaGpsDevice getDevice() {
060: return this .device;
061: }
062:
063: public void onPostInsert(PostInsertEvent postInsertEvent) {
064: postPersist(postInsertEvent.getEntity());
065: }
066:
067: public void onPostUpdate(PostUpdateEvent postUpdateEvent) {
068: postUpdate(postUpdateEvent.getEntity());
069: }
070:
071: public void onPostDelete(PostDeleteEvent postDeleteEvent) {
072: postRemove(postDeleteEvent.getEntity());
073: }
074: }
075:
076: private boolean registerPostCommitListeneres;
077:
078: public HibernateJpaEntityLifecycleInjector() {
079: this (false);
080: }
081:
082: /**
083: * Creates a new lifecycle injector. Allows to control if the insert/update/delete
084: * even listeners will be registered with post commit listeres (flag it <code>true</code>)
085: * or with plain post events (triggered based on Hibrenate flushing logic).
086: *
087: * @param registerPostCommitListeneres <code>true</code> if post commit listeners will be
088: * registered. <code>false</code> for plain listeners.
089: */
090: public HibernateJpaEntityLifecycleInjector(
091: boolean registerPostCommitListeneres) {
092: this .registerPostCommitListeneres = registerPostCommitListeneres;
093: }
094:
095: public void injectLifecycle(
096: EntityManagerFactory entityManagerFactory,
097: JpaGpsDevice device) throws JpaGpsDeviceException {
098:
099: HibernateEntityManagerFactory hibernateEntityManagerFactory = (HibernateEntityManagerFactory) entityManagerFactory;
100: SessionFactoryImpl sessionFactory = (SessionFactoryImpl) hibernateEntityManagerFactory
101: .getSessionFactory();
102: EventListeners eventListeners = sessionFactory
103: .getEventListeners();
104:
105: // TODO add the ability to extend the system and register your own event listener (which maybe performs filtering)
106: HibernateEventListener hibernateEventListener = new HibernateEventListener(
107: device);
108:
109: PostInsertEventListener[] postInsertEventListeners;
110: if (registerPostCommitListeneres) {
111: postInsertEventListeners = eventListeners
112: .getPostCommitInsertEventListeners();
113: } else {
114: postInsertEventListeners = eventListeners
115: .getPostInsertEventListeners();
116: }
117: PostInsertEventListener[] tempPostInsertEventListeners = new PostInsertEventListener[postInsertEventListeners.length + 1];
118: System.arraycopy(postInsertEventListeners, 0,
119: tempPostInsertEventListeners, 0,
120: postInsertEventListeners.length);
121: tempPostInsertEventListeners[postInsertEventListeners.length] = hibernateEventListener;
122: if (registerPostCommitListeneres) {
123: eventListeners
124: .setPostCommitInsertEventListeners(tempPostInsertEventListeners);
125: } else {
126: eventListeners
127: .setPostInsertEventListeners(tempPostInsertEventListeners);
128: }
129:
130: PostUpdateEventListener[] postUpdateEventListeners;
131: if (registerPostCommitListeneres) {
132: postUpdateEventListeners = eventListeners
133: .getPostCommitUpdateEventListeners();
134: } else {
135: postUpdateEventListeners = eventListeners
136: .getPostUpdateEventListeners();
137: }
138: PostUpdateEventListener[] tempPostUpdateEventListeners = new PostUpdateEventListener[postUpdateEventListeners.length + 1];
139: System.arraycopy(postUpdateEventListeners, 0,
140: tempPostUpdateEventListeners, 0,
141: postUpdateEventListeners.length);
142: tempPostUpdateEventListeners[postUpdateEventListeners.length] = hibernateEventListener;
143: if (registerPostCommitListeneres) {
144: eventListeners
145: .setPostCommitUpdateEventListeners(tempPostUpdateEventListeners);
146: } else {
147: eventListeners
148: .setPostUpdateEventListeners(tempPostUpdateEventListeners);
149: }
150:
151: PostDeleteEventListener[] postDeleteEventListeners;
152: if (registerPostCommitListeneres) {
153: postDeleteEventListeners = eventListeners
154: .getPostCommitDeleteEventListeners();
155: } else {
156: postDeleteEventListeners = eventListeners
157: .getPostDeleteEventListeners();
158: }
159: PostDeleteEventListener[] tempPostDeleteEventListeners = new PostDeleteEventListener[postDeleteEventListeners.length + 1];
160: System.arraycopy(postDeleteEventListeners, 0,
161: tempPostDeleteEventListeners, 0,
162: postDeleteEventListeners.length);
163: tempPostDeleteEventListeners[postDeleteEventListeners.length] = hibernateEventListener;
164: if (registerPostCommitListeneres) {
165: eventListeners
166: .setPostCommitDeleteEventListeners(tempPostDeleteEventListeners);
167: } else {
168: eventListeners
169: .setPostDeleteEventListeners(tempPostDeleteEventListeners);
170: }
171: }
172:
173: public void removeLifecycle(
174: EntityManagerFactory entityManagerFactory,
175: JpaGpsDevice device) throws JpaGpsDeviceException {
176: HibernateEntityManagerFactory hibernateEntityManagerFactory = (HibernateEntityManagerFactory) entityManagerFactory;
177: SessionFactoryImpl sessionFactory = (SessionFactoryImpl) hibernateEntityManagerFactory
178: .getSessionFactory();
179: EventListeners eventListeners = sessionFactory
180: .getEventListeners();
181:
182: PostInsertEventListener[] postInsertEventListeners;
183: if (registerPostCommitListeneres) {
184: postInsertEventListeners = eventListeners
185: .getPostCommitInsertEventListeners();
186: } else {
187: postInsertEventListeners = eventListeners
188: .getPostInsertEventListeners();
189: }
190: ArrayList<PostInsertEventListener> tempPostInsertEventListeners = new ArrayList<PostInsertEventListener>();
191: for (PostInsertEventListener postInsertEventListener : postInsertEventListeners) {
192: if (!(postInsertEventListener instanceof HibernateEventListener)) {
193: tempPostInsertEventListeners
194: .add(postInsertEventListener);
195: }
196: }
197: if (registerPostCommitListeneres) {
198: eventListeners
199: .setPostCommitInsertEventListeners(tempPostInsertEventListeners
200: .toArray(new PostInsertEventListener[tempPostInsertEventListeners
201: .size()]));
202: } else {
203: eventListeners
204: .setPostInsertEventListeners(tempPostInsertEventListeners
205: .toArray(new PostInsertEventListener[tempPostInsertEventListeners
206: .size()]));
207: }
208:
209: PostUpdateEventListener[] postUpdateEventListeners;
210: if (registerPostCommitListeneres) {
211: postUpdateEventListeners = eventListeners
212: .getPostCommitUpdateEventListeners();
213: } else {
214: postUpdateEventListeners = eventListeners
215: .getPostUpdateEventListeners();
216: }
217: ArrayList<PostUpdateEventListener> tempPostUpdateEventListeners = new ArrayList<PostUpdateEventListener>();
218: for (PostUpdateEventListener postUpdateEventListener : postUpdateEventListeners) {
219: if (!(postUpdateEventListener instanceof HibernateEventListener)) {
220: tempPostUpdateEventListeners
221: .add(postUpdateEventListener);
222: }
223: }
224: if (registerPostCommitListeneres) {
225: eventListeners
226: .setPostCommitUpdateEventListeners(tempPostUpdateEventListeners
227: .toArray(new PostUpdateEventListener[tempPostUpdateEventListeners
228: .size()]));
229: } else {
230: eventListeners
231: .setPostUpdateEventListeners(tempPostUpdateEventListeners
232: .toArray(new PostUpdateEventListener[tempPostUpdateEventListeners
233: .size()]));
234: }
235:
236: PostDeleteEventListener[] postDeleteEventListeners;
237: if (registerPostCommitListeneres) {
238: postDeleteEventListeners = eventListeners
239: .getPostCommitDeleteEventListeners();
240: } else {
241: postDeleteEventListeners = eventListeners
242: .getPostDeleteEventListeners();
243: }
244: ArrayList<PostDeleteEventListener> tempPostDeleteEventListeners = new ArrayList<PostDeleteEventListener>();
245: for (PostDeleteEventListener postDeleteEventListener : postDeleteEventListeners) {
246: if (!(postDeleteEventListener instanceof HibernateEventListener)) {
247: tempPostDeleteEventListeners
248: .add(postDeleteEventListener);
249: }
250: }
251: if (registerPostCommitListeneres) {
252: eventListeners
253: .setPostCommitDeleteEventListeners(tempPostDeleteEventListeners
254: .toArray(new PostDeleteEventListener[tempPostDeleteEventListeners
255: .size()]));
256: } else {
257: eventListeners
258: .setPostDeleteEventListeners(tempPostDeleteEventListeners
259: .toArray(new PostDeleteEventListener[tempPostDeleteEventListeners
260: .size()]));
261: }
262: }
263: }
|