Package com.dooapp.gaedo.blueprints.queries.executable

Source Code of com.dooapp.gaedo.blueprints.queries.executable.VertexRootsCollector$IndexLazyLoader

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

import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.Map;

import javax.persistence.CascadeType;

import com.dooapp.gaedo.blueprints.AbstractBluePrintsBackedFinderService;
import com.dooapp.gaedo.blueprints.GraphUtils;
import com.dooapp.gaedo.blueprints.ObjectCache;
import com.dooapp.gaedo.blueprints.indexable.IndexNames;
import com.dooapp.gaedo.blueprints.operations.CollectionAccessByValueProperty;
import com.dooapp.gaedo.blueprints.operations.Updater;
import com.dooapp.gaedo.blueprints.queries.tests.CollectionContains;
import com.dooapp.gaedo.blueprints.queries.tests.EqualsTo;
import com.dooapp.gaedo.blueprints.queries.tests.InstanceOf;
import com.dooapp.gaedo.blueprints.queries.tests.NotVertexTest;
import com.dooapp.gaedo.blueprints.queries.tests.OrVertexTest;
import com.dooapp.gaedo.blueprints.queries.tests.VertexTest;
import com.dooapp.gaedo.blueprints.queries.tests.VertexTestVisitorAdapter;
import com.dooapp.gaedo.blueprints.queries.tests.VertextTestUtils;
import com.dooapp.gaedo.blueprints.transformers.LiteralTransformer;
import com.dooapp.gaedo.blueprints.transformers.Literals;
import com.dooapp.gaedo.properties.Property;
import com.dooapp.gaedo.utils.CollectionUtils;
import com.tinkerpop.blueprints.Index;
import com.tinkerpop.blueprints.Vertex;

/**
* Build a sorted set of {@link VertexSet} objects. Each of these sets
*
* @author ndx
*
*/
public class VertexRootsCollector extends VertexTestVisitorAdapter {
  public final class IndexLazyLoader implements LazyLoader, Comparable<LazyLoader> {
    private final Index<Vertex> vertices;
    private final String propertyKeyInIndex;
    private final String propertyValueInIndex;

    public IndexLazyLoader(Index<Vertex> vertices, String propertyKeyInIndex, String propertyValueInIndex) {
      super();
      this.propertyValueInIndex = propertyValueInIndex;
      this.propertyKeyInIndex = propertyKeyInIndex;
      this.vertices = vertices;
    }

    @Override
    public Iterable<Vertex> get() {
      return vertices.get(propertyKeyInIndex, propertyValueInIndex);
    }

    @Override
    public long size() {
      return vertices.count(propertyKeyInIndex, propertyValueInIndex);
    }

    /**
     * @return
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
      StringBuilder builder = new StringBuilder();
      builder.append("IndexLazyLoader [");
      if (propertyKeyInIndex != null) {
        builder.append("key=");
        builder.append(propertyKeyInIndex);
        builder.append(", ");
      }
      if (propertyValueInIndex != null) {
        builder.append("value=");
        builder.append(propertyValueInIndex);
        builder.append(", ");
      }
      builder.append("size()=");
      builder.append(size());
      builder.append("]");
      return builder.toString();
    }

    @Override
    public LazyLoader getSourceLoader() {
      return this;
    }

    @Override
    public int compareTo(LazyLoader o) {
      if (o instanceof IndexLazyLoader) {
        IndexLazyLoader loader = (IndexLazyLoader) o;
        int returned = 0;
        if(returned==0) {
          returned = propertyKeyInIndex.compareTo(loader.propertyKeyInIndex);
        }
        if(returned==0) {
          returned = propertyValueInIndex.compareTo(loader.propertyValueInIndex);
        }
        return returned;
      } else {
        return getClass().getSimpleName().compareTo(o.getClass().getSimpleName());
      }
    }
  }

  /**
   * Temporary map linking sets to the tests that should be executed, were those sets to be chosen as reference ones
   *
   */
  private Map<VertexSet, VertexTest> result = new LinkedHashMap<VertexSet, VertexTest>();

  private final AbstractBluePrintsBackedFinderService<?, ?, ?> service;
  /**
   * Cache of objects being loaded during roots collection building
   */
  private transient ObjectCache objectsBeingAccessed = ObjectCache.create(CascadeType.REFRESH);

  private VertexTest initialTest;

  public VertexRootsCollector(AbstractBluePrintsBackedFinderService<?, ?, ?> service) {
    this.service = service;
  }

  /**
   * Obtain the sorted set of vertex sets
   *
   * @return
   */
  public Map<VertexSet, VertexTest> getSetsToProcessedTests(VertexTest testToScan) {
    this.initialTest = testToScan;
    testToScan.accept(this);
    return result;
  }

