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);
+ }
}