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 2006/07/20 04:33:26 UTC
svn commit: r423717 - in
/incubator/cayenne/main/trunk/cayenne/cayenne-java/src:
cayenne/java/org/apache/cayenne/ cayenne/java/org/apache/cayenne/access/
cayenne/java/org/apache/cayenne/map/ cayenne/java/org/apache/cayenne/query/
tests/java/org/apache/...
Author: aadamchik
Date: Wed Jul 19 19:33:25 2006
New Revision: 423717
URL: http://svn.apache.org/viewvc?rev=423717&view=rev
Log:
merging changes from 3.0 temporary branch. This patch fixes the issues
* CAY-576
* CAY-586
Added:
incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/Validating.java
incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/query/InvalidateListCacheQuery.java
incubator/cayenne/main/trunk/cayenne/cayenne-java/src/tests/java/org/apache/cayenne/CayenneContextValidationTst.java
incubator/cayenne/main/trunk/cayenne/cayenne-java/src/tests/java/org/apache/cayenne/query/InvalidateListCacheQueryTst.java
Removed:
incubator/cayenne/main/trunk/cayenne/cayenne-java/src/tests/java/org/apache/cayenne/access/ObjectStoreValidationTst.java
Modified:
incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/CayenneContext.java
incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/CayenneContextGraphManager.java
incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/CayenneContextQueryAction.java
incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/CayenneDataObject.java
incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/DataObject.java
incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/access/ClientServerChannel.java
incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/access/DataContextQueryAction.java
incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/access/DataDomainQueryAction.java
incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/access/DataRowStore.java
incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/access/ObjectStore.java
incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/access/ObjectStoreGraphDiff.java
incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/map/EntityDescriptor.java
incubator/cayenne/main/trunk/cayenne/cayenne-java/src/tests/java/org/apache/art/MixedPersistenceStrategy2.java
incubator/cayenne/main/trunk/cayenne/cayenne-java/src/tests/java/org/apache/cayenne/testdo/mt/ClientMtTable1.java
Modified: incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/CayenneContext.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/CayenneContext.java?rev=423717&r1=423716&r2=423717&view=diff
==============================================================================
--- incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/CayenneContext.java (original)
+++ incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/CayenneContext.java Wed Jul 19 19:33:25 2006
@@ -21,6 +21,7 @@
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Iterator;
import java.util.List;
import org.apache.cayenne.event.EventManager;
@@ -32,6 +33,8 @@
import org.apache.cayenne.query.ObjectIdQuery;
import org.apache.cayenne.query.Query;
import org.apache.cayenne.util.EventUtil;
+import org.apache.cayenne.validation.ValidationException;
+import org.apache.cayenne.validation.ValidationResult;
/**
* A default generic implementation of ObjectContext suitable for accessing Cayenne from
@@ -181,21 +184,49 @@
* service via an internal instance of CayenneConnector.
*/
public void commitChanges() {
- doCommitChanges();
+ doCommitChanges(true);
}
- GraphDiff doCommitChanges() {
+ GraphDiff doCommitChanges(boolean cascade) {
+
+ int syncType = cascade
+ ? DataChannel.FLUSH_CASCADE_SYNC
+ : DataChannel.FLUSH_NOCASCADE_SYNC;
+
GraphDiff commitDiff = null;
synchronized (graphManager) {
if (graphManager.hasChanges()) {
+ ValidationResult result = new ValidationResult();
+ Iterator it = graphManager.dirtyNodes().iterator();
+ while (it.hasNext()) {
+ Persistent p = (Persistent) it.next();
+ if (p instanceof Validating) {
+ switch (p.getPersistenceState()) {
+ case PersistenceState.NEW:
+ ((Validating) p).validateForInsert(result);
+ break;
+ case PersistenceState.MODIFIED:
+ ((Validating) p).validateForUpdate(result);
+ break;
+ case PersistenceState.DELETED:
+ ((Validating) p).validateForDelete(result);
+ break;
+ }
+ }
+ }
+
+ if (result.hasFailures()) {
+ throw new ValidationException(result);
+ }
+
graphManager.graphCommitStarted();
try {
commitDiff = channel.onSync(this, graphManager
- .getDiffsSinceLastFlush(), DataChannel.FLUSH_CASCADE_SYNC);
+ .getDiffsSinceLastFlush(), syncType);
}
catch (Throwable th) {
graphManager.graphCommitAborted();
@@ -214,6 +245,10 @@
return commitDiff;
}
+
+ public void commitChangesToParent() {
+ doCommitChanges(false);
+ }
public void rollbackChanges() {
synchronized (graphManager) {
@@ -223,16 +258,6 @@
graphManager.graphReverted();
channel.onSync(this, diff, DataChannel.ROLLBACK_CASCADE_SYNC);
- }
- }
- }
-
- public void commitChangesToParent() {
- synchronized (graphManager) {
- if (graphManager.hasChangesSinceLastFlush()) {
- GraphDiff diff = graphManager.getDiffsSinceLastFlush();
- graphManager.graphFlushed();
- channel.onSync(this, diff, DataChannel.FLUSH_NOCASCADE_SYNC);
}
}
}
Modified: incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/CayenneContextGraphManager.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/CayenneContextGraphManager.java?rev=423717&r1=423716&r2=423717&view=diff
==============================================================================
--- incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/CayenneContextGraphManager.java (original)
+++ incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/CayenneContextGraphManager.java Wed Jul 19 19:33:25 2006
@@ -83,6 +83,13 @@
synchronized List getCachedQueryResult(String name) {
return (List) queryResultMap.get(name);
}
+
+ /**
+ * @since 3.0
+ */
+ Map getCachedQueryResults() {
+ return queryResultMap;
+ }
boolean hasChangesSinceLastFlush() {
int size = changeLog.hasMarker(FLUSH_MARKER) ? changeLog
Modified: incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/CayenneContextQueryAction.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/CayenneContextQueryAction.java?rev=423717&r1=423716&r2=423717&view=diff
==============================================================================
--- incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/CayenneContextQueryAction.java (original)
+++ incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/CayenneContextQueryAction.java Wed Jul 19 19:33:25 2006
@@ -19,11 +19,15 @@
package org.apache.cayenne;
+import java.util.Iterator;
import java.util.List;
+import java.util.Map;
+import org.apache.cayenne.query.InvalidateListCacheQuery;
import org.apache.cayenne.query.Query;
import org.apache.cayenne.query.QueryMetadata;
import org.apache.cayenne.remote.RemoteIncrementalFaultList;
+import org.apache.cayenne.util.GenericResponse;
import org.apache.cayenne.util.ListResponse;
import org.apache.cayenne.util.ObjectContextQueryAction;
@@ -42,9 +46,11 @@
if (interceptOIDQuery() != DONE) {
if (interceptRelationshipQuery() != DONE) {
- if (interceptLocalCache() != DONE) {
- if (interceptPaginatedQuery() != DONE) {
- runQuery();
+ if (interceptInvalidateQuery() != DONE) {
+ if (interceptLocalCache() != DONE) {
+ if (interceptPaginatedQuery() != DONE) {
+ runQuery();
+ }
}
}
}
@@ -97,5 +103,38 @@
graphManager.cacheQueryResult(cacheKey, response.firstList());
return DONE;
+ }
+
+ private boolean interceptInvalidateQuery() {
+ if (query instanceof InvalidateListCacheQuery) {
+ InvalidateListCacheQuery invalidateQuery = (InvalidateListCacheQuery) query;
+
+ CayenneContextGraphManager graphManager = ((CayenneContext) actingContext)
+ .internalGraphManager();
+
+ int count = 0;
+ synchronized (graphManager) {
+ Iterator it = graphManager.getCachedQueryResults().entrySet().iterator();
+ while (it.hasNext()) {
+ Map.Entry entry = (Map.Entry) it.next();
+ if (invalidateQuery.matchesCacheKey((String) entry.getKey())) {
+ count++;
+ it.remove();
+ }
+ }
+ }
+
+ if (invalidateQuery.isCascade()) {
+ return !DONE;
+ }
+ else {
+ GenericResponse response = new GenericResponse();
+ response.addUpdateCount(count);
+ this.response = response;
+ return DONE;
+ }
+ }
+
+ return !DONE;
}
}
Modified: incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/CayenneDataObject.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/CayenneDataObject.java?rev=423717&r1=423716&r2=423717&view=diff
==============================================================================
--- incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/CayenneDataObject.java (original)
+++ incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/CayenneDataObject.java Wed Jul 19 19:33:25 2006
@@ -54,7 +54,7 @@
*
* @author Andrei Adamchik
*/
-public class CayenneDataObject implements DataObject, XMLSerializable {
+public class CayenneDataObject implements DataObject, Validating, XMLSerializable {
protected long snapshotVersion = DEFAULT_VERSION;
Modified: incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/DataObject.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/DataObject.java?rev=423717&r1=423716&r2=423717&view=diff
==============================================================================
--- incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/DataObject.java (original)
+++ incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/DataObject.java Wed Jul 19 19:33:25 2006
@@ -20,7 +20,6 @@
package org.apache.cayenne;
import org.apache.cayenne.access.DataContext;
-import org.apache.cayenne.validation.ValidationResult;
/**
* Defines basic methods for a persistent object in Cayenne.
@@ -166,31 +165,4 @@
* @deprecated since 1.2 use 'getObjectContext().prepareForAccess(object)'
*/
public void resolveFault();
-
- /**
- * Performs property validation of the NEW object, appending any validation failures
- * to the provided validationResult object. This method is invoked by DataContext
- * before committing a NEW object to the database.
- *
- * @since 1.1
- */
- public void validateForInsert(ValidationResult validationResult);
-
- /**
- * Performs property validation of the MODIFIED object, appending any validation
- * failures to the provided validationResult object. This method is invoked by
- * DataContext before committing a MODIFIED object to the database.
- *
- * @since 1.1
- */
- public void validateForUpdate(ValidationResult validationResult);
-
- /**
- * Performs property validation of the DELETED object, appending any validation
- * failures to the provided validationResult object. This method is invoked by
- * DataContext before committing a DELETED object to the database.
- *
- * @since 1.1
- */
- public void validateForDelete(ValidationResult validationResult);
}
Added: incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/Validating.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/Validating.java?rev=423717&view=auto
==============================================================================
--- incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/Validating.java (added)
+++ incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/Validating.java Wed Jul 19 19:33:25 2006
@@ -0,0 +1,52 @@
+/*****************************************************************
+ * 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;
+
+import org.apache.cayenne.validation.ValidationResult;
+
+/**
+ * Defines a number of callback methods that allow an object to be validated before safe.
+ * Entity class can implement this interface and its methods will be called automatically.
+ *
+ * @since 3.0
+ * @author Andrus Adamchik
+ */
+public interface Validating {
+
+ /**
+ * Performs property validation of the NEW object, appending any validation failures
+ * to the provided validationResult object. This method is invoked by ObjectContext
+ * before committing a NEW object to the database.
+ */
+ public void validateForInsert(ValidationResult validationResult);
+
+ /**
+ * Performs property validation of the MODIFIED object, appending any validation
+ * failures to the provided validationResult object. This method is invoked by
+ * ObjectContext before committing a MODIFIED object to the database.
+ */
+ public void validateForUpdate(ValidationResult validationResult);
+
+ /**
+ * Performs property validation of the DELETED object, appending any validation
+ * failures to the provided validationResult object. This method is invoked by
+ * ObjectContext before committing a DELETED object to the database.
+ */
+ public void validateForDelete(ValidationResult validationResult);
+}
Modified: incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/access/ClientServerChannel.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/access/ClientServerChannel.java?rev=423717&r1=423716&r2=423717&view=diff
==============================================================================
--- incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/access/ClientServerChannel.java (original)
+++ incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/access/ClientServerChannel.java Wed Jul 19 19:33:25 2006
@@ -19,8 +19,7 @@
package org.apache.cayenne.access;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.List;
import org.apache.cayenne.CayenneRuntimeException;
import org.apache.cayenne.DataChannel;
@@ -44,8 +43,7 @@
protected DataContext serverContext;
protected boolean lifecycleEventsEnabled;
- protected Map paginatedResults;
-
+
public ClientServerChannel(DataDomain domain) {
this(domain, false);
}
@@ -63,17 +61,15 @@
return new ClientServerChannelQueryAction(this, query).execute();
}
- synchronized void addPaginatedResult(String cacheKey, IncrementalFaultList result) {
- if (paginatedResults == null) {
- paginatedResults = new HashMap();
- }
-
- paginatedResults.put(cacheKey, result);
+ void addPaginatedResult(String cacheKey, IncrementalFaultList result) {
+ serverContext.getObjectStore().cacheQueryResult(cacheKey, result);
}
- synchronized IncrementalFaultList getPaginatedResult(String cacheKey) {
- return (paginatedResults != null) ? (IncrementalFaultList) paginatedResults
- .get(cacheKey) : null;
+ IncrementalFaultList getPaginatedResult(String cacheKey) {
+ List result = serverContext.getObjectStore().getCachedQueryResult(cacheKey);
+ return (result instanceof IncrementalFaultList)
+ ? (IncrementalFaultList) result
+ : null;
}
DataContext getServerContext() {
Modified: incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/access/DataContextQueryAction.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/access/DataContextQueryAction.java?rev=423717&r1=423716&r2=423717&view=diff
==============================================================================
--- incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/access/DataContextQueryAction.java (original)
+++ incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/access/DataContextQueryAction.java Wed Jul 19 19:33:25 2006
@@ -19,14 +19,18 @@
package org.apache.cayenne.access;
+import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import org.apache.cayenne.DataObject;
import org.apache.cayenne.ObjectContext;
import org.apache.cayenne.QueryResponse;
+import org.apache.cayenne.query.InvalidateListCacheQuery;
+import org.apache.cayenne.query.ObjectIdQuery;
import org.apache.cayenne.query.Query;
import org.apache.cayenne.query.QueryMetadata;
-import org.apache.cayenne.query.ObjectIdQuery;
+import org.apache.cayenne.util.GenericResponse;
import org.apache.cayenne.util.ListResponse;
import org.apache.cayenne.util.ObjectContextQueryAction;
@@ -50,8 +54,10 @@
if (interceptPaginatedQuery() != DONE) {
if (interceptOIDQuery() != DONE) {
if (interceptRelationshipQuery() != DONE) {
- if (interceptLocalCache() != DONE) {
- runQuery();
+ if (interceptInvalidateQuery() != DONE) {
+ if (interceptLocalCache() != DONE) {
+ runQuery();
+ }
}
}
}
@@ -129,5 +135,37 @@
runQuery();
objectStore.cacheQueryResult(cacheKey, response.firstList());
return DONE;
+ }
+
+ private boolean interceptInvalidateQuery() {
+ if (query instanceof InvalidateListCacheQuery) {
+ InvalidateListCacheQuery invalidateQuery = (InvalidateListCacheQuery) query;
+
+ ObjectStore objectStore = ((DataContext) actingContext).getObjectStore();
+
+ int count = 0;
+ synchronized (objectStore) {
+ Iterator it = objectStore.getCachedQueryResults().entrySet().iterator();
+ while (it.hasNext()) {
+ Map.Entry entry = (Map.Entry) it.next();
+ if (invalidateQuery.matchesCacheKey((String) entry.getKey())) {
+ count++;
+ it.remove();
+ }
+ }
+ }
+
+ if (invalidateQuery.isCascade()) {
+ return !DONE;
+ }
+ else {
+ GenericResponse response = new GenericResponse();
+ response.addUpdateCount(count);
+ this.response = response;
+ return DONE;
+ }
+ }
+
+ return !DONE;
}
}
Modified: incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/access/DataDomainQueryAction.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/access/DataDomainQueryAction.java?rev=423717&r1=423716&r2=423717&view=diff
==============================================================================
--- incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/access/DataDomainQueryAction.java (original)
+++ incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/access/DataDomainQueryAction.java Wed Jul 19 19:33:25 2006
@@ -39,6 +39,7 @@
import org.apache.cayenne.map.DbRelationship;
import org.apache.cayenne.map.ObjEntity;
import org.apache.cayenne.map.ObjRelationship;
+import org.apache.cayenne.query.InvalidateListCacheQuery;
import org.apache.cayenne.query.PrefetchSelectQuery;
import org.apache.cayenne.query.PrefetchTreeNode;
import org.apache.cayenne.query.Query;
@@ -105,8 +106,10 @@
// run chain...
if (interceptOIDQuery() != DONE) {
if (interceptRelationshipQuery() != DONE) {
- if (interceptSharedCache() != DONE) {
- runQueryInTransaction();
+ if (interceptInvalidateQuery() != DONE) {
+ if (interceptSharedCache() != DONE) {
+ runQueryInTransaction();
+ }
}
}
}
@@ -231,6 +234,35 @@
return !DONE;
}
+ /**
+ * @since 3.0
+ */
+ private boolean interceptInvalidateQuery() {
+ if (query instanceof InvalidateListCacheQuery) {
+ InvalidateListCacheQuery invalidateQuery = (InvalidateListCacheQuery) query;
+
+ int count = 0;
+ synchronized (cache) {
+ Iterator it = cache.getCachedSnapshots().entrySet().iterator();
+ while (it.hasNext()) {
+ Map.Entry entry = (Map.Entry) it.next();
+ if (invalidateQuery.matchesCacheKey((String) entry.getKey())) {
+ count++;
+ it.remove();
+ }
+ }
+ }
+
+ // ignore 'cascade' setting - we are at the bottom of the stack already...
+ GenericResponse response = new GenericResponse();
+ response.addUpdateCount(count);
+ this.response = response;
+ return DONE;
+ }
+
+ return !DONE;
+ }
+
/*
* Wraps execution in shared cache checks
*/
Modified: incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/access/DataRowStore.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/access/DataRowStore.java?rev=423717&r1=423716&r2=423717&view=diff
==============================================================================
--- incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/access/DataRowStore.java (original)
+++ incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/access/DataRowStore.java Wed Jul 19 19:33:25 2006
@@ -408,6 +408,13 @@
return snapshot;
}
}
+
+ /**
+ * @since 3.0
+ */
+ Map getCachedSnapshots() {
+ return snapshotLists;
+ }
/**
* Registers a list of snapshots with internal cache, using a String key.
Modified: incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/access/ObjectStore.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/access/ObjectStore.java?rev=423717&r1=423716&r2=423717&view=diff
==============================================================================
--- incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/access/ObjectStore.java (original)
+++ incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/access/ObjectStore.java Wed Jul 19 19:33:25 2006
@@ -48,8 +48,6 @@
import org.apache.cayenne.map.ObjEntity;
import org.apache.cayenne.map.ObjRelationship;
import org.apache.cayenne.query.ObjectIdQuery;
-import org.apache.cayenne.validation.ValidationException;
-import org.apache.cayenne.validation.ValidationResult;
/**
* ObjectStore stores objects using their ObjectId as a key. It works as a dedicated
@@ -662,6 +660,13 @@
// they were originally cached... do no conversions here
return (List) queryResultMap.get(name);
}
+
+ /**
+ * @since 3.0
+ */
+ Map getCachedQueryResults() {
+ return queryResultMap;
+ }
/**
* Caches a list of query results.
@@ -804,83 +809,6 @@
? (ObjectContext) event.getPostedBy()
: null;
context.fireDataChannelChanged(originatingContext, diff);
- }
-
- /**
- * Performs validation of all uncommitted objects in the ObjectStore. If validation
- * fails, a ValidationException is thrown, listing all encountered failures. This is a
- * utility method for the users to call. Cayenne itself uses a different mechanism to
- * validate objects on commit.
- *
- * @since 1.1
- * @throws ValidationException
- * @deprecated since 1.2 - This method is no longer used in Cayenne internally.
- */
- public synchronized void validateUncommittedObjects() throws ValidationException {
-
- // we must iterate over a copy of object list,
- // as calling validateFor* on DataObjects can have a side effect
- // of modifying this ObjectStore, and thus resulting in
- // ConcurrentModificationExceptions in the Iterator
-
- Collection deleted = null;
- Collection inserted = null;
- Collection updated = null;
-
- Iterator allIt = getObjectIterator();
- while (allIt.hasNext()) {
- DataObject dataObject = (DataObject) allIt.next();
- switch (dataObject.getPersistenceState()) {
- case PersistenceState.NEW:
- if (inserted == null) {
- inserted = new ArrayList();
- }
- inserted.add(dataObject);
- break;
- case PersistenceState.MODIFIED:
- if (updated == null) {
- updated = new ArrayList();
- }
- updated.add(dataObject);
- break;
- case PersistenceState.DELETED:
- if (deleted == null) {
- deleted = new ArrayList();
- }
- deleted.add(dataObject);
- break;
- }
- }
-
- ValidationResult validationResult = new ValidationResult();
-
- if (deleted != null) {
- Iterator it = deleted.iterator();
- while (it.hasNext()) {
- DataObject dataObject = (DataObject) it.next();
- dataObject.validateForDelete(validationResult);
- }
- }
-
- if (inserted != null) {
- Iterator it = inserted.iterator();
- while (it.hasNext()) {
- DataObject dataObject = (DataObject) it.next();
- dataObject.validateForInsert(validationResult);
- }
- }
-
- if (updated != null) {
- Iterator it = updated.iterator();
- while (it.hasNext()) {
- DataObject dataObject = (DataObject) it.next();
- dataObject.validateForUpdate(validationResult);
- }
- }
-
- if (validationResult.hasFailures()) {
- throw new ValidationException(validationResult);
- }
}
/**
Modified: incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/access/ObjectStoreGraphDiff.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/access/ObjectStoreGraphDiff.java?rev=423717&r1=423716&r2=423717&view=diff
==============================================================================
--- incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/access/ObjectStoreGraphDiff.java (original)
+++ incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/access/ObjectStoreGraphDiff.java Wed Jul 19 19:33:25 2006
@@ -25,10 +25,10 @@
import java.util.List;
import java.util.Map;
-import org.apache.cayenne.DataObject;
import org.apache.cayenne.ObjectId;
import org.apache.cayenne.PersistenceState;
import org.apache.cayenne.Persistent;
+import org.apache.cayenne.Validating;
import org.apache.cayenne.graph.CompoundDiff;
import org.apache.cayenne.graph.GraphChangeHandler;
import org.apache.cayenne.graph.GraphDiff;
@@ -77,17 +77,20 @@
noop = false;
// accessing objectMap directly to avoid unneeded synchronization.
- DataObject object = (DataObject) objectStore.getNodeNoSync(entry.getKey());
- switch (object.getPersistenceState()) {
- case PersistenceState.NEW:
- object.validateForInsert(result);
- break;
- case PersistenceState.MODIFIED:
- object.validateForUpdate(result);
- break;
- case PersistenceState.DELETED:
- object.validateForDelete(result);
- break;
+ Persistent object = (Persistent) objectStore.getNodeNoSync(entry.getKey());
+
+ if (object instanceof Validating) {
+ switch (object.getPersistenceState()) {
+ case PersistenceState.NEW:
+ ((Validating) object).validateForInsert(result);
+ break;
+ case PersistenceState.MODIFIED:
+ ((Validating) object).validateForUpdate(result);
+ break;
+ case PersistenceState.DELETED:
+ ((Validating) object).validateForDelete(result);
+ break;
+ }
}
}
}
Modified: incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/map/EntityDescriptor.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/map/EntityDescriptor.java?rev=423717&r1=423716&r2=423717&view=diff
==============================================================================
--- incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/map/EntityDescriptor.java (original)
+++ incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/map/EntityDescriptor.java Wed Jul 19 19:33:25 2006
@@ -252,10 +252,12 @@
}
}
- /*
- * Creates an accessor for the property.
+ /**
+ * Creates an accessor for the property. By default uses uses
+ * {@link DataObjectAccessor} for DataObjects and {@link FieldAccessor} for all other
+ * classes.
*/
- PropertyAccessor makeAccessor(String propertyName, Class propertyType)
+ protected PropertyAccessor makeAccessor(String propertyName, Class propertyType)
throws PropertyAccessException {
if (dataObject) {
Added: incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/query/InvalidateListCacheQuery.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/query/InvalidateListCacheQuery.java?rev=423717&view=auto
==============================================================================
--- incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/query/InvalidateListCacheQuery.java (added)
+++ incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/apache/cayenne/query/InvalidateListCacheQuery.java Wed Jul 19 19:33:25 2006
@@ -0,0 +1,125 @@
+/*****************************************************************
+ * 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.query;
+
+import java.util.regex.Pattern;
+
+import org.apache.cayenne.CayenneRuntimeException;
+import org.apache.cayenne.map.EntityResolver;
+
+/**
+ * A Query that allows to clear list caches. Lists to invalidate are located by matching a
+ * regex pattern against the cache key. For non-cascading query result returned from the
+ * query execution is the number of cached invalidated lists. For cascading query the
+ * result is undefined.
+ *
+ * @since 3.0
+ * @author Andrus Adamchik
+ */
+public class InvalidateListCacheQuery implements Query {
+
+ protected String cacheKeyPattern;
+ protected boolean cascade;
+
+ protected transient Pattern cacheKeyCompiledPattern;
+
+ // needed for hessian serialization
+ private InvalidateListCacheQuery() {
+
+ }
+
+ /**
+ * Creates a new InvalidateCacheQuery.
+ *
+ * @param cacheKeyPattern a String that can be compiled to a valid
+ * java.regex.util.Pattern that will be used to match against query cache
+ * keys.
+ * @param cascade whether to invalidate cache in the local ObjectContext, or to
+ * propagate the operation through the entire stack.
+ */
+ public InvalidateListCacheQuery(String cacheKeyPattern, boolean cascade) {
+ this.cacheKeyPattern = cacheKeyPattern;
+ this.cascade = cascade;
+ }
+
+ public boolean isCascade() {
+ return cascade;
+ }
+
+ public Pattern getCacheKeyCompiledPattern() {
+
+ // compiling pattern lazily is good for serialization
+ if (cacheKeyCompiledPattern == null) {
+ cacheKeyCompiledPattern = Pattern.compile(cacheKeyPattern);
+ }
+
+ return cacheKeyCompiledPattern;
+ }
+
+ public String getCacheKeyPattern() {
+ return cacheKeyPattern;
+ }
+
+ /**
+ * Returns true if the cache key argument matches the pattern.
+ */
+ public boolean matchesCacheKey(String cacheKey) {
+ return cacheKey == null ? false : getCacheKeyCompiledPattern()
+ .matcher(cacheKey)
+ .matches();
+ }
+
+ public QueryMetadata getMetaData(EntityResolver resolver) {
+ return new BaseQueryMetadata();
+ }
+
+ public String getName() {
+ return null;
+ }
+
+ /**
+ * @deprecated since 1.2
+ */
+ public Object getRoot() {
+ return null;
+ }
+
+ public void route(QueryRouter router, EntityResolver resolver, Query substitutedQuery) {
+ // noop
+ }
+
+ public SQLAction createSQLAction(SQLActionVisitor visitor) {
+ throw new CayenneRuntimeException("Unsupported operation");
+ }
+
+ /**
+ * @deprecated since 1.2
+ */
+ public void setName(String name) {
+ // noop
+ }
+
+ /**
+ * @deprecated since 1.2
+ */
+ public void setRoot(Object root) {
+ // noop
+ }
+
+}
Modified: incubator/cayenne/main/trunk/cayenne/cayenne-java/src/tests/java/org/apache/art/MixedPersistenceStrategy2.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/cayenne/cayenne-java/src/tests/java/org/apache/art/MixedPersistenceStrategy2.java?rev=423717&r1=423716&r2=423717&view=diff
==============================================================================
--- incubator/cayenne/main/trunk/cayenne/cayenne-java/src/tests/java/org/apache/art/MixedPersistenceStrategy2.java (original)
+++ incubator/cayenne/main/trunk/cayenne/cayenne-java/src/tests/java/org/apache/art/MixedPersistenceStrategy2.java Wed Jul 19 19:33:25 2006
@@ -4,7 +4,4 @@
public class MixedPersistenceStrategy2 extends _MixedPersistenceStrategy2 {
-}
-
-
-
+}
\ No newline at end of file
Added: incubator/cayenne/main/trunk/cayenne/cayenne-java/src/tests/java/org/apache/cayenne/CayenneContextValidationTst.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/cayenne/cayenne-java/src/tests/java/org/apache/cayenne/CayenneContextValidationTst.java?rev=423717&view=auto
==============================================================================
--- incubator/cayenne/main/trunk/cayenne/cayenne-java/src/tests/java/org/apache/cayenne/CayenneContextValidationTst.java (added)
+++ incubator/cayenne/main/trunk/cayenne/cayenne-java/src/tests/java/org/apache/cayenne/CayenneContextValidationTst.java Wed Jul 19 19:33:25 2006
@@ -0,0 +1,91 @@
+/*****************************************************************
+ * 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;
+
+import org.apache.cayenne.access.ClientServerChannel;
+import org.apache.cayenne.remote.ClientChannel;
+import org.apache.cayenne.remote.service.LocalConnection;
+import org.apache.cayenne.testdo.mt.ClientMtTable1;
+import org.apache.cayenne.testdo.mt.ClientMtTable2;
+import org.apache.cayenne.unit.AccessStack;
+import org.apache.cayenne.unit.CayenneTestCase;
+import org.apache.cayenne.unit.CayenneTestResources;
+import org.apache.cayenne.validation.ValidationException;
+
+public class CayenneContextValidationTst extends CayenneTestCase {
+
+ protected AccessStack buildAccessStack() {
+ return CayenneTestResources
+ .getResources()
+ .getAccessStack(MULTI_TIER_ACCESS_STACK);
+ }
+
+ public void testValidate() throws Exception {
+
+ deleteTestData();
+ DataChannel serverChannel = new ClientServerChannel(getDomain(), false);
+ ClientChannel clientChannel = new ClientChannel(
+ new LocalConnection(serverChannel),
+ true);
+
+ CayenneContext c = new CayenneContext(clientChannel);
+
+ ClientMtTable1 o1 = (ClientMtTable1) c.newObject(ClientMtTable1.class);
+ o1.setGlobalAttribute1("G1");
+ o1.resetValidation(false);
+
+ // this one is not validating
+ ClientMtTable2 o2 = (ClientMtTable2) c.newObject(ClientMtTable2.class);
+ o2.setTable1(o1);
+
+ c.commitChanges();
+ assertTrue(o1.isValidatedForInsert());
+ assertFalse(o1.isValidatedForDelete());
+ assertFalse(o1.isValidatedForUpdate());
+
+ o1.resetValidation(false);
+ o1.setGlobalAttribute1("G2");
+
+ c.commitChanges();
+ assertFalse(o1.isValidatedForInsert());
+ assertFalse(o1.isValidatedForDelete());
+ assertTrue(o1.isValidatedForUpdate());
+
+ o1.resetValidation(false);
+ c.deleteObject(o1);
+
+ c.commitChanges();
+ assertFalse(o1.isValidatedForInsert());
+ assertTrue(o1.isValidatedForDelete());
+ assertFalse(o1.isValidatedForUpdate());
+
+ ClientMtTable1 o11 = (ClientMtTable1) c.newObject(ClientMtTable1.class);
+ o11.setGlobalAttribute1("G1");
+ o11.resetValidation(true);
+
+ try {
+ c.commitChanges();
+ fail("Validation failure must have prevented commit");
+ }
+ catch (ValidationException e) {
+ // expected
+ }
+ }
+}
\ No newline at end of file
Added: incubator/cayenne/main/trunk/cayenne/cayenne-java/src/tests/java/org/apache/cayenne/query/InvalidateListCacheQueryTst.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/cayenne/cayenne-java/src/tests/java/org/apache/cayenne/query/InvalidateListCacheQueryTst.java?rev=423717&view=auto
==============================================================================
--- incubator/cayenne/main/trunk/cayenne/cayenne-java/src/tests/java/org/apache/cayenne/query/InvalidateListCacheQueryTst.java (added)
+++ incubator/cayenne/main/trunk/cayenne/cayenne-java/src/tests/java/org/apache/cayenne/query/InvalidateListCacheQueryTst.java Wed Jul 19 19:33:25 2006
@@ -0,0 +1,63 @@
+/*****************************************************************
+ * 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.query;
+
+import junit.framework.TestCase;
+
+import org.apache.cayenne.map.EntityResolver;
+import org.apache.cayenne.remote.hessian.service.HessianUtil;
+
+public class InvalidateListCacheQueryTst extends TestCase {
+
+ public void testMatchesCacheKey() {
+
+ InvalidateListCacheQuery q1 = new InvalidateListCacheQuery("abc.", true);
+
+ assertTrue(q1.matchesCacheKey("abcd"));
+ assertTrue(q1.matchesCacheKey("abc4"));
+
+ assertFalse(q1.matchesCacheKey("abcde"));
+ assertFalse(q1.matchesCacheKey("abc"));
+ assertFalse(q1.matchesCacheKey("xxxx"));
+
+ InvalidateListCacheQuery q2 = new InvalidateListCacheQuery("abc.*", true);
+
+ assertTrue(q2.matchesCacheKey("abcd"));
+ assertTrue(q2.matchesCacheKey("abc4"));
+
+ assertTrue(q2.matchesCacheKey("abcde"));
+ assertTrue(q2.matchesCacheKey("abc"));
+
+ assertFalse(q2.matchesCacheKey("xxxx"));
+ }
+
+ public void testSerializabilityWithHessian() throws Exception {
+ InvalidateListCacheQuery o = new InvalidateListCacheQuery("XXX", true);
+ Object clone = HessianUtil.cloneViaClientServerSerialization(
+ o,
+ new EntityResolver());
+
+ assertTrue(clone instanceof InvalidateListCacheQuery);
+ InvalidateListCacheQuery c1 = (InvalidateListCacheQuery) clone;
+
+ assertNotSame(o, c1);
+ assertEquals(o.getCacheKeyPattern(), c1.getCacheKeyPattern());
+ assertTrue(c1.isCascade());
+ }
+}
Modified: incubator/cayenne/main/trunk/cayenne/cayenne-java/src/tests/java/org/apache/cayenne/testdo/mt/ClientMtTable1.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/cayenne/cayenne-java/src/tests/java/org/apache/cayenne/testdo/mt/ClientMtTable1.java?rev=423717&r1=423716&r2=423717&view=diff
==============================================================================
--- incubator/cayenne/main/trunk/cayenne/cayenne-java/src/tests/java/org/apache/cayenne/testdo/mt/ClientMtTable1.java (original)
+++ incubator/cayenne/main/trunk/cayenne/cayenne-java/src/tests/java/org/apache/cayenne/testdo/mt/ClientMtTable1.java Wed Jul 19 19:33:25 2006
@@ -2,9 +2,17 @@
import java.util.List;
+import org.apache.cayenne.Validating;
import org.apache.cayenne.testdo.mt.auto._ClientMtTable1;
+import org.apache.cayenne.validation.SimpleValidationFailure;
+import org.apache.cayenne.validation.ValidationResult;
-public class ClientMtTable1 extends _ClientMtTable1 {
+public class ClientMtTable1 extends _ClientMtTable1 implements Validating {
+
+ protected boolean validatedForDelete;
+ protected boolean validatedForInsert;
+ protected boolean validatedForUpdate;
+ protected boolean blow;
// provide direct access to persistent properties for testing..
@@ -19,5 +27,50 @@
public List getTable2ArrayDirect() {
return table2Array;
}
+
+ public void resetValidation(boolean blow) {
+ this.blow = blow;
+ this.validatedForDelete = false;
+ this.validatedForInsert = false;
+ this.validatedForUpdate = false;
+ }
+
+ public void validateForDelete(ValidationResult validationResult) {
+ validatedForDelete = true;
+
+ if(blow) {
+ validationResult.addFailure(new SimpleValidationFailure(this, "test error"));
+ }
+ }
+
+ public void validateForInsert(ValidationResult validationResult) {
+ validatedForInsert = true;
+
+ if(blow) {
+ validationResult.addFailure(new SimpleValidationFailure(this, "test error"));
+ }
+ }
+
+ public void validateForUpdate(ValidationResult validationResult) {
+ validatedForUpdate = true;
+
+ if(blow) {
+ validationResult.addFailure(new SimpleValidationFailure(this, "test error"));
+ }
+ }
+
+
+ public boolean isValidatedForDelete() {
+ return validatedForDelete;
+ }
+
+ public boolean isValidatedForInsert() {
+ return validatedForInsert;
+ }
+
+
+ public boolean isValidatedForUpdate() {
+ return validatedForUpdate;
+ }
}