You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@usergrid.apache.org by sn...@apache.org on 2014/01/28 23:21:40 UTC
[30/96] [abbrv] [partial] Change package namespace to
org.apache.usergrid
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/OrderByIterator.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/OrderByIterator.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/OrderByIterator.java
new file mode 100644
index 0000000..183615a
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/OrderByIterator.java
@@ -0,0 +1,251 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.ir.result;
+
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.UUID;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.commons.collections.comparators.ComparatorChain;
+import org.apache.usergrid.persistence.Entity;
+import org.apache.usergrid.persistence.EntityManager;
+import org.apache.usergrid.persistence.EntityPropertyComparator;
+import org.apache.usergrid.persistence.Query;
+import org.apache.usergrid.persistence.Query.SortPredicate;
+import org.apache.usergrid.persistence.cassandra.CursorCache;
+import org.apache.usergrid.persistence.query.ir.QuerySlice;
+
+import me.prettyprint.cassandra.serializers.UUIDSerializer;
+
+
+/**
+ * 1) Take a result set iterator as the child 2) Iterate only over candidates and create a cursor from the candidates
+ *
+ * @author tnine
+ */
+
+public class OrderByIterator extends MergeIterator {
+
+ private static final UUIDSerializer UUID_SER = new UUIDSerializer();
+
+ private static final String NAME_UUID = "uuid";
+ private static final Logger logger = LoggerFactory.getLogger( OrderByIterator.class );
+ private final QuerySlice slice;
+ private final ResultIterator candidates;
+ private final ComparatorChain subSortCompare;
+ private final List<String> secondaryFields;
+ private final EntityManager em;
+
+ //our last result from in memory sorting
+ private SortedEntitySet entries;
+
+
+ /**
+ * @param pageSize
+ */
+ public OrderByIterator( QuerySlice slice, List<Query.SortPredicate> secondary, ResultIterator candidates,
+ EntityManager em, int pageSize ) {
+ super( pageSize );
+ this.slice = slice;
+ this.em = em;
+ this.candidates = candidates;
+ this.subSortCompare = new ComparatorChain();
+ this.secondaryFields = new ArrayList<String>( 1 + secondary.size() );
+
+ //add the sort of the primary column
+ this.secondaryFields.add( slice.getPropertyName() );
+ this.subSortCompare
+ .addComparator( new EntityPropertyComparator( slice.getPropertyName(), slice.isReversed() ) );
+
+ for ( SortPredicate sort : secondary ) {
+ this.subSortCompare.addComparator( new EntityPropertyComparator( sort.getPropertyName(),
+ sort.getDirection() == Query.SortDirection.DESCENDING ) );
+ this.secondaryFields.add( sort.getPropertyName() );
+ }
+
+ //do uuid sorting last, this way if all our previous sorts are equal, we'll have a reproducible sort order for
+ // paging
+ this.secondaryFields.add( NAME_UUID );
+ this.subSortCompare.addComparator( new EntityPropertyComparator( NAME_UUID, false ) );
+ }
+
+
+ @Override
+ protected Set<ScanColumn> advance() {
+
+ ByteBuffer cursor = slice.getCursor();
+
+ UUID minEntryId = null;
+
+ if ( cursor != null ) {
+ minEntryId = UUID_SER.fromByteBuffer( cursor );
+ }
+
+ entries = new SortedEntitySet( subSortCompare, em, secondaryFields, pageSize, minEntryId );
+
+ /**
+ * keep looping through our peek iterator. We need to inspect each forward page to ensure we have performed a
+ * seek to the end of our primary range. Otherwise we need to keep aggregating. I.E if the value is a boolean
+ * and we order by "true
+ * asc, timestamp desc" we must load every entity that has the value "true" before sub sorting,
+ * then drop all values that fall out of the sort.
+ */
+ while ( candidates.hasNext() ) {
+
+
+ for ( ScanColumn id : candidates.next() ) {
+ entries.add( id );
+ }
+
+ entries.load();
+ }
+
+
+ return entries.toIds();
+ }
+
+
+ @Override
+ protected void doReset() {
+ // no op
+ }
+
+
+ @Override
+ public void finalizeCursor( CursorCache cache, UUID lastValue ) {
+ int sliceHash = slice.hashCode();
+
+ ByteBuffer bytes = UUID_SER.toByteBuffer( lastValue );
+
+ if ( bytes == null ) {
+ return;
+ }
+
+ cache.setNextCursor( sliceHash, bytes );
+ }
+
+
+ /** A Sorted set with a max size. When a new entry is added, the max is removed */
+ public static final class SortedEntitySet extends TreeSet<Entity> {
+
+ private final int maxSize;
+ private final Map<UUID, ScanColumn> cursorVal = new HashMap<UUID, ScanColumn>();
+ private final EntityManager em;
+ private final List<String> fields;
+ private final Entity minEntity;
+ private final Comparator<Entity> comparator;
+
+
+ public SortedEntitySet( Comparator<Entity> comparator, EntityManager em, List<String> fields, int maxSize,
+ UUID minEntityId ) {
+ super( comparator );
+ this.maxSize = maxSize;
+ this.em = em;
+ this.fields = fields;
+ this.comparator = comparator;
+ this.minEntity = getPartialEntity( minEntityId );
+ }
+
+
+ @Override
+ public boolean add( Entity entity ) {
+
+ // don't add this entity. We get it in our scan range, but it's <= the minimum value that
+ //should be allowed in the result set
+ if ( minEntity != null && comparator.compare( entity, minEntity ) <= 0 ) {
+ return false;
+ }
+
+ boolean added = super.add( entity );
+
+ while ( size() > maxSize ) {
+ //remove our last element, we're over size
+ Entity e = this.pollLast();
+ //remove it from the cursors as well
+ cursorVal.remove( e.getUuid() );
+ }
+
+ return added;
+ }
+
+
+ /** add the id to be loaded, and the dynamiccomposite column that belongs with it */
+ public void add( ScanColumn col ) {
+ cursorVal.put( col.getUUID(), col );
+ }
+
+
+ private Entity getPartialEntity( UUID minEntityId ) {
+ List<Entity> entities;
+
+ try {
+ entities = em.getPartialEntities( Collections.singletonList( minEntityId ), fields );
+ }
+ catch ( Exception e ) {
+ logger.error( "Unable to load partial entities", e );
+ throw new RuntimeException( e );
+ }
+
+ if ( entities == null || entities.size() == 0 ) {
+ return null;
+ }
+
+ return entities.get( 0 );
+ }
+
+
+ public void load() {
+ try {
+ for ( Entity e : em.getPartialEntities( cursorVal.keySet(), fields ) ) {
+ add( e );
+ }
+ }
+ catch ( Exception e ) {
+ logger.error( "Unable to load partial entities", e );
+ throw new RuntimeException( e );
+ }
+ }
+
+
+ /** Turn our sorted entities into a set of ids */
+ public Set<ScanColumn> toIds() {
+ Iterator<Entity> itr = iterator();
+
+ Set<ScanColumn> columns = new LinkedHashSet<ScanColumn>( this.size() );
+
+ while ( itr.hasNext() ) {
+
+ UUID id = itr.next().getUuid();
+
+ columns.add( cursorVal.get( id ) );
+ }
+
+ return columns;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/ResultIterator.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/ResultIterator.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/ResultIterator.java
new file mode 100644
index 0000000..cde2bc8
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/ResultIterator.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.ir.result;
+
+
+import java.util.Iterator;
+import java.util.Set;
+import java.util.UUID;
+
+import org.apache.usergrid.persistence.cassandra.CursorCache;
+
+
+/**
+ * Interface for iterating slice results per node. This is to be used to iterate and join or intersect values Each
+ * iterator element is a set. Each set size is determined by the underlying implementation. When no sets of uuids are
+ * left the iterator should fail the next statement. Note that you should not rely on the returned set being exactly
+ * the same size as the specified page size. Valid sets can be returned with size >= that of the set value in the
+ * underlying implementation
+ *
+ * @author tnine
+ */
+public interface ResultIterator extends Iterable<Set<ScanColumn>>, Iterator<Set<ScanColumn>> {
+
+
+ /** Reset this iterator to the start to begin iterating again */
+ public void reset();
+
+ /** Finalize the cursor for this results. Pass in the uuid of the last entity loaded. */
+ public void finalizeCursor( CursorCache cache, UUID lastValue );
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/ResultsLoader.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/ResultsLoader.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/ResultsLoader.java
new file mode 100644
index 0000000..9d0c70c
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/ResultsLoader.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.ir.result;
+
+
+import java.util.List;
+
+import org.apache.usergrid.persistence.Results;
+
+
+/** @author tnine */
+public interface ResultsLoader {
+
+ /** Load results from the list of uuids. Should return a Results entity where the query cursor can be set */
+ public Results getResults( List<ScanColumn> entityIds ) throws Exception;
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/ResultsLoaderFactory.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/ResultsLoaderFactory.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/ResultsLoaderFactory.java
new file mode 100644
index 0000000..c1c5fbb
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/ResultsLoaderFactory.java
@@ -0,0 +1,21 @@
+package org.apache.usergrid.persistence.query.ir.result;
+
+
+import org.apache.usergrid.persistence.EntityManager;
+import org.apache.usergrid.persistence.Query;
+import org.apache.usergrid.persistence.Results;
+
+
+/**
+ *
+ * @author: tnine
+ *
+ */
+public interface ResultsLoaderFactory {
+
+ /**
+ * Get the results loaded that will load all Ids given the results level. The original query and the entity manager
+ * may be needed to load these results
+ */
+ public ResultsLoader getResultsLoader( EntityManager em, Query query, Results.Level level );
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/ScanColumn.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/ScanColumn.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/ScanColumn.java
new file mode 100644
index 0000000..91603c8
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/ScanColumn.java
@@ -0,0 +1,16 @@
+package org.apache.usergrid.persistence.query.ir.result;
+
+
+import java.nio.ByteBuffer;
+import java.util.UUID;
+
+
+/** An interface that represents a column */
+public interface ScanColumn {
+
+ /** Get the uuid from the column */
+ public UUID getUUID();
+
+ /** Get the cursor value of this column */
+ public ByteBuffer getCursorValue();
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/ScanColumnTransformer.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/ScanColumnTransformer.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/ScanColumnTransformer.java
new file mode 100644
index 0000000..3102404
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/ScanColumnTransformer.java
@@ -0,0 +1,23 @@
+package org.apache.usergrid.persistence.query.ir.result;
+
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.UUID;
+
+
+/** Simple utility to convert Scan Columns collections to lists */
+public class ScanColumnTransformer {
+
+ public static List<UUID> getIds( Collection<ScanColumn> cols ) {
+
+ List<UUID> ids = new ArrayList<UUID>( cols.size() );
+
+ for ( ScanColumn col : cols ) {
+ ids.add( col.getUUID() );
+ }
+
+ return ids;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SecondaryIndexSliceParser.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SecondaryIndexSliceParser.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SecondaryIndexSliceParser.java
new file mode 100644
index 0000000..68bc37a
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SecondaryIndexSliceParser.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.ir.result;
+
+
+import java.nio.ByteBuffer;
+import java.util.UUID;
+
+import me.prettyprint.hector.api.beans.DynamicComposite;
+
+
+/**
+ * Parser for reading and writing secondary index composites
+ *
+ * @author tnine
+ */
+public class SecondaryIndexSliceParser implements SliceParser {
+
+
+ /* (non-Javadoc)
+ * @see org.apache.usergrid.persistence.query.ir.result.SliceParser#parse(java.nio.ByteBuffer)
+ */
+ @Override
+ public ScanColumn parse( ByteBuffer buff ) {
+ DynamicComposite composite = DynamicComposite.fromByteBuffer( buff.duplicate() );
+
+ return new SecondaryIndexColumn( ( UUID ) composite.get( 2 ), composite.get( 1 ), buff );
+ }
+
+
+ public static class SecondaryIndexColumn extends AbstractScanColumn {
+
+ private final Object value;
+
+
+ public SecondaryIndexColumn( UUID uuid, Object value, ByteBuffer buff ) {
+ super( uuid, buff );
+ this.value = value;
+ }
+
+
+ /** Get the value from the node */
+ public Object getValue() {
+ return this.value;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SliceIterator.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SliceIterator.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SliceIterator.java
new file mode 100644
index 0000000..3829ad8
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SliceIterator.java
@@ -0,0 +1,251 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.ir.result;
+
+
+import java.nio.ByteBuffer;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.Set;
+import java.util.UUID;
+
+import org.apache.usergrid.persistence.cassandra.CursorCache;
+import org.apache.usergrid.persistence.cassandra.index.IndexScanner;
+import org.apache.usergrid.persistence.exceptions.QueryIterationException;
+import org.apache.usergrid.persistence.query.ir.QuerySlice;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import me.prettyprint.hector.api.beans.HColumn;
+
+
+/**
+ * An iterator that will take all slices and order them correctly
+ *
+ * @author tnine
+ */
+public class SliceIterator implements ResultIterator {
+
+ private static final Logger logger = LoggerFactory.getLogger( SliceIterator.class );
+
+ private final LinkedHashMap<UUID, ScanColumn> cols;
+ private final QuerySlice slice;
+ private final SliceParser parser;
+ private final IndexScanner scanner;
+ private final int pageSize;
+ private final boolean skipFirst;
+
+ /**
+ * Pointer to the uuid set until it's returned
+ */
+ private Set<ScanColumn> lastResult;
+
+ /**
+ * The pointer to the last set of parsed columns
+ */
+ private Set<ScanColumn> parsedCols;
+
+ /**
+ * counter that's incremented as we load pages. If pages loaded = 1 when reset, we don't have to reload from cass
+ */
+ private int pagesLoaded = 0;
+
+ /**
+ * Pointer to the last column we parsed
+ */
+ private ScanColumn last;
+
+
+ /**
+ * @param scanner The scanner to use to read the cols
+ * @param slice The slice used in the scanner
+ * @param parser The parser for the scanner results
+ * @param skipFirst True if the first record should be skipped, used with cursors
+ */
+ public SliceIterator( QuerySlice slice, IndexScanner scanner, SliceParser parser, boolean skipFirst ) {
+ this.slice = slice;
+ this.parser = parser;
+ this.scanner = scanner;
+ this.skipFirst = skipFirst;
+ this.pageSize = scanner.getPageSize();
+ this.cols = new LinkedHashMap<UUID, ScanColumn>( this.pageSize );
+ this.parsedCols = new LinkedHashSet<ScanColumn>( this.pageSize );
+ }
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Iterable#iterator()
+ */
+ @Override
+ public Iterator<Set<ScanColumn>> iterator() {
+ return this;
+ }
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.util.Iterator#hasNext()
+ */
+ @Override
+ public boolean hasNext() {
+ if ( lastResult == null ) {
+ return load();
+ }
+
+ return true;
+ }
+
+
+ private boolean load() {
+ if ( !scanner.hasNext() ) {
+ return false;
+ }
+
+ Iterator<HColumn<ByteBuffer, ByteBuffer>> results = scanner.next().iterator();
+
+ cols.clear();
+
+ /**
+ * Skip the first value, it's from the previous cursor
+ */
+ if ( skipFirst && pagesLoaded == 0 && results.hasNext() ) {
+ results.next();
+ }
+
+ parsedCols.clear();
+
+ while ( results.hasNext() ) {
+
+ ByteBuffer colName = results.next().getName().duplicate();
+
+ ScanColumn parsed = parser.parse( colName );
+
+ //skip this value, the parser has discarded it
+ if ( parsed == null ) {
+ continue;
+ }
+
+ last = parsed;
+ cols.put( parsed.getUUID(), parsed );
+ parsedCols.add( parsed );
+ }
+
+
+ pagesLoaded++;
+
+ lastResult = parsedCols;
+
+ return lastResult != null && lastResult.size() > 0;
+ }
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.util.Iterator#next()
+ */
+ @Override
+ public Set<ScanColumn> next() {
+ Set<ScanColumn> temp = lastResult;
+ lastResult = null;
+ return temp;
+ }
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.util.Iterator#remove()
+ */
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException( "Remove is not supported" );
+ }
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.usergrid.persistence.query.ir.result.ResultIterator#reset()
+ */
+ @Override
+ public void reset() {
+ // Do nothing, we'll just return the first page again
+ if ( pagesLoaded == 1 ) {
+ lastResult = parsedCols;
+ return;
+ }
+ scanner.reset();
+ }
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.apache.usergrid.persistence.query.ir.result.ResultIterator#finalizeCursor()
+ */
+ @Override
+ public void finalizeCursor( CursorCache cache, UUID lastLoaded ) {
+ final int sliceHash = slice.hashCode();
+
+ ByteBuffer bytes = null;
+
+ ScanColumn col = cols.get( lastLoaded );
+
+
+ //the column came from the current page
+ if ( col != null ) {
+ bytes = col.getCursorValue();
+ }
+ else {
+
+ //check if we reached the end of our iterator. If we did, set the last value into the cursor. Otherwise
+ //this is a bug
+ if ( scanner.hasNext() ) {
+ logger.error(
+ "An iterator attempted to access a slice that was not iterated over. This will result in the" +
+ " cursor construction failing" );
+ throw new QueryIterationException(
+ "An iterator attempted to access a slice that was not iterated over. This will result in the" +
+ " cursor construction failing" );
+ }
+
+ final ByteBuffer sliceCursor = slice.getCursor();
+
+ //we've never loaded anything, just re-use the existing slice
+ if (last == null && sliceCursor != null ) {
+ bytes = sliceCursor;
+ }
+
+ //use the last column we loaded. This way our scan returns nothing next time since start == finish
+ else if(last != null) {
+ bytes = last.getCursorValue();
+ }
+ }
+
+
+ if ( bytes == null ) {
+ return;
+ }
+
+ cache.setNextCursor( sliceHash, bytes );
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SliceParser.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SliceParser.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SliceParser.java
new file mode 100644
index 0000000..6f45efb
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SliceParser.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.ir.result;
+
+
+import java.nio.ByteBuffer;
+
+
+/**
+ * Interface to parse and compare range slices
+ *
+ * @author tnine
+ */
+public interface SliceParser {
+
+ /** Parse the slice and return it's parse type. If null is returned, the column should be considered discarded */
+ public ScanColumn parse( ByteBuffer buff );
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/StaticIdIterator.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/StaticIdIterator.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/StaticIdIterator.java
new file mode 100644
index 0000000..10ee4b8
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/StaticIdIterator.java
@@ -0,0 +1,66 @@
+package org.apache.usergrid.persistence.query.ir.result;
+
+
+import java.nio.ByteBuffer;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.UUID;
+
+import org.apache.usergrid.persistence.cassandra.CursorCache;
+
+
+/** Simple iterator that just returns UUIDs that are set into it */
+public class StaticIdIterator implements ResultIterator {
+
+ private final Set<ScanColumn> ids;
+
+ private boolean returnedOnce = false;
+
+
+ /**
+ *
+ */
+ public StaticIdIterator( UUID id ) {
+ final ScanColumn col = new UUIDIndexSliceParser.UUIDColumn( id, ByteBuffer.allocate( 0 ) );
+
+ ids = Collections.singleton( col );
+ }
+
+
+ @Override
+ public void reset() {
+ //no op
+ }
+
+
+ @Override
+ public void finalizeCursor( CursorCache cache, UUID lastValue ) {
+ //no cursor, it's a static list
+ }
+
+
+ @Override
+ public Iterator<Set<ScanColumn>> iterator() {
+ return this;
+ }
+
+
+ @Override
+ public boolean hasNext() {
+ return !returnedOnce;
+ }
+
+
+ @Override
+ public Set<ScanColumn> next() {
+ returnedOnce = true;
+ return ids;
+ }
+
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException( "This iterator does not support remove" );
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SubtractionIterator.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SubtractionIterator.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SubtractionIterator.java
new file mode 100644
index 0000000..8475756
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/SubtractionIterator.java
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.ir.result;
+
+
+import java.util.LinkedHashSet;
+import java.util.Set;
+import java.util.UUID;
+
+import org.apache.usergrid.persistence.cassandra.CursorCache;
+
+import com.google.common.collect.Sets;
+
+
+/**
+ * Simple iterator to perform Unions
+ *
+ * @author tnine
+ */
+public class SubtractionIterator extends MergeIterator {
+
+ private ResultIterator keepIterator;
+ private ResultIterator subtractIterator;
+
+
+ public SubtractionIterator( int pageSize ) {
+ super( pageSize );
+ }
+
+
+ /** @param subtractIterator the subtractIterator to set */
+ public void setSubtractIterator( ResultIterator subtractIterator ) {
+ this.subtractIterator = subtractIterator;
+ }
+
+
+ /** @param keepIterator the keepIterator to set */
+ public void setKeepIterator( ResultIterator keepIterator ) {
+ this.keepIterator = keepIterator;
+ }
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.usergrid.persistence.query.ir.result.ResultIterator#reset()
+ */
+ @Override
+ public void doReset() {
+ keepIterator.reset();
+ subtractIterator.reset();
+ }
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.usergrid.persistence.query.ir.result.MergeIterator#advance()
+ */
+ @Override
+ protected Set<ScanColumn> advance() {
+ if ( !keepIterator.hasNext() ) {
+ return null;
+ }
+
+ Set<ScanColumn> results = new LinkedHashSet<ScanColumn>( pageSize );
+
+ while ( keepIterator.hasNext() && results.size() < pageSize ) {
+
+ Set<ScanColumn> keepPage = keepIterator.next();
+
+ while ( subtractIterator.hasNext() && keepPage.size() > 0 ) {
+ keepPage = Sets.difference( keepPage, subtractIterator.next() );
+ }
+
+ subtractIterator.reset();
+
+ results.addAll( keepPage );
+ }
+
+ return results;
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.apache.usergrid.persistence.query.ir.result.ResultIterator#finalizeCursor(org.apache.usergrid.persistence.cassandra
+ * .CursorCache)
+ */
+ @Override
+ public void finalizeCursor( CursorCache cache, UUID lastLoaded ) {
+ //we can only keep a cursor on our keep result set, we must subtract from every page of keep when loading
+ // results
+ keepIterator.finalizeCursor( cache, lastLoaded );
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/UUIDIndexSliceParser.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/UUIDIndexSliceParser.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/UUIDIndexSliceParser.java
new file mode 100644
index 0000000..fecbc24
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/UUIDIndexSliceParser.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.ir.result;
+
+
+import java.nio.ByteBuffer;
+import java.util.UUID;
+
+import me.prettyprint.cassandra.serializers.UUIDSerializer;
+
+
+/**
+ * Parser for reading and writing secondary index composites
+ *
+ * @author tnine
+ */
+public class UUIDIndexSliceParser implements SliceParser {
+
+ private static final UUIDSerializer SERIALIZER = UUIDSerializer.get();
+
+
+ /* (non-Javadoc)
+ * @see org.apache.usergrid.persistence.query.ir.result.SliceParser#parse(java.nio.ByteBuffer)
+ */
+ @Override
+ public ScanColumn parse( ByteBuffer buff ) {
+ return new UUIDColumn( SERIALIZER.fromByteBuffer( buff.duplicate() ), buff );
+ }
+
+
+ public static class UUIDColumn extends AbstractScanColumn {
+
+ public UUIDColumn( UUID uuid, ByteBuffer buffer ) {
+ super( uuid, buffer );
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/UnionIterator.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/UnionIterator.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/UnionIterator.java
new file mode 100644
index 0000000..9630eda
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/ir/result/UnionIterator.java
@@ -0,0 +1,252 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.ir.result;
+
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
+
+import org.apache.usergrid.persistence.cassandra.CursorCache;
+import org.apache.usergrid.utils.UUIDUtils;
+
+import me.prettyprint.cassandra.serializers.UUIDSerializer;
+
+
+/**
+ * Simple iterator to perform Unions
+ *
+ * @author tnine
+ */
+public class UnionIterator extends MultiIterator {
+
+ private static final ScanColumnComparator COMP = new ScanColumnComparator();
+
+ private static final UUIDSerializer UUID_SERIALIZER = UUIDSerializer.get();
+
+
+ private SortedColumnList list;
+
+ private final int id;
+
+
+ /**
+ * @param pageSize The page size to return
+ * @param id The id assigned to this node
+ * @param minUuid The minimum UUID to return
+ */
+ public UnionIterator( int pageSize, int id, ByteBuffer minUuid ) {
+ super( pageSize );
+
+ this.id = id;
+
+ UUID parseMinUuid = null;
+
+ if(minUuid != null) {
+ parseMinUuid = UUID_SERIALIZER.fromByteBuffer( minUuid );
+ }
+
+ list = new SortedColumnList( pageSize, parseMinUuid );
+ }
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.usergrid.persistence.query.ir.result.MergeIterator#advance()
+ */
+ @Override
+ protected Set<ScanColumn> advance() {
+
+ int size = iterators.size();
+
+ if ( size == 0 ) {
+ return null;
+ }
+
+
+ list.clear();
+
+ for ( ResultIterator itr : iterators ) {
+
+ while ( itr.hasNext() ) {
+ list.addAll( itr.next() );
+ }
+
+ itr.reset();
+ }
+
+ //mark us for the next page
+ list.mark();
+
+
+ return list.asSet();
+ }
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.apache.usergrid.persistence.query.ir.result.ResultIterator#finalizeCursor(
+ * org.apache.usergrid.persistence.cassandra.CursorCache)
+ */
+ @Override
+ public void finalizeCursor( CursorCache cache, UUID lastLoaded ) {
+
+ ByteBuffer buff = UUIDSerializer.get().toByteBuffer( lastLoaded );
+ cache.setNextCursor( id, buff );
+ //get our scan column and put them in the cache
+ //we finalize the cursor of the min
+ }
+
+
+ /**
+ * A Sorted Set with a max size. When a new entry is added, the max is removed. You can mark the next "min" by
+ * calling the mark method. Values > min are accepted. Values > min and that are over size are discarded
+ */
+ public static final class SortedColumnList {
+
+ private static final ScanColumnComparator COMP = new ScanColumnComparator();
+
+ private final int maxSize;
+
+ private final List<ScanColumn> list;
+
+
+ private ScanColumn min;
+
+
+ public SortedColumnList( final int maxSize, final UUID minUuid ) {
+ //we need to allocate the extra space if required
+ this.list = new ArrayList<ScanColumn>( maxSize );
+ this.maxSize = maxSize;
+
+ if ( minUuid != null ) {
+ min = new AbstractScanColumn( minUuid, null ) {};
+ }
+ }
+
+
+ /**
+ * Add the column to this list
+ */
+ public void add( ScanColumn col ) {
+ //less than our min, don't add
+ if ( COMP.compare( min, col ) >= 0 ) {
+ return;
+ }
+
+ int index = Collections.binarySearch( this.list, col, COMP );
+
+ //already present
+ if ( index > -1 ) {
+ return;
+ }
+
+ index = ( index * -1 ) - 1;
+
+ //outside the renage
+ if ( index >= maxSize ) {
+ return;
+ }
+
+ this.list.add( index, col );
+
+ final int size = this.list.size();
+
+ if ( size > maxSize ) {
+ this.list.subList( maxSize, size ).clear();
+ }
+ }
+
+
+ /**
+ * Add all the elements to this list
+ */
+ public void addAll( final Collection<? extends ScanColumn> cols ) {
+ for ( ScanColumn col : cols ) {
+ add( col );
+ }
+ }
+
+
+ /**
+ * Returns a new list. If no elements are present, returns null
+ */
+ public Set<ScanColumn> asSet() {
+ if ( this.list.size() == 0 ) {
+ return null;
+ }
+
+ return new LinkedHashSet<ScanColumn>( this.list );
+ }
+
+
+ /**
+ * Mark our last element in the tree as the max
+ */
+ public void mark() {
+
+ final int size = this.list.size();
+
+ //we don't have any elements in the list, and we've never set a min
+ if ( size == 0 ) {
+ return;
+ }
+
+ min = this.list.get( size - 1 );
+ }
+
+
+ /**
+ * Clear the list
+ */
+ public void clear() {
+ this.list.clear();
+ }
+ }
+
+
+ /**
+ * Simple comparator for comparing scan columns. Orders them by time uuid
+ */
+ private static class ScanColumnComparator implements Comparator<ScanColumn> {
+
+ @Override
+ public int compare( final ScanColumn o1, final ScanColumn o2 ) {
+ if ( o1 == null ) {
+ if ( o2 == null ) {
+ return 0;
+ }
+
+ return -1;
+ }
+
+ else if ( o2 == null ) {
+ return 1;
+ }
+
+ return UUIDUtils.compare( o1.getUUID(), o2.getUUID() );
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/.gitignore
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/.gitignore b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/.gitignore
new file mode 100644
index 0000000..65eb766
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/.gitignore
@@ -0,0 +1,2 @@
+/QueryFilterLexer.java
+/QueryFilterParser.java
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/AndOperand.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/AndOperand.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/AndOperand.java
new file mode 100644
index 0000000..e4c82ed
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/AndOperand.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.tree;
+
+
+import org.antlr.runtime.CommonToken;
+import org.antlr.runtime.Token;
+import org.apache.usergrid.persistence.exceptions.PersistenceException;
+
+
+/** @author tnine */
+public class AndOperand extends BooleanOperand {
+
+ public AndOperand() {
+ super( new CommonToken( 0, "and" ) );
+ }
+
+
+ public AndOperand( Token t ) {
+ super( t );
+ }
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.apache.usergrid.persistence.query.tree.Operand#visit(org.apache.usergrid.persistence
+ * .query.tree.QueryVisitor)
+ */
+ @Override
+ public void visit( QueryVisitor visitor ) throws PersistenceException {
+ visitor.visit( this );
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/BooleanLiteral.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/BooleanLiteral.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/BooleanLiteral.java
new file mode 100644
index 0000000..e624e25
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/BooleanLiteral.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.tree;
+
+
+import org.antlr.runtime.ClassicToken;
+import org.antlr.runtime.Token;
+
+
+/** @author tnine */
+public class BooleanLiteral extends Literal<Boolean> {
+
+ private boolean value;
+
+
+ /**
+ * @param t
+ */
+ protected BooleanLiteral( Token t ) {
+ super( t );
+ value = Boolean.valueOf( t.getText() );
+ }
+
+
+ /** The boolean literal */
+ public BooleanLiteral( boolean value ) {
+ super( new ClassicToken( 0, String.valueOf( value ) ) );
+ this.value = value;
+ }
+
+
+ public Boolean getValue() {
+ return value;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/BooleanOperand.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/BooleanOperand.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/BooleanOperand.java
new file mode 100644
index 0000000..ecf5451
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/BooleanOperand.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.tree;
+
+
+import org.antlr.runtime.Token;
+
+
+/**
+ * A base class for any equality expression. Expressions must have a property and a value. Examples are >=, >, =, <,
+ * <=,
+ *
+ * @author tnine
+ */
+public abstract class BooleanOperand extends Operand {
+
+
+ /**
+ * @param property
+ * @param literal
+ */
+ public BooleanOperand( Token t ) {
+ super( t );
+ }
+
+
+ public Operand getLeft() {
+ return ( Operand ) this.children.get( 0 );
+ }
+
+
+ public Operand getRight() {
+ return ( Operand ) this.children.get( 1 );
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/ContainsOperand.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/ContainsOperand.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/ContainsOperand.java
new file mode 100644
index 0000000..aa75a1e
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/ContainsOperand.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.tree;
+
+
+import org.antlr.runtime.Token;
+import org.apache.usergrid.persistence.exceptions.PersistenceException;
+
+
+/** @author tnine */
+public class ContainsOperand extends EqualityOperand {
+
+ /**
+ * @param property
+ * @param literal
+ */
+ public ContainsOperand( Token t ) {
+ super( t );
+ }
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.apache.usergrid.persistence.query.tree.Operand#visit(org.apache.usergrid.persistence
+ * .query.tree.QueryVisitor)
+ */
+ @Override
+ public void visit( QueryVisitor visitor ) throws PersistenceException {
+ visitor.visit( this );
+ }
+
+
+ public StringLiteral getString() {
+ return ( StringLiteral ) getLiteral();
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.apache.usergrid.persistence.query.tree.EqualityOperand#newProperty(java.lang.String)
+ */
+ @Override
+ protected Property newProperty( String name ) {
+ return new ContainsProperty( name );
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.apache.usergrid.persistence.query.tree.EqualityOperand#getProperty()
+ */
+ @Override
+ public ContainsProperty getProperty() {
+ return ( ContainsProperty ) this.children.get( 0 );
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/ContainsProperty.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/ContainsProperty.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/ContainsProperty.java
new file mode 100644
index 0000000..1e35af6
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/ContainsProperty.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.tree;
+
+
+import org.antlr.runtime.ClassicToken;
+import org.antlr.runtime.Token;
+
+
+/**
+ * A property for full text searching that requires special renaming
+ *
+ * @author tnine
+ */
+public class ContainsProperty extends Property {
+
+ private String indexedName = null;
+
+
+ public ContainsProperty( Token t ) {
+ super( t );
+ this.indexedName = String.format( "%s.keywords", super.getValue() );
+ }
+
+
+ public ContainsProperty( String property ) {
+ this( new ClassicToken( 0, property ) );
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.apache.usergrid.persistence.query.tree.Property#getIndexedValue()
+ */
+ @Override
+ public String getIndexedValue() {
+ return this.indexedName;
+ }
+
+
+ /** @return the property */
+ public ContainsProperty getProperty() {
+ return ( ContainsProperty ) this.children.get( 0 );
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/Equal.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/Equal.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/Equal.java
new file mode 100644
index 0000000..d4d4406
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/Equal.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.tree;
+
+
+import org.antlr.runtime.ClassicToken;
+import org.antlr.runtime.Token;
+import org.apache.usergrid.persistence.exceptions.NoIndexException;
+
+
+/** @author tnine */
+public class Equal extends EqualityOperand {
+
+ /**
+ * @param property
+ * @param literal
+ */
+ public Equal( Token t ) {
+ super( t );
+ }
+
+
+ public Equal() {
+ super( new ClassicToken( 0, "=" ) );
+ }
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.apache.usergrid.persistence.query.tree.Operand#visit(org.apache.usergrid.persistence
+ * .query.tree.QueryVisitor)
+ */
+ @Override
+ public void visit( QueryVisitor visitor ) throws NoIndexException {
+ visitor.visit( this );
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/EqualityOperand.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/EqualityOperand.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/EqualityOperand.java
new file mode 100644
index 0000000..1e3cbc9
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/EqualityOperand.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.tree;
+
+
+import org.antlr.runtime.Token;
+
+
+/**
+ * A base class for any equality expression. Expressions must have a property and a value. Examples are >=, >, =, <,
+ * <=,
+ *
+ * @author tnine
+ */
+public abstract class EqualityOperand extends Operand {
+
+ /**
+ * @param property
+ * @param literal
+ */
+ public EqualityOperand( Token t ) {
+ super( t );
+ }
+
+
+ public EqualityOperand( String propName, Literal<?> value ) {
+ super( null );
+ }
+
+
+ /** Set the property on this operand */
+ public void setProperty( String name ) {
+ setAtIndex( 0, newProperty( name ) );
+ }
+
+
+ /** Get the property to set into the equality. Allows subclasses to override the type */
+ protected Property newProperty( String name ) {
+ return new Property( name );
+ }
+
+
+ /** Set the literal on this operand from the given value */
+ public void setLiteral( Object value ) {
+ setAtIndex( 1, LiteralFactory.getLiteral( value ) );
+ }
+
+
+ /** Set the child at the specified index. If it doesn't exist, it's added until it does */
+ @SuppressWarnings("unchecked")
+ private void setAtIndex( int index, Literal<?> value ) {
+
+ if ( children == null ) {
+ children = createChildrenList();
+ }
+
+ while ( children.size() - 1 < index ) {
+ children.add( null );
+ }
+
+ setChild( index, value );
+ }
+
+
+ /** @return the property */
+ public Property getProperty() {
+ return ( Property ) this.children.get( 0 );
+ }
+
+
+ /** @return the literal */
+ public Literal<?> getLiteral() {
+ return ( Literal<?> ) this.children.get( 1 );
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/FloatLiteral.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/FloatLiteral.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/FloatLiteral.java
new file mode 100644
index 0000000..6363234
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/FloatLiteral.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.tree;
+
+
+import org.antlr.runtime.ClassicToken;
+import org.antlr.runtime.Token;
+
+
+/** @author tnine */
+public class FloatLiteral extends Literal<Float> implements NumericLiteral {
+
+ private float value;
+
+
+ /**
+ * @param t
+ */
+ public FloatLiteral( Token t ) {
+ super( t );
+ value = Float.valueOf( t.getText() );
+ }
+
+
+ public FloatLiteral( float f ) {
+ super( new ClassicToken( 0, String.valueOf( f ) ) );
+ value = f;
+ }
+
+
+ /** @return the value */
+ public Float getValue() {
+ return value;
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.apache.usergrid.persistence.query.tree.NumericLiteral#getFloatValue()
+ */
+ @Override
+ public float getFloatValue() {
+ return value;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/GreaterThan.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/GreaterThan.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/GreaterThan.java
new file mode 100644
index 0000000..0f6495f
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/GreaterThan.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.tree;
+
+
+import org.antlr.runtime.CommonToken;
+import org.antlr.runtime.Token;
+import org.apache.usergrid.persistence.exceptions.NoIndexException;
+
+
+/** @author tnine */
+public class GreaterThan extends EqualityOperand {
+
+ /**
+ * @param property
+ * @param literal
+ */
+ public GreaterThan( Token t ) {
+ super( t );
+ }
+
+
+ public GreaterThan() {
+ super( new CommonToken( 0, ">" ) );
+ }
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.apache.usergrid.persistence.query.tree.Operand#visit(org.apache.usergrid.persistence
+ * .query.tree.QueryVisitor)
+ */
+ @Override
+ public void visit( QueryVisitor visitor ) throws NoIndexException {
+ visitor.visit( this );
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/GreaterThanEqual.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/GreaterThanEqual.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/GreaterThanEqual.java
new file mode 100644
index 0000000..5d5d431
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/GreaterThanEqual.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.tree;
+
+
+import org.antlr.runtime.CommonToken;
+import org.antlr.runtime.Token;
+import org.apache.usergrid.persistence.exceptions.NoIndexException;
+
+
+/** @author tnine */
+public class GreaterThanEqual extends EqualityOperand {
+
+ /**
+ * @param property
+ * @param literal
+ */
+ public GreaterThanEqual( Token t ) {
+ super( t );
+ }
+
+
+ /**
+ * @param property
+ * @param literal
+ */
+ public GreaterThanEqual() {
+ super( new CommonToken( 0, ">=" ) );
+ }
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.apache.usergrid.persistence.query.tree.Operand#visit(org.apache.usergrid.persistence
+ * .query.tree.QueryVisitor)
+ */
+ @Override
+ public void visit( QueryVisitor visitor ) throws NoIndexException {
+ visitor.visit( this );
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/LessThan.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/LessThan.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/LessThan.java
new file mode 100644
index 0000000..a3c7979
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/LessThan.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.tree;
+
+
+import org.antlr.runtime.CommonToken;
+import org.antlr.runtime.Token;
+import org.apache.usergrid.persistence.exceptions.NoIndexException;
+
+
+/** @author tnine */
+public class LessThan extends EqualityOperand {
+
+ /**
+ * @param property
+ * @param literal
+ */
+ public LessThan( Token t ) {
+ super( t );
+ }
+
+
+ public LessThan() {
+ super( new CommonToken( 0, "<" ) );
+ }
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.apache.usergrid.persistence.query.tree.Operand#visit(org.apache.usergrid.persistence
+ * .query.tree.QueryVisitor)
+ */
+ @Override
+ public void visit( QueryVisitor visitor ) throws NoIndexException {
+ visitor.visit( this );
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/LessThanEqual.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/LessThanEqual.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/LessThanEqual.java
new file mode 100644
index 0000000..7638721
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/LessThanEqual.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.tree;
+
+
+import org.antlr.runtime.CommonToken;
+import org.antlr.runtime.Token;
+import org.apache.usergrid.persistence.exceptions.NoIndexException;
+
+
+/** @author tnine */
+public class LessThanEqual extends EqualityOperand {
+
+ /**
+ * @param property
+ * @param literal
+ */
+ public LessThanEqual( Token t ) {
+ super( t );
+ }
+
+
+ /**
+ */
+ public LessThanEqual() {
+ super( new CommonToken( 0, "<=" ) );
+ }
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.apache.usergrid.persistence.query.tree.Operand#visit(org.apache.usergrid.persistence
+ * .query.tree.QueryVisitor)
+ */
+ @Override
+ public void visit( QueryVisitor visitor ) throws NoIndexException {
+ visitor.visit( this );
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/Literal.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/Literal.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/Literal.java
new file mode 100644
index 0000000..60071c4
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/Literal.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.tree;
+
+
+import org.antlr.runtime.Token;
+import org.antlr.runtime.tree.CommonTree;
+
+
+/**
+ * Abstract class for literals
+ *
+ * @author tnine
+ */
+public abstract class Literal<V> extends CommonTree {
+
+
+ protected Literal( Token t ) {
+ super( t );
+ }
+
+
+ /** Return the value of the literal the user has passed in */
+ public abstract V getValue();
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/LiteralFactory.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/LiteralFactory.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/LiteralFactory.java
new file mode 100644
index 0000000..cc69f9d
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/LiteralFactory.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.tree;
+
+
+import java.util.UUID;
+
+
+/**
+ * Simple factory for generating literal instance based on the runtime value
+ *
+ * @author tnine
+ */
+public class LiteralFactory {
+
+ /** Generate the correct literal subclass based on the runtime instance. */
+ public static final Literal<?> getLiteral( Object value ) {
+ if ( value instanceof Integer ) {
+ return new LongLiteral( ( Integer ) value );
+ }
+ if ( value instanceof Long ) {
+ return new LongLiteral( ( Long ) value );
+ }
+
+ if ( value instanceof String ) {
+ return new StringLiteral( ( String ) value );
+ }
+
+ if ( value instanceof Float ) {
+ return new FloatLiteral( ( Float ) value );
+ }
+
+ if ( value instanceof UUID ) {
+ return new UUIDLiteral( ( UUID ) value );
+ }
+
+ if ( value instanceof Boolean ) {
+ return new BooleanLiteral( ( Boolean ) value );
+ }
+
+ throw new UnsupportedOperationException(
+ String.format( "Unsupported type of %s was passed when trying to construct a literal",
+ value.getClass() ) );
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/LongLiteral.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/LongLiteral.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/LongLiteral.java
new file mode 100644
index 0000000..8f1b084
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/LongLiteral.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.tree;
+
+
+import org.antlr.runtime.ClassicToken;
+import org.antlr.runtime.Token;
+
+
+/** @author tnine */
+public class LongLiteral extends Literal<Long> implements NumericLiteral {
+
+ private long value;
+
+
+ /**
+ * @param t
+ */
+ public LongLiteral( Token t ) {
+ super( t );
+ this.value = Long.valueOf( t.getText() );
+ }
+
+
+ /**
+ *
+ * @param value
+ */
+ public LongLiteral( long value ) {
+ super( new ClassicToken( 0, String.valueOf( value ) ) );
+ this.value = value;
+ }
+
+
+ /**
+ *
+ * @return
+ */
+ public Long getValue() {
+ return this.value;
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.apache.usergrid.persistence.query.tree.NumericLiteral#getFloatValue()
+ */
+ @Override
+ public float getFloatValue() {
+ return value;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/NotOperand.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/NotOperand.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/NotOperand.java
new file mode 100644
index 0000000..8388e5d
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/NotOperand.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.tree;
+
+
+import org.antlr.runtime.Token;
+import org.apache.usergrid.persistence.exceptions.PersistenceException;
+
+
+/** @author tnine */
+public class NotOperand extends Operand {
+
+
+ public NotOperand( Token t ) {
+ super( t );
+ }
+
+
+ /** get the only child operation */
+ public Operand getOperation() {
+ return ( Operand ) this.children.get( 0 );
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.apache.usergrid.persistence.query.tree.Operand#visit(org.apache.usergrid.persistence.query.tree.QueryVisitor)
+ */
+ @Override
+ public void visit( QueryVisitor visitor ) throws PersistenceException {
+ visitor.visit( this );
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/NumericLiteral.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/NumericLiteral.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/NumericLiteral.java
new file mode 100644
index 0000000..96d5f49
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/NumericLiteral.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.tree;
+
+
+/** @author tnine */
+public interface NumericLiteral {
+
+ /** Return the value of this numeric literal as a float */
+ public float getFloatValue();
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/Operand.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/Operand.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/Operand.java
new file mode 100644
index 0000000..0f59ca8
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/Operand.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.tree;
+
+
+import org.antlr.runtime.Token;
+import org.antlr.runtime.tree.CommonTree;
+import org.apache.usergrid.persistence.exceptions.PersistenceException;
+
+
+/**
+ * Any logical operation should subclass. Boolean logic, equality, not, contains, within and others are examples of
+ * operands
+ *
+ * @author tnine
+ */
+public abstract class Operand extends CommonTree {
+
+
+ /** Default constructor to take a token */
+ public Operand( Token t ) {
+ super( t );
+ }
+
+
+ /** Get the pointer to the parent node */
+ public Operand getParent() {
+ return ( Operand ) super.getParent();
+ }
+
+
+ /** Visitor method */
+ public abstract void visit( QueryVisitor visitor ) throws PersistenceException;
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/OrOperand.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/OrOperand.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/OrOperand.java
new file mode 100644
index 0000000..1771dbc
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/OrOperand.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.tree;
+
+
+import org.antlr.runtime.CommonToken;
+import org.antlr.runtime.Token;
+import org.apache.usergrid.persistence.exceptions.PersistenceException;
+
+
+/** @author tnine */
+public class OrOperand extends BooleanOperand {
+
+ /**
+ * @param left
+ * @param token
+ * @param right
+ */
+ public OrOperand( Token t ) {
+ super( t );
+ }
+
+
+ public OrOperand() {
+ super( new CommonToken( 0, "or" ) );
+ }
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.apache.usergrid.persistence.query.tree.Operand#visit(org.apache.usergrid.persistence
+ * .query.tree.QueryVisitor)
+ */
+ @Override
+ public void visit( QueryVisitor visitor ) throws PersistenceException {
+ visitor.visit( this );
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/Property.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/Property.java b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/Property.java
new file mode 100644
index 0000000..36028c8
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/query/tree/Property.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright 2012 Apigee Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package org.apache.usergrid.persistence.query.tree;
+
+
+import org.antlr.runtime.ClassicToken;
+import org.antlr.runtime.Token;
+
+
+/**
+ * A property
+ *
+ * @author tnine
+ */
+public class Property extends Literal<String> {
+
+ private String property;
+
+
+ public Property( Token t ) {
+ super( t );
+ this.property = t.getText();
+ }
+
+
+ public Property( String property ) {
+ this( new ClassicToken( 0, property ) );
+ }
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.usergrid.persistence.query.tree.Literal#getValue()
+ */
+ @Override
+ public String getValue() {
+ return this.property;
+ }
+
+
+ /**
+ * Subclasses an override. Indexed value could be different when stored internally. By default returns the same
+ * property
+ */
+ public String getIndexedValue() {
+ return this.property;
+ }
+}