Skip to content

Commit

Permalink
Refactor the TCK serialization of results
Browse files Browse the repository at this point in the history
  • Loading branch information
Mats-SX committed May 18, 2016
1 parent ac56a78 commit 2e18243
Show file tree
Hide file tree
Showing 3 changed files with 194 additions and 99 deletions.
Expand Up @@ -88,109 +88,11 @@ public Map<String,Object> next()
Map<String,Object> next = inner.next(); Map<String,Object> next = inner.next();
builder.append( "[" ).append( rowCounter++ ).append( "] " ); builder.append( "[" ).append( rowCounter++ ).append( "] " );
builder.append( "actualRow:" ); builder.append( "actualRow:" );
builder.append( serialize( next ) ); builder.append( TckSerializer.serialize( next ) );
builder.append( "\n" ); builder.append( "\n" );
return next; return next;
} }


private String serialize( Object obj )
{
StringBuilder sb = new StringBuilder();
if ( obj == null )
{
sb.append( "null" );
}
else if ( obj instanceof Node )
{
Node n = (Node) obj;
sb.append( "(" );
n.getLabels().forEach( ( l ) -> sb.append( ":" ).append( l.name() ) );
sb.append( " {" );
String[] comma = new String[]{ "" };
n.getAllProperties().forEach( ( k, v ) -> {
sb.append( comma[0] ).append( k ).append( ": " ).append( serialize( v ) );
comma[0] = ", ";
} );
sb.append( "})" );
}
else if ( obj instanceof Relationship )
{
Relationship r = (Relationship) obj;
sb.append( "[:" );
sb.append( r.getType().name() );
sb.append( " {" );
String[] comma = new String[]{ "" };
r.getAllProperties().forEach( ( k, v ) -> {
sb.append( comma[0] ).append( k ).append( ": " ).append( serialize( v ) );
comma[0] = ", ";
} );
sb.append( "}]" );
}
else if ( obj instanceof Path )
{
Path p = (Path) obj;
sb.append( "<" );
sb.append( Paths.pathToString( p, new Paths.PathDescriptor<Path>()
{
@Override
public String nodeRepresentation( Path path, Node node )
{
return serialize( node );
}

@Override
public String relationshipRepresentation( Path path,
Node from, Relationship relationship )
{
String prefix = "-", suffix = "-";
if ( from.equals( relationship.getEndNode() ) )
{
prefix = "<-";
}
else
{
suffix = "->";
}
return prefix + serialize( relationship ) + suffix;
}
} ) );
sb.append( ">" );
}
else if ( obj instanceof String )
{
sb.append( "'" ).append( obj.toString() ).append( "'" );
}
else if ( obj instanceof List )
{
List<?> list = (List) obj;
List<String> output = new ArrayList<>( list.size() );
list.forEach( item -> output.add( serialize( item ) ) );
sb.append( output );
}
else if ( obj.getClass().isArray() )
{
List<Object> list = new ArrayList<>();
for ( int i = 0; i < Array.getLength( obj ); ++i )
{
list.add( Array.get( obj, i ) );
}
sb.append( serialize( list ) );
}
else if ( obj instanceof Map )
{
Map<?,?> map = (Map) obj;
Map<String,String> output = new HashMap<>( map.size() );
map.forEach( ( k, v ) -> output.put( k.toString(), serialize( v ) ) );
sb.append( output );
}
else
{
sb.append( obj.toString() );
}

return sb.toString();
}

