cayenne-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From aadamc...@apache.org
Subject svn commit: r1486133 - in /cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src: main/java/org/apache/cayenne/ main/java/org/apache/cayenne/access/ main/java/org/apache/cayenne/access/jdbc/ main/java/org/apache/cayenne/access/util/ test/java/org...
Date Fri, 24 May 2013 17:41:56 GMT
Author: aadamchik
Date: Fri May 24 17:41:56 2013
New Revision: 1486133

URL: http://svn.apache.org/r1486133
Log:
CAY-1829 Make ResultIterator implement Iterable<T>, create ObjectContext.iterate method

callback-based iteration

Added:
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ResultIteratorCallback.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/ResultIteratorIterator.java
Modified:
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/BaseContext.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/CayenneContext.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ObjectContext.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataContext.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/IncrementalFaultList.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/util/IteratedSelectObserver.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/MockBaseContext.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/MockObjectContext.java

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/BaseContext.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/BaseContext.java?rev=1486133&r1=1486132&r2=1486133&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/BaseContext.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/BaseContext.java Fri May 24 17:41:56 2013
@@ -70,8 +70,8 @@ public abstract class BaseContext implem
      * 
      * @since 3.0
      * @return the ObjectContext associated with caller thread.
-     * @throws IllegalStateException if there is no ObjectContext bound to the current
-     *             thread.
+     * @throws IllegalStateException
+     *             if there is no ObjectContext bound to the current thread.
      */
     public static ObjectContext getThreadObjectContext() throws IllegalStateException {
         ObjectContext context = threadObjectContext.get();
@@ -83,9 +83,10 @@ public abstract class BaseContext implem
     }
 
     /**
-     * Binds a ObjectContext to the current thread. ObjectContext can later be retrieved
-     * by users in the same thread by calling {@link BaseContext#getThreadObjectContext}.
-     * Using null parameter will unbind currently bound ObjectContext.
+     * Binds a ObjectContext to the current thread. ObjectContext can later be
+     * retrieved by users in the same thread by calling
+     * {@link BaseContext#getThreadObjectContext}. Using null parameter will
+     * unbind currently bound ObjectContext.
      * 
      * @since 3.0
      */
@@ -93,7 +94,8 @@ public abstract class BaseContext implem
         threadObjectContext.set(context);
     }
 
-    // transient variables that should be reinitialized on deserialization from the
+    // transient variables that should be reinitialized on deserialization from
+    // the
     // registry
     protected transient DataChannel channel;
     protected transient QueryCache queryCache;
@@ -120,17 +122,18 @@ public abstract class BaseContext implem
     }
 
     /**
-     * Checks whether this context is attached to Cayenne runtime stack and if not,
-     * attempts to attach itself to the runtime using Injector returned from the call to
-     * {@link CayenneRuntime#getThreadInjector()}. If thread Injector is not available and
-     * the context is not attached, throws CayenneRuntimeException.
+     * Checks whether this context is attached to Cayenne runtime stack and if
+     * not, attempts to attach itself to the runtime using Injector returned
+     * from the call to {@link CayenneRuntime#getThreadInjector()}. If thread
+     * Injector is not available and the context is not attached, throws
+     * CayenneRuntimeException.
      * <p>
-     * This method is called internally by the context before access to transient
-     * variables to allow the context to attach to the stack lazily following
-     * deserialization.
+     * This method is called internally by the context before access to
+     * transient variables to allow the context to attach to the stack lazily
+     * following deserialization.
      * 
-     * @return true if the context successfully attached to the thread runtime, false - if
-     *         it was already attached.
+     * @return true if the context successfully attached to the thread runtime,
+     *         false - if it was already attached.
      * @since 3.1
      */
     protected boolean attachToRuntimeIfNeeded() {
@@ -149,8 +152,8 @@ public abstract class BaseContext implem
     }
 
     /**
-     * Attaches this context to the CayenneRuntime whose Injector is passed as an argument
-     * to this method.
+     * Attaches this context to the CayenneRuntime whose Injector is passed as
+     * an argument to this method.
      * 
      * @since 3.1
      */
@@ -208,8 +211,8 @@ public abstract class BaseContext implem
     }
 
     /**
-     * Returns whether this ObjectContext performs object validation before commit is
-     * executed.
+     * Returns whether this ObjectContext performs object validation before
+     * commit is executed.
      * 
      * @since 1.1
      */
@@ -218,8 +221,8 @@ public abstract class BaseContext implem
     }
 
     /**
-     * Sets the property defining whether this ObjectContext should perform object
-     * validation before commit is executed.
+     * Sets the property defining whether this ObjectContext should perform
+     * object validation before commit is executed.
      * 
      * @since 1.1
      */
@@ -253,12 +256,13 @@ public abstract class BaseContext implem
                 return localObject;
             }
 
-            // create a hollow object, optimistically assuming that the ID we got from
-            // 'objectFromAnotherContext' is a valid ID either in the parent context or in
+            // create a hollow object, optimistically assuming that the ID we
+            // got from
+            // 'objectFromAnotherContext' is a valid ID either in the parent
+            // context or in
             // the DB. This essentially defers possible FaultFailureExceptions.
 
