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.domain;
    21
    22  import java.util.Arrays;
    23  import java.util.Collection;
    24  import java.util.Map;
    25
    26  import org.neo4j.graphdb.DynamicRelationshipType;
    27  import org.neo4j.graphdb.RelationshipType;
    28  import org.neo4j.graphdb.Traverser.Order;
    29  import org.neo4j.graphdb.traversal.TraversalDescription;
    30  import org.neo4j.kernel.Traversal;
    31
    32  /*
    33   * Maybe refactor to have a constructor with default stuff and make
    34   * methods non-static
    35   */
    36  public class TraversalDescriptionBuilder
    37  {
    38      public static TraversalDescription from( Map<String, Object> description )
    39      {
    40          try
    41          {
    42              TraversalDescription result = Traversal.description();
    43              result = describeOrder( result, description );
    44              result = describeUniqueness( result, description );
    45              result = describeRelationships( result, description );
    46              result = describePruneEvaluator( result, description );
    47              result = describeReturnFilter( result, description );
    48              return result;
    49          }
    50          catch ( NoClassDefFoundError e )
    51          {
    52              // This one can happen if you run on Java 5, but haven't included the
    53              // backported javax.script jar file(s) on the classpath.
    54              throw new EvaluationException( e );
    55          }
    56      }
    57
    58      @SuppressWarnings("unchecked")
    59      private static TraversalDescription describeReturnFilter(
    60              TraversalDescription result, Map<String, Object> description )
    61      {
    62          Object returnDescription = description.get( "return filter" );
    63          if ( returnDescription != null )
    64          {
    65              result = result.filter( EvaluatorFactory.returnFilter( (Map) returnDescription ) );
    66          }
    67          else
    68          {
    69              // Default return evaluator
    70              result = result.filter( Traversal.returnAllButStartNode() );
    71          }
    72          return result;
    73      }
    74
    75      @SuppressWarnings("unchecked")
    76      private static TraversalDescription describePruneEvaluator(
    77              TraversalDescription result, Map<String, Object> description )
    78      {
    79          Object pruneDescription = description.get( "prune evaluator" );
    80          if ( pruneDescription != null )
    81          {
    82              result = result.prune( EvaluatorFactory.pruneEvaluator( (Map) pruneDescription ) );
    83          }
    84
    85          Object maxDepth = description.get( "max depth" );
    86          maxDepth = maxDepth != null || pruneDescription != null ? maxDepth : 1;
    87          if ( maxDepth != null )
    88          {
    89              result = result.prune( Traversal.pruneAfterDepth(
    90                      ((Number) maxDepth).intValue() ) );
    91          }
    92          return result;
    93      }
    94
    95      @SuppressWarnings("unchecked")
    96      private static TraversalDescription describeRelationships(
    97              TraversalDescription result, Map<String, Object> description )
    98      {
    99          Object relationshipsDescription = description.get( "relationships" );
    100         if ( relationshipsDescription != null )
    101         {
    102             Collection<Object> pairDescriptions;
    103             if ( relationshipsDescription instanceof Collection )
    104             {
    105                 pairDescriptions = (Collection<Object>) relationshipsDescription;
    106             }
    107             else
    108             {
    109                 pairDescriptions = Arrays.asList( relationshipsDescription );
    110             }
    111
    112             for ( Object pairDescription : pairDescriptions )
    113             {
    114                 Map map = (Map) pairDescription;
    115                 String name = (String) map.get( "type" );
    116                 RelationshipType type = DynamicRelationshipType.withName( name );
    117                 String directionName = (String) map.get( "direction" );
    118                 result = directionName == null ? result.relationships( type ) :
    119                         result.relationships( type, stringToEnum( directionName,
    120                                 RelationshipDirection.class, true ).internal );
    121             }
    122         }
    123         return result;
    124     }
    125
    126     private static TraversalDescription describeUniqueness(
    127             TraversalDescription result, Map<String, Object> description )
    128     {
    129         Object uniquenessDescription = description.get( "uniqueness" );
    130         if ( uniquenessDescription != null )
    131         {
    132             String name = null;
    133             Object value = null;
    134             if ( uniquenessDescription instanceof Map )
    135             {
    136                 Map map = (Map) uniquenessDescription;
    137                 name = (String) map.get( "name" );
    138                 value = map.get( "value" );
    139             }
    140             else
    141             {
    142                 name = (String) uniquenessDescription;
    143             }
    144             org.neo4j.kernel.Uniqueness uniqueness = stringToEnum( enumifyName( name ), org.neo4j.kernel.Uniqueness.class, true );
    145             result = value == null ? result.uniqueness( uniqueness ) :
    146                     result.uniqueness( uniqueness, value );
    147         }
    148         return result;
    149     }
    150
    151     private static TraversalDescription describeOrder(
    152             TraversalDescription result, Map<String, Object> description )
    153     {
    154         String orderDescription = (String) description.get( "order" );
    155         if ( orderDescription != null )
    156         {
    157             Order order = stringToEnum( enumifyName( orderDescription ), Order.class, true );
    158             // TODO Fix
    159             switch ( order )
    160             {
    161             case BREADTH_FIRST:
    162                 result = result.breadthFirst();
    163                 break;
    164             case DEPTH_FIRST:
    165                 result = result.depthFirst();
    166                 break;
    167             }
    168         }
    169         return result;
    170     }
    171
    172     private static <T extends Enum<T>> T stringToEnum( String name, Class<T> enumClass,
    173             boolean fuzzyMatch )
    174     {
    175         if ( name == null )
    176         {
    177             return null;
    178         }
    179
    180 //        name = enumifyName( name );
    181         for ( T candidate : enumClass.getEnumConstants() )
    182         {
    183             if ( candidate.name().equals( name ) )
    184             {
    185                 return candidate;
    186             }
    187         }
    188         if ( fuzzyMatch )
    189         {
    190             for ( T candidate : enumClass.getEnumConstants() )
    191             {
    192                 if ( candidate.name().startsWith( name ) )
    193                 {
    194                     return candidate;
    195                 }
    196             }
    197         }
    198         throw new RuntimeException( "Unregognized " + enumClass.getSimpleName() + " '" +
    199                 name + "'" );
    200     }
    201
    202     private static String enumifyName( String name )
    203     {
    204         return name.replaceAll( " ", "_" ).toUpperCase();
    205     }
    206 }