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 2010/11/09 04:07:19 UTC
svn commit: r1032831 - in /cayenne/main/branches/STABLE-3.0:
docs/doc/src/main/resources/RELEASE-NOTES.txt
framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/CayenneDataObject.java
Author: aadamchik
Date: Tue Nov 9 03:07:19 2010
New Revision: 1032831
URL: http://svn.apache.org/viewvc?rev=1032831&view=rev
Log:
CAY-1403 Method "readNestedProperty" Should Resolve Through Iterative Invocations onto DataObject and Not Complete Within Cayenne.readNestedProperty
* patch by Andrew Lindesay with minimal edits by aadamchik
Modified:
cayenne/main/branches/STABLE-3.0/docs/doc/src/main/resources/RELEASE-NOTES.txt
cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/CayenneDataObject.java
Modified: cayenne/main/branches/STABLE-3.0/docs/doc/src/main/resources/RELEASE-NOTES.txt
URL: http://svn.apache.org/viewvc/cayenne/main/branches/STABLE-3.0/docs/doc/src/main/resources/RELEASE-NOTES.txt?rev=1032831&r1=1032830&r2=1032831&view=diff
==============================================================================
--- cayenne/main/branches/STABLE-3.0/docs/doc/src/main/resources/RELEASE-NOTES.txt (original)
+++ cayenne/main/branches/STABLE-3.0/docs/doc/src/main/resources/RELEASE-NOTES.txt Tue Nov 9 03:07:19 2010
@@ -18,6 +18,7 @@ CAY-1500 MySQL JDBC Batching
Bug Fixes Since 3.0.1:
+CAY-1403 Method "readNestedProperty" Should Resolve Through Iterative Invocations onto DataObject and Not Complete Within Cayenne.readNestedProperty
CAY-1484 Flattened attribute queries are incorrectly generated
CAY-1485 Memory information for about dialog
CAY-1488 OutOfMemory when selecting "Remove Foreign Keys Mapped as Object Attributes"
Modified: cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/CayenneDataObject.java
URL: http://svn.apache.org/viewvc/cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/CayenneDataObject.java?rev=1032831&r1=1032830&r2=1032831&view=diff
==============================================================================
--- cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/CayenneDataObject.java (original)
+++ cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/CayenneDataObject.java Tue Nov 9 03:07:19 2010
@@ -30,7 +30,6 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.StringTokenizer;
import org.apache.cayenne.access.DataContext;
import org.apache.cayenne.conf.Configuration;
@@ -111,57 +110,77 @@ public class CayenneDataObject extends P
}
public Object readNestedProperty(String path) {
- 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 ((null == path) || (0 == path.length())) {
+ throw new IllegalArgumentException(
+ "the path must be supplied in order to lookup a nested property");
+ }
- if (tokenIndex == tokenizedPath.length - 1) { //last component
- return property;
+ int dotIndex = path.indexOf('.');
+
+ if (0 == dotIndex) {
+ throw new IllegalArgumentException(
+ "the path is invalid because it starts with a period character");
}
-
- pathIndex += tokenizedPath[tokenIndex].length() + 1;
+
+ if (dotIndex == path.length() - 1) {
+ throw new IllegalArgumentException(
+ "the path is invalid because it ends with a period character");
+ }
+
+ if (-1 == dotIndex) {
+ return readSimpleProperty(path);
+ }
+
+ String path0 = path.substring(0, dotIndex);
+ String pathRemainder = path.substring(dotIndex + 1);
+
+ // this is copied from the old code where the placement of a plus
+ // character at the end of a segment of a property path would
+ // simply strip out the plus. I am not entirely sure why this is
+ // done. See unit test 'testReadNestedPropertyToManyInMiddle1'.
+
+ if ('+' == path0.charAt(path0.length() - 1)) {
+ path0 = path0.substring(0, path0.length() - 1);
+ }
+
+ Object property = readSimpleProperty(path0);
+
if (property == null) {
return null;
}
- else if (property instanceof CayenneDataObject) {
- return readNestedProperty((CayenneDataObject) property, path, tokenizedPath, tokenIndex + 1,
- tokenIndex);
+ else if (property instanceof DataObject) {
+ DataObject cdo = (DataObject) property;
+ return cdo.readNestedProperty(pathRemainder);
}
else if (property instanceof Collection) {
-
- // CAY-1402
- // This is back-ported from 3.1's trunk and from the Cayenne utility
- // object. This will allow people to put @size at the end of a property
- // path and be able to find out the size of a relationship.
-
+
+ // CAY-1402
+ // This is back-ported from 3.1's trunk and from the Cayenne utility
+ // object. This will allow people to put @size at the end of a property
+ // path and be able to find out the size of a relationship.
+
Collection<?> collection = (Collection) property;
-
- if (tokenIndex < tokenizedPath.length - 1) {
- if (tokenizedPath[tokenIndex + 1].equals(PROPERTY_COLLECTION_SIZE)) {
- return collection.size();
- }
- }
-
+
+ if (pathRemainder.equals(PROPERTY_COLLECTION_SIZE))
+ return new Integer(collection.size());
+
/**
* Support for collection property in the middle of the path
*/
- Collection<Object> result = property instanceof List ?
- new ArrayList<Object>() : new HashSet<Object>() ;
+ 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);
+ CayenneDataObject cdo = (CayenneDataObject) obj;
+ Object rest = cdo.readNestedProperty(pathRemainder);
+
if (rest instanceof Collection) {
/**
- * We don't want nested collections.
- * E.g. readNestedProperty("paintingArray.paintingTitle") should return List<String>
+ * We don't want nested collections. E.g.
+ * readNestedProperty("paintingArray.paintingTitle") should return
+ * List<String>
*/
result.addAll((Collection<?>) rest);
}
@@ -174,42 +193,12 @@ public class CayenneDataObject extends P
}
else {
// read the rest of the path via introspection
- return PropertyUtils.getProperty(property, path.substring(pathIndex));
- }
- }
-
- private static final String[] tokenizePath(String path) {
- if (path == null) {
- throw new NullPointerException("Null property path.");
- }
-
- if (path.length() == 0) {
- throw new IllegalArgumentException("Empty property path.");
- }
-
- // take a shortcut for simple properties
- if (!path.contains(".")) {
- return new String[] {
- path
- };
- }
-
- StringTokenizer tokens = new StringTokenizer(path, ".");
- int length = tokens.countTokens();
- String[] tokenized = new String[length];
- for (int i = 0; i < length; i++) {
- String temp = tokens.nextToken();
- if(temp.endsWith("+")){
- tokenized[i] = temp.substring(0, temp.length() - 1);
- }
- else{
- tokenized[i] = temp;
- }
+ return PropertyUtils.getProperty(property, pathRemainder);
}
- return tokenized;
}
private final Object readSimpleProperty(String property) {
+
// side effect - resolves HOLLOW object
Object object = readProperty(property);