-            ClassDescriptor descriptor = getEntityResolver().getClassDescriptor(
-                    id.getEntityName());
+            ClassDescriptor descriptor = getEntityResolver().getClassDescriptor(id.getEntityName());
             Persistent persistent = (Persistent) descriptor.createObject();
 
             persistent.setObjectContext(this);
@@ -287,49 +291,48 @@ public abstract class BaseContext implem
 
     @SuppressWarnings("unchecked")
     public <T> List<T> select(Select<T> query) {
-    	return performQuery(query);
+        return performQuery(query);
     }
-    
+
     /**
      * @since 3.2
      */
-    public abstract <T> ResultIterator<T> iterate(Select<T> query);
-    
+    public <T> void iterate(Select<T> query, ResultIteratorCallback<T> callback) {
+        ResultIterator<T> it = iterator(query);
+        try {
+            callback.iterate(it);
+        } finally {
+            it.close();
+        }
+    }
+
+    protected abstract <T> ResultIterator<T> iterator(Select<T> query);
+
     public void prepareForAccess(Persistent object, String property, boolean lazyFaulting) {
         if (object.getPersistenceState() == PersistenceState.HOLLOW) {
 
             ObjectId oid = object.getObjectId();
-            List<?> objects = performQuery(new ObjectIdQuery(
-                    oid,
-                    false,
-                    ObjectIdQuery.CACHE));
+            List<?> objects = performQuery(new ObjectIdQuery(oid, false, ObjectIdQuery.CACHE));
 
             if (objects.size() == 0) {
                 throw new FaultFailureException(
-                        "Error resolving fault, no matching row exists in the database for ObjectId: "
-                                + oid);
-            }
-            else if (objects.size() > 1) {
+                        "Error resolving fault, no matching row exists in the database for ObjectId: " + oid);
+            } else if (objects.size() > 1) {
                 throw new FaultFailureException(
-                        "Error resolving fault, more than one row exists in the database for ObjectId: "
-                                + oid);
+                        "Error resolving fault, more than one row exists in the database for ObjectId: " + oid);
             }
 
             // sanity check...
             if (object.getPersistenceState() != PersistenceState.COMMITTED) {
 
-                String state = PersistenceState.persistenceStateName(object
-                        .getPersistenceState());
+                String state = PersistenceState.persistenceStateName(object.getPersistenceState());
 
-                // TODO: andrus 4/13/2006, modified and deleted states are possible due to
+                // TODO: andrus 4/13/2006, modified and deleted states are
+                // possible due to
                 // a race condition, should we handle them here?
 
-                throw new FaultFailureException(
-                        "Error resolving fault for ObjectId: "
-                                + oid
-                                + " and state ("
-                                + state
-                                + "). Possible cause - matching row is missing from the database.");
+                throw new FaultFailureException("Error resolving fault for ObjectId: " + oid + " and state (" + state
+                        + "). Possible cause - matching row is missing from the database.");
             }
         }
 
@@ -339,16 +342,17 @@ public abstract class BaseContext implem
                     object.getObjectId().getEntityName());
             PropertyDescriptor propertyDescriptor = classDescriptor.getProperty(property);
 
-            // If we don't have a property descriptor, there's not much we can do.
-            // Let the caller know that the specified property could not be found and list
-            // all of the properties that could be so the caller knows what can be used.
+            // If we don't have a property descriptor, there's not much we can
+            // do.
+            // Let the caller know that the specified property could not be
+            // found and list
+            // all of the properties that could be so the caller knows what can
+            // be used.
             if (propertyDescriptor == null) {
                 final StringBuilder errorMessage = new StringBuilder();
 
-                errorMessage.append(String.format(
-                        "Property '%s' is not declared for entity '%s'.",
-                        property,
-                        object.getObjectId().getEntityName()));
+                errorMessage.append(String.format("Property '%s' is not declared for entity '%s'.", property, object
+                        .getObjectId().getEntityName()));
 
                 errorMessage.append(" Declared properties are: ");
 
@@ -382,8 +386,7 @@ public abstract class BaseContext implem
                         errorMessage.append(String.format("'%s'", declaredProperty));
 
                         first = false;
-                    }
-                    else {
+                    } else {
                         errorMessage.append(String.format(", '%s'", declaredProperty));
                     }
                 }
@@ -398,11 +401,7 @@ public abstract class BaseContext implem
         }
     }
 
-    public void propertyChanged(
-            Persistent object,
-            String property,
-            Object oldValue,
-            Object newValue) {
+    public void propertyChanged(Persistent object, String property, Object oldValue, Object newValue) {
 
         graphAction.handlePropertyChange(object, property, oldValue, newValue);
     }
@@ -434,20 +433,16 @@ public abstract class BaseContext implem
         return channel != null ? channel.getEventManager() : null;
     }
 