@Override @Override
public void close() public void close()
{ {
Expand Down
@@ -0,0 +1,144 @@
/*
* Copyright (c) 2002-2016 "Neo Technology,"
* Network Engine for Objects in Lund AB [http://neotechnology.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cypher.feature.parser.matchers;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Path;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.traversal.Paths;

class TckSerializer
{
private final StringBuilder sb;

private TckSerializer( )
{
this.sb = new StringBuilder();
}

static String serialize( Object obj )
{
return new TckSerializer().innerSerialize( obj );
}

private String innerSerialize( Object obj )
{
if ( obj == null )
{
sb.append( "null" );
}
else if ( obj instanceof Node )
{
Node n = (Node) obj;
sb.append( "(" );
n.getLabels().forEach( ( l ) -> sb.append( ":" ).append( l.name() ) );
sb.append( " {" );
String[] comma = new String[]{ "" };
n.getAllProperties().forEach( ( k, v ) -> {
sb.append( comma[0] ).append( k ).append( ": " ).append( serialize( v ) );
comma[0] = ", ";
} );
sb.append( "})" );
}
else if ( obj instanceof Relationship )
{
Relationship r = (Relationship) obj;
sb.append( "[:" );
sb.append( r.getType().name() );
sb.append( " {" );
String[] comma = new String[]{ "" };
r.getAllProperties().forEach( ( k, v ) -> {
sb.append( comma[0] ).append( k ).append( ": " ).append( serialize( v ) );
comma[0] = ", ";
} );
sb.append( "}]" );
}
else if ( obj instanceof Path )
{
Path p = (Path) obj;
sb.append( "<" );
sb.append( Paths.pathToString( p, new Paths.PathDescriptor<Path>()
{
@Override
public String nodeRepresentation( Path path, Node node )
{
return serialize( node );
}

@Override
public String relationshipRepresentation( Path path,
Node from, Relationship relationship )
{
String prefix = "-", suffix = "-";
if ( from.equals( relationship.getEndNode() ) )
{
prefix = "<-";
}
else
{
suffix = "->";
}
return prefix + serialize( relationship ) + suffix;
}
} ) );
sb.append( ">" );
}
else if ( obj instanceof String )
{
sb.append( "'" ).append( obj.toString() ).append( "'" );
}
else if ( obj instanceof List )
{
List<?> list = (List) obj;
List<String> output = new ArrayList<>( list.size() );
list.forEach( item -> output.add( serialize( item ) ) );
sb.append( output );
}
else if ( obj.getClass().isArray() )
{
List<Object> list = new ArrayList<>();
for ( int i = 0; i < Array.getLength( obj ); ++i )
{
list.add( Array.get( obj, i ) );
}
sb.append( serialize( list ) );
}
else if ( obj instanceof Map )
{
Map<?,?> map = (Map) obj;
Map<String,String> output = new HashMap<>( map.size() );
map.forEach( ( k, v ) -> output.put( k.toString(), serialize( v ) ) );
sb.append( output );
}
else
{
sb.append( obj.toString() );
}

return sb.toString();
}

}
@@ -0,0 +1,49 @@
/*
* Copyright (c) 2002-2016 "Neo Technology,"
* Network Engine for Objects in Lund AB [http://neotechnology.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cypher.feature.parser.matchers

import scala.collection.JavaConverters._
import org.scalatest.{FunSuite, Matchers}

class TckSerializerTest extends FunSuite with Matchers {

test("should serialize primitives") {
serialize(true) should equal("true")
serialize(1) should equal("1")
serialize("1") should equal("'1'")
serialize(1.5) should equal("1.5")
serialize(null) should equal("null")
}

test("should serialize lists") {
serialize(List.empty.asJava) should equal("[]")
serialize(List(1).asJava) should equal("[1]")
serialize(List("1", 1, 1.0).asJava) should equal("['1', 1, 1.0]")
serialize(List(List("foo").asJava).asJava) should equal("[['foo']]")
}

test("should serialize maps") {
serialize(Map.empty.asJava) should equal("{}")
serialize(Map("key" -> true, "key2" -> 1000).asJava) should equal("{key2=1000, key=true}")
serialize(Map("key" -> Map("inner" -> 50.0).asJava, "key2" -> List("foo").asJava).asJava) should equal("{key2=['foo'], key={inner=50.0}}")
}

private def serialize(v: Any) = TckSerializer.serialize(v)
}

0 comments on commit 2e18243

Please sign in to comment.