Skip to content

Commit

Permalink
Support returning new types when using resultDataContents: "rest""
Browse files Browse the repository at this point in the history
Fixes #12036
  • Loading branch information
pontusmelke committed Oct 12, 2018
1 parent 29f2a4c commit 0b19162
Show file tree
Hide file tree
Showing 8 changed files with 244 additions and 17 deletions.
Expand Up @@ -19,12 +19,18 @@
*/
package org.neo4j.server.helpers;

import java.time.temporal.Temporal;
import java.time.temporal.TemporalAmount;
import java.util.Iterator;
import java.util.Map;

import org.neo4j.graphdb.PropertyContainer;
import org.neo4j.graphdb.spatial.Geometry;
import org.neo4j.graphdb.spatial.Point;
import org.neo4j.helpers.collection.ArrayIterator;

import static org.neo4j.helpers.collection.MapUtil.genericMap;

/*
* THIS CLASS SHOULD BE MOVED TO KERNEL ASAP!!!
*/
Expand Down Expand Up @@ -75,6 +81,18 @@ else if ( property instanceof Character )
{
return dispatchCharacterProperty( (Character) property, param );
}
else if ( property instanceof Point )
{
return dispatchPointProperty( (Point) property, param );
}
else if ( property instanceof Temporal )
{
return dispatchTemporalProperty( (Temporal) property, param );
}
else if ( property instanceof TemporalAmount )
{
return dispatchTemporalAmountProperty( (TemporalAmount) property, param );
}
else if ( property instanceof String[] )
{
return dispatchStringArrayProperty( (String[]) property, param );
Expand Down Expand Up @@ -240,6 +258,12 @@ protected T dispatchNullProperty( K param )
@SuppressWarnings( "boxing" )
protected abstract T dispatchBooleanProperty( boolean property, K param );

protected abstract T dispatchPointProperty( Point property, K param );

protected abstract T dispatchTemporalProperty( Temporal property, K param );

protected abstract T dispatchTemporalAmountProperty( TemporalAmount property, K param );

protected T dispatchOtherProperty( Object property, K param )
{
throw new IllegalArgumentException( "Unsupported property type: "
Expand Down
Expand Up @@ -19,6 +19,13 @@
*/
package org.neo4j.server.rest.repr;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetTime;
import java.time.ZonedDateTime;
import java.time.temporal.Temporal;
import java.time.temporal.TemporalAmount;
import java.util.HashMap;
import java.util.Map;

Expand All @@ -29,6 +36,9 @@
import org.neo4j.graphdb.RelationshipType;
import org.neo4j.graphdb.schema.ConstraintDefinition;
import org.neo4j.graphdb.schema.IndexDefinition;
import org.neo4j.graphdb.spatial.Geometry;
import org.neo4j.graphdb.spatial.Point;
import org.neo4j.values.storable.DateTimeValue;

public final class RepresentationType
{
Expand Down Expand Up @@ -76,6 +86,9 @@ public final class RepresentationType
public static final RepresentationType URI = new RepresentationType( "uri", null );
public static final RepresentationType TEMPLATE = new RepresentationType( "uri-template" );
public static final RepresentationType STRING = new RepresentationType( "string", "strings", String.class );
public static final RepresentationType POINT = new RepresentationType( "point", "points", Point.class );
public static final RepresentationType TEMPORAL = new RepresentationType( "temporal", "temporals", Temporal.class );
public static final RepresentationType TEMPORAL_AMOUNT = new RepresentationType( "temporal-amount", "temporal-amounts", TemporalAmount.class );
public static final RepresentationType BYTE = new RepresentationType( "byte", "bytes", byte.class );
public static final RepresentationType CHAR = new RepresentationType( "character", "characters", char.class );
public static final RepresentationType SHORT = new RepresentationType( "short", "shorts", short.class );
Expand Down
Expand Up @@ -20,8 +20,14 @@
package org.neo4j.server.rest.repr;

import java.net.URI;
import java.time.temporal.Temporal;
import java.time.temporal.TemporalAmount;

import org.neo4j.graphdb.RelationshipType;
import org.neo4j.graphdb.spatial.CRS;
import org.neo4j.graphdb.spatial.Coordinate;
import org.neo4j.graphdb.spatial.Geometry;
import org.neo4j.graphdb.spatial.Point;
import org.neo4j.helpers.collection.IterableWrapper;
import org.neo4j.server.helpers.PropertyTypeDispatcher;

Expand Down Expand Up @@ -155,6 +161,24 @@ protected Representation dispatchBooleanProperty( boolean property, Void param )
return bool( property );
}

@Override
protected Representation dispatchPointProperty( Point point, Void param )
{
return new ValueRepresentation( RepresentationType.POINT, point );
}

@Override
protected Representation dispatchTemporalProperty( Temporal temporal, Void param )
{
return new ValueRepresentation( RepresentationType.TEMPORAL, temporal );
}

@Override
protected Representation dispatchTemporalAmountProperty( TemporalAmount temporalAmount, Void param )
{
return new ValueRepresentation( RepresentationType.TEMPORAL_AMOUNT, temporalAmount );
}

@Override
protected Representation dispatchByteProperty( byte property, Void param )
{
Expand Down
Expand Up @@ -19,7 +19,14 @@
*/
package org.neo4j.server.rest.repr;

import java.time.temporal.Temporal;
import java.time.temporal.TemporalAmount;

import org.neo4j.graphdb.PropertyContainer;
import org.neo4j.graphdb.spatial.CRS;
import org.neo4j.graphdb.spatial.Coordinate;
import org.neo4j.graphdb.spatial.Geometry;
import org.neo4j.graphdb.spatial.Point;
import org.neo4j.server.helpers.PropertyTypeDispatcher;

public final class PropertiesRepresentation extends MappingRepresentation
Expand Down Expand Up @@ -67,6 +74,51 @@ protected Void dispatchBooleanProperty( boolean property, String param )
return null;
}

@Override
protected Void dispatchPointProperty( Point property, String param )
{
MappingWriter pointWriter = writer.newMapping( RepresentationType.POINT, param );

pointWriter.writeString( "type", property.getGeometryType() );

//write coordinates
ListWriter coordinatesWriter = pointWriter.newList( RepresentationType.DOUBLE, "coordinates" );
for ( Double coordinate : property.getCoordinate().getCoordinate() )
{
coordinatesWriter.writeFloatingPointNumber( RepresentationType.DOUBLE, coordinate );
}
coordinatesWriter.done();

//Write coordinate reference system
CRS crs = property.getCRS();
MappingWriter crsWriter = pointWriter.newMapping( RepresentationType.MAP, "crs" );
crsWriter.writeInteger( RepresentationType.INTEGER, "srid", crs.getCode() );
crsWriter.writeString( "name", crs.getType() );
crsWriter.writeString( "type", "link" );
MappingWriter propertiesWriter = crsWriter.newMapping( Representation.MAP, "properties" );
propertiesWriter.writeString( "href", crs.getHref() + "ogcwkt/" );
propertiesWriter.writeString( "type","ogcwkt" );
propertiesWriter.done();
crsWriter.done();

pointWriter.done();
return null;
}

@Override
protected Void dispatchTemporalProperty( Temporal property, String param )
{
writer.writeString( param, property.toString() );
return null;
}

@Override
protected Void dispatchTemporalAmountProperty( TemporalAmount property, String param )
{
writer.writeString( param, property.toString() );
return null;
}

@Override
protected Void dispatchByteProperty( byte property, String param )
{
Expand Down
Expand Up @@ -19,10 +19,15 @@
*/
package org.neo4j.server.rest.repr;

import java.time.temporal.Temporal;
import java.time.temporal.TemporalAmount;
import java.util.ArrayList;
import java.util.LinkedHashMap;

import org.neo4j.graphdb.spatial.Point;
import org.neo4j.server.helpers.PropertyTypeDispatcher;

import static org.neo4j.helpers.collection.MapUtil.genericMap;
import static org.neo4j.server.rest.repr.ValueRepresentation.bool;
import static org.neo4j.server.rest.repr.ValueRepresentation.number;
import static org.neo4j.server.rest.repr.ValueRepresentation.string;
Expand Down Expand Up @@ -139,7 +144,7 @@ protected Representation dispatchFloatArrayProperty( PropertyArray<float[], Floa

@Override
@SuppressWarnings( "boxing" )
protected Representation dispatchDoubleArrayProperty( PropertyArray<double[], Double> array, String param )
protected Representation dispatchDoubleArrayProperty( PropertyArray<double[], Double> array, String parfam )
{
ArrayList<Representation> values = new ArrayList<>();
for ( Double z : array )
Expand Down Expand Up @@ -167,6 +172,26 @@ protected Representation dispatchByteProperty( byte property, String param )
throw new UnsupportedOperationException( "Representing bytes not implemented." );
}

@Override
protected Representation dispatchPointProperty( Point property, String param )
{
return new MapRepresentation(
genericMap( new LinkedHashMap<>(), "type", property.getGeometryType(), "coordinates",
property.getCoordinate(), "crs", property.getCRS() ) );
}

@Override
protected Representation dispatchTemporalProperty( Temporal property, String param )
{
return string( property.toString() );
}

@Override
protected Representation dispatchTemporalAmountProperty( TemporalAmount property, String param )
{
return string( property.toString() );
}

@Override
protected Representation dispatchCharacterProperty( char property, String param )
{
Expand Down
Expand Up @@ -24,8 +24,10 @@
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
import java.util.stream.Collectors;
import javax.ws.rs.core.Response.Status;

import org.neo4j.graphdb.GraphDatabaseService;
Expand All @@ -44,6 +46,7 @@

import static java.lang.String.format;
import static java.net.URLEncoder.encode;
import static java.util.stream.Collectors.joining;
import static org.junit.Assert.assertEquals;
import static org.neo4j.server.rest.domain.JsonHelper.createJsonFrom;
import static org.neo4j.server.rest.web.Surface.PATH_NODES;
Expand Down Expand Up @@ -287,9 +290,15 @@ public static int getLocalHttpPort()
return connectorPortRegister.getLocalAddress( "http" ).getPort();
}

public static HTTP.Response runQuery( String query )
public static HTTP.Response runQuery( String query, String...contentTypes )
{
return POST( txCommitUri(), quotedJson( "{'statements': [{'statement': '" + query + "'}]}" ) );
String resultDataContents = "";
if (contentTypes.length > 0 )
{
resultDataContents = ", 'resultDataContents': [" + Arrays.stream( contentTypes )
.map( unquoted -> format( "'%s'", unquoted ) ).collect( joining( "," ) ) + "]";
}
return POST( txCommitUri(), quotedJson( format( "{'statements': [{'statement': '%s'%s}]}", query, resultDataContents) ) );
}

public static void assertNoErrors( HTTP.Response response ) throws JsonParseException
Expand Down
Expand Up @@ -90,21 +90,49 @@ public void shouldHandlePointArrays() throws Exception
try ( Transaction tx = db.beginTx() )
{
Node node = db.createNode( label( "N" ) );
//node.setProperty( "coordinates", new double[]{30.655691, 104.081602} );
node.setProperty( "coordinates", new Point[]{pointValue( WGS84, 30.655691, 104.081602 )} );
node.setProperty( "location", "Shanghai" );
node.setProperty( "type", "gps" );
tx.success();
}

// When
//When
HTTP.Response response = runQuery( "MATCH (n:N) RETURN n" );

assertEquals( 200, response.status() );
assertNoErrors( response );

JsonNode data = response.get( "results" ).get( 0 ).get( "data" ).get(0);
JsonNode row = data.get( "row" ).get(0).get( "coordinates" ).get(0);
//Then
JsonNode row = response.get( "results" ).get( 0 ).get( "data" ).get( 0 ).get( "row" ).get( 0 )
.get( "coordinates" ).get( 0 );
assertGeometryTypeEqual( GeometryType.GEOMETRY_POINT, row );
assertCoordinatesEqual( new double[]{30.655691, 104.081602}, row );
assertCrsEqual( WGS84, row );
}

@Test
public void shouldHandlePointsUsingRestResultDataContent() throws Exception
{
//Given
GraphDatabaseFacade db = server().getDatabase().getGraph();
try ( Transaction tx = db.beginTx() )
{
Node node = db.createNode( label( "N" ) );
node.setProperty( "coordinates", pointValue( WGS84, 30.655691, 104.081602 ) );
node.setProperty( "location", "Shanghai" );
node.setProperty( "type", "gps" );
tx.success();
}

//When
HTTP.Response response = runQuery( "MATCH (n:N) RETURN n", "rest" );

assertEquals( 200, response.status() );
assertNoErrors( response );

//Then
JsonNode row = response.get( "results" ).get( 0 ).get( "data" ).get( 0 ).get( "rest" )
.get( 0 ).get( "data" ).get( "coordinates" );
assertGeometryTypeEqual( GeometryType.GEOMETRY_POINT, row );
assertCoordinatesEqual( new double[]{30.655691, 104.081602}, row );
assertCrsEqual( WGS84, row );
Expand Down

0 comments on commit 0b19162

Please sign in to comment.