-    public GraphDiff onSync(
-            ObjectContext originatingContext,
-            GraphDiff changes,
-            int syncType) {
+    public GraphDiff onSync(ObjectContext originatingContext, GraphDiff changes, int syncType) {
         switch (syncType) {
-            case DataChannel.ROLLBACK_CASCADE_SYNC:
-                return onContextRollback(originatingContext);
-            case DataChannel.FLUSH_NOCASCADE_SYNC:
-                return onContextFlush(originatingContext, changes, false);
-            case DataChannel.FLUSH_CASCADE_SYNC:
-                return onContextFlush(originatingContext, changes, true);
-            default:
-                throw new CayenneRuntimeException("Unrecognized SyncMessage type: "
-                        + syncType);
+        case DataChannel.ROLLBACK_CASCADE_SYNC:
+            return onContextRollback(originatingContext);
+        case DataChannel.FLUSH_NOCASCADE_SYNC:
+            return onContextFlush(originatingContext, changes, false);
+        case DataChannel.FLUSH_CASCADE_SYNC:
+            return onContextFlush(originatingContext, changes, true);
+        default:
+            throw new CayenneRuntimeException("Unrecognized SyncMessage type: " + syncType);
         }
     }
 
@@ -456,10 +451,7 @@ public abstract class BaseContext implem
         return new CompoundDiff();
     }
 
-    protected abstract GraphDiff onContextFlush(
-            ObjectContext originatingContext,
-            GraphDiff changes,
-            boolean cascade);
+    protected abstract GraphDiff onContextFlush(ObjectContext originatingContext, GraphDiff changes, boolean cascade);
 
     /**
      * @since 1.2
@@ -519,7 +511,8 @@ public abstract class BaseContext implem
     }
 
     /**
-     * Returns a map of user-defined properties associated with this DataContext.
+     * Returns a map of user-defined properties associated with this
+     * DataContext.
      * 
      * @since 3.0
      */
@@ -539,8 +532,9 @@ public abstract class BaseContext implem
     }
 
     /**
-     * Returns a user-defined property previously set via 'setUserProperty'. Note that it
-     * is a caller responsibility to synchronize access to properties.
+     * Returns a user-defined property previously set via 'setUserProperty'.
+     * Note that it is a caller responsibility to synchronize access to
+     * properties.
      * 
      * @since 3.0
      */
@@ -559,11 +553,12 @@ public abstract class BaseContext implem
     }
 
     /**
-     * If ObjEntity qualifier is set, asks it to inject initial value to an object. Also
-     * performs all Persistent initialization operations
+     * If ObjEntity qualifier is set, asks it to inject initial value to an
+     * object. Also performs all Persistent initialization operations
      */
     protected void injectInitialValue(Object obj) {
-        // must follow this exact order of property initialization per CAY-653, i.e. have
+        // must follow this exact order of property initialization per CAY-653,
+        // i.e. have
         // the id and the context in place BEFORE setPersistence is called
 
         Persistent object = (Persistent) obj;
@@ -580,8 +575,7 @@ public abstract class BaseContext implem
         ObjEntity entity;
         try {
             entity = getEntityResolver().lookupObjEntity(object.getClass());
-        }
-        catch (CayenneRuntimeException ex) {
+        } catch (CayenneRuntimeException ex) {
             // ObjEntity cannot be fetched, ignored
             entity = null;
         }
@@ -593,9 +587,7 @@ public abstract class BaseContext implem
         }
 
         // invoke callbacks
-        getEntityResolver().getCallbackRegistry().performCallbacks(
-                LifecycleEvent.POST_ADD,
-                object);
+        getEntityResolver().getCallbackRegistry().performCallbacks(LifecycleEvent.POST_ADD, object);
     }
 
     /**

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/CayenneContext.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/CayenneContext.java?rev=1486133&r1=1486132&r2=1486133&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/CayenneContext.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/CayenneContext.java Fri May 24 17:41:56 2013
@@ -32,7 +32,6 @@ import org.apache.cayenne.graph.GraphDif
 import org.apache.cayenne.graph.GraphManager;
 import org.apache.cayenne.map.ObjEntity;
 import org.apache.cayenne.query.Query;
-import org.apache.cayenne.query.Select;
 import org.apache.cayenne.reflect.ClassDescriptor;
 import org.apache.cayenne.util.EventUtil;
 import org.apache.cayenne.validation.ValidationException;
@@ -389,9 +388,9 @@ public class CayenneContext extends Base
      * 
      * @since 3.2
      */
-    @Override
-    public <T> ResultIterator<T> iterate(Select<T> query) {
+    protected <T> ResultIterator<T> iterator(org.apache.cayenne.query.Select<T> query) {
         List<T> objects = select(query);
         return new CollectionResultIterator<T>(objects);
     }
+
 }

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ObjectContext.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ObjectContext.java?rev=1486133&r1=1486132&r2=1486133&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ObjectContext.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ObjectContext.java Fri May 24 17:41:56 2013
@@ -175,13 +175,13 @@ public interface ObjectContext extends S
     <T> List<T> select(Select<T> query);
 
     /**
-     * Returns an iterable object over the open result set. Note that teration
-     * must be wrapped in try/finally, and ResultIterator must be explicitly
-     * closed when iteration is finished.
+     * Creates a ResultIterator based on the provided query and passes it to a
+     * callback for processing. The caller does not need to worry about closing
+     * the iterator. Thius methoid takes care of it.
      * 
      * @since 3.2
      */
