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.plugins;
    21
    22  import java.lang.reflect.ParameterizedType;
    23  import java.lang.reflect.Type;
    24
    25  import org.neo4j.graphdb.Node;
    26  import org.neo4j.graphdb.Path;
    27  import org.neo4j.graphdb.Relationship;
    28  import org.neo4j.helpers.collection.IterableWrapper;
    29  import org.neo4j.server.rest.repr.ListRepresentation;
    30  import org.neo4j.server.rest.repr.NodeRepresentation;
    31  import org.neo4j.server.rest.repr.PathRepresentation;
    32  import org.neo4j.server.rest.repr.RelationshipRepresentation;
    33  import org.neo4j.server.rest.repr.Representation;
    34  import org.neo4j.server.rest.repr.RepresentationType;
    35  import org.neo4j.server.rest.repr.ValueRepresentation;
    36
    37  abstract class ResultConverter
    38  {
    39      static ResultConverter get( Type type )
    40      {
    41          return get( type, true );
    42      }
    43
    44      private static ResultConverter get( Type type, boolean allowComplex )
    45      {
    46          if ( type instanceof Class<?> )
    47          {
    48              Class<?> cls = (Class<?>) type;
    49              if ( allowComplex && Representation.class.isAssignableFrom( cls ) )
    50              {
    51                  return IDENTITY_RESULT;
    52              }
    53              else if ( cls == Node.class )
    54              {
    55                  return NODE_RESULT;
    56              }
    57              else if ( cls == Relationship.class )
    58              {
    59                  return RELATIONSHIP_RESULT;
    60              }
    61              else if ( cls == Path.class )
    62              {
    63                  return PATH_RESULT;
    64              }
    65              else if ( cls == String.class )
    66              {
    67                  return STRING_RESULT;
    68              }
    69              else if ( cls == void.class || cls == Void.class )
    70              {
    71                  return VOID_RESULT;
    72              }
    73              else if ( cls == long.class || cls == Long.class )
    74              {
    75                  return LONG_RESULT;
    76              }
    77              else if ( cls == double.class || cls == float.class || //
    78                        cls == Double.class || cls == Float.class )
    79              {
    80                  return DOUBLE_RESULT;
    81              }
    82              else if ( cls == boolean.class || cls == Boolean.class )
    83              {
    84                  return BOOL_RESULT;
    85              }
    86              else if ( cls == char.class || cls == Character.class )
    87              {
    88                  return CHAR_RESULT;
    89              }
    90              else if ( cls.isPrimitive() || ( Number.class.isAssignableFrom( cls ) && //
    91                        cls.getPackage().getName().equals( "java.lang" ) ) )
    92              {
    93                  return INT_RESULT;
    94              }
    95          }
    96          else if ( allowComplex && type instanceof ParameterizedType )
    97          {
    98              ParameterizedType parameterizedType = (ParameterizedType) type;
    99              Class<?> raw = (Class<?>) parameterizedType.getRawType();
    100             Type paramType = parameterizedType.getActualTypeArguments()[0];
    101             if ( !( paramType instanceof Class<?> ) )
    102             {
    103                 throw new IllegalStateException(
    104                         "Parameterized result types must have a concrete type parameter." );
    105             }
    106             Class<?> param = (Class<?>) paramType;
    107             if ( Iterable.class.isAssignableFrom( raw ) )
    108             {
    109                 return new ListResult( get( param, false ) );
    110             }
    111         }
    112         throw new IllegalStateException( "Illegal result type: " + type );
    113     }
    114
    115     abstract Representation convert( Object obj );
    116
    117     abstract RepresentationType type();
    118
    119     private static abstract class ValueResult extends ResultConverter
    120     {
    121         private final RepresentationType type;
    122
    123         ValueResult( RepresentationType type )
    124         {
    125             this.type = type;
    126         }
    127
    128         @Override
    129         final RepresentationType type()
    130         {
    131             return type;
    132         }
    133     }
    134
    135     private static final ResultConverter//
    136             IDENTITY_RESULT = new ResultConverter()
    137             {
    138                 @Override
    139                 Representation convert( Object obj )
    140                 {
    141                     return (Representation) obj;
    142                 }
    143
    144                 @Override
    145                 RepresentationType type()
    146                 {
    147                     return null;
    148                 }
    149             },
    150             NODE_RESULT = new ValueResult( RepresentationType.NODE )
    151             {
    152                 @Override
    153                 Representation convert( Object obj )
    154                 {
    155                     return new NodeRepresentation( (Node) obj );
    156                 }
    157             }, RELATIONSHIP_RESULT = new ValueResult( RepresentationType.RELATIONSHIP )
    158             {
    159                 @Override
    160                 Representation convert( Object obj )
    161                 {
    162                     return new RelationshipRepresentation( (Relationship) obj );
    163                 }
    164             }, PATH_RESULT = new ValueResult( RepresentationType.PATH )
    165             {
    166                 @Override
    167                 Representation convert( Object obj )
    168                 {
    169                     return new PathRepresentation( (Path) obj );
    170                 }
    171             }, STRING_RESULT = new ValueResult( RepresentationType.STRING )
    172             {
    173                 @Override
    174                 Representation convert( Object obj )
    175                 {
    176                     return ValueRepresentation.string( (String) obj );
    177                 }
    178             }, LONG_RESULT = new ValueResult( RepresentationType.LONG )
    179             {
    180                 @Override
    181                 Representation convert( Object obj )
    182                 {
    183                     return ValueRepresentation.number( ( (Number) obj ).longValue() );
    184                 }
    185             }, DOUBLE_RESULT = new ValueResult( RepresentationType.DOUBLE )
    186             {
    187                 @Override
    188                 Representation convert( Object obj )
    189                 {
    190                     return ValueRepresentation.number( ( (Number) obj ).doubleValue() );
    191                 }
    192             }, BOOL_RESULT = new ValueResult( RepresentationType.BOOLEAN )
    193             {
    194                 @Override
    195                 @SuppressWarnings( "boxing" )
    196                 Representation convert( Object obj )
    197                 {
    198                     return ValueRepresentation.bool( (Boolean) obj );
    199                 }
    200             }, INT_RESULT = new ValueResult( RepresentationType.INTEGER )
    201             {
    202                 @Override
    203                 Representation convert( Object obj )
    204                 {
    205                     return ValueRepresentation.number( ( (Number) obj ).intValue() );
    206                 }
    207             }, CHAR_RESULT = new ValueResult( RepresentationType.CHAR )
    208             {
    209                 @Override
    210                 @SuppressWarnings( "boxing" )
    211                 Representation convert( Object obj )
    212                 {
    213                     return ValueRepresentation.number( (Character) obj );
    214                 }
    215             }, VOID_RESULT = new ValueResult( RepresentationType.NOTHING )
    216             {
    217                 @Override
    218                 Representation convert( Object obj )
    219                 {
    220                     return Representation.emptyRepresentation();
    221                 }
    222             };
    223
    224     private static class ListResult extends ResultConverter
    225     {
    226         private final ResultConverter itemConverter;
    227
    228         ListResult( ResultConverter itemConverter )
    229         {
    230             this.itemConverter = itemConverter;
    231         }
    232
    233         @Override
    234         @SuppressWarnings( "unchecked" )
    235         Representation convert( Object obj )
    236         {
    237             return new ListRepresentation( itemConverter.type(),
    238                     new IterableWrapper<Representation, Object>( (Iterable<Object>) obj )
    239                     {
    240                         @Override
    241                         protected Representation underlyingObjectToObject( Object object )
    242                         {
    243                             return itemConverter.convert( object );
    244                         }
    245                     } );
    246         }
    247
    248         @Override
    249         RepresentationType type()
    250         {
    251             return null;
    252         }
    253     }
    254 }