Package com.dooapp.gaedo.blueprints.queries.tests

Source Code of com.dooapp.gaedo.blueprints.queries.tests.MonovaluedValuedVertexTest

package com.dooapp.gaedo.blueprints.queries.tests;

import java.util.Iterator;

import javax.persistence.CascadeType;

import com.dooapp.gaedo.blueprints.AbstractBluePrintsBackedFinderService;
import com.dooapp.gaedo.blueprints.GraphDatabaseDriver;
import com.dooapp.gaedo.blueprints.ObjectCache;
import com.dooapp.gaedo.blueprints.indexable.IndexableGraphBackedFinderService;
import com.dooapp.gaedo.blueprints.operations.Loader;
import com.dooapp.gaedo.blueprints.strategies.GraphMappingStrategy;
import com.dooapp.gaedo.blueprints.utils.VertexPathNavigator;
import com.dooapp.gaedo.blueprints.utils.VertexPathNavigator.VertexLocation;
import com.dooapp.gaedo.properties.Property;
import com.dooapp.gaedo.utils.PrimitiveUtils;
import com.dooapp.gaedo.utils.Utils;
import com.tinkerpop.blueprints.Direction;
import com.tinkerpop.blueprints.Edge;
import com.tinkerpop.blueprints.Vertex;

/**
* Base class for all simple tests (like contains, greater than, ...).
* Notice {@link #expected} is used for both direct value comparison (for literals) and id check (for managed objects).
* This is done by asking the {@link TargettedVertexTest#serviceRrepository} if {@link #expected} is a managed value
*
* @author ndx
*
* @param <ValueType> current value type
*/
public abstract class MonovaluedValuedVertexTest<ValueType extends Object> extends TargettedVertexTest implements VertexTest {

  /**
   * Expected value
   */
  protected final ValueType expected;

  public MonovaluedValuedVertexTest(GraphMappingStrategy<?> strategy, GraphDatabaseDriver driver, Iterable<Property> p, ValueType value) {
    super(strategy, driver, p);
    this.expected = value;
  }

  /**
   * To match node
   * @param examined
   * @return
   * @see com.dooapp.gaedo.blueprints.queries.tests.VertexTest#matches(com.tinkerpop.blueprints.pgm.Vertex)
   */
  @Override
  public boolean matches(Vertex examined) {
    // Navigates to the first target edge and perform test when reached
    VertexPathNavigator navigator = new VertexPathNavigator(strategy, examined);
    VertexLocation destination = navigator.navigateOn(path);
    // null final property indicates object has no value for that property
    if(!destination.isNavigationSuccessfull()) {
      return matchesNull();
    } else {
      return matchesVertex(destination.vertex(), destination.property());
    }
  }

  /**
   * Define what that test must do when encountering a null value.
   * @return true if expected is null, false elsewhere.
   */
  protected boolean matchesNull() {
    return getExpected()==null;
  }

  /**
   * Perform the final vertex match
   * @param currentVertex
   * @param finalProperty
   * @return
   */
  public boolean matchesVertex(Vertex currentVertex, Property finalProperty) {
    if(expected==null) {
      return currentVertex==null;
    } else {
      if(shouldMatchManagedVertex(currentVertex, finalProperty)) {
        return callMatchManaged(currentVertex, finalProperty);
      } else {
        return callMatchLiteral(currentVertex, finalProperty);
      }
    }
  }

  /**
   * Check if match should be made for a literal value or a managed value.
   * @param currentVertex currently evaluated verted
   * @param finalProperty property on which match should be performed
   * @return
   */
  protected boolean shouldMatchManagedVertex(Vertex currentVertex, Property finalProperty) {
    return getRepository().containsKey(expected.getClass());
  }

  /**
   * Check vertex corresponding to given final property matches with a managed object (that's to say an object
   * for which exist a {@link IndexableGraphBackedFinderService}
   * @param currentVertex vertex corresponding to finalProperty in property path
   * @param finalProperty property giving infos on class to use to read vertex value (when needed)
   * @return true if managed value matches ... yup, really awesome
   */
  protected abstract boolean callMatchManaged(Vertex currentVertex, Property finalProperty);

  /**
   * Check if literal (or tuple) value matches.
   * Notice expected may in that case be a null value.
   * @param currentVertex vertex corresponding to finalProperty in property path
   * @param finalProperty property giving infos on class to use to read vertex value (when needed)
   * @return true if literal value matches ... yup, really awesome
   */
  protected abstract boolean callMatchLiteral(Vertex currentVertex, Property finalProperty);

  /**
   * Obtain service associated to expected value. BEWARE ! This service corresponds to {@link #expected}, which may be a literal (in which case obtained service will only be an exception).
   * Usage iof this method should be restricted to cases where user is sure value is a serviceable one.
   * @return
   */
  protected AbstractBluePrintsBackedFinderService getService() {
    return (AbstractBluePrintsBackedFinderService) getRepository().get(expected.getClass());
  }

  /**
   * @return the expected
   * @category getter
   * @category expected
   */
  protected ValueType getExpected() {
    return expected;
  }

  public Object getExpectedAsValue() {
    return getExpectedAsValueOf(getEndProperty(), getExpected());
  }

  public static Object getExpectedAsValueOf(Property used, Object expected) {
    Class<?> usedType = Utils.maybeObjectify(expected==null ? Object.class : used.getType());
    Class<?> expectedValueClass = Utils.maybeObjectify(expected==null ? Object.class : expected.getClass());
    if(Number.class.isAssignableFrom(expectedValueClass) && Number.class.isAssignableFrom(usedType)) {
      // same class cases are already handled with calls to maybeObjectify
      return PrimitiveUtils.as((Number) expected, (Class<? extends Number>) usedType);
    }
    return expected;
  }

  @Override
  protected StringBuilder toString(int deepness, StringBuilder builder) {
    StringBuilder returned = super.toString(deepness, builder);
    returned.append(expected).append("\n");
    return returned;
  }

  /**
   * Helper method transforming a vertex property into a literal. mainly useful for "basic" literals
   * @param currentVertex
   * @param finalProperty
   * @return
   */
  protected ValueType getLiteralValue(Vertex currentVertex, Property finalProperty) {
    Loader loader = new Loader();
    ClassLoader classLoader = expected==null ? expected.getClass().getClassLoader() : getClass().getClassLoader();
    return (ValueType) loader.loadSingleLiteral(classLoader, finalProperty, currentVertex, objectsBeingAccessed);
  }
}
TOP

Related Classes of com.dooapp.gaedo.blueprints.queries.tests.MonovaluedValuedVertexTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.