Donate Share

Flexjson

Tracker: Bugs

5 Bug in PathMatcher for recursive objects - ID: 1904154
Last Update: Attachment added ( bitmeizer )

Great library - just one problem I have found.

When attempting to output all descendents of an object via property which
has the same name in each decendent, the matcher fails to recognise the
pattern correctly. For example, given the following structure:

public class Person {
private String name;
private List<Person> children;

public String getName() {
return name;
}

public List<Person> getChildren() {
return children;
}
}

I would like to have the library serialise the original person and all it's
decendents. I would expect this to work:

String output = new JSONSerializer().include( "*.children" ).serialize();

This works for the original object, and will output their immediate
children, but will not list any of the 2nd generation. Eg, it might look
something like this:

{"name":"Bob","children":[{"name":"Jane"},{"name":"Will"}]}

The 'children' property doesn't show up for the 2nd generation.

I tracked the problem down to the 'match' method in PathMatcher. The path
for the second generation is 'children.children'. It would match the first
'children' step in the path and then fail because of the second one.

A corrected version is here:

public boolean matches( Path path ) {
int exprCurrentIndex = 0;
int exprStartIndex = 0;
int pathCurrentIndex = 0;
int pathStartIndex = 0;
boolean wildcard = false;
while( pathCurrentIndex < path.length() ) {
String current = path.getPath().get( pathCurrentIndex );
if( exprCurrentIndex < expression.length &&
expression[exprCurrentIndex].equals("*") ) {
wildcard = true;
exprCurrentIndex++;
exprStartIndex = exprCurrentIndex;
pathStartIndex = pathCurrentIndex;
} else if( exprCurrentIndex < expression.length &&
expression[exprCurrentIndex].equals( current ) ) {
pathCurrentIndex++;
exprCurrentIndex++;
} else if ( wildcard ) { // this match failed - try again one
further step up the path
exprCurrentIndex = exprStartIndex;
pathCurrentIndex = ++pathStartIndex;
} else {
return false;
}

}
if( exprCurrentIndex > 0 &&
expression[exprCurrentIndex-1].equals("*") ) {
return pathCurrentIndex >= path.length() && exprCurrentIndex >=
expression.length;
} else {
return pathCurrentIndex >= path.length() && path.length() > 0;
}
}

I've attached a zip file which contains the source from flexjson 1.6 with
the above fix, as well as an updated test class for PathMatcher which
checks some extra cases which are similar to the above. I hope it's useful.


David Peterson ( bitmeizer ) - 2008-02-28 18:10

5

Open

None

Nobody/Anonymous

None

None

Public


Comments




Log in to comment.

No follow-up comments have been posted.

Attached File ( 1 )

Filename Description Download
flexjson-1.7-SNAPSHOT-sources.zip Updated source code Download

Change ( 1 )

Field Old Value Date By
File Added 268476: flexjson-1.7-SNAPSHOT-sources.zip 2008-02-28 18:10 bitmeizer