Author: aadamchik
Date: Tue Dec 14 20:29:29 2010
New Revision: 1049252
URL: http://svn.apache.org/viewvc?rev=1049252&view=rev
Log:
changeset package
Added:
cayenne/sandbox/cayenne-mixin/trunk/src/main/java/org/apache/cayenne/mixin/changeset/
cayenne/sandbox/cayenne-mixin/trunk/src/main/java/org/apache/cayenne/mixin/changeset/ChangeSet.java
cayenne/sandbox/cayenne-mixin/trunk/src/main/java/org/apache/cayenne/mixin/changeset/ChangeSetFilter.java
cayenne/sandbox/cayenne-mixin/trunk/src/main/java/org/apache/cayenne/mixin/changeset/GenericChangeSet.java
cayenne/sandbox/cayenne-mixin/trunk/src/main/java/org/apache/cayenne/mixin/changeset/PropertyChange.java
Modified:
cayenne/sandbox/cayenne-mixin/trunk/README.txt
cayenne/sandbox/cayenne-mixin/trunk/pom.xml
Modified: cayenne/sandbox/cayenne-mixin/trunk/README.txt
URL:
http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-mixin/trunk/README.txt?rev=1049252&r1=1049251&r2=1049252&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-mixin/trunk/README.txt (original)
+++ cayenne/sandbox/cayenne-mixin/trunk/README.txt Tue Dec 14 20:29:29 2010
@@ -4,6 +4,7 @@ TODO:
IMPLEMENTED:
+4. Changeset tracking functionality
3. @MixinRelationship and MixinRelationshipFilter to batch-fault and inject
related objects into mixin entity (e.g. Audit entity)
2. @Auditable mixin with abstract handler allowing to store audit records in
an arbitrary format.
1. @Referenceable mixin and generic UUID processing classes
Modified: cayenne/sandbox/cayenne-mixin/trunk/pom.xml
URL:
http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-mixin/trunk/pom.xml?rev=1049252&r1=1049251&r2=1049252&view=diff
==============================================================================
--- cayenne/sandbox/cayenne-mixin/trunk/pom.xml (original)
+++ cayenne/sandbox/cayenne-mixin/trunk/pom.xml Tue Dec 14 20:29:29 2010
@@ -8,7 +8,7 @@
<version>3.1M1</version>
</parent>
<artifactId>cayenne-mixin</artifactId>
- <version>3.1.0.6</version>
+ <version>3.1.0.7</version>
<name>Library: cayenne-mixin</name>
<packaging>jar</packaging>
<properties>
Added:
cayenne/sandbox/cayenne-mixin/trunk/src/main/java/org/apache/cayenne/mixin/changeset/ChangeSet.java
URL:
http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-mixin/trunk/src/main/java/org/apache/cayenne/mixin/changeset/ChangeSet.java?rev=1049252&view=auto
==============================================================================
---
cayenne/sandbox/cayenne-mixin/trunk/src/main/java/org/apache/cayenne/mixin/changeset/ChangeSet.java
(added)
+++
cayenne/sandbox/cayenne-mixin/trunk/src/main/java/org/apache/cayenne/mixin/changeset/ChangeSet.java
Tue Dec 14 20:29:29 2010
@@ -0,0 +1,37 @@
+/*****************************************************************
+ * 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.mixin.changeset;
+
+import java.util.Map;
+
+import org.apache.cayenne.Persistent;
+import org.apache.cayenne.graph.GraphDiff;
+
+/**
+ * Represents a set of changes to persistent objects corresponding to a
certain lifecycle
+ * stage. The changes are presented in a more usable form compared to the
internal Cayenne
+ * representation as {...@link GraphDiff}. One or more changes to the same
property of the
+ * same object are all combined in a single {...@link PropertyChange} instance.
+ */
+public interface ChangeSet {
+
+ public static final String OBJECT_ID_PROPERTY_NAME = "cayenne:objectId";
+
+ Map<String, PropertyChange> getChanges(Persistent object);
+}
Added:
cayenne/sandbox/cayenne-mixin/trunk/src/main/java/org/apache/cayenne/mixin/changeset/ChangeSetFilter.java
URL:
http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-mixin/trunk/src/main/java/org/apache/cayenne/mixin/changeset/ChangeSetFilter.java?rev=1049252&view=auto
==============================================================================
---
cayenne/sandbox/cayenne-mixin/trunk/src/main/java/org/apache/cayenne/mixin/changeset/ChangeSetFilter.java
(added)
+++
cayenne/sandbox/cayenne-mixin/trunk/src/main/java/org/apache/cayenne/mixin/changeset/ChangeSetFilter.java
Tue Dec 14 20:29:29 2010
@@ -0,0 +1,73 @@
+/*****************************************************************
+ * 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.mixin.changeset;
+
+import org.apache.cayenne.DataChannel;
+import org.apache.cayenne.DataChannelFilter;
+import org.apache.cayenne.DataChannelFilterChain;
+import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.QueryResponse;
+import org.apache.cayenne.graph.GraphDiff;
+import org.apache.cayenne.query.Query;
+
+/**
+ * A {...@link DataChannelFilter} that provides interested parties with a
thread-local access
+ * to the current commit changeset. It will only return a non-null change set
when commit
+ * within the scope of the filter
+ * {...@link #onSync(ObjectContext, GraphDiff, int, DataChannelFilterChain)}
method. The
+ * filter is intended to be used by pre-commit and post-commit listeners.
+ */
+public class ChangeSetFilter implements DataChannelFilter {
+
+ private static final ThreadLocal<ChangeSet> PRE_COMMIT_CHANGE_SET = new
ThreadLocal<ChangeSet>();
+
+ public static ChangeSet preCommitChangeSet() {
+ return PRE_COMMIT_CHANGE_SET.get();
+ }
+
+ @Override
+ public void init(DataChannel channel) {
+ // noop..
+ }
+
+ @Override
+ public QueryResponse onQuery(
+ ObjectContext originatingContext,
+ Query query,
+ DataChannelFilterChain filterChain) {
+ return filterChain.onQuery(originatingContext, query);
+ }
+
+ @Override
+ public GraphDiff onSync(
+ ObjectContext originatingContext,
+ GraphDiff changes,
+ int syncType,
+ DataChannelFilterChain filterChain) {
+
+ try {
+ PRE_COMMIT_CHANGE_SET.set(new GenericChangeSet(changes));
+ return filterChain.onSync(originatingContext, changes, syncType);
+ }
+ finally {
+ PRE_COMMIT_CHANGE_SET.set(null);
+ }
+ }
+
+}
Added:
cayenne/sandbox/cayenne-mixin/trunk/src/main/java/org/apache/cayenne/mixin/changeset/GenericChangeSet.java
URL:
http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-mixin/trunk/src/main/java/org/apache/cayenne/mixin/changeset/GenericChangeSet.java?rev=1049252&view=auto
==============================================================================
---
cayenne/sandbox/cayenne-mixin/trunk/src/main/java/org/apache/cayenne/mixin/changeset/GenericChangeSet.java
(added)
+++
cayenne/sandbox/cayenne-mixin/trunk/src/main/java/org/apache/cayenne/mixin/changeset/GenericChangeSet.java
Tue Dec 14 20:29:29 2010
@@ -0,0 +1,137 @@
+/*****************************************************************
+ * 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.mixin.changeset;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.cayenne.ObjectId;
+import org.apache.cayenne.Persistent;
+import org.apache.cayenne.graph.GraphChangeHandler;
+import org.apache.cayenne.graph.GraphDiff;
+
+/**
+ * A {...@link ChangeSet} implemented as a wrapper on top of {...@link
GraphDiff} of unspecified
+ * nature.
+ * <p>
+ * Synchronization note: While this class is thread safe, but is not generally
intended
+ * for use in multi-threaded manner. It is common to use it within a single
transaction
+ * thread.
+ */
+public class GenericChangeSet implements ChangeSet {
+
+ private GraphDiff diff;
+ private Map<ObjectId, Map<String, PropertyChange>> changes;
+
+ public GenericChangeSet(GraphDiff diff) {
+ this.diff = diff;
+ }
+
+ /**
+ * Returns a map of changes for a given object in its context, keyed by
property name.
+ * If the object is unchanged, an empty map is returned.
+ */
+ @Override
+ public Map<String, PropertyChange> getChanges(Persistent object) {
+ return getChanges().get(object.getObjectId());
+ }
+
+ private Map<ObjectId, Map<String, PropertyChange>> getChanges() {
+ if (changes == null) {
+ changes = parseDiff();
+ }
+
+ return changes;
+ }
+
+ private Map<ObjectId, Map<String, PropertyChange>> parseDiff() {
+
+ final Map<ObjectId, Map<String, PropertyChange>> changes = new
HashMap<ObjectId, Map<String, PropertyChange>>();
+
+ diff.apply(new GraphChangeHandler() {
+
+ private Map<String, PropertyChange> getChangeMap(Object id) {
+ Map<String, PropertyChange> map = changes.get(id);
+
+ if (map == null) {
+ map = new HashMap<String, PropertyChange>();
+ changes.put((ObjectId) id, map);
+ }
+
+ return map;
+ }
+
+ PropertyChange getChange(Object id, String property, Object
oldValue) {
+ Map<String, PropertyChange> map = getChangeMap(id);
+
+ PropertyChange change = map.get(property);
+ if (change == null) {
+ change = new PropertyChange(property, oldValue);
+ map.put(property, change);
+ }
+
+ return change;
+ }
+
+ @Override
+ public void nodeRemoved(Object nodeId) {
+ // noop, don't care, we'll still track the changes for deleted
objects.
+ }
+
+ @Override
+ public void nodeCreated(Object nodeId) {
+ // noop (??)
+ }
+
+ @Override
+ public void arcDeleted(Object nodeId, Object targetNodeId, Object
arcId) {
+ // noop... ignoring for now... ideally should at least track
to-one
+ }
+
+ @Override
+ public void arcCreated(Object nodeId, Object targetNodeId, Object
arcId) {
+ // noop... ignoring for now... ideally should at least track
to-one
+ }
+
+ @Override
+ public void nodePropertyChanged(
+ Object nodeId,
+ String property,
+ Object oldValue,
+ Object newValue) {
+ getChange(nodeId, property, oldValue).setNewValue(newValue);
+ }
+
+ @Override
+ public void nodeIdChanged(Object nodeId, Object newId) {
+
+ // store the same change set under old and new ids to allow
lookup before
+ // and after the commit
+ Map<String, PropertyChange> map = getChangeMap(nodeId);
+ changes.put((ObjectId) newId, map);
+
+ // record a change for a special ID "property"
+ getChange(nodeId, OBJECT_ID_PROPERTY_NAME,
nodeId).setNewValue(newId);
+ }
+
+ });
+
+ return changes;
+ }
+}
Added:
cayenne/sandbox/cayenne-mixin/trunk/src/main/java/org/apache/cayenne/mixin/changeset/PropertyChange.java
URL:
http://svn.apache.org/viewvc/cayenne/sandbox/cayenne-mixin/trunk/src/main/java/org/apache/cayenne/mixin/changeset/PropertyChange.java?rev=1049252&view=auto
==============================================================================
---
cayenne/sandbox/cayenne-mixin/trunk/src/main/java/org/apache/cayenne/mixin/changeset/PropertyChange.java
(added)
+++
cayenne/sandbox/cayenne-mixin/trunk/src/main/java/org/apache/cayenne/mixin/changeset/PropertyChange.java
Tue Dec 14 20:29:29 2010
@@ -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.mixin.changeset;
+
+/**
+ * A change to a single object property.
+ */
+public class PropertyChange {
+
+ private String propertyName;
+ private Object oldValue;
+ private Object newValue;
+
+ PropertyChange(String propertyName, Object oldValue) {
+ this.propertyName = propertyName;
+ this.oldValue = oldValue;
+ }
+
+ public Object getOldValue() {
+ return oldValue;
+ }
+
+ public Object getNewValue() {
+ return newValue;
+ }
+
+ public String getPropertyName() {
+ return propertyName;
+ }
+
+ void setNewValue(Object newValue) {
+ this.newValue = newValue;
+ }
+}