View Javadoc

    1   /**
    2    * Copyright (c) 2002-2011 "Neo Technology,"
    3    * Network Engine for Objects in Lund AB [http://neotechnology.com]
    4    *
    5    * This file is part of Neo4j.
    6    *
    7    * Neo4j is free software: you can redistribute it and/or modify
    8    * it under the terms of the GNU General Public License as published by
    9    * the Free Software Foundation, either version 3 of the License, or
    10   * (at your option) any later version.
    11   *
    12   * This program is distributed in the hope that it will be useful,
    13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    15   * GNU General Public License for more details.
    16   *
    17   * You should have received a copy of the GNU General Public License
    18   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    19   */
    20  package org.neo4j.server.rest.web;
    21
    22  import org.neo4j.graphdb.GraphDatabaseService;
    23  import org.neo4j.graphdb.Node;
    24  import org.neo4j.graphdb.NotFoundException;
    25  import org.neo4j.graphdb.Relationship;
    26  import org.neo4j.kernel.AbstractGraphDatabase;
    27  import org.neo4j.server.database.Database;
    28  import org.neo4j.server.plugins.BadPluginInvocationException;
    29  import org.neo4j.server.plugins.ParameterList;
    30  import org.neo4j.server.plugins.PluginInvocationFailureException;
    31  import org.neo4j.server.plugins.PluginInvocator;
    32  import org.neo4j.server.plugins.PluginLookupException;
    33  import org.neo4j.server.rest.repr.BadInputException;
    34  import org.neo4j.server.rest.repr.InputFormat;
    35  import org.neo4j.server.rest.repr.MappingRepresentation;
    36  import org.neo4j.server.rest.repr.MappingSerializer;
    37  import org.neo4j.server.rest.repr.OutputFormat;
    38  import org.neo4j.server.rest.repr.Representation;
    39  import org.neo4j.server.rest.repr.ServerExtensionRepresentation;
    40
    41  import javax.ws.rs.GET;
    42  import javax.ws.rs.POST;
    43  import javax.ws.rs.Path;
    44  import javax.ws.rs.PathParam;
    45  import javax.ws.rs.core.Context;
    46  import javax.ws.rs.core.Response;
    47
    48  @Path( "ext" )
    49  public class ExtensionService
    50  {
    51      private static final String PATH_EXTENSION = "/{name}";
    52      private static final String PATH_GRAPHDB_EXTENSION_METHOD = PATH_EXTENSION
    53                                                                  + "/graphdb/{method}";
    54      private static final String PATH_NODE_EXTENSION_METHOD = PATH_EXTENSION + "/node/{nodeId}/{method}";
    55      private static final String PATH_RELATIONSHIP_EXTENSION_METHOD = PATH_EXTENSION
    56                                                                       + "/relationship/{relationshipId}/{method}";
    57      private final InputFormat input;
    58      private final OutputFormat output;
    59      private final PluginInvocator extensions;
    60      private final AbstractGraphDatabase graphDb;
    61
    62      public ExtensionService( @Context InputFormat input, @Context OutputFormat output,
    63              @Context PluginInvocator extensions, @Context Database database )
    64      {
    65          this.input = input;
    66          this.output = output;
    67          this.extensions = extensions;
    68          this.graphDb = database.graph;
    69      }
    70
    71      private Node node( long id ) throws NodeNotFoundException
    72      {
    73          try
    74          {
    75              return graphDb.getNodeById( id );
    76          }
    77          catch ( NotFoundException e )
    78          {
    79              throw new NodeNotFoundException();
    80          }
    81      }
    82
    83      private Relationship relationship( long id ) throws RelationshipNotFoundException
    84      {
    85          try
    86          {
    87              return graphDb.getRelationshipById( id );
    88          }
    89          catch ( NotFoundException e )
    90          {
    91              throw new RelationshipNotFoundException();
    92          }
    93      }
    94
    95      @GET
    96      public Response getExtensionsList()
    97      {
    98          return output.ok( this.extensionsList() );
    99      }
    100
    101     @GET
    102     @Path( PATH_EXTENSION )
    103     public Response getExtensionList( @PathParam( "name" ) String name )
    104     {
    105         try
    106         {
    107             return output.ok( this.extensionList( name ) );
    108         }
    109         catch ( PluginLookupException e )
    110         {
    111             return output.notFound( e );
    112         }
    113     }
    114
    115     @POST
    116     @Path( PATH_GRAPHDB_EXTENSION_METHOD )
    117     public Response invokeGraphDatabaseExtension( @PathParam( "name" ) String name,
    118             @PathParam( "method" ) String method, String data )
    119     {
    120         try
    121         {
    122             return output.ok( this.invokeGraphDatabaseExtension( name, method,
    123                     input.readParameterList( data ) ) );
    124         }
    125         catch ( BadInputException e )
    126         {
    127             return output.badRequest( e );
    128         }
    129         catch ( PluginLookupException e )
    130         {
    131             return output.notFound( e );
    132         }
    133         catch ( BadPluginInvocationException e )
    134         {
    135             return output.badRequest( e.getCause() );
    136         }
    137         catch ( PluginInvocationFailureException e )
    138         {
    139             return output.serverError( e.getCause() );
    140         }
    141     }
    142
    143     @GET
    144     @Path( PATH_GRAPHDB_EXTENSION_METHOD )
    145     public Response getGraphDatabaseExtensionDescription( @PathParam( "name" ) String name,
    146             @PathParam( "method" ) String method )
    147     {
    148         try
    149         {
    150             return output.ok( this.describeGraphDatabaseExtension( name, method ) );
    151         }
    152         catch ( PluginLookupException e )
    153         {
    154             return output.notFound( e );
    155         }
    156     }
    157
    158     @POST
    159     @Path( PATH_NODE_EXTENSION_METHOD )
    160     public Response invokeNodeExtension( @PathParam( "name" ) String name,
    161             @PathParam( "method" ) String method, @PathParam( "nodeId" ) long nodeId, String data )
    162     {
    163         try
    164         {
    165             return output.ok( this.invokeNodeExtension( nodeId, name, method,
    166                     input.readParameterList( data ) ) );
    167         }
    168         catch ( NodeNotFoundException e )
    169         {
    170             return output.notFound( e );
    171         }
    172         catch ( BadInputException e )
    173         {
    174             return output.badRequest( e );
    175         }
    176         catch ( PluginLookupException e )
    177         {
    178             return output.notFound( e );
    179         }
    180         catch ( BadPluginInvocationException e )
    181         {
    182             return output.badRequest( e.getCause() );
    183         }
    184         catch ( PluginInvocationFailureException e )
    185         {
    186             return output.serverError( e.getCause() );
    187         }
    188     }
    189
    190     @GET
    191     @Path( PATH_NODE_EXTENSION_METHOD )
    192     public Response getNodeExtensionDescription( @PathParam( "name" ) String name,
    193             @PathParam( "method" ) String method, @PathParam( "nodeId" ) long nodeId )
    194     {
    195         try
    196         {
    197             return output.ok( this.describeNodeExtension( name, method ) );
    198         }
    199         catch ( PluginLookupException e )
    200         {
    201             return output.notFound( e );
    202         }
    203     }
    204
    205     @POST
    206     @Path( PATH_RELATIONSHIP_EXTENSION_METHOD )
    207     public Response invokeRelationshipExtension( @PathParam( "name" ) String name,
    208             @PathParam( "method" ) String method,
    209             @PathParam( "relationshipId" ) long relationshipId, String data )
    210     {
    211         try
    212         {
    213             return output.ok( this.invokeRelationshipExtension( relationshipId, name, method,
    214                     input.readParameterList( data ) ) );
    215         }
    216         catch ( RelationshipNotFoundException e )
    217         {
    218             return output.notFound( e );
    219         }
    220         catch ( BadInputException e )
    221         {
    222             return output.badRequest( e );
    223         }
    224         catch ( PluginLookupException e )
    225         {
    226             return output.notFound( e );
    227         }
    228         catch ( BadPluginInvocationException e )
    229         {
    230             return output.badRequest( e.getCause() );
    231         }
    232         catch ( PluginInvocationFailureException e )
    233         {
    234             return output.serverError( e.getCause() );
    235         }
    236     }
    237
    238     @GET
    239     @Path( PATH_RELATIONSHIP_EXTENSION_METHOD )
    240     public Response getRelationshipExtensionDescription( @PathParam( "name" ) String name,
    241             @PathParam( "method" ) String method, @PathParam( "relationshipId" ) long relationshipId )
    242     {
    243         try
    244         {
    245             return output.ok( this.describeRelationshipExtension( name, method ) );
    246         }
    247         catch ( PluginLookupException e )
    248         {
    249             return output.notFound( e );
    250         }
    251     }
    252
    253     // Extensions
    254
    255     protected Representation extensionsList()
    256     {
    257         return new MappingRepresentation( "extensions" )
    258         {
    259             @Override
    260             protected void serialize( MappingSerializer serializer )
    261             {
    262                 for ( String extension : extensions.extensionNames() )
    263                 {
    264                     serializer.putUri( extension, "ext/" + extension );
    265                 }
    266             }
    267         };
    268     }
    269
    270     protected Representation extensionList( String extensionName ) throws PluginLookupException
    271     {
    272         return new ServerExtensionRepresentation( extensionName,
    273                 extensions.describeAll( extensionName ) );
    274     }
    275
    276     protected Representation invokeGraphDatabaseExtension( String extensionName, String method,
    277             ParameterList data ) throws PluginLookupException, BadInputException,
    278             PluginInvocationFailureException, BadPluginInvocationException
    279     {
    280         return extensions.invoke( graphDb, extensionName, GraphDatabaseService.class, method,
    281                 graphDb, data );
    282     }
    283
    284     protected Representation describeGraphDatabaseExtension( String extensionName, String method )
    285             throws PluginLookupException
    286     {
    287         return extensions.describe( extensionName, GraphDatabaseService.class, method );
    288     }
    289
    290     protected Representation invokeNodeExtension( long nodeId, String extensionName, String method,
    291             ParameterList data ) throws NodeNotFoundException, PluginLookupException,
    292             BadInputException, PluginInvocationFailureException, BadPluginInvocationException
    293     {
    294         return extensions.invoke( graphDb, extensionName, Node.class, method, node( nodeId ), data );
    295     }
    296
    297     protected Representation describeNodeExtension( String extensionName, String method )
    298             throws PluginLookupException
    299     {
    300         return extensions.describe( extensionName, Node.class, method );
    301     }
    302
    303     protected Representation invokeRelationshipExtension( long relationshipId,
    304             String extensionName, String method, ParameterList data )
    305             throws RelationshipNotFoundException, PluginLookupException, BadInputException,
    306             PluginInvocationFailureException, BadPluginInvocationException
    307     {
    308         return extensions.invoke( graphDb, extensionName, Relationship.class, method,
    309                 relationship( relationshipId ), data );
    310     }
    311
    312     protected Representation describeRelationshipExtension( String extensionName, String method )
    313             throws PluginLookupException
    314     {
    315         return extensions.describe( extensionName, Relationship.class, method );
    316     }
    317 }