Author: aadamchik
Date: Sun Sep 24 09:44:16 2006
New Revision: 449434
URL: http://svn.apache.org/viewvc?view=rev&rev=449434
Log:
CAY-666 - adding a full callback interceptor
Added:
incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/intercept/DataChannelFullCallbackInterceptor.java
incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/intercept/SyncCallbackProcessor.java
incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/intercept/SyncFullCallbackProcessor.java
Modified:
incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/intercept/DataChannelCallbackInterceptor.java
Modified:
incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/intercept/DataChannelCallbackInterceptor.java
URL:
http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/intercept/DataChannelCallbackInterceptor.java?view=diff&rev=449434&r1=449433&r2=449434
==============================================================================
---
incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/intercept/DataChannelCallbackInterceptor.java
(original)
+++
incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/intercept/DataChannelCallbackInterceptor.java
Sun Sep 24 09:44:16 2006
@@ -18,18 +18,12 @@
****************************************************************/
package org.apache.cayenne.intercept;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
import java.util.List;
-import java.util.Set;
import org.apache.cayenne.DataChannel;
import org.apache.cayenne.ObjectContext;
import org.apache.cayenne.QueryResponse;
-import org.apache.cayenne.graph.GraphChangeHandler;
import org.apache.cayenne.graph.GraphDiff;
-import org.apache.cayenne.graph.GraphManager;
import org.apache.cayenne.map.EntityResolver;
import org.apache.cayenne.map.LifecycleEventCallback;
import org.apache.cayenne.map.LifecycleEventCallbackMap;
@@ -37,13 +31,17 @@
/**
* Implements JPA-compliant "PreUpdate", "PostUpdate", "PostPersist",
"PostRemove",
- * "PostLoad" callbacks for the DataChannel operations. Most often this
interceptor is
- * inserted between a DataContext and its DataDomain. <p/>Depending on how
callbacks are
- * registered, they are invoked either on the persistent object instances
themselves or on
- * an instance of an arbitrary listener class. Signature of a method of a
persistent
+ * "PostLoad" callbacks for the DataChannel operations. <p/>Depending on how
callbacks are
+ * registered, they are invoked either on persistent object instances directly
or on an
+ * instance of an arbitrary listener class. Signature of a callback method of
a persistent
* object is <code>"void method()"</code>, while for a non-persistent listener
it is
- * <code>"void method(Object)"</code>.
+ * <code>"void method(Object)"</code>. <p/>Note that this interceptor does not
apply
+ * "PreRemove" and "PrePersist" callbacks during "onSync", assuming that a
child
+ * ObjectContext did that already. It is often used in conjunction with
+ * [EMAIL PROTECTED] ObjectContextCallbackInterceptor} that adds those
callbacks.
*
+ * @see DataChannelFullCallbackInterceptor
+ * @see ObjectContextCallbackInterceptor
* @since 3.0
* @author Andrus Adamchik
*/
@@ -114,151 +112,38 @@
return channel.onSync(originatingContext, changes, syncType);
}
- CommitState commitState = new CommitState(originatingContext, changes);
+ SyncCallbackProcessor processor =
createSyncProcessor(originatingContext, changes);
- commitState.applyPreCommit(syncType);
+ processor.applyPreCommit(syncType);
GraphDiff parentDiff = channel.onSync(originatingContext, changes,
syncType);
- commitState.applyPostCommit(syncType);
+ processor.applyPostCommit(syncType);
return parentDiff;
}
- class CommitState implements GraphChangeHandler {
-
- private GraphManager graphManager;
- private Collection updated;
- private Collection persisted;
- private Collection removed;
- private Set seenIds;
-
- CommitState(ObjectContext originatingContext, GraphDiff changes) {
- this.seenIds = new HashSet();
- this.graphManager = originatingContext.getGraphManager();
- changes.apply(this);
- }
-
- void applyPreCommit(int syncType) {
- switch (syncType) {
- case DataChannel.FLUSH_CASCADE_SYNC:
- case DataChannel.FLUSH_NOCASCADE_SYNC:
- applyPreUpdate();
- }
- }
-
- void applyPostCommit(int syncType) {
- switch (syncType) {
- case DataChannel.FLUSH_CASCADE_SYNC:
- case DataChannel.FLUSH_NOCASCADE_SYNC:
- applyPostUpdate();
- applyPostRemove();
- applyPostPersist();
- break;
- case DataChannel.ROLLBACK_CASCADE_SYNC:
- applyPostLoad();
- }
- }
-
- private void applyPostLoad() {
-
- if (!postLoad.isEmpty()) {
- if (updated != null) {
- postLoad.performCallbacks(updated);
- }
-
- if (removed != null) {
- postLoad.performCallbacks(removed);
- }
- }
- }
-
- private void applyPreUpdate() {
- if (updated != null && !preUpdate.isEmpty()) {
- preUpdate.performCallbacks(updated);
- }
- }
-
- private void applyPostUpdate() {
- if (updated != null && !postUpdate.isEmpty()) {
- postUpdate.performCallbacks(updated);
- }
- }
-
- private void applyPostPersist() {
- if (persisted != null && !postPersist.isEmpty()) {
- postPersist.performCallbacks(persisted);
- }
- }
-
- private void applyPostRemove() {
- if (removed != null && !postRemove.isEmpty()) {
- postRemove.performCallbacks(removed);
- }
- }
-
- public void nodeCreated(Object nodeId) {
- if (seenIds.add(nodeId)) {
-
- Object node = graphManager.getNode(nodeId);
- if (node != null) {
-
- if (persisted == null) {
- persisted = new ArrayList();
- }
-
- persisted.add(node);
- }
- }
- }
-
- public void nodeRemoved(Object nodeId) {
- if (seenIds.add(nodeId)) {
-
- Object node = graphManager.getNode(nodeId);
- if (node != null) {
-
- if (removed == null) {
- removed = new ArrayList();
- }
-
- removed.add(node);
- }
- }
- }
-
- public void arcCreated(Object nodeId, Object targetNodeId, Object
arcId) {
- // TODO: andrus, 9/21/2006 - should we register to-many
relationship updates?
- nodeUpdated(nodeId);
- }
-
- public void arcDeleted(Object nodeId, Object targetNodeId, Object
arcId) {
- // TODO: andrus, 9/21/2006 - should we register to-many
relationship updates?
- nodeUpdated(nodeId);
- }
-
- public void nodeIdChanged(Object nodeId, Object newId) {
- }
+ SyncCallbackProcessor createSyncProcessor(
+ ObjectContext originatingContext,
+ GraphDiff changes) {
+ return new SyncCallbackProcessor(this, originatingContext, changes);
+ }
- public void nodePropertyChanged(
- Object nodeId,
- String property,
- Object oldValue,
- Object newValue) {
- nodeUpdated(nodeId);
- }
+ public LifecycleEventCallbackMap getPostLoad() {
+ return postLoad;
+ }
- private void nodeUpdated(Object nodeId) {
- if (seenIds.add(nodeId)) {
+ public LifecycleEventCallbackMap getPostPersist() {
+ return postPersist;
+ }
- Object node = graphManager.getNode(nodeId);
- if (node != null) {
+ public LifecycleEventCallbackMap getPostRemove() {
+ return postRemove;
+ }
- if (updated == null) {
- updated = new ArrayList();
- }
+ public LifecycleEventCallbackMap getPostUpdate() {
+ return postUpdate;
+ }
- updated.add(node);
- }
- }
- }
+ public LifecycleEventCallbackMap getPreUpdate() {
+ return preUpdate;
}
}
Added:
incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/intercept/DataChannelFullCallbackInterceptor.java
URL:
http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/intercept/DataChannelFullCallbackInterceptor.java?view=auto&rev=449434
==============================================================================
---
incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/intercept/DataChannelFullCallbackInterceptor.java
(added)
+++
incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/intercept/DataChannelFullCallbackInterceptor.java
Sun Sep 24 09:44:16 2006
@@ -0,0 +1,75 @@
+/*****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ****************************************************************/
+package org.apache.cayenne.intercept;
+
+import org.apache.cayenne.DataChannel;
+import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.graph.GraphDiff;
+import org.apache.cayenne.map.EntityResolver;
+import org.apache.cayenne.map.LifecycleEventCallback;
+import org.apache.cayenne.map.LifecycleEventCallbackMap;
+
+/**
+ * Extends [EMAIL PROTECTED] DataChannelCallbackInterceptor} to add
"PreRemove" and "PrePersist"
+ * callbacks. This interceptor is appropriate when the upstream contexts do
not apply
+ * these callbacks themselves within "newObject" or "deleteObject" methods
(e.g. Remote
+ * Object Persistence situation).
+ *
+ * @author Andrus Adamchik
+ * @since 3.0
+ */
+public class DataChannelFullCallbackInterceptor extends
DataChannelCallbackInterceptor {
+
+ protected LifecycleEventCallbackMap prePersist;
+ protected LifecycleEventCallbackMap preRemove;
+
+ public void setChannel(DataChannel channel) {
+ super.setChannel(channel);
+
+ // init callback ivars for faster access...
+ if (channel != null) {
+ EntityResolver resolver = getEntityResolver();
+
+ prePersist =
resolver.getCallbacks(LifecycleEventCallback.PRE_PERSIST);
+ preRemove =
resolver.getCallbacks(LifecycleEventCallback.PRE_REMOVE);
+ }
+ else {
+ prePersist = null;
+ preRemove = null;
+ }
+ }
+
+ protected boolean isEmpty() {
+ return super.isEmpty() && prePersist.isEmpty() && preRemove.isEmpty();
+ }
+
+ SyncCallbackProcessor createSyncProcessor(
+ ObjectContext originatingContext,
+ GraphDiff changes) {
+ return super.createSyncProcessor(originatingContext, changes);
+ }
+
+ public LifecycleEventCallbackMap getPrePersist() {
+ return prePersist;
+ }
+
+ public LifecycleEventCallbackMap getPreRemove() {
+ return preRemove;
+ }
+}
Added:
incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/intercept/SyncCallbackProcessor.java
URL:
http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/intercept/SyncCallbackProcessor.java?view=auto&rev=449434
==============================================================================
---
incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/intercept/SyncCallbackProcessor.java
(added)
+++
incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/intercept/SyncCallbackProcessor.java
Sun Sep 24 09:44:16 2006
@@ -0,0 +1,143 @@
+/*****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ****************************************************************/
+package org.apache.cayenne.intercept;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.cayenne.DataChannel;
+import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.graph.GraphChangeHandler;
+import org.apache.cayenne.graph.GraphDiff;
+import org.apache.cayenne.graph.GraphManager;
+import org.apache.cayenne.map.LifecycleEventCallbackMap;
+
+class SyncCallbackProcessor implements GraphChangeHandler {
+
+ final DataChannelCallbackInterceptor interceptor;
+ private GraphManager graphManager;
+ Collection updated;
+ Collection persisted;
+ Collection removed;
+ private Set seenIds;
+
+ SyncCallbackProcessor(DataChannelCallbackInterceptor interceptor,
+ ObjectContext originatingContext, GraphDiff changes) {
+ this.interceptor = interceptor;
+ this.seenIds = new HashSet();
+ this.graphManager = originatingContext.getGraphManager();
+ changes.apply(this);
+ }
+
+ void applyPreCommit(int syncType) {
+ switch (syncType) {
+ case DataChannel.FLUSH_CASCADE_SYNC:
+ case DataChannel.FLUSH_NOCASCADE_SYNC:
+ apply(interceptor.getPreUpdate(), updated);
+ }
+ }
+
+ void applyPostCommit(int syncType) {
+ switch (syncType) {
+ case DataChannel.FLUSH_CASCADE_SYNC:
+ case DataChannel.FLUSH_NOCASCADE_SYNC:
+ apply(interceptor.getPostUpdate(), updated);
+ apply(interceptor.getPostRemove(), removed);
+ apply(interceptor.getPostPersist(), persisted);
+ break;
+ case DataChannel.ROLLBACK_CASCADE_SYNC:
+ apply(interceptor.getPostLoad(), updated);
+ apply(interceptor.getPostLoad(), removed);
+ }
+ }
+
+ void apply(LifecycleEventCallbackMap callbacks, Collection objects) {
+ if (objects != null && !callbacks.isEmpty()) {
+ callbacks.performCallbacks(objects);
+ }
+ }
+
+ public void nodeCreated(Object nodeId) {
+ if (seenIds.add(nodeId)) {
+
+ Object node = graphManager.getNode(nodeId);
+ if (node != null) {
+
+ if (persisted == null) {
+ persisted = new ArrayList();
+ }
+
+ persisted.add(node);
+ }
+ }
+ }
+
+ public void nodeRemoved(Object nodeId) {
+ if (seenIds.add(nodeId)) {
+
+ Object node = graphManager.getNode(nodeId);
+ if (node != null) {
+
+ if (removed == null) {
+ removed = new ArrayList();
+ }
+
+ removed.add(node);
+ }
+ }
+ }
+
+ public void arcCreated(Object nodeId, Object targetNodeId, Object arcId) {
+ // TODO: andrus, 9/21/2006 - should we register to-many relationship
updates?
+ nodeUpdated(nodeId);
+ }
+
+ public void arcDeleted(Object nodeId, Object targetNodeId, Object arcId) {
+ // TODO: andrus, 9/21/2006 - should we register to-many relationship
updates?
+ nodeUpdated(nodeId);
+ }
+
+ public void nodeIdChanged(Object nodeId, Object newId) {
+ }
+
+ public void nodePropertyChanged(
+ Object nodeId,
+ String property,
+ Object oldValue,
+ Object newValue) {
+ nodeUpdated(nodeId);
+ }
+
+ private void nodeUpdated(Object nodeId) {
+ if (seenIds.add(nodeId)) {
+
+ Object node = graphManager.getNode(nodeId);
+ if (node != null) {
+
+ if (updated == null) {
+ updated = new ArrayList();
+ }
+
+ updated.add(node);
+ }
+ }
+ }
+}
\ No newline at end of file
Added:
incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/intercept/SyncFullCallbackProcessor.java
URL:
http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/intercept/SyncFullCallbackProcessor.java?view=auto&rev=449434
==============================================================================
---
incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/intercept/SyncFullCallbackProcessor.java
(added)
+++
incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/intercept/SyncFullCallbackProcessor.java
Sun Sep 24 09:44:16 2006
@@ -0,0 +1,50 @@
+/*****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ****************************************************************/
+package org.apache.cayenne.intercept;
+
+import org.apache.cayenne.DataChannel;
+import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.graph.GraphDiff;
+
+/**
+ * Extends [EMAIL PROTECTED] SyncCallbackProcessor} to provide "PrePersist"
and "PreRemove"
+ * callbacks.
+ *
+ * @author Andrus Adamchik
+ * @since 3.0
+ */
+class SyncFullCallbackProcessor extends SyncCallbackProcessor {
+
+ public SyncFullCallbackProcessor(DataChannelFullCallbackInterceptor
interceptor,
+ ObjectContext originatingContext, GraphDiff changes) {
+ super(interceptor, originatingContext, changes);
+ }
+
+ void applyPreCommit(int syncType) {
+ super.applyPreCommit(syncType);
+
+ switch (syncType) {
+ case DataChannel.FLUSH_CASCADE_SYNC:
+ case DataChannel.FLUSH_NOCASCADE_SYNC:
+ DataChannelFullCallbackInterceptor interceptor =
(DataChannelFullCallbackInterceptor) this.interceptor;
+ apply(interceptor.getPrePersist(), persisted);
+ apply(interceptor.getPreRemove(), removed);
+ }
+ }
+}