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:56 UTC
[46/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/mq/QueryFilterParser.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/mq/QueryFilterParser.java b/stack/core/src/main/java/org/apache/usergrid/mq/QueryFilterParser.java
new file mode 100644
index 0000000..3450d1b
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/mq/QueryFilterParser.java
@@ -0,0 +1,1102 @@
+// $ANTLR 3.1.3 Mar 17, 2009 19:23:44 org.apache.usergrid/persistence/query/QueryFilter.g 2012-03-07 22:54:28
+
+package org.apache.usergrid.mq;
+
+
+import org.antlr.runtime.BitSet;
+import org.antlr.runtime.MismatchedSetException;
+import org.antlr.runtime.NoViableAltException;
+import org.antlr.runtime.Parser;
+import org.antlr.runtime.ParserRuleReturnScope;
+import org.antlr.runtime.RecognitionException;
+import org.antlr.runtime.RecognizerSharedState;
+import org.antlr.runtime.Token;
+import org.antlr.runtime.TokenStream;
+import org.apache.usergrid.mq.Query.FilterPredicate;
+import org.apache.usergrid.mq.Query.SortPredicate;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class QueryFilterParser extends Parser {
+ public static final String[] tokenNames = new String[] {
+ "<invalid>", "<EOR>", "<DOWN>", "<UP>", "ID", "INT", "EXPONENT", "FLOAT", "ESC_SEQ", "STRING", "BOOLEAN",
+ "HEX_DIGIT", "UUID", "UNICODE_ESC", "OCTAL_ESC", "WS", "'<'", "'<='", "'='", "'>'", "'>='", "'in'", "'eq'",
+ "'lt'", "'gt'", "'lte'", "'gte'", "'contains'", "'within'", "','", "'of'", "':'", "'asc'", "'desc'", "'*'",
+ "'{'", "'}'", "'select'", "'where'", "'and'", "'order by'"
+ };
+ public static final int T__40 = 40;
+ public static final int EXPONENT = 6;
+ public static final int T__29 = 29;
+ public static final int T__28 = 28;
+ public static final int T__27 = 27;
+ public static final int T__26 = 26;
+ public static final int UUID = 12;
+ public static final int T__25 = 25;
+ public static final int T__24 = 24;
+ public static final int T__23 = 23;
+ public static final int T__22 = 22;
+ public static final int T__21 = 21;
+ public static final int UNICODE_ESC = 13;
+ public static final int T__20 = 20;
+ public static final int OCTAL_ESC = 14;
+ public static final int HEX_DIGIT = 11;
+ public static final int FLOAT = 7;
+ public static final int INT = 5;
+ public static final int ID = 4;
+ public static final int EOF = -1;
+ public static final int T__19 = 19;
+ public static final int T__30 = 30;
+ public static final int T__31 = 31;
+ public static final int T__32 = 32;
+ public static final int WS = 15;
+ public static final int BOOLEAN = 10;
+ public static final int ESC_SEQ = 8;
+ public static final int T__33 = 33;
+ public static final int T__16 = 16;
+ public static final int T__34 = 34;
+ public static final int T__35 = 35;
+ public static final int T__18 = 18;
+ public static final int T__36 = 36;
+ public static final int T__17 = 17;
+ public static final int T__37 = 37;
+ public static final int T__38 = 38;
+ public static final int T__39 = 39;
+ public static final int STRING = 9;
+
+ // delegates
+ // delegators
+
+
+ public QueryFilterParser( TokenStream input ) {
+ this( input, new RecognizerSharedState() );
+ }
+
+
+ public QueryFilterParser( TokenStream input, RecognizerSharedState state ) {
+ super( input, state );
+ }
+
+
+ public String[] getTokenNames() { return QueryFilterParser.tokenNames; }
+
+
+ public String getGrammarFileName() { return "org.apache.usergrid/persistence/query/QueryFilter.g"; }
+
+
+ Query query = new Query();
+
+ private static final Logger logger = LoggerFactory.getLogger( QueryFilterLexer.class );
+
+
+ @Override
+ public void emitErrorMessage( String msg ) {
+ logger.info( msg );
+ }
+
+
+ public static class property_return extends ParserRuleReturnScope {}
+
+
+ ;
+
+
+ // $ANTLR start "property"
+ // org.apache.usergrid/persistence/query/QueryFilter.g:101:1: property : ( ID ) ;
+ public final QueryFilterParser.property_return property() throws RecognitionException {
+ QueryFilterParser.property_return retval = new QueryFilterParser.property_return();
+ retval.start = input.LT( 1 );
+
+ try {
+ // org.apache.usergrid/persistence/query/QueryFilter.g:102:2: ( ( ID ) )
+ // org.apache.usergrid/persistence/query/QueryFilter.g:102:5: ( ID )
+ {
+ // org.apache.usergrid/persistence/query/QueryFilter.g:102:5: ( ID )
+ // org.apache.usergrid/persistence/query/QueryFilter.g:102:6: ID
+ {
+ match( input, ID, FOLLOW_ID_in_property597 );
+ }
+ }
+
+ retval.stop = input.LT( -1 );
+ }
+ catch ( RecognitionException re ) {
+ reportError( re );
+ recover( input, re );
+ }
+ finally {
+ }
+ return retval;
+ }
+ // $ANTLR end "property"
+
+
+ public static class operator_return extends ParserRuleReturnScope {}
+
+
+ ;
+
+
+ // $ANTLR start "operator"
+ // org.apache.usergrid/persistence/query/QueryFilter.g:104:1: operator : ( '<' | '<=' | '=' | '>' | '>=' | 'in' | 'eq' |
+ // 'lt' | 'gt' | 'lte' | 'gte' | 'contains' | 'within' ) ;
+ public final QueryFilterParser.operator_return operator() throws RecognitionException {
+ QueryFilterParser.operator_return retval = new QueryFilterParser.operator_return();
+ retval.start = input.LT( 1 );
+
+ try {
+ // org.apache.usergrid/persistence/query/QueryFilter.g:105:2: ( ( '<' | '<=' | '=' | '>' | '>=' | 'in' | 'eq' |
+ // 'lt' | 'gt' | 'lte' | 'gte' | 'contains' | 'within' ) )
+ // org.apache.usergrid/persistence/query/QueryFilter.g:105:4: ( '<' | '<=' | '=' | '>' | '>=' | 'in' | 'eq' |
+ // 'lt' | 'gt' | 'lte' | 'gte' | 'contains' | 'within' )
+ {
+ if ( ( input.LA( 1 ) >= 16 && input.LA( 1 ) <= 28 ) ) {
+ input.consume();
+ state.errorRecovery = false;
+ }
+ else {
+ MismatchedSetException mse = new MismatchedSetException( null, input );
+ throw mse;
+ }
+ }
+
+ retval.stop = input.LT( -1 );
+ }
+ catch ( RecognitionException re ) {
+ reportError( re );
+ recover( input, re );
+ }
+ finally {
+ }
+ return retval;
+ }
+ // $ANTLR end "operator"
+
+
+ public static class value_return extends ParserRuleReturnScope {}
+
+
+ ;
+
+
+ // $ANTLR start "value"
+ // org.apache.usergrid/persistence/query/QueryFilter.g:107:1: value : ( BOOLEAN | STRING | INT | FLOAT | UUID ) ;
+ public final QueryFilterParser.value_return value() throws RecognitionException {
+ QueryFilterParser.value_return retval = new QueryFilterParser.value_return();
+ retval.start = input.LT( 1 );
+
+ try {
+ // org.apache.usergrid/persistence/query/QueryFilter.g:107:8: ( ( BOOLEAN | STRING | INT | FLOAT | UUID ) )
+ // org.apache.usergrid/persistence/query/QueryFilter.g:107:10: ( BOOLEAN | STRING | INT | FLOAT | UUID )
+ {
+ if ( input.LA( 1 ) == INT || input.LA( 1 ) == FLOAT || ( input.LA( 1 ) >= STRING
+ && input.LA( 1 ) <= BOOLEAN ) || input.LA( 1 ) == UUID ) {
+ input.consume();
+ state.errorRecovery = false;
+ }
+ else {
+ MismatchedSetException mse = new MismatchedSetException( null, input );
+ throw mse;
+ }
+ }
+
+ retval.stop = input.LT( -1 );
+ }
+ catch ( RecognitionException re ) {
+ reportError( re );
+ recover( input, re );
+ }
+ finally {
+ }
+ return retval;
+ }
+ // $ANTLR end "value"
+
+
+ public static class second_value_return extends ParserRuleReturnScope {}
+
+
+ ;
+
+
+ // $ANTLR start "second_value"
+ // org.apache.usergrid/persistence/query/QueryFilter.g:109:1: second_value : ( BOOLEAN | STRING | INT | FLOAT | UUID ) ;
+ public final QueryFilterParser.second_value_return second_value() throws RecognitionException {
+ QueryFilterParser.second_value_return retval = new QueryFilterParser.second_value_return();
+ retval.start = input.LT( 1 );
+
+ try {
+ // org.apache.usergrid/persistence/query/QueryFilter.g:109:15: ( ( BOOLEAN | STRING | INT | FLOAT | UUID ) )
+ // org.apache.usergrid/persistence/query/QueryFilter.g:109:17: ( BOOLEAN | STRING | INT | FLOAT | UUID )
+ {
+ if ( input.LA( 1 ) == INT || input.LA( 1 ) == FLOAT || ( input.LA( 1 ) >= STRING
+ && input.LA( 1 ) <= BOOLEAN ) || input.LA( 1 ) == UUID ) {
+ input.consume();
+ state.errorRecovery = false;
+ }
+ else {
+ MismatchedSetException mse = new MismatchedSetException( null, input );
+ throw mse;
+ }
+ }
+
+ retval.stop = input.LT( -1 );
+ }
+ catch ( RecognitionException re ) {
+ reportError( re );
+ recover( input, re );
+ }
+ finally {
+ }
+ return retval;
+ }
+ // $ANTLR end "second_value"
+
+
+ public static class third_value_return extends ParserRuleReturnScope {}
+
+
+ ;
+
+
+ // $ANTLR start "third_value"
+ // org.apache.usergrid/persistence/query/QueryFilter.g:111:1: third_value : ( BOOLEAN | STRING | INT | FLOAT | UUID ) ;
+ public final QueryFilterParser.third_value_return third_value() throws RecognitionException {
+ QueryFilterParser.third_value_return retval = new QueryFilterParser.third_value_return();
+ retval.start = input.LT( 1 );
+
+ try {
+ // org.apache.usergrid/persistence/query/QueryFilter.g:111:14: ( ( BOOLEAN | STRING | INT | FLOAT | UUID ) )
+ // org.apache.usergrid/persistence/query/QueryFilter.g:111:16: ( BOOLEAN | STRING | INT | FLOAT | UUID )
+ {
+ if ( input.LA( 1 ) == INT || input.LA( 1 ) == FLOAT || ( input.LA( 1 ) >= STRING
+ && input.LA( 1 ) <= BOOLEAN ) || input.LA( 1 ) == UUID ) {
+ input.consume();
+ state.errorRecovery = false;
+ }
+ else {
+ MismatchedSetException mse = new MismatchedSetException( null, input );
+ throw mse;
+ }
+ }
+
+ retval.stop = input.LT( -1 );
+ }
+ catch ( RecognitionException re ) {
+ reportError( re );
+ recover( input, re );
+ }
+ finally {
+ }
+ return retval;
+ }
+ // $ANTLR end "third_value"
+
+
+ // $ANTLR start "filter"
+ // org.apache.usergrid/persistence/query/QueryFilter.g:113:1: filter returns [FilterPredicate filter] : property
+ // operator value ( ( ',' | 'of' ) second_value ( ',' third_value )? )? EOF ;
+ public final FilterPredicate filter() throws RecognitionException {
+ FilterPredicate filter = null;
+
+ QueryFilterParser.property_return property1 = null;
+
+ QueryFilterParser.operator_return operator2 = null;
+
+ QueryFilterParser.value_return value3 = null;
+
+ QueryFilterParser.second_value_return second_value4 = null;
+
+ QueryFilterParser.third_value_return third_value5 = null;
+
+
+ try {
+ // org.apache.usergrid/persistence/query/QueryFilter.g:114:5: ( property operator value ( ( ',
+ // ' | 'of' ) second_value ( ',' third_value )? )? EOF )
+ // org.apache.usergrid/persistence/query/QueryFilter.g:114:9: property operator value ( ( ',
+ // ' | 'of' ) second_value ( ',' third_value )? )? EOF
+ {
+ pushFollow( FOLLOW_property_in_filter759 );
+ property1 = property();
+
+ state._fsp--;
+
+ pushFollow( FOLLOW_operator_in_filter761 );
+ operator2 = operator();
+
+ state._fsp--;
+
+ pushFollow( FOLLOW_value_in_filter763 );
+ value3 = value();
+
+ state._fsp--;
+
+ // org.apache.usergrid/persistence/query/QueryFilter.g:114:33: ( ( ',' | 'of' ) second_value ( ',
+ // ' third_value )? )?
+ int alt2 = 2;
+ int LA2_0 = input.LA( 1 );
+
+ if ( ( ( LA2_0 >= 29 && LA2_0 <= 30 ) ) ) {
+ alt2 = 1;
+ }
+ switch ( alt2 ) {
+ case 1:
+ // org.apache.usergrid/persistence/query/QueryFilter.g:114:34: ( ',' | 'of' ) second_value ( ',
+ // ' third_value )?
+ {
+ if ( ( input.LA( 1 ) >= 29 && input.LA( 1 ) <= 30 ) ) {
+ input.consume();
+ state.errorRecovery = false;
+ }
+ else {
+ MismatchedSetException mse = new MismatchedSetException( null, input );
+ throw mse;
+ }
+
+ pushFollow( FOLLOW_second_value_in_filter774 );
+ second_value4 = second_value();
+
+ state._fsp--;
+
+ // org.apache.usergrid/persistence/query/QueryFilter.g:114:60: ( ',' third_value )?
+ int alt1 = 2;
+ int LA1_0 = input.LA( 1 );
+
+ if ( ( LA1_0 == 29 ) ) {
+ alt1 = 1;
+ }
+ switch ( alt1 ) {
+ case 1:
+ // org.apache.usergrid/persistence/query/QueryFilter.g:114:62: ',' third_value
+ {
+ match( input, 29, FOLLOW_29_in_filter778 );
+ pushFollow( FOLLOW_third_value_in_filter780 );
+ third_value5 = third_value();
+
+ state._fsp--;
+ }
+ break;
+ }
+ }
+ break;
+ }
+
+
+ String property = ( property1 != null ? input.toString( property1.start, property1.stop ) : null );
+ String operator = ( operator2 != null ? input.toString( operator2.start, operator2.stop ) : null );
+ String value = ( value3 != null ? input.toString( value3.start, value3.stop ) : null );
+ String second_value =
+ ( second_value4 != null ? input.toString( second_value4.start, second_value4.stop ) : null );
+ String third_value =
+ ( third_value5 != null ? input.toString( third_value5.start, third_value5.stop ) : null );
+ filter = new FilterPredicate( property, operator, value, second_value, third_value );
+ //System.out.println("Parsed query filter: " + property + " " + operator + " " + value + " " +
+ // second_value);
+
+
+ match( input, EOF, FOLLOW_EOF_in_filter789 );
+ }
+ }
+ catch ( RecognitionException re ) {
+ reportError( re );
+ recover( input, re );
+ }
+ finally {
+ }
+ return filter;
+ }
+ // $ANTLR end "filter"
+
+
+ public static class select_subject_return extends ParserRuleReturnScope {}
+
+
+ ;
+
+
+ // $ANTLR start "select_subject"
+ // org.apache.usergrid/persistence/query/QueryFilter.g:127:1: select_subject : ID ;
+ public final QueryFilterParser.select_subject_return select_subject() throws RecognitionException {
+ QueryFilterParser.select_subject_return retval = new QueryFilterParser.select_subject_return();
+ retval.start = input.LT( 1 );
+
+ try {
+ // org.apache.usergrid/persistence/query/QueryFilter.g:128:2: ( ID )
+ // org.apache.usergrid/persistence/query/QueryFilter.g:128:4: ID
+ {
+ match( input, ID, FOLLOW_ID_in_select_subject800 );
+
+
+ query.addSelect( input.toString( retval.start, input.LT( -1 ) ) );
+ }
+
+ retval.stop = input.LT( -1 );
+ }
+ catch ( RecognitionException re ) {
+ reportError( re );
+ recover( input, re );
+ }
+ finally {
+ }
+ return retval;
+ }
+ // $ANTLR end "select_subject"
+
+
+ public static class select_assign_target_return extends ParserRuleReturnScope {}
+
+
+ ;
+
+
+ // $ANTLR start "select_assign_target"
+ // org.apache.usergrid/persistence/query/QueryFilter.g:134:1: select_assign_target : ID ;
+ public final QueryFilterParser.select_assign_target_return select_assign_target() throws RecognitionException {
+ QueryFilterParser.select_assign_target_return retval = new QueryFilterParser.select_assign_target_return();
+ retval.start = input.LT( 1 );
+
+ try {
+ // org.apache.usergrid/persistence/query/QueryFilter.g:135:2: ( ID )
+ // org.apache.usergrid/persistence/query/QueryFilter.g:135:4: ID
+ {
+ match( input, ID, FOLLOW_ID_in_select_assign_target812 );
+ }
+
+ retval.stop = input.LT( -1 );
+ }
+ catch ( RecognitionException re ) {
+ reportError( re );
+ recover( input, re );
+ }
+ finally {
+ }
+ return retval;
+ }
+ // $ANTLR end "select_assign_target"
+
+
+ public static class select_assign_source_return extends ParserRuleReturnScope {}
+
+
+ ;
+
+
+ // $ANTLR start "select_assign_source"
+ // org.apache.usergrid/persistence/query/QueryFilter.g:137:1: select_assign_source : ID ;
+ public final QueryFilterParser.select_assign_source_return select_assign_source() throws RecognitionException {
+ QueryFilterParser.select_assign_source_return retval = new QueryFilterParser.select_assign_source_return();
+ retval.start = input.LT( 1 );
+
+ try {
+ // org.apache.usergrid/persistence/query/QueryFilter.g:138:2: ( ID )
+ // org.apache.usergrid/persistence/query/QueryFilter.g:138:4: ID
+ {
+ match( input, ID, FOLLOW_ID_in_select_assign_source823 );
+ }
+
+ retval.stop = input.LT( -1 );
+ }
+ catch ( RecognitionException re ) {
+ reportError( re );
+ recover( input, re );
+ }
+ finally {
+ }
+ return retval;
+ }
+ // $ANTLR end "select_assign_source"
+
+
+ // $ANTLR start "select_assign"
+ // org.apache.usergrid/persistence/query/QueryFilter.g:140:1: select_assign : select_assign_target ':'
+ // select_assign_source ;
+ public final void select_assign() throws RecognitionException {
+ QueryFilterParser.select_assign_source_return select_assign_source6 = null;
+
+ QueryFilterParser.select_assign_target_return select_assign_target7 = null;
+
+
+ try {
+ // org.apache.usergrid/persistence/query/QueryFilter.g:141:2: ( select_assign_target ':' select_assign_source )
+ // org.apache.usergrid/persistence/query/QueryFilter.g:141:4: select_assign_target ':' select_assign_source
+ {
+ pushFollow( FOLLOW_select_assign_target_in_select_assign836 );
+ select_assign_target7 = select_assign_target();
+
+ state._fsp--;
+
+ match( input, 31, FOLLOW_31_in_select_assign838 );
+ pushFollow( FOLLOW_select_assign_source_in_select_assign840 );
+ select_assign_source6 = select_assign_source();
+
+ state._fsp--;
+
+
+ query.addSelect( ( select_assign_source6 != null ?
+ input.toString( select_assign_source6.start, select_assign_source6.stop ) : null ),
+ ( select_assign_target7 != null ?
+ input.toString( select_assign_target7.start, select_assign_target7.stop ) : null ) );
+ }
+ }
+ catch ( RecognitionException re ) {
+ reportError( re );
+ recover( input, re );
+ }
+ finally {
+ }
+ return;
+ }
+ // $ANTLR end "select_assign"
+
+
+ // $ANTLR start "where"
+ // org.apache.usergrid/persistence/query/QueryFilter.g:148:1: where : ( property operator value ( ( ',
+ // ' | 'of' ) second_value ( ',' third_value )? )? ) ;
+ public final void where() throws RecognitionException {
+ QueryFilterParser.property_return property8 = null;
+
+ QueryFilterParser.operator_return operator9 = null;
+
+ QueryFilterParser.value_return value10 = null;
+
+ QueryFilterParser.second_value_return second_value11 = null;
+
+ QueryFilterParser.third_value_return third_value12 = null;
+
+
+ try {
+ // org.apache.usergrid/persistence/query/QueryFilter.g:149:2: ( ( property operator value ( ( ',
+ // ' | 'of' ) second_value ( ',' third_value )? )? ) )
+ // org.apache.usergrid/persistence/query/QueryFilter.g:149:4: ( property operator value ( ( ',
+ // ' | 'of' ) second_value ( ',' third_value )? )? )
+ {
+ // org.apache.usergrid/persistence/query/QueryFilter.g:149:4: ( property operator value ( ( ',
+ // ' | 'of' ) second_value ( ',' third_value )? )? )
+ // org.apache.usergrid/persistence/query/QueryFilter.g:149:5: property operator value ( ( ',
+ // ' | 'of' ) second_value ( ',' third_value )? )?
+ {
+ pushFollow( FOLLOW_property_in_where855 );
+ property8 = property();
+
+ state._fsp--;
+
+ pushFollow( FOLLOW_operator_in_where857 );
+ operator9 = operator();
+
+ state._fsp--;
+
+ pushFollow( FOLLOW_value_in_where859 );
+ value10 = value();
+
+ state._fsp--;
+
+ // org.apache.usergrid/persistence/query/QueryFilter.g:149:29: ( ( ',' | 'of' ) second_value ( ',
+ // ' third_value )? )?
+ int alt4 = 2;
+ int LA4_0 = input.LA( 1 );
+
+ if ( ( ( LA4_0 >= 29 && LA4_0 <= 30 ) ) ) {
+ alt4 = 1;
+ }
+ switch ( alt4 ) {
+ case 1:
+ // org.apache.usergrid/persistence/query/QueryFilter.g:149:30: ( ',' | 'of' ) second_value ( ',
+ // ' third_value )?
+ {
+ if ( ( input.LA( 1 ) >= 29 && input.LA( 1 ) <= 30 ) ) {
+ input.consume();
+ state.errorRecovery = false;
+ }
+ else {
+ MismatchedSetException mse = new MismatchedSetException( null, input );
+ throw mse;
+ }
+
+ pushFollow( FOLLOW_second_value_in_where870 );
+ second_value11 = second_value();
+
+ state._fsp--;
+
+ // org.apache.usergrid/persistence/query/QueryFilter.g:149:56: ( ',' third_value )?
+ int alt3 = 2;
+ int LA3_0 = input.LA( 1 );
+
+ if ( ( LA3_0 == 29 ) ) {
+ alt3 = 1;
+ }
+ switch ( alt3 ) {
+ case 1:
+ // org.apache.usergrid/persistence/query/QueryFilter.g:149:58: ',' third_value
+ {
+ match( input, 29, FOLLOW_29_in_where874 );
+ pushFollow( FOLLOW_third_value_in_where876 );
+ third_value12 = third_value();
+
+ state._fsp--;
+ }
+ break;
+ }
+ }
+ break;
+ }
+
+
+ String property = ( property8 != null ? input.toString( property8.start, property8.stop ) : null );
+ String operator = ( operator9 != null ? input.toString( operator9.start, operator9.stop ) : null );
+ String value = ( value10 != null ? input.toString( value10.start, value10.stop ) : null );
+ int value_type = ( value10 != null ? ( ( Token ) value10.start ) : null ) != null ?
+ ( value10 != null ? ( ( Token ) value10.start ) : null ).getType() : 0;
+ String second_value =
+ ( second_value11 != null ? input.toString( second_value11.start, second_value11.stop ) :
+ null );
+ int second_value_type =
+ ( second_value11 != null ? ( ( Token ) second_value11.start ) : null ) != null ?
+ ( second_value11 != null ? ( ( Token ) second_value11.start ) : null ).getType() : 0;
+ String third_value =
+ ( third_value12 != null ? input.toString( third_value12.start, third_value12.stop ) :
+ null );
+ int third_value_type =
+ ( third_value12 != null ? ( ( Token ) third_value12.start ) : null ) != null ?
+ ( third_value12 != null ? ( ( Token ) third_value12.start ) : null ).getType() : 0;
+ FilterPredicate filter =
+ new FilterPredicate( property, operator, value, value_type, second_value, second_value_type,
+ third_value, third_value_type );
+ query.addFilter( filter );
+ //System.out.println("Parsed query filter: " + property + " " + operator + " " + value + " " +
+ // second_value);
+
+
+ }
+ }
+ }
+ catch ( RecognitionException re ) {
+ reportError( re );
+ recover( input, re );
+ }
+ finally {
+ }
+ return;
+ }
+ // $ANTLR end "where"
+
+
+ public static class direction_return extends ParserRuleReturnScope {}
+
+
+ ;
+
+
+ // $ANTLR start "direction"
+ // org.apache.usergrid/persistence/query/QueryFilter.g:165:1: direction : ( 'asc' | 'desc' ) ;
+ public final QueryFilterParser.direction_return direction() throws RecognitionException {
+ QueryFilterParser.direction_return retval = new QueryFilterParser.direction_return();
+ retval.start = input.LT( 1 );
+
+ try {
+ // org.apache.usergrid/persistence/query/QueryFilter.g:165:12: ( ( 'asc' | 'desc' ) )
+ // org.apache.usergrid/persistence/query/QueryFilter.g:165:14: ( 'asc' | 'desc' )
+ {
+ if ( ( input.LA( 1 ) >= 32 && input.LA( 1 ) <= 33 ) ) {
+ input.consume();
+ state.errorRecovery = false;
+ }
+ else {
+ MismatchedSetException mse = new MismatchedSetException( null, input );
+ throw mse;
+ }
+ }
+
+ retval.stop = input.LT( -1 );
+ }
+ catch ( RecognitionException re ) {
+ reportError( re );
+ recover( input, re );
+ }
+ finally {
+ }
+ return retval;
+ }
+ // $ANTLR end "direction"
+
+
+ // $ANTLR start "order"
+ // org.apache.usergrid/persistence/query/QueryFilter.g:167:1: order : ( property ( direction )? ) ;
+ public final void order() throws RecognitionException {
+ QueryFilterParser.property_return property13 = null;
+
+ QueryFilterParser.direction_return direction14 = null;
+
+
+ try {
+ // org.apache.usergrid/persistence/query/QueryFilter.g:168:2: ( ( property ( direction )? ) )
+ // org.apache.usergrid/persistence/query/QueryFilter.g:168:4: ( property ( direction )? )
+ {
+ // org.apache.usergrid/persistence/query/QueryFilter.g:168:4: ( property ( direction )? )
+ // org.apache.usergrid/persistence/query/QueryFilter.g:168:5: property ( direction )?
+ {
+ pushFollow( FOLLOW_property_in_order909 );
+ property13 = property();
+
+ state._fsp--;
+
+ // org.apache.usergrid/persistence/query/QueryFilter.g:168:14: ( direction )?
+ int alt5 = 2;
+ int LA5_0 = input.LA( 1 );
+
+ if ( ( ( LA5_0 >= 32 && LA5_0 <= 33 ) ) ) {
+ alt5 = 1;
+ }
+ switch ( alt5 ) {
+ case 1:
+ // org.apache.usergrid/persistence/query/QueryFilter.g:168:14: direction
+ {
+ pushFollow( FOLLOW_direction_in_order911 );
+ direction14 = direction();
+
+ state._fsp--;
+ }
+ break;
+ }
+ }
+
+
+ String property = ( property13 != null ? input.toString( property13.start, property13.stop ) : null );
+ String direction =
+ ( direction14 != null ? input.toString( direction14.start, direction14.stop ) : null );
+ SortPredicate sort = new SortPredicate( property, direction );
+ query.addSort( sort );
+ System.out.println( "Parsed query order: " + property + " " + direction );
+ }
+ }
+ catch ( RecognitionException re ) {
+ reportError( re );
+ recover( input, re );
+ }
+ finally {
+ }
+ return;
+ }
+ // $ANTLR end "order"
+
+
+ // $ANTLR start "select_expr"
+ // org.apache.usergrid/persistence/query/QueryFilter.g:178:1: select_expr : ( '*' | select_subject ( ',
+ // ' select_subject )* | '{' select_assign ( ',' select_assign )* '}' ) ;
+ public final void select_expr() throws RecognitionException {
+ try {
+ // org.apache.usergrid/persistence/query/QueryFilter.g:179:2: ( ( '*' | select_subject ( ',
+ // ' select_subject )* | '{' select_assign ( ',' select_assign )* '}' ) )
+ // org.apache.usergrid/persistence/query/QueryFilter.g:179:4: ( '*' | select_subject ( ',
+ // ' select_subject )* | '{' select_assign ( ',' select_assign )* '}' )
+ {
+ // org.apache.usergrid/persistence/query/QueryFilter.g:179:4: ( '*' | select_subject ( ',
+ // ' select_subject )* | '{' select_assign ( ',' select_assign )* '}' )
+ int alt8 = 3;
+ switch ( input.LA( 1 ) ) {
+ case 34: {
+ alt8 = 1;
+ }
+ break;
+ case ID: {
+ alt8 = 2;
+ }
+ break;
+ case 35: {
+ alt8 = 3;
+ }
+ break;
+ default:
+ NoViableAltException nvae = new NoViableAltException( "", 8, 0, input );
+
+ throw nvae;
+ }
+
+ switch ( alt8 ) {
+ case 1:
+ // org.apache.usergrid/persistence/query/QueryFilter.g:179:5: '*'
+ {
+ match( input, 34, FOLLOW_34_in_select_expr925 );
+ }
+ break;
+ case 2:
+ // org.apache.usergrid/persistence/query/QueryFilter.g:179:11: select_subject ( ',' select_subject )*
+ {
+ pushFollow( FOLLOW_select_subject_in_select_expr929 );
+ select_subject();
+
+ state._fsp--;
+
+ // org.apache.usergrid/persistence/query/QueryFilter.g:179:26: ( ',' select_subject )*
+ loop6:
+ do {
+ int alt6 = 2;
+ int LA6_0 = input.LA( 1 );
+
+ if ( ( LA6_0 == 29 ) ) {
+ alt6 = 1;
+ }
+
+
+ switch ( alt6 ) {
+ case 1:
+ // org.apache.usergrid/persistence/query/QueryFilter.g:179:27: ',' select_subject
+ {
+ match( input, 29, FOLLOW_29_in_select_expr932 );
+ pushFollow( FOLLOW_select_subject_in_select_expr934 );
+ select_subject();
+
+ state._fsp--;
+ }
+ break;
+
+ default:
+ break loop6;
+ }
+ }
+ while ( true );
+ }
+ break;
+ case 3:
+ // org.apache.usergrid/persistence/query/QueryFilter.g:179:51: '{' select_assign ( ',
+ // ' select_assign )* '}'
+ {
+ match( input, 35, FOLLOW_35_in_select_expr941 );
+ pushFollow( FOLLOW_select_assign_in_select_expr943 );
+ select_assign();
+
+ state._fsp--;
+
+ // org.apache.usergrid/persistence/query/QueryFilter.g:179:69: ( ',' select_assign )*
+ loop7:
+ do {
+ int alt7 = 2;
+ int LA7_0 = input.LA( 1 );
+
+ if ( ( LA7_0 == 29 ) ) {
+ alt7 = 1;
+ }
+
+
+ switch ( alt7 ) {
+ case 1:
+ // org.apache.usergrid/persistence/query/QueryFilter.g:179:70: ',' select_assign
+ {
+ match( input, 29, FOLLOW_29_in_select_expr946 );
+ pushFollow( FOLLOW_select_assign_in_select_expr948 );
+ select_assign();
+
+ state._fsp--;
+ }
+ break;
+
+ default:
+ break loop7;
+ }
+ }
+ while ( true );
+
+ match( input, 36, FOLLOW_36_in_select_expr953 );
+ }
+ break;
+ }
+ }
+ }
+ catch ( RecognitionException re ) {
+ reportError( re );
+ recover( input, re );
+ }
+ finally {
+ }
+ return;
+ }
+ // $ANTLR end "select_expr"
+
+
+ // $ANTLR start "ql"
+ // org.apache.usergrid/persistence/query/QueryFilter.g:181:1: ql returns [Query q] : 'select' select_expr ( 'where'
+ // where ( 'and' where )* )? ( 'order by' order ( ',' order )* )? ;
+ public final Query ql() throws RecognitionException {
+ Query q = null;
+
+ try {
+ // org.apache.usergrid/persistence/query/QueryFilter.g:182:2: ( 'select' select_expr ( 'where' where ( 'and'
+ // where )* )? ( 'order by' order ( ',' order )* )? )
+ // org.apache.usergrid/persistence/query/QueryFilter.g:182:4: 'select' select_expr ( 'where' where ( 'and' where
+ // )* )? ( 'order by' order ( ',' order )* )?
+ {
+ match( input, 37, FOLLOW_37_in_ql970 );
+ pushFollow( FOLLOW_select_expr_in_ql972 );
+ select_expr();
+
+ state._fsp--;
+
+ // org.apache.usergrid/persistence/query/QueryFilter.g:182:25: ( 'where' where ( 'and' where )* )?
+ int alt10 = 2;
+ int LA10_0 = input.LA( 1 );
+
+ if ( ( LA10_0 == 38 ) ) {
+ alt10 = 1;
+ }
+ switch ( alt10 ) {
+ case 1:
+ // org.apache.usergrid/persistence/query/QueryFilter.g:182:26: 'where' where ( 'and' where )*
+ {
+ match( input, 38, FOLLOW_38_in_ql975 );
+ pushFollow( FOLLOW_where_in_ql977 );
+ where();
+
+ state._fsp--;
+
+ // org.apache.usergrid/persistence/query/QueryFilter.g:182:40: ( 'and' where )*
+ loop9:
+ do {
+ int alt9 = 2;
+ int LA9_0 = input.LA( 1 );
+
+ if ( ( LA9_0 == 39 ) ) {
+ alt9 = 1;
+ }
+
+
+ switch ( alt9 ) {
+ case 1:
+ // org.apache.usergrid/persistence/query/QueryFilter.g:182:41: 'and' where
+ {
+ match( input, 39, FOLLOW_39_in_ql980 );
+ pushFollow( FOLLOW_where_in_ql982 );
+ where();
+
+ state._fsp--;
+ }
+ break;
+
+ default:
+ break loop9;
+ }
+ }
+ while ( true );
+ }
+ break;
+ }
+
+ // org.apache.usergrid/persistence/query/QueryFilter.g:182:57: ( 'order by' order ( ',' order )* )?
+ int alt12 = 2;
+ int LA12_0 = input.LA( 1 );
+
+ if ( ( LA12_0 == 40 ) ) {
+ alt12 = 1;
+ }
+ switch ( alt12 ) {
+ case 1:
+ // org.apache.usergrid/persistence/query/QueryFilter.g:182:58: 'order by' order ( ',' order )*
+ {
+ match( input, 40, FOLLOW_40_in_ql989 );
+ pushFollow( FOLLOW_order_in_ql991 );
+ order();
+
+ state._fsp--;
+
+ // org.apache.usergrid/persistence/query/QueryFilter.g:182:75: ( ',' order )*
+ loop11:
+ do {
+ int alt11 = 2;
+ int LA11_0 = input.LA( 1 );
+
+ if ( ( LA11_0 == 29 ) ) {
+ alt11 = 1;
+ }
+
+
+ switch ( alt11 ) {
+ case 1:
+ // org.apache.usergrid/persistence/query/QueryFilter.g:182:76: ',' order
+ {
+ match( input, 29, FOLLOW_29_in_ql994 );
+ pushFollow( FOLLOW_order_in_ql996 );
+ order();
+
+ state._fsp--;
+ }
+ break;
+
+ default:
+ break loop11;
+ }
+ }
+ while ( true );
+ }
+ break;
+ }
+
+
+ q = query;
+ }
+ }
+ catch ( RecognitionException re ) {
+ reportError( re );
+ recover( input, re );
+ }
+ finally {
+ }
+ return q;
+ }
+ // $ANTLR end "ql"
+
+ // Delegated rules
+
+
+ public static final BitSet FOLLOW_ID_in_property597 = new BitSet( new long[] { 0x0000000000000002L } );
+ public static final BitSet FOLLOW_set_in_operator609 = new BitSet( new long[] { 0x0000000000000002L } );
+ public static final BitSet FOLLOW_set_in_value668 = new BitSet( new long[] { 0x0000000000000002L } );
+ public static final BitSet FOLLOW_set_in_second_value695 = new BitSet( new long[] { 0x0000000000000002L } );
+ public static final BitSet FOLLOW_set_in_third_value722 = new BitSet( new long[] { 0x0000000000000002L } );
+ public static final BitSet FOLLOW_property_in_filter759 = new BitSet( new long[] { 0x000000001FFF0000L } );
+ public static final BitSet FOLLOW_operator_in_filter761 = new BitSet( new long[] { 0x00000000000016A0L } );
+ public static final BitSet FOLLOW_value_in_filter763 = new BitSet( new long[] { 0x0000000060000000L } );
+ public static final BitSet FOLLOW_set_in_filter766 = new BitSet( new long[] { 0x00000000000016A0L } );
+ public static final BitSet FOLLOW_second_value_in_filter774 = new BitSet( new long[] { 0x0000000020000000L } );
+ public static final BitSet FOLLOW_29_in_filter778 = new BitSet( new long[] { 0x00000000000016A0L } );
+ public static final BitSet FOLLOW_third_value_in_filter780 = new BitSet( new long[] { 0x0000000000000000L } );
+ public static final BitSet FOLLOW_EOF_in_filter789 = new BitSet( new long[] { 0x0000000000000002L } );
+ public static final BitSet FOLLOW_ID_in_select_subject800 = new BitSet( new long[] { 0x0000000000000002L } );
+ public static final BitSet FOLLOW_ID_in_select_assign_target812 = new BitSet( new long[] { 0x0000000000000002L } );
+ public static final BitSet FOLLOW_ID_in_select_assign_source823 = new BitSet( new long[] { 0x0000000000000002L } );
+ public static final BitSet FOLLOW_select_assign_target_in_select_assign836 =
+ new BitSet( new long[] { 0x0000000080000000L } );
+ public static final BitSet FOLLOW_31_in_select_assign838 = new BitSet( new long[] { 0x0000000000000010L } );
+ public static final BitSet FOLLOW_select_assign_source_in_select_assign840 =
+ new BitSet( new long[] { 0x0000000000000002L } );
+ public static final BitSet FOLLOW_property_in_where855 = new BitSet( new long[] { 0x000000001FFF0000L } );
+ public static final BitSet FOLLOW_operator_in_where857 = new BitSet( new long[] { 0x00000000000016A0L } );
+ public static final BitSet FOLLOW_value_in_where859 = new BitSet( new long[] { 0x0000000060000002L } );
+ public static final BitSet FOLLOW_set_in_where862 = new BitSet( new long[] { 0x00000000000016A0L } );
+ public static final BitSet FOLLOW_second_value_in_where870 = new BitSet( new long[] { 0x0000000020000002L } );
+ public static final BitSet FOLLOW_29_in_where874 = new BitSet( new long[] { 0x00000000000016A0L } );
+ public static final BitSet FOLLOW_third_value_in_where876 = new BitSet( new long[] { 0x0000000000000002L } );
+ public static final BitSet FOLLOW_set_in_direction893 = new BitSet( new long[] { 0x0000000000000002L } );
+ public static final BitSet FOLLOW_property_in_order909 = new BitSet( new long[] { 0x0000000300000002L } );
+ public static final BitSet FOLLOW_direction_in_order911 = new BitSet( new long[] { 0x0000000000000002L } );
+ public static final BitSet FOLLOW_34_in_select_expr925 = new BitSet( new long[] { 0x0000000000000002L } );
+ public static final BitSet FOLLOW_select_subject_in_select_expr929 =
+ new BitSet( new long[] { 0x0000000020000002L } );
+ public static final BitSet FOLLOW_29_in_select_expr932 = new BitSet( new long[] { 0x0000000000000010L } );
+ public static final BitSet FOLLOW_select_subject_in_select_expr934 =
+ new BitSet( new long[] { 0x0000000020000002L } );
+ public static final BitSet FOLLOW_35_in_select_expr941 = new BitSet( new long[] { 0x0000000000000010L } );
+ public static final BitSet FOLLOW_select_assign_in_select_expr943 =
+ new BitSet( new long[] { 0x0000001020000000L } );
+ public static final BitSet FOLLOW_29_in_select_expr946 = new BitSet( new long[] { 0x0000000000000010L } );
+ public static final BitSet FOLLOW_select_assign_in_select_expr948 =
+ new BitSet( new long[] { 0x0000001020000000L } );
+ public static final BitSet FOLLOW_36_in_select_expr953 = new BitSet( new long[] { 0x0000000000000002L } );
+ public static final BitSet FOLLOW_37_in_ql970 = new BitSet( new long[] { 0x0000000C00000010L } );
+ public static final BitSet FOLLOW_select_expr_in_ql972 = new BitSet( new long[] { 0x0000014000000002L } );
+ public static final BitSet FOLLOW_38_in_ql975 = new BitSet( new long[] { 0x0000000000000010L } );
+ public static final BitSet FOLLOW_where_in_ql977 = new BitSet( new long[] { 0x0000018000000002L } );
+ public static final BitSet FOLLOW_39_in_ql980 = new BitSet( new long[] { 0x0000000000000010L } );
+ public static final BitSet FOLLOW_where_in_ql982 = new BitSet( new long[] { 0x0000018000000002L } );
+ public static final BitSet FOLLOW_40_in_ql989 = new BitSet( new long[] { 0x0000000000000010L } );
+ public static final BitSet FOLLOW_order_in_ql991 = new BitSet( new long[] { 0x0000000020000002L } );
+ public static final BitSet FOLLOW_29_in_ql994 = new BitSet( new long[] { 0x0000000000000010L } );
+ public static final BitSet FOLLOW_order_in_ql996 = new BitSet( new long[] { 0x0000000020000002L } );
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/mq/QueryProcessor.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/mq/QueryProcessor.java b/stack/core/src/main/java/org/apache/usergrid/mq/QueryProcessor.java
new file mode 100644
index 0000000..86cd9ea
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/mq/QueryProcessor.java
@@ -0,0 +1,560 @@
+package org.apache.usergrid.mq;
+
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.commons.collections.comparators.ComparatorChain;
+import org.apache.usergrid.mq.Query.FilterOperator;
+import org.apache.usergrid.mq.Query.FilterPredicate;
+import org.apache.usergrid.mq.Query.SortPredicate;
+import org.apache.usergrid.persistence.Entity;
+import org.apache.usergrid.persistence.EntityPropertyComparator;
+import org.apache.usergrid.utils.ListUtils;
+import org.apache.usergrid.utils.NumberUtils;
+import org.apache.usergrid.utils.StringUtils;
+
+import static java.lang.Integer.parseInt;
+import static org.apache.commons.codec.binary.Base64.decodeBase64;
+import static org.apache.commons.lang.StringUtils.isBlank;
+import static org.apache.commons.lang.StringUtils.isNotBlank;
+import static org.apache.commons.lang.StringUtils.removeEnd;
+import static org.apache.commons.lang.StringUtils.split;
+import static org.apache.usergrid.mq.Query.SortDirection.DESCENDING;
+import static org.apache.usergrid.persistence.cassandra.IndexUpdate.indexValueCode;
+import static org.apache.usergrid.persistence.cassandra.IndexUpdate.toIndexableValue;
+
+
+public class QueryProcessor {
+
+ private static final Logger logger = LoggerFactory.getLogger( QueryProcessor.class );
+
+ Query query;
+
+ String cursor;
+ List<QuerySlice> slices;
+ List<FilterPredicate> filters;
+ List<SortPredicate> sorts;
+
+
+ public QueryProcessor( Query query ) {
+ this.query = query;
+ cursor = query.getCursor();
+ filters = query.getFilterPredicates();
+ sorts = query.getSortPredicates();
+ process();
+ }
+
+
+ public Query getQuery() {
+ return query;
+ }
+
+
+ public String getCursor() {
+ return cursor;
+ }
+
+
+ public List<QuerySlice> getSlices() {
+ return slices;
+ }
+
+
+ public List<FilterPredicate> getFilters() {
+ return filters;
+ }
+
+
+ public List<SortPredicate> getSorts() {
+ return sorts;
+ }
+
+
+ private void process() {
+ slices = new ArrayList<QuerySlice>();
+
+ // consolidate all the filters into a set of ranges
+ Set<String> names = getFilterPropertyNames();
+ for ( String name : names ) {
+ FilterOperator operator = null;
+ Object value = null;
+ RangeValue start = null;
+ RangeValue finish = null;
+ for ( FilterPredicate f : filters ) {
+ if ( f.getPropertyName().equals( name ) ) {
+ operator = f.getOperator();
+ value = f.getValue();
+ RangePair r = getRangeForFilter( f );
+ if ( r.start != null ) {
+ if ( ( start == null ) || ( r.start.compareTo( start, false ) < 0 ) ) {
+ start = r.start;
+ }
+ }
+ if ( r.finish != null ) {
+ if ( ( finish == null ) || ( r.finish.compareTo( finish, true ) > 0 ) ) {
+ finish = r.finish;
+ }
+ }
+ }
+ }
+ slices.add( new QuerySlice( name, operator, value, start, finish, null, false ) );
+ }
+
+ // process sorts
+ if ( ( slices.size() == 0 ) && ( sorts.size() > 0 ) ) {
+ // if no filters, turn first filter into a sort
+ SortPredicate sort = ListUtils.dequeue( sorts );
+ slices.add( new QuerySlice( sort.getPropertyName(), null, null, null, null, null,
+ sort.getDirection() == DESCENDING ) );
+ }
+ else if ( sorts.size() > 0 ) {
+ // match up sorts with existing filters
+ for ( ListIterator<SortPredicate> iter = sorts.listIterator(); iter.hasNext(); ) {
+ SortPredicate sort = iter.next();
+ QuerySlice slice = getSliceForProperty( sort.getPropertyName() );
+ if ( slice != null ) {
+ slice.reversed = sort.getDirection() == DESCENDING;
+ iter.remove();
+ }
+ }
+ }
+
+ // attach cursors to slices
+ if ( ( cursor != null ) && ( cursor.indexOf( ':' ) >= 0 ) ) {
+ String[] cursors = split( cursor, '|' );
+ for ( String c : cursors ) {
+ String[] parts = split( c, ':' );
+ if ( parts.length == 2 ) {
+ int cursorHashCode = parseInt( parts[0] );
+ for ( QuerySlice slice : slices ) {
+ int sliceHashCode = slice.hashCode();
+ logger.info( "Comparing cursor hashcode " + cursorHashCode + " to " + sliceHashCode );
+ if ( sliceHashCode == cursorHashCode ) {
+ if ( isNotBlank( parts[1] ) ) {
+ ByteBuffer cursorBytes = ByteBuffer.wrap( decodeBase64( parts[1] ) );
+ slice.setCursor( cursorBytes );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public List<Entity> sort( List<Entity> entities ) {
+
+ if ( ( entities != null ) && ( sorts.size() > 0 ) ) {
+ // Performing in memory sort
+ logger.info( "Performing in-memory sort of {} entities", entities.size() );
+ ComparatorChain chain = new ComparatorChain();
+ for ( SortPredicate sort : sorts ) {
+ chain.addComparator(
+ new EntityPropertyComparator( sort.getPropertyName(), sort.getDirection() == DESCENDING ) );
+ }
+ Collections.sort( entities, chain );
+ }
+ return entities;
+ }
+
+
+ private Set<String> getFilterPropertyNames() {
+ Set<String> names = new LinkedHashSet<String>();
+ for ( FilterPredicate f : filters ) {
+ names.add( f.getPropertyName() );
+ }
+ return names;
+ }
+
+
+ public QuerySlice getSliceForProperty( String name ) {
+ for ( QuerySlice s : slices ) {
+ if ( s.propertyName.equals( name ) ) {
+ return s;
+ }
+ }
+ return null;
+ }
+
+
+ public static class RangeValue {
+ byte code;
+ Object value;
+ boolean inclusive;
+
+
+ public RangeValue( byte code, Object value, boolean inclusive ) {
+ this.code = code;
+ this.value = value;
+ this.inclusive = inclusive;
+ }
+
+
+ public byte getCode() {
+ return code;
+ }
+
+
+ public void setCode( byte code ) {
+ this.code = code;
+ }
+
+
+ public Object getValue() {
+ return value;
+ }
+
+
+ public void setValue( Object value ) {
+ this.value = value;
+ }
+
+
+ public boolean isInclusive() {
+ return inclusive;
+ }
+
+
+ public void setInclusive( boolean inclusive ) {
+ this.inclusive = inclusive;
+ }
+
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + code;
+ result = prime * result + ( inclusive ? 1231 : 1237 );
+ result = prime * result + ( ( value == null ) ? 0 : value.hashCode() );
+ return result;
+ }
+
+
+ @Override
+ public boolean equals( Object obj ) {
+ if ( this == obj ) {
+ return true;
+ }
+ if ( obj == null ) {
+ return false;
+ }
+ if ( getClass() != obj.getClass() ) {
+ return false;
+ }
+ RangeValue other = ( RangeValue ) obj;
+ if ( code != other.code ) {
+ return false;
+ }
+ if ( inclusive != other.inclusive ) {
+ return false;
+ }
+ if ( value == null ) {
+ if ( other.value != null ) {
+ return false;
+ }
+ }
+ else if ( !value.equals( other.value ) ) {
+ return false;
+ }
+ return true;
+ }
+
+
+ public int compareTo( RangeValue other, boolean finish ) {
+ if ( other == null ) {
+ return 1;
+ }
+ if ( code != other.code ) {
+ return NumberUtils.sign( code - other.code );
+ }
+ @SuppressWarnings({ "unchecked", "rawtypes" }) int c = ( ( Comparable ) value ).compareTo( other.value );
+ if ( c != 0 ) {
+ return c;
+ }
+ if ( finish ) {
+ // for finish values, inclusive means <= which is greater than <
+ if ( inclusive != other.inclusive ) {
+ return inclusive ? 1 : -1;
+ }
+ }
+ else {
+ // for start values, inclusive means >= which is lest than >
+ if ( inclusive != other.inclusive ) {
+ return inclusive ? -1 : 1;
+ }
+ }
+ return 0;
+ }
+
+
+ public static int compare( RangeValue v1, RangeValue v2, boolean finish ) {
+ if ( v1 == null ) {
+ if ( v2 == null ) {
+ return 0;
+ }
+ return -1;
+ }
+ return v1.compareTo( v2, finish );
+ }
+ }
+
+
+ public static class RangePair {
+ RangeValue start;
+ RangeValue finish;
+
+
+ public RangePair( RangeValue start, RangeValue finish ) {
+ this.start = start;
+ this.finish = finish;
+ }
+
+
+ public RangeValue getStart() {
+ return start;
+ }
+
+
+ public void setStart( RangeValue start ) {
+ this.start = start;
+ }
+
+
+ public RangeValue getFinish() {
+ return finish;
+ }
+
+
+ public void setFinish( RangeValue finish ) {
+ this.finish = finish;
+ }
+
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ( ( finish == null ) ? 0 : finish.hashCode() );
+ result = prime * result + ( ( start == null ) ? 0 : start.hashCode() );
+ return result;
+ }
+
+
+ @Override
+ public boolean equals( Object obj ) {
+ if ( this == obj ) {
+ return true;
+ }
+ if ( obj == null ) {
+ return false;
+ }
+ if ( getClass() != obj.getClass() ) {
+ return false;
+ }
+ RangePair other = ( RangePair ) obj;
+ if ( finish == null ) {
+ if ( other.finish != null ) {
+ return false;
+ }
+ }
+ else if ( !finish.equals( other.finish ) ) {
+ return false;
+ }
+ if ( start == null ) {
+ if ( other.start != null ) {
+ return false;
+ }
+ }
+ else if ( !start.equals( other.start ) ) {
+ return false;
+ }
+ return true;
+ }
+ }
+
+
+ public RangePair getRangeForFilter( FilterPredicate f ) {
+ Object searchStartValue = toIndexableValue( f.getStartValue() );
+ Object searchFinishValue = toIndexableValue( f.getFinishValue() );
+ if ( StringUtils.isString( searchStartValue ) && StringUtils.isStringOrNull( searchFinishValue ) ) {
+ if ( "*".equals( searchStartValue ) ) {
+ searchStartValue = null;
+ }
+ if ( searchFinishValue == null ) {
+ searchFinishValue = searchStartValue;
+ ;
+ }
+ if ( ( searchStartValue != null ) && searchStartValue.toString().endsWith( "*" ) ) {
+ searchStartValue = removeEnd( searchStartValue.toString(), "*" );
+ searchFinishValue = searchStartValue + "\uFFFF";
+ if ( isBlank( searchStartValue.toString() ) ) {
+ searchStartValue = "\0000";
+ }
+ }
+ else if ( searchFinishValue != null ) {
+ searchFinishValue = searchFinishValue + "\u0000";
+ }
+ }
+ RangeValue rangeStart = null;
+ if ( searchStartValue != null ) {
+ rangeStart = new RangeValue( indexValueCode( searchStartValue ), searchStartValue,
+ f.getOperator() != FilterOperator.GREATER_THAN );
+ }
+ RangeValue rangeFinish = null;
+ if ( searchFinishValue != null ) {
+ rangeFinish = new RangeValue( indexValueCode( searchFinishValue ), searchFinishValue,
+ f.getOperator() != FilterOperator.LESS_THAN );
+ }
+ return new RangePair( rangeStart, rangeFinish );
+ }
+
+
+ public static class QuerySlice {
+
+ String propertyName;
+ FilterOperator operator;
+ Object value;
+ RangeValue start;
+ RangeValue finish;
+ ByteBuffer cursor;
+ boolean reversed;
+
+
+ QuerySlice( String propertyName, FilterOperator operator, Object value, RangeValue start, RangeValue finish,
+ ByteBuffer cursor, boolean reversed ) {
+ this.propertyName = propertyName;
+ this.operator = operator;
+ this.value = value;
+ this.start = start;
+ this.finish = finish;
+ this.cursor = cursor;
+ this.reversed = reversed;
+ }
+
+
+ public String getPropertyName() {
+ return propertyName;
+ }
+
+
+ public void setPropertyName( String propertyName ) {
+ this.propertyName = propertyName;
+ }
+
+
+ public RangeValue getStart() {
+ return start;
+ }
+
+
+ public void setStart( RangeValue start ) {
+ this.start = start;
+ }
+
+
+ public RangeValue getFinish() {
+ return finish;
+ }
+
+
+ public void setFinish( RangeValue finish ) {
+ this.finish = finish;
+ }
+
+
+ public Object getValue() {
+ return value;
+ }
+
+
+ public void setValue( Object value ) {
+ this.value = value;
+ }
+
+
+ public ByteBuffer getCursor() {
+ return cursor;
+ }
+
+
+ public void setCursor( ByteBuffer cursor ) {
+ this.cursor = cursor;
+ }
+
+
+ public boolean isReversed() {
+ return reversed;
+ }
+
+
+ public void setReversed( boolean reversed ) {
+ this.reversed = reversed;
+ }
+
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ( ( finish == null ) ? 0 : finish.hashCode() );
+ result = prime * result + ( ( propertyName == null ) ? 0 : propertyName.hashCode() );
+ result = prime * result + ( ( start == null ) ? 0 : start.hashCode() );
+
+ //NOTE. We have explicitly left out direction. According to IndexTest:testCollectionOrdering,
+ // a cursor can be used and change direction
+ //of the ordering.
+ return result;
+ }
+
+
+ @Override
+ public boolean equals( Object obj ) {
+ if ( this == obj ) {
+ return true;
+ }
+ if ( obj == null ) {
+ return false;
+ }
+ if ( getClass() != obj.getClass() ) {
+ return false;
+ }
+ QuerySlice other = ( QuerySlice ) obj;
+ if ( finish == null ) {
+ if ( other.finish != null ) {
+ return false;
+ }
+ }
+ else if ( !finish.equals( other.finish ) ) {
+ return false;
+ }
+ if ( propertyName == null ) {
+ if ( other.propertyName != null ) {
+ return false;
+ }
+ }
+ else if ( !propertyName.equals( other.propertyName ) ) {
+ return false;
+ }
+
+ if ( start == null ) {
+ if ( other.start != null ) {
+ return false;
+ }
+ }
+ else if ( !start.equals( other.start ) ) {
+ return false;
+ }
+ return true;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/mq/Queue.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/mq/Queue.java b/stack/core/src/main/java/org/apache/usergrid/mq/Queue.java
new file mode 100644
index 0000000..c9794b5
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/mq/Queue.java
@@ -0,0 +1,289 @@
+/*******************************************************************************
+ * 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.mq;
+
+
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.UUID;
+
+import org.codehaus.jackson.annotate.JsonAnyGetter;
+import org.codehaus.jackson.annotate.JsonAnySetter;
+import org.codehaus.jackson.annotate.JsonIgnore;
+import org.apache.commons.lang.StringUtils;
+import org.apache.usergrid.utils.UUIDUtils;
+
+import static java.util.UUID.nameUUIDFromBytes;
+import static org.apache.commons.collections.MapUtils.getBooleanValue;
+import static org.apache.commons.collections.MapUtils.getByteValue;
+import static org.apache.commons.collections.MapUtils.getDoubleValue;
+import static org.apache.commons.collections.MapUtils.getFloatValue;
+import static org.apache.commons.collections.MapUtils.getIntValue;
+import static org.apache.commons.collections.MapUtils.getLongValue;
+import static org.apache.commons.collections.MapUtils.getShortValue;
+import static org.apache.commons.collections.MapUtils.getString;
+import static org.apache.usergrid.utils.MapUtils.hashMap;
+
+
+public class Queue {
+
+ public static final String QUEUE_ID = "uuid";
+ public static final String QUEUE_PATH = "path";
+ public static final String QUEUE_CREATED = "created";
+ public static final String QUEUE_MODIFIED = "modified";
+ public static final String QUEUE_NEWEST = "newest";
+ public static final String QUEUE_OLDEST = "oldest";
+
+ @SuppressWarnings("rawtypes")
+ public static final Map<String, Class> QUEUE_PROPERTIES =
+ hashMap( QUEUE_PATH, ( Class ) String.class ).map( QUEUE_ID, UUID.class ).map( QUEUE_CREATED, Long.class )
+ .map( QUEUE_MODIFIED, Long.class ).map( QUEUE_NEWEST, UUID.class ).map( QUEUE_OLDEST, UUID.class );
+
+ protected Map<String, Object> properties = new TreeMap<String, Object>( String.CASE_INSENSITIVE_ORDER );
+
+
+ public Queue( String path ) {
+ setPath( path );
+ }
+
+
+ public Queue( Map<String, Object> properties ) {
+ this.properties.putAll( properties );
+ }
+
+
+ @Override
+ public String toString() {
+ return getPath();
+ }
+
+
+ @JsonIgnore
+ public String getPath() {
+ return getString( properties, QUEUE_PATH );
+ }
+
+
+ public void setPath( String path ) {
+ properties.put( QUEUE_PATH, path );
+ }
+
+
+ @JsonIgnore
+ public long getCreated() {
+ return getLongValue( properties, QUEUE_CREATED );
+ }
+
+
+ public void setCreated( long created ) {
+ properties.put( QUEUE_CREATED, created );
+ }
+
+
+ @JsonIgnore
+ public long getModified() {
+ return getLongValue( properties, QUEUE_MODIFIED );
+ }
+
+
+ public void setModified( long modified ) {
+ properties.put( QUEUE_MODIFIED, modified );
+ }
+
+
+ public static Queue getDestination( String path ) {
+ if ( path == null ) {
+ return null;
+ }
+ return new Queue( path );
+ }
+
+
+ @JsonAnySetter
+ public void setProperty( String key, Object value ) {
+ properties.put( key, value );
+ }
+
+
+ @JsonAnyGetter
+ public Map<String, Object> getProperties() {
+ return properties;
+ }
+
+
+ public static String[] getQueueParentPaths( String queuePath ) {
+ queuePath = queuePath.toLowerCase().trim();
+ String[] segments = StringUtils.split( queuePath, '/' );
+ String[] paths = new String[segments.length + 1];
+ paths[0] = "/";
+ for ( int i = 0; i < segments.length; i++ ) {
+ paths[i + 1] = "/" + StringUtils.join( segments, '/', 0, i + 1 ) + "/";
+ }
+ return paths;
+ }
+
+
+ public static String[] getQueuePathSegments( String queuePath ) {
+ queuePath = queuePath.toLowerCase().trim();
+ String[] segments = StringUtils.split( queuePath, '/' );
+ return segments;
+ }
+
+
+ public static String normalizeQueuePath( String queuePath ) {
+ if ( queuePath == null ) {
+ return null;
+ }
+ queuePath = queuePath.toLowerCase().trim();
+ if ( queuePath.length() == 0 ) {
+ return null;
+ }
+ queuePath = "/" + StringUtils.join( StringUtils.split( queuePath, '/' ), '/' );
+ if ( !queuePath.endsWith( "/" ) ) {
+ queuePath += "/";
+ }
+ return queuePath;
+ }
+
+
+ public static UUID getQueueId( String queuePath ) {
+ if ( queuePath == null ) {
+ return null;
+ }
+ // is the queuePath already a UUID?
+ UUID uuid = UUIDUtils.tryGetUUID( queuePath );
+ if ( uuid != null ) {
+ return uuid;
+ }
+ // UUID queuePath string might have been normalized
+ // look for /00000000-0000-0000-0000-000000000000/
+ // or /00000000-0000-0000-0000-000000000000
+ if ( ( queuePath.length() == 38 ) && queuePath.startsWith( "/" ) && queuePath.endsWith( "/" ) ) {
+ uuid = UUIDUtils.tryExtractUUID( queuePath, 1 );
+ if ( uuid != null ) {
+ return uuid;
+ }
+ }
+ else if ( ( queuePath.length() == 37 ) && queuePath.startsWith( "/" ) ) {
+ uuid = UUIDUtils.tryExtractUUID( queuePath, 1 );
+ if ( uuid != null ) {
+ return uuid;
+ }
+ }
+ queuePath = normalizeQueuePath( queuePath );
+ if ( queuePath == null ) {
+ return null;
+ }
+ uuid = nameUUIDFromBytes( queuePath.getBytes() );
+ return uuid;
+ }
+
+
+ @JsonIgnore
+ public UUID getUuid() {
+ return getQueueId( getPath() );
+ }
+
+
+ public float getFloatProperty( String name ) {
+ return getFloatValue( properties, name );
+ }
+
+
+ public void setFloatProperty( String name, float value ) {
+ properties.put( name, value );
+ }
+
+
+ public double getDoubleProperty( String name ) {
+ return getDoubleValue( properties, name );
+ }
+
+
+ public void setDoubleProperty( String name, double value ) {
+ properties.put( name, value );
+ }
+
+
+ public int getIntProperty( String name ) {
+ return getIntValue( properties, name );
+ }
+
+
+ public void setIntProperty( String name, int value ) {
+ properties.put( name, value );
+ }
+
+
+ public long getLongProperty( String name ) {
+ return getLongValue( properties, name );
+ }
+
+
+ public void setLongProperty( String name, long value ) {
+ properties.put( name, value );
+ }
+
+
+ public Object getObjectProperty( String name ) {
+ return properties.get( name );
+ }
+
+
+ public void setObjectProperty( String name, Object value ) {
+ properties.put( name, value );
+ }
+
+
+ public short getShortProperty( String name ) {
+ return getShortValue( properties, name );
+ }
+
+
+ public void setShortProperty( String name, short value ) {
+ properties.put( name, value );
+ }
+
+
+ public String getStringProperty( String name ) {
+ return getString( properties, name );
+ }
+
+
+ public void setStringProperty( String name, String value ) {
+ properties.put( name, value );
+ }
+
+
+ public boolean getBooleanProperty( String name ) {
+ return getBooleanValue( properties, name );
+ }
+
+
+ public void setBooleanProperty( String name, boolean value ) {
+ properties.put( name, value );
+ }
+
+
+ public byte getByteProperty( String name ) {
+ return getByteValue( properties, name );
+ }
+
+
+ public void setByteProperty( String name, byte value ) {
+ properties.put( name, value );
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/mq/QueueManager.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/mq/QueueManager.java b/stack/core/src/main/java/org/apache/usergrid/mq/QueueManager.java
new file mode 100644
index 0000000..6118671
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/mq/QueueManager.java
@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * 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.mq;
+
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+import org.apache.usergrid.persistence.CounterResolution;
+import org.apache.usergrid.persistence.Results;
+import org.apache.usergrid.persistence.exceptions.TransactionNotFoundException;
+
+
+public interface QueueManager {
+
+ public Queue getQueue( String queuePath );
+
+ public Queue updateQueue( String queuePath, Map<String, Object> properties );
+
+ public Queue updateQueue( String queuePath, Queue queue );
+
+ public Message postToQueue( String queuePath, Message message );
+
+ public List<Message> postToQueue( String queuePath, List<Message> messages );
+
+ public QueueResults getFromQueue( String queuePath, QueueQuery query );
+
+ public Message getMessage( UUID messageId );
+
+ public UUID getNewConsumerId();
+
+ public QueueSet getQueues( String firstQueuePath, int limit );
+
+ public QueueSet subscribeToQueue( String publisherQueuePath, String subscriberQueuePath );
+
+ public QueueSet unsubscribeFromQueue( String publisherQueuePath, String subscriberQueuePath );
+
+ public QueueSet addSubscribersToQueue( String publisherQueuePath, List<String> subscriberQueuePaths );
+
+ public QueueSet removeSubscribersFromQueue( String publisherQueuePath, List<String> subscriberQueuePaths );
+
+ public QueueSet subscribeToQueues( String subscriberQueuePath, List<String> publisherQueuePaths );
+
+ public QueueSet unsubscribeFromQueues( String subscriberQueuePath, List<String> publisherQueuePaths );
+
+ public QueueSet getSubscribers( String publisherQueuePath, String firstSubscriberQueuePath, int limit );
+
+ public QueueSet getSubscriptions( String subscriberQueuePath, String firstSubscriptionQueuePath, int limit );
+
+ public QueueSet searchSubscribers( String publisherQueuePath, Query query );
+
+ public QueueSet getChildQueues( String publisherQueuePath, String firstQueuePath, int count );
+
+ public void incrementAggregateQueueCounters( String queuePath, String category, String counterName, long value );
+
+ public Results getAggregateQueueCounters( String queuePath, String category, String counterName,
+ CounterResolution resolution, long start, long finish, boolean pad );
+
+ public Results getAggregateQueueCounters( String queuePath, CounterQuery query ) throws Exception;
+
+ public Set<String> getQueueCounterNames( String queuePath ) throws Exception;
+
+ public void incrementQueueCounters( String queuePath, Map<String, Long> counts );
+
+ public void incrementQueueCounter( String queuePath, String name, long value );
+
+ public Map<String, Long> getQueueCounters( String queuePath ) throws Exception;
+
+ /**
+ * Renew a transaction. Will remove the current transaction and return a new one
+ *
+ * @param queuePath The path to the queue
+ * @param transactionId The transaction id
+ */
+ public UUID renewTransaction( String queuePath, UUID transactionId, QueueQuery query )
+ throws TransactionNotFoundException;
+
+ /**
+ * Deletes the transaction for the consumer. Synonymous with "commit."
+ *
+ * @param queuePath The path to the queue
+ * @param transactionId The transaction id
+ *
+ * @see #commitTransaction(String, java.util.UUID, QueueQuery)
+ */
+ public void deleteTransaction( String queuePath, UUID transactionId, QueueQuery query );
+
+ /**
+ * Commits the Transaction for the consumer.
+ *
+ * @param queuePath The path to the queue
+ * @param transactionId The transaction id
+ */
+ public void commitTransaction( String queuePath, UUID transactionId, QueueQuery query );
+
+ /**
+ * Determines if there are any outstanding transactions on a queue
+ *
+ * @param queuePath The path to the queue
+ * @param consumerId The consumer id
+ */
+ public boolean hasOutstandingTransactions( String queuePath, UUID consumerId );
+
+ /**
+ * Determines if there are any Messages to retrieve in a queue. DOES NOT INCLUDE TRANSACTIONS! If you've tried and
+ * failed to process a transaction on the last message in the queue, this will return false
+ *
+ * @param queuePath The path to the queue
+ * @param consumerId The consumer id
+ */
+ public boolean hasMessagesInQueue( String queuePath, UUID consumerId );
+
+ /** Returns true if there are messages waiting to be consumed or pending transactions */
+ public boolean hasPendingReads( String queuePath, UUID consumerId );
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/mq/QueueManagerFactory.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/mq/QueueManagerFactory.java b/stack/core/src/main/java/org/apache/usergrid/mq/QueueManagerFactory.java
new file mode 100644
index 0000000..37323c4
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/mq/QueueManagerFactory.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * 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.mq;
+
+
+import java.util.UUID;
+
+
+public interface QueueManagerFactory {
+
+ /**
+ * A string description provided by the implementing class.
+ *
+ * @return description text
+ *
+ * @throws Exception the exception
+ */
+ public abstract String getImpementationDescription() throws Exception;
+
+ /**
+ * Gets the entity manager.
+ *
+ * @param applicationId the application id
+ *
+ * @return EntityDao for the specfied parameters
+ */
+ public abstract QueueManager getQueueManager( UUID applicationId );
+}
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/2c2acbe4/stack/core/src/main/java/org/apache/usergrid/mq/QueuePosition.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/mq/QueuePosition.java b/stack/core/src/main/java/org/apache/usergrid/mq/QueuePosition.java
new file mode 100644
index 0000000..054569d
--- /dev/null
+++ b/stack/core/src/main/java/org/apache/usergrid/mq/QueuePosition.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * 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.mq;
+
+
+import java.util.EnumSet;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+
+public enum QueuePosition {
+ START( "start" ), END( "end" ), LAST( "last" ), CONSUMER( "consumer" );
+
+ private final String shortName;
+
+
+ QueuePosition( String shortName ) {
+ this.shortName = shortName;
+ }
+
+
+ static Map<String, QueuePosition> nameMap = new ConcurrentHashMap<String, QueuePosition>();
+
+
+ static {
+ for ( QueuePosition op : EnumSet.allOf( QueuePosition.class ) ) {
+ if ( op.shortName != null ) {
+ nameMap.put( op.shortName, op );
+ }
+ }
+ }
+
+
+ public static QueuePosition find( String s ) {
+ if ( s == null ) {
+ return null;
+ }
+ return nameMap.get( s.toLowerCase() );
+ }
+
+
+ @Override
+ public String toString() {
+ return shortName;
+ }
+}