You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by aa...@apache.org on 2012/04/26 20:06:11 UTC
svn commit: r1331001 - in
/cayenne/main/trunk/framework/cayenne-lifecycle/src:
main/java/org/apache/cayenne/lifecycle/audit/
test/java/org/apache/cayenne/lifecycle/audit/
test/java/org/apache/cayenne/lifecycle/db/
test/java/org/apache/cayenne/lifecycle...
Author: aadamchik
Date: Thu Apr 26 18:06:10 2012
New Revision: 1331001
URL: http://svn.apache.org/viewvc?rev=1331001&view=rev
Log:
CAY-1698 ObjectIdRelationship support for AuditableChild
patch by Denis Koyro
Added:
cayenne/main/trunk/framework/cayenne-lifecycle/src/test/java/org/apache/cayenne/lifecycle/db/AuditableChildUuid.java
cayenne/main/trunk/framework/cayenne-lifecycle/src/test/java/org/apache/cayenne/lifecycle/db/auto/_AuditableChildUuid.java
Modified:
cayenne/main/trunk/framework/cayenne-lifecycle/src/main/java/org/apache/cayenne/lifecycle/audit/AuditableChild.java
cayenne/main/trunk/framework/cayenne-lifecycle/src/main/java/org/apache/cayenne/lifecycle/audit/AuditableFilter.java
cayenne/main/trunk/framework/cayenne-lifecycle/src/test/java/org/apache/cayenne/lifecycle/audit/AuditableFilterTest.java
cayenne/main/trunk/framework/cayenne-lifecycle/src/test/java/org/apache/cayenne/lifecycle/audit/AuditableFilter_InRuntime_Test.java
cayenne/main/trunk/framework/cayenne-lifecycle/src/test/resources/lifecycle-map.map.xml
Modified: cayenne/main/trunk/framework/cayenne-lifecycle/src/main/java/org/apache/cayenne/lifecycle/audit/AuditableChild.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-lifecycle/src/main/java/org/apache/cayenne/lifecycle/audit/AuditableChild.java?rev=1331001&r1=1331000&r2=1331001&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-lifecycle/src/main/java/org/apache/cayenne/lifecycle/audit/AuditableChild.java (original)
+++ cayenne/main/trunk/framework/cayenne-lifecycle/src/main/java/org/apache/cayenne/lifecycle/audit/AuditableChild.java Thu Apr 26 18:06:10 2012
@@ -45,4 +45,6 @@ public @interface AuditableChild {
String value();
String[] ignoredProperties() default {};
+
+ String objectIdRelationship() default "";
}
Modified: cayenne/main/trunk/framework/cayenne-lifecycle/src/main/java/org/apache/cayenne/lifecycle/audit/AuditableFilter.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-lifecycle/src/main/java/org/apache/cayenne/lifecycle/audit/AuditableFilter.java?rev=1331001&r1=1331000&r2=1331001&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-lifecycle/src/main/java/org/apache/cayenne/lifecycle/audit/AuditableFilter.java (original)
+++ cayenne/main/trunk/framework/cayenne-lifecycle/src/main/java/org/apache/cayenne/lifecycle/audit/AuditableFilter.java Thu Apr 26 18:06:10 2012
@@ -36,6 +36,7 @@ import org.apache.cayenne.lifecycle.chan
import org.apache.cayenne.map.EntityResolver;
import org.apache.cayenne.map.ObjEntity;
import org.apache.cayenne.query.Query;
+import org.apache.commons.lang.StringUtils;
/**
* A {@link DataChannelFilter} that enables audit of entities annotated with
@@ -182,7 +183,19 @@ public class AuditableFilter implements
throw new IllegalArgumentException("No 'AuditableChild' annotation found");
}
- return dataObject.readNestedProperty(annotation.value());
+ String propertyPath = StringUtils.isNotEmpty(annotation.value())
+ ? annotation.value()
+
+ : objectIdRelationshipName(annotation.objectIdRelationship());
+ return dataObject.readNestedProperty(propertyPath);
+ }
+
+ /**
+ * It's a temporary clone method of {@link org.apache.cayenne.lifecycle.relationship.ObjectIdRelationshipHandler#objectIdRelationshipName(String)}
+ * //todo Needs to be encapsulated to some separate class to avoid a code duplication
+ */
+ private String objectIdRelationshipName(String uuidPropertyName) {
+ return "cay:related:" + uuidPropertyName;
}
protected boolean isAuditableUpdate(Object object, boolean child) {
Modified: cayenne/main/trunk/framework/cayenne-lifecycle/src/test/java/org/apache/cayenne/lifecycle/audit/AuditableFilterTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-lifecycle/src/test/java/org/apache/cayenne/lifecycle/audit/AuditableFilterTest.java?rev=1331001&r1=1331000&r2=1331001&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-lifecycle/src/test/java/org/apache/cayenne/lifecycle/audit/AuditableFilterTest.java (original)
+++ cayenne/main/trunk/framework/cayenne-lifecycle/src/test/java/org/apache/cayenne/lifecycle/audit/AuditableFilterTest.java Thu Apr 26 18:06:10 2012
@@ -18,28 +18,35 @@
****************************************************************/
package org.apache.cayenne.lifecycle.audit;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
import junit.framework.TestCase;
-
import org.apache.cayenne.CayenneDataObject;
import org.apache.cayenne.DataChannel;
import org.apache.cayenne.DataChannelFilterChain;
import org.apache.cayenne.DataObject;
import org.apache.cayenne.ObjectContext;
import org.apache.cayenne.ObjectId;
+import org.apache.cayenne.configuration.server.ServerRuntime;
import org.apache.cayenne.graph.GraphDiff;
+import org.apache.cayenne.lifecycle.db.Auditable1;
+import org.apache.cayenne.lifecycle.db.AuditableChildUuid;
+import org.apache.cayenne.lifecycle.id.IdCoder;
+import org.apache.cayenne.lifecycle.relationship.ObjectIdRelationshipFilter;
+import org.apache.cayenne.lifecycle.relationship.ObjectIdRelationshipHandler;
import org.apache.cayenne.map.EntityResolver;
import org.apache.cayenne.map.ObjEntity;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
public class AuditableFilterTest extends TestCase {
private AuditableProcessor processor;
private EntityResolver resolver;
+ private ServerRuntime runtime;
@Override
protected void setUp() throws Exception {
@@ -48,6 +55,17 @@ public class AuditableFilterTest extends
ObjEntity objectEntity = new ObjEntity("CayenneDataObject");
when(resolver.lookupObjEntity(any(Object.class))).thenReturn(objectEntity);
+
+ runtime = new ServerRuntime("cayenne-lifecycle.xml");
+ // a filter is required to invalidate root objects after commit
+ ObjectIdRelationshipFilter filter = new ObjectIdRelationshipFilter();
+ runtime.getDataDomain().addFilter(filter);
+ runtime.getDataDomain().getEntityResolver().getCallbackRegistry().addListener(filter);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ runtime.shutdown();
}
public void testInsertAudit() {
@@ -94,6 +112,23 @@ public class AuditableFilterTest extends
verify(processor).audit(auditedParent, AuditableOperation.UPDATE);
}
+ public void testUpdateAuditChildByObjectIdRelationship() {
+
+ ObjectContext context = runtime.getContext();
+ Auditable1 auditedParent = context.newObject(Auditable1.class);
+ AuditableChildUuid audited = context.newObject(AuditableChildUuid.class);
+
+ IdCoder refHandler = new IdCoder(context.getEntityResolver());
+ ObjectIdRelationshipHandler handler = new ObjectIdRelationshipHandler(refHandler);
+ handler.relate(audited, auditedParent);
+ context.commitChanges();
+
+ AuditableFilter filter = new AuditableFilter(resolver, processor);
+ filter.updateAuditChild(audited);
+ filter.postSync();
+ verify(processor).audit(auditedParent, AuditableOperation.UPDATE);
+ }
+
public void testOnSyncPassThrough() {
AuditableFilter filter = new AuditableFilter(resolver, processor);
Modified: cayenne/main/trunk/framework/cayenne-lifecycle/src/test/java/org/apache/cayenne/lifecycle/audit/AuditableFilter_InRuntime_Test.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-lifecycle/src/test/java/org/apache/cayenne/lifecycle/audit/AuditableFilter_InRuntime_Test.java?rev=1331001&r1=1331000&r2=1331001&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-lifecycle/src/test/java/org/apache/cayenne/lifecycle/audit/AuditableFilter_InRuntime_Test.java (original)
+++ cayenne/main/trunk/framework/cayenne-lifecycle/src/test/java/org/apache/cayenne/lifecycle/audit/AuditableFilter_InRuntime_Test.java Thu Apr 26 18:06:10 2012
@@ -35,6 +35,9 @@ import org.apache.cayenne.lifecycle.db.A
import org.apache.cayenne.lifecycle.db.AuditableChild1;
import org.apache.cayenne.lifecycle.db.AuditableChild2;
import org.apache.cayenne.lifecycle.db.AuditableChild3;
+import org.apache.cayenne.lifecycle.db.AuditableChildUuid;
+import org.apache.cayenne.lifecycle.id.IdCoder;
+import org.apache.cayenne.lifecycle.relationship.ObjectIdRelationshipHandler;
import org.apache.cayenne.test.jdbc.DBHelper;
import org.apache.cayenne.test.jdbc.TableHelper;
@@ -48,6 +51,7 @@ public class AuditableFilter_InRuntime_T
private TableHelper auditable2;
private TableHelper auditableChild3;
+ private TableHelper auditableChildUuid;
@Override
protected void setUp() throws Exception {
@@ -80,12 +84,20 @@ public class AuditableFilter_InRuntime_T
"CHAR_PROPERTY1",
"CHAR_PROPERTY2");
+ auditableChildUuid = new TableHelper(dbHelper, "AUDITABLE_CHILD_UUID").setColumns(
+ "ID",
+ "UUID",
+ "CHAR_PROPERTY1",
+ "CHAR_PROPERTY2");
+
auditableChild1.deleteAll();
auditableChild2.deleteAll();
auditable1.deleteAll();
auditableChild3.deleteAll();
auditable2.deleteAll();
+
+ auditableChildUuid.deleteAll();
}
public void testAudit_IgnoreRuntimeRelationships() throws Exception {
@@ -244,6 +256,41 @@ public class AuditableFilter_InRuntime_T
assertEquals(1, processor.size);
}
+ public void testAuditableChild_objectIdRelationship() throws Exception {
+ auditable1.insert(1, "xx");
+ auditableChildUuid.insert(1, "Auditable1:1", "xxx", "yyy");
+
+ DataDomain domain = runtime.getDataDomain();
+ Processor processor = new Processor();
+
+ AuditableFilter filter = new AuditableFilter(domain.getEntityResolver(), processor);
+ domain.addFilter(filter);
+ domain.getEntityResolver().getCallbackRegistry().addListener(filter);
+
+ // prerequisite for BaseAuditableProcessor use
+ ChangeSetFilter changeSetFilter = new ChangeSetFilter();
+ domain.addFilter(changeSetFilter);
+ domain.getEntityResolver().getCallbackRegistry().addListener(changeSetFilter);
+
+ ObjectContext context = runtime.getContext();
+ AuditableChildUuid ac = Cayenne.objectForPK(context, AuditableChildUuid.class, 1);
+ Auditable1 a1 = Cayenne.objectForPK(context, Auditable1.class, 1);
+ IdCoder refHandler = new IdCoder(domain.getEntityResolver());
+ ObjectIdRelationshipHandler handler = new ObjectIdRelationshipHandler(refHandler);
+ handler.relate(ac, a1);
+
+ ac.setCharProperty1("xxxx");
+ context.commitChanges();
+ assertEquals(1, processor.size);
+ Collection<Object> auditables = processor.audited.get(AuditableOperation.UPDATE);
+ assertSame(a1, auditables.toArray()[0]);
+
+ ac.setCharProperty2("yyyy");
+ context.commitChanges();
+ assertEquals(2, processor.size);
+ assertSame(a1, auditables.toArray()[1]);
+ }
+
private final class Processor implements AuditableProcessor {
Map<AuditableOperation, Collection<Object>> audited;
Added: cayenne/main/trunk/framework/cayenne-lifecycle/src/test/java/org/apache/cayenne/lifecycle/db/AuditableChildUuid.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-lifecycle/src/test/java/org/apache/cayenne/lifecycle/db/AuditableChildUuid.java?rev=1331001&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-lifecycle/src/test/java/org/apache/cayenne/lifecycle/db/AuditableChildUuid.java (added)
+++ cayenne/main/trunk/framework/cayenne-lifecycle/src/test/java/org/apache/cayenne/lifecycle/db/AuditableChildUuid.java Thu Apr 26 18:06:10 2012
@@ -0,0 +1,10 @@
+package org.apache.cayenne.lifecycle.db;
+
+import org.apache.cayenne.lifecycle.audit.AuditableChild;
+import org.apache.cayenne.lifecycle.db.auto._AuditableChildUuid;
+import org.apache.cayenne.lifecycle.relationship.ObjectIdRelationship;
+
+@ObjectIdRelationship(_AuditableChildUuid.UUID_PROPERTY)
+@AuditableChild(value = "", objectIdRelationship = _AuditableChildUuid.UUID_PROPERTY)
+public class AuditableChildUuid extends _AuditableChildUuid {
+}
Added: cayenne/main/trunk/framework/cayenne-lifecycle/src/test/java/org/apache/cayenne/lifecycle/db/auto/_AuditableChildUuid.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-lifecycle/src/test/java/org/apache/cayenne/lifecycle/db/auto/_AuditableChildUuid.java?rev=1331001&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-lifecycle/src/test/java/org/apache/cayenne/lifecycle/db/auto/_AuditableChildUuid.java (added)
+++ cayenne/main/trunk/framework/cayenne-lifecycle/src/test/java/org/apache/cayenne/lifecycle/db/auto/_AuditableChildUuid.java Thu Apr 26 18:06:10 2012
@@ -0,0 +1,40 @@
+package org.apache.cayenne.lifecycle.db.auto;
+
+import org.apache.cayenne.CayenneDataObject;
+
+/**
+ * Class _AuditableChildUuid was generated by Cayenne.
+ * It is probably a good idea to avoid changing this class manually,
+ * since it may be overwritten next time code is regenerated.
+ * If you need to make any customizations, please use subclass.
+ */
+public abstract class _AuditableChildUuid extends CayenneDataObject {
+
+ public static final String CHAR_PROPERTY1_PROPERTY = "charProperty1";
+ public static final String CHAR_PROPERTY2_PROPERTY = "charProperty2";
+ public static final String UUID_PROPERTY = "uuid";
+
+ public static final String ID_PK_COLUMN = "ID";
+
+ public void setCharProperty1(String charProperty1) {
+ writeProperty("charProperty1", charProperty1);
+ }
+ public String getCharProperty1() {
+ return (String)readProperty("charProperty1");
+ }
+
+ public void setCharProperty2(String charProperty2) {
+ writeProperty("charProperty2", charProperty2);
+ }
+ public String getCharProperty2() {
+ return (String)readProperty("charProperty2");
+ }
+
+ public void setUuid(String uuid) {
+ writeProperty("uuid", uuid);
+ }
+ public String getUuid() {
+ return (String)readProperty("uuid");
+ }
+
+}
Modified: cayenne/main/trunk/framework/cayenne-lifecycle/src/test/resources/lifecycle-map.map.xml
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-lifecycle/src/test/resources/lifecycle-map.map.xml?rev=1331001&r1=1331000&r2=1331001&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-lifecycle/src/test/resources/lifecycle-map.map.xml (original)
+++ cayenne/main/trunk/framework/cayenne-lifecycle/src/test/resources/lifecycle-map.map.xml Thu Apr 26 18:06:10 2012
@@ -29,6 +29,12 @@
<db-attribute name="CHAR_PROPERTY2" type="VARCHAR" length="200"/>
<db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
</db-entity>
+ <db-entity name="AUDITABLE_CHILD_UUID">
+ <db-attribute name="CHAR_PROPERTY1" type="VARCHAR" length="200"/>
+ <db-attribute name="CHAR_PROPERTY2" type="VARCHAR" length="200"/>
+ <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" isMandatory="true"/>
+ <db-attribute name="UUID" type="VARCHAR" length="200"/>
+ </db-entity>
<db-entity name="E1">
<db-attribute name="ID" type="BIGINT" isPrimaryKey="true" isMandatory="true"/>
</db-entity>
@@ -63,6 +69,11 @@
<obj-attribute name="charProperty1" type="java.lang.String" db-attribute-path="CHAR_PROPERTY1"/>
<obj-attribute name="charProperty2" type="java.lang.String" db-attribute-path="CHAR_PROPERTY2"/>
</obj-entity>
+ <obj-entity name="AuditableChildUuid" className="org.apache.cayenne.lifecycle.db.AuditableChildUuid" dbEntityName="AUDITABLE_CHILD_UUID">
+ <obj-attribute name="charProperty1" type="java.lang.String" db-attribute-path="CHAR_PROPERTY1"/>
+ <obj-attribute name="charProperty2" type="java.lang.String" db-attribute-path="CHAR_PROPERTY2"/>
+ <obj-attribute name="uuid" type="java.lang.String" db-attribute-path="UUID"/>
+ </obj-entity>
<obj-entity name="E1" className="org.apache.cayenne.lifecycle.db.E1" dbEntityName="E1">
</obj-entity>
<obj-entity name="E2" className="org.apache.cayenne.lifecycle.db.E2" dbEntityName="E2">