-    <T> ResultIterator<T> iterate(Select<T> query);
+    <T> void iterate(Select<T> query, ResultIteratorCallback<T> callback);
 
     /**
      * Executes any kind of query providing the result in a form of

Added: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ResultIteratorCallback.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ResultIteratorCallback.java?rev=1486133&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ResultIteratorCallback.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ResultIteratorCallback.java Fri May 24 17:41:56 2013
@@ -0,0 +1,29 @@
+/*****************************************************************
+ *   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.ResultIterator;
+
+/**
+ * @since 3.2
+ */
+public interface ResultIteratorCallback<T> {
+
+    void iterate(ResultIterator<T> iterator);
+}

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataContext.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataContext.java?rev=1486133&r1=1486132&r2=1486133&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataContext.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataContext.java Fri May 24 17:41:56 2013
@@ -30,7 +30,6 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.cayenne.BaseContext;
-import org.apache.cayenne.CayenneException;
 import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.DataChannel;
 import org.apache.cayenne.DataObject;
@@ -783,12 +782,9 @@ public class DataContext extends BaseCon
     }
 
     @SuppressWarnings("unchecked")
-    public <T> ResultIterator<T> iterate(Select<T> query) {
-        try {
-            return performIteratedQuery(query);
-        } catch (CayenneException e) {
-            throw new CayenneRuntimeException(e);
-        }
+    @Override
+    protected <T> ResultIterator<T> iterator(Select<T> query) {
+        return performIteratedQuery(query);
     }
 
     /**
@@ -803,7 +799,7 @@ public class DataContext extends BaseCon
     // TODO: deprecate once all selecting queries start implementing Select<T>
     // interface
     @SuppressWarnings({ "rawtypes" })
-    public ResultIterator performIteratedQuery(Query query) throws CayenneException {
+    public ResultIterator performIteratedQuery(Query query) {
         // TODO: use 3.2 TransactionManager
         if (Transaction.getThreadTransaction() != null) {
             return internalPerformIteratedQuery(query);
@@ -821,7 +817,7 @@ public class DataContext extends BaseCon
             } catch (Exception e) {
                 Transaction.bindThreadTransaction(null);
                 tx.setRollbackOnly();
-                throw new CayenneException(e);
+                throw new CayenneRuntimeException(e);
             } finally {
                 // note: we are keeping the transaction bound to the current
                 // thread on
@@ -844,7 +840,7 @@ public class DataContext extends BaseCon
     /**
      * Runs an iterated query in a transactional context provided by the caller.
      */
-    ResultIterator internalPerformIteratedQuery(Query query) throws CayenneException {
+    ResultIterator internalPerformIteratedQuery(Query query) {
         // note that for now DataChannel API does not support cursors (aka
         // ResultIterator), so we have to go directly to the DataDomain.
         IteratedSelectObserver observer = new IteratedSelectObserver();

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/IncrementalFaultList.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/IncrementalFaultList.java?rev=1486133&r1=1486132&r2=1486133&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/IncrementalFaultList.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/IncrementalFaultList.java Fri May 24 17:41:56 2013
@@ -29,7 +29,6 @@ import java.util.ListIterator;
 import java.util.Map;
 import java.util.NoSuchElementException;
 
-import org.apache.cayenne.CayenneException;
 import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.Persistent;
 import org.apache.cayenne.exp.Expression;
@@ -41,19 +40,19 @@ import org.apache.cayenne.query.SelectQu
 import org.apache.cayenne.util.Util;
 
 /**
- * A synchronized list that serves as a container of DataObjects. It is returned when a
- * paged query is performed by DataContext. On creation, only the first "page" is fully
- * resolved, for the rest of the objects only their ObjectIds are read. Pages following
- * the first page are resolved on demand only. On access to an element, the list would
- * ensure that this element as well as all its siblings on the same page are fully
- * resolved.
+ * A synchronized list that serves as a container of DataObjects. It is returned
+ * when a paged query is performed by DataContext. On creation, only the first
+ * "page" is fully resolved, for the rest of the objects only their ObjectIds
+ * are read. Pages following the first page are resolved on demand only. On
+ * access to an element, the list would ensure that this element as well as all
+ * its siblings on the same page are fully resolved.
  * <p>
- * The list can hold DataRows or DataObjects. Attempts to add any other object types will
- * result in an exception.
+ * The list can hold DataRows or DataObjects. Attempts to add any other object
+ * types will result in an exception.
  * </p>
  * <p>
- * Performance note: certain operations like <code>toArray</code> would trigger full list
- * fetch.
+ * Performance note: certain operations like <code>toArray</code> would trigger
+ * full list fetch.
  * </p>
  */
 public class IncrementalFaultList<E> implements List<E>, Serializable {
@@ -66,39 +65,45 @@ public class IncrementalFaultList<E> imp
     protected int unfetchedObjects;
 
     /**
-     * Stores a hint allowing to distinguish data rows from unfetched ids when the query
-     * fetches data rows.
+     * Stores a hint allowing to distinguish data rows from unfetched ids when
+     * the query fetches data rows.
      */
     protected int idWidth;
 
     private IncrementalListHelper helper;
 
     /**
-     * Defines the upper limit on the size of fetches. This is needed to avoid where
-     * clause size limitations.
+     * Defines the upper limit on the size of fetches. This is needed to avoid
+     * where clause size limitations.
      */
     protected int maxFetchSize;
 
-    // Don't confuse this with the JDBC ResultSet fetch size setting - this controls
-    // the where clause generation that is necessary to fetch specific records a page
-    // at a time. Some JDBC Drivers/Databases may have limits on statement length
-    // or complexity of the where clause - e.g., PostgreSQL having a default limit of
+    // Don't confuse this with the JDBC ResultSet fetch size setting - this
+    // controls
+    // the where clause generation that is necessary to fetch specific records a
+    // page
+    // at a time. Some JDBC Drivers/Databases may have limits on statement
+    // length
+    // or complexity of the where clause - e.g., PostgreSQL having a default
+    // limit of
     // 10,000 nested expressions.
 
     /**
      * Creates a new IncrementalFaultList using a given DataContext and query.
      * 
-     * @param dataContext DataContext used by IncrementalFaultList to fill itself with
+     * @param dataContext
+     *            DataContext used by IncrementalFaultList to fill itself with
      *            objects.
-     * @param query Main query used to retrieve data. Must have "pageSize" property set to
-     *            a value greater than zero.
-     * @param maxFetchSize maximum number of fetches in one query
+     * @param query
+     *            Main query used to retrieve data. Must have "pageSize"
+     *            property set to a value greater than zero.
+     * @param maxFetchSize
+     *            maximum number of fetches in one query
      */
     public IncrementalFaultList(DataContext dataContext, Query query, int maxFetchSize) {
         QueryMetadata metadata = query.getMetaData(dataContext.getEntityResolver());
         if (metadata.getPageSize() <= 0) {
-            throw new CayenneRuntimeException("Not a paginated query; page size: "
-                    + metadata.getPageSize());
+            throw new CayenneRuntimeException("Not a paginated query; page size: " + metadata.getPageSize());
         }
 
         this.dataContext = dataContext;
@@ -106,8 +111,7 @@ public class IncrementalFaultList<E> imp
         this.rootEntity = metadata.getObjEntity();
 
         if (rootEntity == null) {
-            throw new CayenneRuntimeException(
-                    "Pagination is not supported for queries not rooted in an ObjEntity");
+            throw new CayenneRuntimeException("Pagination is not supported for queries not rooted in an ObjEntity");
         }
 
         // create an internal query, it is a partial replica of
@@ -133,8 +137,7 @@ public class IncrementalFaultList<E> imp
     IncrementalListHelper createHelper(QueryMetadata metadata) {
         if (metadata.isFetchingDataRows()) {
             return new DataRowListHelper();
-        }
-        else {
+        } else {
             return new PersistentListHelper();
         }
     }
@@ -147,8 +150,8 @@ public class IncrementalFaultList<E> imp
     }
 
     /**
-     * Performs initialization of the list of objects. Only the first page is fully
-     * resolved. For the rest of the list, only ObjectIds are read.
+     * Performs initialization of the list of objects. Only the first page is
+     * fully resolved. For the rest of the list, only ObjectIds are read.
      * 
      * @since 3.0
      */
@@ -156,23 +159,14 @@ public class IncrementalFaultList<E> imp
 
         elementsList.clear();
 
+        ResultIterator it = dataContext.performIteratedQuery(query);
         try {
-            long t1 = System.currentTimeMillis();
-            ResultIterator it = dataContext.performIteratedQuery(query);
-            try {
 
-                while (it.hasNextRow()) {
-                    elementsList.add(it.nextRow());
-                }
-            }
-            finally {
-                it.close();
+            while (it.hasNextRow()) {
+                elementsList.add(it.nextRow());
             }
-        }
-        catch (CayenneException e) {
-            throw new CayenneRuntimeException(
-                    "Error performing query.",
-                    Util.unwindException(e));
+        } finally {
+            it.close();
         }
 
         unfetchedObjects = elementsList.size();
@@ -186,8 +180,8 @@ public class IncrementalFaultList<E> imp
     }
 
     /**
-     * Checks that an object is of the same type as the rest of objects (DataObject or
-     * DataRows depending on the query type).
+     * Checks that an object is of the same type as the rest of objects
+     * (DataObject or DataRows depending on the query type).
      */
     private void validateListObject(Object object) throws IllegalArgumentException {
 
@@ -195,22 +189,19 @@ public class IncrementalFaultList<E> imp
 
         if (internalQuery.isFetchingDataRows()) {
             if (!(object instanceof Map)) {
-                throw new IllegalArgumentException(
-                        "Only Map objects can be stored in this list.");
+                throw new IllegalArgumentException("Only Map objects can be stored in this list.");
             }
-        }
-        else {
+        } else {
             if (!(object instanceof Persistent)) {
-                throw new IllegalArgumentException(
-                        "Only DataObjects can be stored in this list.");
+                throw new IllegalArgumentException("Only DataObjects can be stored in this list.");
             }
         }
     }
 
     /**
-     * Resolves a sublist of objects starting at <code>fromIndex</code> up to but not
-     * including <code>toIndex</code>. Internally performs bound checking and trims
-     * indexes accordingly.
+     * Resolves a sublist of objects starting at <code>fromIndex</code> up to
+     * but not including <code>toIndex</code>. Internally performs bound
+     * checking and trims indexes accordingly.
      */
     protected void resolveInterval(int fromIndex, int toIndex) {
         if (fromIndex >= toIndex) {
@@ -255,11 +246,8 @@ public class IncrementalFaultList<E> imp
             int fetchEnd = Math.min(qualsSize, fetchSize);
             int fetchBegin = 0;
             while (fetchBegin < qualsSize) {
-                SelectQuery<Object> query = new SelectQuery<Object>(
-                        rootEntity,
-                        ExpressionFactory.joinExp(
-                                Expression.OR,
-                                quals.subList(fetchBegin, fetchEnd)));
+                SelectQuery<Object> query = new SelectQuery<Object>(rootEntity, ExpressionFactory.joinExp(
+                        Expression.OR, quals.subList(fetchBegin, fetchEnd)));
 
                 query.setFetchingDataRows(fetchesDataRows);
 
@@ -309,11 +297,7 @@ public class IncrementalFaultList<E> imp
             // find missing ids
             StringBuilder buffer = new StringBuilder();
             buffer.append("Some ObjectIds are missing from the database. ");
-            buffer
-                    .append("Expected ")
-                    .append(ids.size())
-                    .append(", fetched ")
-                    .append(objects.size());
+            buffer.append("Expected ").append(ids.size()).append(", fetched ").append(objects.size());
 
             boolean first = true;
             for (Object id : ids) {
@@ -330,8 +314,7 @@ public class IncrementalFaultList<E> imp
                 if (!found) {
                     if (first) {
                         first = false;
-                    }
-                    else {
+                    } else {
                         buffer.append(", ");
                     }
 
@@ -340,17 +323,14 @@ public class IncrementalFaultList<E> imp
             }
 
             throw new CayenneRuntimeException(buffer.toString());
-        }
-        else if (objects.size() > ids.size()) {
-            throw new CayenneRuntimeException("Expected "
-                    + ids.size()
-                    + " objects, retrieved "
-                    + objects.size());
+        } else if (objects.size() > ids.size()) {
+            throw new CayenneRuntimeException("Expected " + ids.size() + " objects, retrieved " + objects.size());
         }
     }
 
     /**
-     * Returns zero-based index of the virtual "page" for a given array element index.
+     * Returns zero-based index of the virtual "page" for a given array element
+     * index.
      */
     public int pageIndex(int elementIndex) {
         if (elementIndex < 0 || elementIndex > size()) {
@@ -365,10 +345,11 @@ public class IncrementalFaultList<E> imp
     }
 
     /**
-     * Get the upper bound on the number of records to resolve in one round trip to the
-     * database. This setting governs the size/complexity of the where clause generated to
-     * retrieve the next page of records. If the fetch size is less than the page size,
-     * then multiple fetches will be made to resolve a page.
+     * Get the upper bound on the number of records to resolve in one round trip
+     * to the database. This setting governs the size/complexity of the where
+     * clause generated to retrieve the next page of records. If the fetch size
+     * is less than the page size, then multiple fetches will be made to resolve
+     * a page.
      */
     public int getMaxFetchSize() {
         return maxFetchSize;
@@ -397,21 +378,22 @@ public class IncrementalFaultList<E> imp
     }
 
     /**
-     * Returns a list iterator for this list. DataObjects are resolved a page (according
-     * to getPageSize()) at a time as necessary - when retrieved with next() or
-     * previous().
+     * Returns a list iterator for this list. DataObjects are resolved a page
+     * (according to getPageSize()) at a time as necessary - when retrieved with
+     * next() or previous().
      */
     public ListIterator<E> listIterator() {
         return new IncrementalListIterator(0);
     }
 
     /**
-     * Returns a list iterator of the elements in this list (in proper sequence), starting
-     * at the specified position in this list. The specified index indicates the first
-     * element that would be returned by an initial call to the next method. An initial
-     * call to the previous method would return the element with the specified index minus
-     * one. DataObjects are resolved a page at a time (according to getPageSize()) as
-     * necessary - when retrieved with next() or previous().
+     * Returns a list iterator of the elements in this list (in proper
+     * sequence), starting at the specified position in this list. The specified
+     * index indicates the first element that would be returned by an initial
+     * call to the next method. An initial call to the previous method would
+     * return the element with the specified index minus one. DataObjects are
+     * resolved a page at a time (according to getPageSize()) as necessary -
+     * when retrieved with next() or previous().
      */
     public ListIterator<E> listIterator(int index) {
         if (index < 0 || index > size()) {
@@ -422,8 +404,9 @@ public class IncrementalFaultList<E> imp
     }
 
     /**
-     * Return an iterator for this list. DataObjects are resolved a page (according to
-     * getPageSize()) at a time as necessary - when retrieved with next().
+     * Return an iterator for this list. DataObjects are resolved a page
+     * (according to getPageSize()) at a time as necessary - when retrieved with
+     * next().
      */
     public Iterator<E> iterator() {
         // by virtue of get(index)'s implementation, resolution of ids into
@@ -526,8 +509,7 @@ public class IncrementalFaultList<E> imp
                 resolveInterval(pageStart, pageStart + pageSize);
 
                 return (E) elements.get(index);
-            }
-            else {
+            } else {
                 return (E) o;
             }
         }
@@ -679,12 +661,12 @@ public class IncrementalFaultList<E> imp
         }
 
         /**
-         * Returns true if an object is not the type of object expected in the list. This
-         * method is not expected to perform thorough checking of the object type. What's
-         * important is the guarantee that an unresolved object representation will always
-         * return true for this method, and resolved will return false. Other types of
-         * objects that users may choose to add to the list will not be analyzed in
-         * detail.
+         * Returns true if an object is not the type of object expected in the
+         * list. This method is not expected to perform thorough checking of the
+         * object type. What's important is the guarantee that an unresolved
+         * object representation will always return true for this method, and
+         * resolved will return false. Other types of objects that users may
+         * choose to add to the list will not be analyzed in detail.
          */
         abstract boolean unresolvedSuspect(Object object);
 
@@ -701,10 +683,14 @@ public class IncrementalFaultList<E> imp
                 return true;
             }
 
-            // don't do a full check for object type matching the type of objects in the
-            // list... what's important is a quick "false" return if the object is of type
-            // representing unresolved objects.. furthermore, if inheritance is involved,
-            // we'll need an even more extensive check (see CAY-1142 on inheritance
+            // don't do a full check for object type matching the type of
+            // objects in the
+            // list... what's important is a quick "false" return if the object
+            // is of type
+            // representing unresolved objects.. furthermore, if inheritance is
+            // involved,
+            // we'll need an even more extensive check (see CAY-1142 on
+            // inheritance
             // issues).
 
             return false;
@@ -716,12 +702,8 @@ public class IncrementalFaultList<E> imp
             if (objectInTheList instanceof Persistent) {
                 // due to object uniquing this should be sufficient
                 return object == objectInTheList;
-            }
-            else {
-                return ((Persistent) object)
-                        .getObjectId()
-                        .getIdSnapshot()
-                        .equals(objectInTheList);
+            } else {
+                return ((Persistent) object).getObjectId().getIdSnapshot().equals(objectInTheList);
             }
         }
 

Added: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/ResultIteratorIterator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/ResultIteratorIterator.java?rev=1486133&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/ResultIteratorIterator.java (added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/ResultIteratorIterator.java Fri May 24 17:41:56 2013
@@ -0,0 +1,46 @@
+/*****************************************************************
+ *   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.access.jdbc;
+
+import java.util.Iterator;
+
+import org.apache.cayenne.access.ResultIterator;
+
+class ResultIteratorIterator<T> implements Iterator<T> {
+
+    private ResultIterator<T> parent;
+
+    ResultIteratorIterator(ResultIterator<T> parent) {
+        this.parent = parent;
+    }
+
+    public boolean hasNext() {
+        return parent.hasNextRow();
+    }
+
+    public T next() {
+        return parent.nextRow();
+    }
+
+    public void remove() {
+        // TODO: hmm... JDBC ResultSet does support in-place remove
+        throw new UnsupportedOperationException("'remove' is not supported");
+    }
+
+}

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/util/IteratedSelectObserver.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/util/IteratedSelectObserver.java?rev=1486133&r1=1486132&r2=1486133&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/util/IteratedSelectObserver.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/util/IteratedSelectObserver.java Fri May 24 17:41:56 2013
@@ -17,7 +17,6 @@
  *  under the License.
  ****************************************************************/
 
-
 package org.apache.cayenne.access.util;
 
 import java.io.IOException;
@@ -31,47 +30,46 @@ import org.apache.cayenne.access.ResultI
 import org.apache.cayenne.query.Query;
 
 /**
- * OperationObserver that is used to track the execution
- * of SelectQueries with results returned as ResultIterator.
- *  
+ * OperationObserver that is used to track the execution of SelectQueries with
+ * results returned as ResultIterator.
+ * 
  */
 public class IteratedSelectObserver extends DefaultOperationObserver {
-	protected ResultIterator resultIterator;
+    protected ResultIterator resultIterator;
 
-	@Override
+    @Override
     public boolean isIteratedResult() {
-		return true;
-	}
+        return true;
+    }
 
-	@Override
+    @Override
     public void nextRows(Query query, List<?> dataRows) {
-		throw new CayenneRuntimeException("Results unexpectedly returned as list.");
-	}
+        throw new CayenneRuntimeException("Results unexpectedly returned as list.");
+    }
 
-	@Override
+    @Override
     public void nextRows(Query q, ResultIterator it) {
-	    // don't call super - it closes the iterator
-		resultIterator = it;
-	}
-
-	public ResultIterator getResultIterator() throws CayenneException {
-		if (super.hasExceptions()) {
-			StringWriter str = new StringWriter();
-			PrintWriter out = new PrintWriter(str);
-			super.printExceptions(out);
-
-			try {
-				out.close();
-				str.close();
-			} catch (IOException ioex) {
-				// this should never happen
-			}
-
-			throw new CayenneException(
-				"Error getting ResultIterator: " + str.getBuffer());
-		}
+        // don't call super - it closes the iterator
+        resultIterator = it;
+    }
+
+    public ResultIterator getResultIterator() {
+        if (super.hasExceptions()) {
+            StringWriter str = new StringWriter();
+            PrintWriter out = new PrintWriter(str);
+            super.printExceptions(out);
+
+            try {
+                out.close();
+                str.close();
+            } catch (IOException ioex) {
+                // this should never happen
+            }
+
+            throw new CayenneRuntimeException("Error getting ResultIterator: " + str.getBuffer());
+        }
 
-		return resultIterator;
-	}
+        return resultIterator;
+    }
 
 }

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/MockBaseContext.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/MockBaseContext.java?rev=1486133&r1=1486132&r2=1486133&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/MockBaseContext.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/MockBaseContext.java Fri May 24 17:41:56 2013
@@ -69,10 +69,7 @@ public class MockBaseContext extends Bas
     }
 
     @Override
-    protected GraphDiff onContextFlush(
-            ObjectContext originatingContext,
-            GraphDiff changes,
-            boolean cascade) {
+    protected GraphDiff onContextFlush(ObjectContext originatingContext, GraphDiff changes, boolean cascade) {
         return null;
     }
 
@@ -114,9 +111,9 @@ public class MockBaseContext extends Bas
     public QueryResponse onQuery(ObjectContext originatingContext, Query query) {
         return null;
     }
-    
+
     @Override
-    public <T> ResultIterator<T> iterate(Select<T> query) {
+    protected <T> ResultIterator<T> iterator(Select<T> query) {
         return null;
     }
 

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/MockObjectContext.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/MockObjectContext.java?rev=1486133&r1=1486132&r2=1486133&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/MockObjectContext.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/MockObjectContext.java Fri May 24 17:41:56 2013
@@ -22,12 +22,10 @@ package org.apache.cayenne;
 import java.util.Collection;
 import java.util.List;
 
-import org.apache.cayenne.access.ResultIterator;
 import org.apache.cayenne.graph.GraphManager;
 import org.apache.cayenne.map.EntityResolver;
 import org.apache.cayenne.query.Query;
 import org.apache.cayenne.query.Select;
-import org.apache.cayenne.query.SelectQuery;
 
 /**
  * A noop ObjectContext used for unit testing.
@@ -88,7 +86,7 @@ public class MockObjectContext implement
     public <T> List<T> select(Select<T> query) {
         return performQuery(query);
     }
-    
+
     public int[] performNonSelectingQuery(Query query) {
         return null;
     }
@@ -109,23 +107,13 @@ public class MockObjectContext implement
     public void prepareForAccess(Persistent object, String property, boolean lazyFaulting) {
     }
 
-    public void propertyChanged(
-            Persistent persistent,
-            String property,
-            Object oldValue,
-            Object newValue) {
-    }
-
-    public void addedToCollectionProperty(
-            Persistent object,
-            String property,
-            Persistent added) {
-    }
-
-    public void removedFromCollectionProperty(
-            Persistent object,
-            String property,
-            Persistent removed) {
+    public void propertyChanged(Persistent persistent, String property, Object oldValue, Object newValue) {
+    }
+
+    public void addedToCollectionProperty(Persistent object, String property, Persistent added) {
+    }
+
+    public void removedFromCollectionProperty(Persistent object, String property, Persistent removed) {
     }
 
     public Collection uncommittedObjects() {
@@ -160,8 +148,8 @@ public class MockObjectContext implement
 
     public void setUserProperty(String key, Object value) {
     }
-    
-    public <T> ResultIterator<T> iterate(Select<T> query) {
-        return null;
+
+    public <T> void iterate(Select<T> query, ResultIteratorCallback<T> callback) {
+
     }
 }



Mime
View raw message