  /**
   * Those queries are never visited, as they lead to unresolvable path (or at
   * least i think so)
   *
   * @param orVertexTest
   * @return
   * @see com.dooapp.gaedo.blueprints.queries.tests.VertexTestVisitorAdapter#startVisit(com.dooapp.gaedo.blueprints.queries.tests.OrVertexTest)
   */
  @Override
  public boolean startVisit(OrVertexTest orVertexTest) {
    return false;
  }

  /**
   * Those queries are never visited, as they lead to unresolvable path (or at
   * least i think so)
   *
   * @param notVertexTest
   * @return
   * @see com.dooapp.gaedo.blueprints.queries.tests.VertexTestVisitorAdapter#startVisit(com.dooapp.gaedo.blueprints.queries.tests.NotVertexTest)
   */
  @Override
  public boolean startVisit(NotVertexTest notVertexTest) {
    return false;
  }

  /**
   * @param collectionContains
   * @see com.dooapp.gaedo.blueprints.queries.tests.VertexTestVisitorAdapter#visit(com.dooapp.gaedo.blueprints.queries.tests.CollectionContains)
   */
  @Override
  public void visit(CollectionContains collectionContains) {
    result.put(load(collectionContains.getExpectedAsValue(), collectionContains.getPath()), testWithout(collectionContains));
  }

  @Override
  public void visit(InstanceOf instanceOf) {
    if(instanceOf.getRepository().containsKey(instanceOf.getExpectedAsValue())) {
      result.put(load(instanceOf.getExpectedAsValue(), instanceOf.getPath()), testWithout(instanceOf));
    }
  }

  /**
   * We use equalsTo test as base for query only when tested value is non null.
   * @param equalsTo
   * @see com.dooapp.gaedo.blueprints.queries.tests.VertexTestVisitorAdapter#visit(com.dooapp.gaedo.blueprints.queries.tests.EqualsTo)
   */
  @Override
  public void visit(EqualsTo equalsTo) {
    if(equalsTo.getExpectedAsValue()!=null)
      result.put(load(equalsTo.getExpectedAsValue(), equalsTo.getPath()), testWithout(equalsTo));
  }

  /**
   * Create a test from initial one without the given one
   * @param toRemove test to remove from initial test
   * @return
   */
  private VertexTest testWithout(VertexTest toRemove) {
    return VertextTestUtils.testWithout(initialTest, toRemove);
  }

  /**
   * Load the VertexSet corresponding to the vertex associated with expected
   * value, and accessible through given path
   *
   * @param expected
   * @param path
   * @return
   */
  private <Type> VertexSet load(Type expected, Iterable<Property> path) {
    LinkedList<Property> updatablePath = new LinkedList<Property>(CollectionUtils.asList(path));
    Property lastProperty = updatablePath.removeLast();
    // if value is a literal, well, it's time for an index lookup
    Class<Type> expectedClass = (Class<Type>) expected.getClass();
    if (expected != null && Literals.containsKey(expectedClass)) {
      // Yup : gladly using implementation as it provides a last() method !
      Index<Vertex> vertices = (Index<Vertex>) service.getDatabase().getIndex(IndexNames.VERTICES.getIndexName(), IndexNames.VERTICES.getIndexed());
      // stinky code fragment for collections : as each value is stored under
      // a key in the form propertyName:index, we have to iterate upon them
      String propertyKeyInIndex = null;
      String propertyValueInIndex = null;
      if (Collection.class.isAssignableFrom(lastProperty.getType())) {
        propertyKeyInIndex = GraphUtils.getEdgeNameFor(new CollectionAccessByValueProperty(lastProperty, expected, Updater.ELEMENT_IN_COLLECTION_MARKER));
        propertyValueInIndex = Updater.ELEMENT_IN_COLLECTION_MARKER_GRAPH_VALUE;
      } else {
        propertyKeyInIndex = GraphUtils.getEdgeNameFor(lastProperty);
        LiteralTransformer<Type> transformer = Literals.get(expectedClass);
        if(Literals.containsKey(lastProperty.getType())) {
          transformer = Literals.get(lastProperty.getType());
        }
        propertyValueInIndex = transformer.toString(expected);
      }
      VertexSet returned = new VertexSet().withPropertyPath(updatablePath);
      returned.setVertices(new IndexLazyLoader(vertices, propertyKeyInIndex, propertyValueInIndex));
      return returned;
    } else {
      Vertex vertexFor = service.getVertexFor(expected, CascadeType.REFRESH, objectsBeingAccessed);
      if (vertexFor == null) {
        return new VertexSet().withVertices(new LinkedList<Vertex>()).withPropertyPath(new LinkedList<Property>());
      } else {
        return new VertexSet().withVertices(Arrays.asList(vertexFor)).withPropertyPath(new LinkedList<Property>(CollectionUtils.asList(path)));
      }
    }
  }
}
TOP

Related Classes of com.dooapp.gaedo.blueprints.queries.executable.VertexRootsCollector$IndexLazyLoader

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.