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 2013/05/18 15:22:09 UTC
svn commit: r1484110 -
/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomain.java
Author: aadamchik
Date: Sat May 18 13:22:09 2013
New Revision: 1484110
URL: http://svn.apache.org/r1484110
Log:
CAY-1819 When adding a filter, auto-register it as a listener
Modified:
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomain.java
Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomain.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomain.java?rev=1484110&r1=1484109&r2=1484110&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomain.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomain.java Sat May 18 13:22:09 2013
@@ -52,10 +52,10 @@ import org.apache.cayenne.util.ToStringB
import org.apache.commons.collections.Transformer;
/**
- * DataDomain performs query routing functions in Cayenne. DataDomain creates single data
- * source abstraction hiding multiple physical data sources from the user. When a child
- * DataContext sends a query to the DataDomain, it is transparently routed to an
- * appropriate DataNode.
+ * DataDomain performs query routing functions in Cayenne. DataDomain creates
+ * single data source abstraction hiding multiple physical data sources from the
+ * user. When a child DataContext sends a query to the DataDomain, it is
+ * transparently routed to an appropriate DataNode.
*/
public class DataDomain implements QueryEngine, DataChannel {
@@ -123,9 +123,11 @@ public class DataDomain implements Query
/**
* Creates new DataDomain.
*
- * @param name DataDomain name. Domain can be located using its name in the
+ * @param name
+ * DataDomain name. Domain can be located using its name in the
* Configuration object.
- * @param properties A Map containing domain configuration properties.
+ * @param properties
+ * A Map containing domain configuration properties.
*/
public DataDomain(String name, Map properties) {
init(name);
@@ -138,7 +140,8 @@ public class DataDomain implements Query
this.nodesByDataMapName = new ConcurrentHashMap<String, DataNode>();
this.nodes = new ConcurrentHashMap<String, DataNode>();
- // properties are read-only, so no need for concurrent map, or any specific map
+ // properties are read-only, so no need for concurrent map, or any
+ // specific map
// for that matter
this.properties = Collections.EMPTY_MAP;
@@ -146,14 +149,14 @@ public class DataDomain implements Query
}
/**
- * Checks that Domain is not stopped. Throws DomainStoppedException otherwise.
+ * Checks that Domain is not stopped. Throws DomainStoppedException
+ * otherwise.
*
* @since 3.0
*/
protected void checkStopped() throws DomainStoppedException {
if (stopped) {
- throw new DomainStoppedException("Domain "
- + name
+ throw new DomainStoppedException("Domain " + name
+ " was shutdown and can no longer be used to access the database");
}
}
@@ -191,25 +194,19 @@ public class DataDomain implements Query
public void initWithProperties(Map<String, String> properties) {
// clone properties to ensure that it is read-only internally
- properties = properties != null
- ? new HashMap<String, String>(properties)
- : Collections.EMPTY_MAP;
+ properties = properties != null ? new HashMap<String, String>(properties) : Collections.EMPTY_MAP;
String sharedCacheEnabled = properties.get(SHARED_CACHE_ENABLED_PROPERTY);
- String validatingObjectsOnCommit = properties
- .get(VALIDATING_OBJECTS_ON_COMMIT_PROPERTY);
- String usingExternalTransactions = properties
- .get(USING_EXTERNAL_TRANSACTIONS_PROPERTY);
+ String validatingObjectsOnCommit = properties.get(VALIDATING_OBJECTS_ON_COMMIT_PROPERTY);
+ String usingExternalTransactions = properties.get(USING_EXTERNAL_TRANSACTIONS_PROPERTY);
// init ivars from properties
- this.sharedCacheEnabled = (sharedCacheEnabled != null) ? "true"
- .equalsIgnoreCase(sharedCacheEnabled) : SHARED_CACHE_ENABLED_DEFAULT;
- this.validatingObjectsOnCommit = (validatingObjectsOnCommit != null)
- ? "true".equalsIgnoreCase(validatingObjectsOnCommit)
- : VALIDATING_OBJECTS_ON_COMMIT_DEFAULT;
- this.usingExternalTransactions = (usingExternalTransactions != null)
- ? "true".equalsIgnoreCase(usingExternalTransactions)
- : USING_EXTERNAL_TRANSACTIONS_DEFAULT;
+ this.sharedCacheEnabled = (sharedCacheEnabled != null) ? "true".equalsIgnoreCase(sharedCacheEnabled)
+ : SHARED_CACHE_ENABLED_DEFAULT;
+ this.validatingObjectsOnCommit = (validatingObjectsOnCommit != null) ? "true"
+ .equalsIgnoreCase(validatingObjectsOnCommit) : VALIDATING_OBJECTS_ON_COMMIT_DEFAULT;
+ this.usingExternalTransactions = (usingExternalTransactions != null) ? "true"
+ .equalsIgnoreCase(usingExternalTransactions) : USING_EXTERNAL_TRANSACTIONS_DEFAULT;
this.properties = properties;
}
@@ -254,10 +251,10 @@ public class DataDomain implements Query
}
/**
- * Returns <code>true</code> if DataContexts produced by this DataDomain are using
- * shared DataRowStore. Returns <code>false</code> if each DataContext would work with
- * its own DataRowStore. Note that this setting can be overwritten per DataContext.
- * See {@link #createDataContext(boolean)}.
+ * Returns <code>true</code> if DataContexts produced by this DataDomain are
+ * using shared DataRowStore. Returns <code>false</code> if each DataContext
+ * would work with its own DataRowStore. Note that this setting can be
+ * overwritten per DataContext. See {@link #createDataContext(boolean)}.
*/
public boolean isSharedCacheEnabled() {
return sharedCacheEnabled;
@@ -268,8 +265,8 @@ public class DataDomain implements Query
}
/**
- * Returns whether child DataContexts default behavior is to perform object validation
- * before commit is executed.
+ * Returns whether child DataContexts default behavior is to perform object
+ * validation before commit is executed.
*
* @since 1.1
*/
@@ -278,8 +275,8 @@ public class DataDomain implements Query
}
/**
- * Sets the property defining whether child DataContexts should perform object
- * validation before commit is executed.
+ * Sets the property defining whether child DataContexts should perform
+ * object validation before commit is executed.
*
* @since 1.1
*/
@@ -288,8 +285,8 @@ public class DataDomain implements Query
}
/**
- * Returns whether this DataDomain should internally commit all transactions, or let
- * container do that.
+ * Returns whether this DataDomain should internally commit all
+ * transactions, or let container do that.
*
* @since 1.1
*/
@@ -298,8 +295,8 @@ public class DataDomain implements Query
}
/**
- * Sets a property defining whether this DataDomain should internally commit all
- * transactions, or let container do that.
+ * Sets a property defining whether this DataDomain should internally commit
+ * all transactions, or let container do that.
*
* @since 1.1
*/
@@ -317,16 +314,16 @@ public class DataDomain implements Query
/**
* @since 1.1
- * @return TransactionDelegate associated with this DataDomain, or null if no delegate
- * exist.
+ * @return TransactionDelegate associated with this DataDomain, or null if
+ * no delegate exist.
*/
public TransactionDelegate getTransactionDelegate() {
return transactionDelegate;
}
/**
- * Initializes TransactionDelegate used by all DataContexts associated with this
- * DataDomain.
+ * Initializes TransactionDelegate used by all DataContexts associated with
+ * this DataDomain.
*
* @since 1.1
*/
@@ -335,8 +332,8 @@ public class DataDomain implements Query
}
/**
- * Returns snapshots cache for this DataDomain, lazily initializing it on the first
- * call if 'sharedCacheEnabled' flag is true.
+ * Returns snapshots cache for this DataDomain, lazily initializing it on
+ * the first call if 'sharedCacheEnabled' flag is true.
*/
public DataRowStore getSharedSnapshotCache() {
if (sharedSnapshotCache == null && sharedCacheEnabled) {
@@ -359,8 +356,9 @@ public class DataDomain implements Query
}
/**
- * Shuts down the previous cache instance, sets cache to the new DataSowStore instance
- * and updates two properties of the new DataSowStore: name and eventManager.
+ * Shuts down the previous cache instance, sets cache to the new
+ * DataSowStore instance and updates two properties of the new DataSowStore:
+ * name and eventManager.
*/
public synchronized void setSharedSnapshotCache(DataRowStore snapshotCache) {
if (this.sharedSnapshotCache != snapshotCache) {
@@ -389,8 +387,8 @@ public class DataDomain implements Query
}
/**
- * Removes named DataMap from this DataDomain and any underlying DataNodes that
- * include it.
+ * Removes named DataMap from this DataDomain and any underlying DataNodes
+ * that include it.
*
* @since 3.1
*/
@@ -414,8 +412,9 @@ public class DataDomain implements Query
}
/**
- * Removes a DataNode from DataDomain. Any maps previously associated with this node
- * within domain will still be kept around, however they wan't be mapped to any node.
+ * Removes a DataNode from DataDomain. Any maps previously associated with
+ * this node within domain will still be kept around, however they wan't be
+ * mapped to any node.
*/
public void removeDataNode(String nodeName) {
DataNode removed = nodes.remove(nodeName);
@@ -440,7 +439,8 @@ public class DataDomain implements Query
}
/**
- * Returns an unmodifiable collection of DataNodes associated with this domain.
+ * Returns an unmodifiable collection of DataNodes associated with this
+ * domain.
*/
public Collection<DataNode> getDataNodes() {
return Collections.unmodifiableCollection(nodes.values());
@@ -463,8 +463,8 @@ public class DataDomain implements Query
}
/**
- * Creates and returns a new inactive transaction. Returned transaction is bound to
- * the current execution thread.
+ * Creates and returns a new inactive transaction. Returned transaction is
+ * bound to the current execution thread.
* <p>
* If there is a TransactionDelegate, adds the delegate to the newly created
* Transaction. Behavior of the returned Transaction depends on
@@ -475,21 +475,19 @@ public class DataDomain implements Query
*/
public Transaction createTransaction() {
if (isUsingExternalTransactions()) {
- Transaction transaction = Transaction
- .externalTransaction(getTransactionDelegate());
+ Transaction transaction = Transaction.externalTransaction(getTransactionDelegate());
transaction.setJdbcEventLogger(jdbcEventLogger);
return transaction;
- }
- else {
- Transaction transaction = Transaction
- .internalTransaction(getTransactionDelegate());
+ } else {
+ Transaction transaction = Transaction.internalTransaction(getTransactionDelegate());
transaction.setJdbcEventLogger(jdbcEventLogger);
return transaction;
}
}
/**
- * Returns registered DataNode whose name matches <code>name</code> parameter.
+ * Returns registered DataNode whose name matches <code>name</code>
+ * parameter.
*
* @since 3.1
*/
@@ -498,7 +496,8 @@ public class DataDomain implements Query
}
/**
- * Returns a DataNode that should handle queries for all entities in a DataMap.
+ * Returns a DataNode that should handle queries for all entities in a
+ * DataMap.
*
* @since 1.1
*/
@@ -507,7 +506,8 @@ public class DataDomain implements Query
DataNode node = nodesByDataMapName.get(map.getName());
if (node == null) {
- // see if one of the node states has changed, and the map is now linked...
+ // see if one of the node states has changed, and the map is now
+ // linked...
for (DataNode n : getDataNodes()) {
for (DataMap m : n.getDataMaps()) {
if (m == map) {
@@ -527,12 +527,9 @@ public class DataDomain implements Query
if (defaultNode != null) {
nodesByDataMapName.put(map.getName(), defaultNode);
node = defaultNode;
- }
- else {
- throw new CayenneRuntimeException(
- "No DataNode configured for DataMap '"
- + map.getName()
- + "' and no default DataNode set");
+ } else {
+ throw new CayenneRuntimeException("No DataNode configured for DataMap '" + map.getName()
+ + "' and no default DataNode set");
}
}
}
@@ -576,17 +573,12 @@ public class DataDomain implements Query
/**
* Routes queries to appropriate DataNodes for execution.
*/
- public void performQueries(
- final Collection<? extends Query> queries,
- final OperationObserver callback) {
+ public void performQueries(final Collection<? extends Query> queries, final OperationObserver callback) {
runInTransaction(new Transformer() {
public Object transform(Object input) {
- new DataDomainLegacyQueryAction(
- DataDomain.this,
- new QueryChain(queries),
- callback).execute();
+ new DataDomainLegacyQueryAction(DataDomain.this, new QueryChain(queries), callback).execute();
return null;
}
});
@@ -605,19 +597,17 @@ public class DataDomain implements Query
return new DataDomainQueryFilterChain().onQuery(originatingContext, query);
}
- QueryResponse onQueryNoFilters(
- final ObjectContext originatingContext,
- final Query query) {
+ QueryResponse onQueryNoFilters(final ObjectContext originatingContext, final Query query) {
// transaction note:
// we don't wrap this code in transaction to reduce transaction scope to
// just the DB operation for better performance ... query action will
// start a transaction itself when and if needed
- return new DataDomainQueryAction(originatingContext, DataDomain.this, query)
- .execute();
+ return new DataDomainQueryAction(originatingContext, DataDomain.this, query).execute();
}
/**
- * Returns an EntityResolver that stores mapping information for this domain.
+ * Returns an EntityResolver that stores mapping information for this
+ * domain.
*/
public EntityResolver getEntityResolver() {
if (entityResolver == null) {
@@ -632,52 +622,38 @@ public class DataDomain implements Query
*
* @since 1.2
*/
- public GraphDiff onSync(
- final ObjectContext originatingContext,
- final GraphDiff changes,
- int syncType) {
+ public GraphDiff onSync(final ObjectContext originatingContext, final GraphDiff changes, int syncType) {
checkStopped();
- return new DataDomainSyncFilterChain().onSync(
- originatingContext,
- changes,
- syncType);
- }
-
- GraphDiff onSyncNoFilters(
- final ObjectContext originatingContext,
- final GraphDiff changes,
- int syncType) {
- DataChannelSyncCallbackAction callbackAction = DataChannelSyncCallbackAction
- .getCallbackAction(
- getEntityResolver().getCallbackRegistry(),
- originatingContext.getGraphManager(),
- changes,
- syncType);
+ return new DataDomainSyncFilterChain().onSync(originatingContext, changes, syncType);
+ }
+
+ GraphDiff onSyncNoFilters(final ObjectContext originatingContext, final GraphDiff changes, int syncType) {
+ DataChannelSyncCallbackAction callbackAction = DataChannelSyncCallbackAction.getCallbackAction(
+ getEntityResolver().getCallbackRegistry(), originatingContext.getGraphManager(), changes, syncType);
callbackAction.applyPreCommit();
GraphDiff result;
switch (syncType) {
- case DataChannel.ROLLBACK_CASCADE_SYNC:
- result = onSyncRollback(originatingContext);
- break;
- // "cascade" and "no_cascade" are the same from the DataDomain
- // perspective,
- // including transaction handling logic
- case DataChannel.FLUSH_NOCASCADE_SYNC:
- case DataChannel.FLUSH_CASCADE_SYNC:
- result = (GraphDiff) runInTransaction(new Transformer() {
+ case DataChannel.ROLLBACK_CASCADE_SYNC:
+ result = onSyncRollback(originatingContext);
+ break;
+ // "cascade" and "no_cascade" are the same from the DataDomain
+ // perspective,
+ // including transaction handling logic
+ case DataChannel.FLUSH_NOCASCADE_SYNC:
+ case DataChannel.FLUSH_CASCADE_SYNC:
+ result = (GraphDiff) runInTransaction(new Transformer() {
- public Object transform(Object input) {
- return onSyncFlush(originatingContext, changes);
- }
- });
- break;
- default:
- throw new CayenneRuntimeException("Invalid synchronization type: "
- + syncType);
+ public Object transform(Object input) {
+ return onSyncFlush(originatingContext, changes);
+ }
+ });
+ break;
+ default:
+ throw new CayenneRuntimeException("Invalid synchronization type: " + syncType);
}
callbackAction.applyPostCommit();
@@ -700,8 +676,7 @@ public class DataDomain implements Query
if (!(originatingContext instanceof DataContext)) {
throw new CayenneRuntimeException(
"No support for committing ObjectContexts that are not DataContexts yet. "
- + "Unsupported context: "
- + originatingContext);
+ + "Unsupported context: " + originatingContext);
}
DataDomainFlushAction action = new DataDomainFlushAction(this);
@@ -711,12 +686,15 @@ public class DataDomain implements Query
}
/**
- * Executes Transformer.transform() method in a transaction. Transaction policy is to
- * check for the thread transaction, and use it if one exists. If it doesn't, a new
- * transaction is created, with a scope limited to this method.
- */
- // WARNING: (andrus) if we ever decide to make this method protected or public, we
- // need to change the signature to avoid API dependency on commons-collections
+ * Executes Transformer.transform() method in a transaction. Transaction
+ * policy is to check for the thread transaction, and use it if one exists.
+ * If it doesn't, a new transaction is created, with a scope limited to this
+ * method.
+ */
+ // WARNING: (andrus) if we ever decide to make this method protected or
+ // public, we
+ // need to change the signature to avoid API dependency on
+ // commons-collections
Object runInTransaction(Transformer operation) {
// user or container-managed or nested transaction
@@ -734,27 +712,25 @@ public class DataDomain implements Query
Object result = operation.transform(null);
transaction.commit();
return result;
- }
- catch (Exception ex) {
+ } catch (Exception ex) {
transaction.setRollbackOnly();
// must rethrow
if (ex instanceof CayenneRuntimeException) {
throw (CayenneRuntimeException) ex;
- }
- else {
+ } else {
throw new CayenneRuntimeException(ex);
}
- }
- finally {
+ } finally {
Transaction.bindThreadTransaction(null);
if (transaction.getStatus() == Transaction.STATUS_MARKED_ROLLEDBACK) {
try {
transaction.rollback();
- }
- catch (Exception rollbackEx) {
- // although we don't expect an exception here, print the stack, as
- // there have been some Cayenne bugs already (CAY-557) that were
+ } catch (Exception rollbackEx) {
+ // although we don't expect an exception here, print the
+ // stack, as
+ // there have been some Cayenne bugs already (CAY-557) that
+ // were
// masked by this 'catch' clause.
jdbcEventLogger.logQueryError(rollbackEx);
}
@@ -796,8 +772,9 @@ public class DataDomain implements Query
/**
* Returns an unmodifiable list of filters registered with this DataDomain.
* <p>
- * Filter ordering note: filters are applied in reverse order of their occurrence in
- * the filter list. I.e. the last filter in the list called first in the chain.
+ * Filter ordering note: filters are applied in reverse order of their
+ * occurrence in the filter list. I.e. the last filter in the list called
+ * first in the chain.
*
* @since 3.1
*/
@@ -806,12 +783,15 @@ public class DataDomain implements Query
}
/**
- * Adds a new filter, calling its 'init' method.
+ * Adds a new filter, immediately calling its 'init' method. Since 3.2 this
+ * method also registers passed filter as an event listener, if any of its
+ * methods have event annotations.
*
* @since 3.1
*/
public void addFilter(DataChannelFilter filter) {
filter.init(this);
+ getEntityResolver().getCallbackRegistry().addListener(filter);
filters.add(filter);
}
@@ -844,44 +824,32 @@ public class DataDomain implements Query
public QueryResponse onQuery(ObjectContext originatingContext, Query query) {
DataChannelFilter filter = nextFilter();
- return (filter != null)
- ? filter.onQuery(originatingContext, query, this)
- : onQueryNoFilters(originatingContext, query);
+ return (filter != null) ? filter.onQuery(originatingContext, query, this) : onQueryNoFilters(
+ originatingContext, query);
}
- public GraphDiff onSync(
- ObjectContext originatingContext,
- GraphDiff changes,
- int syncType) {
- throw new UnsupportedOperationException(
- "It is illegal to call 'onSync' inside 'onQuery' chain");
+ public GraphDiff onSync(ObjectContext originatingContext, GraphDiff changes, int syncType) {
+ throw new UnsupportedOperationException("It is illegal to call 'onSync' inside 'onQuery' chain");
}
}
final class DataDomainSyncFilterChain extends DataDomainFilterChain {
- public GraphDiff onSync(
- final ObjectContext originatingContext,
- final GraphDiff changes,
- int syncType) {
+ public GraphDiff onSync(final ObjectContext originatingContext, final GraphDiff changes, int syncType) {
DataChannelFilter filter = nextFilter();
- return (filter != null) ? filter.onSync(
- originatingContext,
- changes,
- syncType,
- this) : onSyncNoFilters(originatingContext, changes, syncType);
+ return (filter != null) ? filter.onSync(originatingContext, changes, syncType, this) : onSyncNoFilters(
+ originatingContext, changes, syncType);
}
public QueryResponse onQuery(ObjectContext originatingContext, Query query) {
- throw new UnsupportedOperationException(
- "It is illegal to call 'onQuery' inside 'onSync' chain");
+ throw new UnsupportedOperationException("It is illegal to call 'onQuery' inside 'onSync' chain");
}
}
/**
- * An optional DataNode that is used for DataMaps that are not linked to a DataNode
- * explicitly.
+ * An optional DataNode that is used for DataMaps that are not linked to a
+ * DataNode explicitly.
*
* @since 3.1
*/
@@ -897,13 +865,15 @@ public class DataDomain implements Query
}
/**
- * Returns a maximum number of object IDs to match in a single query for queries that
- * select objects based on collection of ObjectIds. This affects queries generated by
- * Cayenne when processing paginated queries and DISJOINT_BY_ID prefetches and is
- * intended to address database limitations on the size of SQL statements as well as
- * to cap memory use in Cayenne when generating such queries. The default is 10000. It
- * can be changed either by calling {@link #setMaxIdQualifierSize(int)} or changing
- * the value for property {@link Constants#SERVER_MAX_ID_QUALIFIER_SIZE_PROPERTY}.
+ * Returns a maximum number of object IDs to match in a single query for
+ * queries that select objects based on collection of ObjectIds. This
+ * affects queries generated by Cayenne when processing paginated queries
+ * and DISJOINT_BY_ID prefetches and is intended to address database
+ * limitations on the size of SQL statements as well as to cap memory use in
+ * Cayenne when generating such queries. The default is 10000. It can be
+ * changed either by calling {@link #setMaxIdQualifierSize(int)} or changing
+ * the value for property
+ * {@link Constants#SERVER_MAX_ID_QUALIFIER_SIZE_PROPERTY}.
*
* @since 3.1
*/