You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by an...@apache.org on 2009/04/11 10:39:12 UTC

svn commit: r764184 - in /cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src: main/java/org/apache/cayenne/CayenneDataObject.java main/java/org/apache/cayenne/DataObject.java test/java/org/apache/cayenne/CayenneDataObjectTest.java

Author: andrey
Date: Sat Apr 11 08:39:11 2009
New Revision: 764184

URL: http://svn.apache.org/viewvc?rev=764184&view=rev
Log:
CAY-816 Improve readNestedProperty() to handle to-many relationships in the path.

Modified:
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/CayenneDataObject.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/DataObject.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/CayenneDataObjectTest.java

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/CayenneDataObject.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/CayenneDataObject.java?rev=764184&r1=764183&r2=764184&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/CayenneDataObject.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/CayenneDataObject.java Sat Apr 11 08:39:11 2009
@@ -23,8 +23,10 @@
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.lang.reflect.Array;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -72,6 +74,7 @@
      * 
      * @deprecated since 3.0 use {@link #getObjectContext()}.
      */
+    @Deprecated
     public DataContext getDataContext() {
         if (objectContext == null || objectContext instanceof DataContext) {
             return (DataContext) objectContext;
@@ -86,6 +89,7 @@
      * 
      * @deprecated since 3.0 use {@link #setObjectContext(ObjectContext)}.
      */
+    @Deprecated
     public void setDataContext(DataContext dataContext) {
         this.objectContext = dataContext;
 
@@ -127,31 +131,57 @@
     }
 
     public Object readNestedProperty(String path) {
-        Object object = null;
-        CayenneDataObject dataObject = this;
-        String[] tokenized = tokenizePath(path);
-        int length = tokenized.length;
-
-        int pathIndex = 0;
-
-        for (int i = 0; i < length; i++) {
-            pathIndex += tokenized[i].length() + 1;
-
-            object = dataObject.readSimpleProperty(tokenized[i]);
-
-            if (object == null) {
-                return null;
-            }
-            else if (object instanceof CayenneDataObject) {
-                dataObject = (CayenneDataObject) object;
-            }
-            else if (i + 1 < length) {
-                // read the rest of the path via introspection
-                return PropertyUtils.getProperty(object, path.substring(pathIndex));
+        return readNestedProperty(this, path, tokenizePath(path), 0, 0);
+    }
+    
+    /**
+     * Recursively resolves nested property path 
+     */
+    private static Object readNestedProperty(CayenneDataObject dataObject, 
+        String path, String[] tokenizedPath, int tokenIndex, int pathIndex) {
+        
+        Object property = dataObject.readSimpleProperty(tokenizedPath[tokenIndex]);
+
+        if (tokenIndex == tokenizedPath.length - 1) { //last component
+            return property;
+        }
+        
+        pathIndex += tokenizedPath[tokenIndex].length() + 1;
+        if (property == null) {
+            return null;
+        }
+        else if (property instanceof CayenneDataObject) {
+            return readNestedProperty((CayenneDataObject) property, path, tokenizedPath, tokenIndex + 1,
+                tokenIndex);
+        }
+        else if (property instanceof Collection) {
+            /**
+             * Support for collection property in the middle of the path
+             */
+            Collection<Object> result = property instanceof List ?
+                    new ArrayList<Object>() : new HashSet<Object>() ;
+            for (Object obj : (Collection) property) {
+                if (obj instanceof CayenneDataObject) {
+                    Object rest = readNestedProperty((CayenneDataObject) obj, path, tokenizedPath, 
+                            tokenIndex + 1, tokenIndex);
+                    if (rest instanceof Collection) {
+                        /**
+                         * We don't want nested collections.
+                         * E.g. readNestedProperty("paintingArray.paintingTitle") should return List<String>
+                         */
+                        result.addAll((Collection) rest);
+                    }
+                    else {
+                        result.add(rest);
+                    }
+                }
             }
+            return result;
+        }
+        else {
+            // read the rest of the path via introspection
+            return PropertyUtils.getProperty(property, path.substring(pathIndex));
         }
-
-        return object;
     }
 
     private static final String[] tokenizePath(String path) {
@@ -471,6 +501,7 @@
      * @deprecated since 3.0 use callbacks.
      * @see LifecycleListener
      */
+    @Deprecated
     public void fetchFinished() {
     }
 

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/DataObject.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/DataObject.java?rev=764184&r1=764183&r2=764184&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/DataObject.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/DataObject.java Sat Apr 11 08:39:11 2009
@@ -35,6 +35,7 @@
      * 
      * @deprecated since 3.0 use {@link #getObjectContext()}.
      */
+    @Deprecated
     public DataContext getDataContext();
 
     /**
@@ -42,6 +43,7 @@
      * 
      * @deprecated since 3.0 use {@link #setObjectContext(ObjectContext)}.
      */
+    @Deprecated
     public void setDataContext(DataContext ctxt);
 
     /**
@@ -93,8 +95,8 @@
      * <br>
      * <br>
      * </li>
-     * <li>Read to-many relationship in the middle of the path <b>(throws exception)</b>:<br>
-     * <code>String name = (String)artist.readNestedProperty("paintingArray.paintingName");</code>
+     * <li>Read to-many relationship in the middle of the path:<br>
+     * <code>List<String> names = (List<String>)artist.readNestedProperty("paintingArray.paintingName");</code>
      * <br>
      * <br>
      * </li>
@@ -153,6 +155,7 @@
      *             invoked by Cayenne runtime.
      * @see LifecycleListener
      */
+    @Deprecated
     public void fetchFinished();
 
     /**

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/CayenneDataObjectTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/CayenneDataObjectTest.java?rev=764184&r1=764183&r2=764184&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/CayenneDataObjectTest.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/CayenneDataObjectTest.java Sat Apr 11 08:39:11 2009
@@ -19,9 +19,13 @@
 
 package org.apache.cayenne;
 
+import java.util.List;
+
 import junit.framework.TestCase;
 
 import org.apache.art.Artist;
+import org.apache.art.ArtistExhibit;
+import org.apache.art.Painting;
 import org.apache.cayenne.access.DataContext;
 import org.apache.cayenne.unit.util.TestBean;
 
@@ -48,6 +52,7 @@
     /**
      * @deprecated since 3.0.
      */
+    @Deprecated
     public void testSetDataContext() throws Exception {
         CayenneDataObject obj = new CayenneDataObject();
         assertNull(obj.getDataContext());
@@ -90,4 +95,27 @@
         assertEquals(TestBean.class, o1.readNestedProperty("o2.class"));
         assertEquals(TestBean.class.getName(), o1.readNestedProperty("o2.class.name"));
     }
+    
+    public void testReadNestedPropertyToManyInMiddle() throws Exception {
+        DataContext context = DataContext.createDataContext();
+        
+        Artist a = context.newObject(Artist.class);
+        ArtistExhibit ex = context.newObject(ArtistExhibit.class);
+        Painting p1 = context.newObject(Painting.class);
+        Painting p2 = context.newObject(Painting.class);
+        p1.setPaintingTitle("p1");
+        p2.setPaintingTitle("p2");
+        a.addToPaintingArray(p1);
+        a.addToPaintingArray(p2);
+        ex.setToArtist(a);
+        
+        List<String> names = (List<String>) a.readNestedProperty("paintingArray.paintingTitle");
+        assertEquals(names.size(), 2);
+        assertEquals(names.get(0), "p1");
+        assertEquals(names.get(1), "p2");
+        
+        List<String> names2 = (List<String>) 
+            ex.readNestedProperty("toArtist.paintingArray.paintingTitle");
+        assertEquals(names, names2);
+    }
 }