/*@bgen(jjtree) Generated By:JJTree: Do not edit this line. ./QueryParser.jj */
/*@egen*//*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */

options {
  JDK_VERSION = "1.5";
  STATIC = false;
}

PARSER_BEGIN(QueryParser)
	package org.apache.oodt.cas.catalog.query.parser;

	import java.io.ByteArrayInputStream;
	import java.util.Arrays;
	import java.util.HashSet;
	import java.util.Vector;
	import java.util.Properties;
	import org.apache.oodt.cas.catalog.query.QueryExpression;
	import org.apache.oodt.cas.catalog.query.QueryLogicalGroup;
	import org.apache.oodt.cas.catalog.query.StdQueryExpression;
	import org.apache.oodt.cas.catalog.query.ComparisonQueryExpression;
	import org.apache.oodt.cas.catalog.query.CustomQueryExpression;
	import org.apache.oodt.cas.catalog.term.Term;
	
    public class QueryParser/*@bgen(jjtree)*/implements QueryParserTreeConstants/*@egen*/ {/*@bgen(jjtree)*/
  protected JJTQueryParserState jjtree = new JJTQueryParserState();

/*@egen*/
    	
    	public static QueryExpression parseQueryExpression(String queryExpressionString) throws ParseException, TokenMgrError {
    		return new QueryParser(new ByteArrayInputStream(queryExpressionString.getBytes())).parseInput();
    	}
    	
       	public static void main( String[] args ) throws ParseException, TokenMgrError {
          	System.out.println(new QueryParser( System.in ).parseInput());
       	} 
       	
    }
PARSER_END(QueryParser)

SKIP : { "\r" | "\n" | "\r\n" }
TOKEN: { < SPACE : " " > }
TOKEN: { < AND : " AND " > }
TOKEN: { < OR : " OR " > }
TOKEN: { < QUOTE : "'" > }
TOKEN: { < EQUALS : "=" > }
TOKEN: { < SEMI_COLON : ";" > }
TOKEN: { < COMMA : "," > }
TOKEN: { < OPEN_BRACES : "{" > }
TOKEN: { < CLOSE_BRACES : "}" > }
TOKEN: { < OPEN_PARENS : "(" > }
TOKEN: { < CLOSE_PARENS : ")" > }
TOKEN: { < BUCKET_NAME_KEY : "bucketNames" > }
TOKEN: { < CUSTOM_NAME_KEY : "name" > }
TOKEN: { < P_KEY : "p:" <TERM> > }
TOKEN: {
      < EQ : "==" >
    | < GE : ">=" >
    | < GT : ">" >
    | < LE : "<=" >
    | < LT : "<" >
}
TOKEN: { < TERM: (["a"-"z","A"-"Z"])+ (<STRING_LITERAL>)* > }
TOKEN: { < VALUE : "'" ( <TERM> | <NON_TERM> ) "'" > }
TOKEN: { < #NON_TERM: (<STRING_LITERAL> | <SPECIAL_CHARS>)+ (<STRING_LITERAL> | " "<STRING_LITERAL> | " "<SPECIAL_CHARS> | <SPECIAL_CHARS>)* > }
TOKEN: { < #STRING_LITERAL: (["0"-"9","a"-"z","A"-"Z","-","_",".",":","/"]) > }
TOKEN: { < #SPECIAL_CHARS: (["/","\\","?","<",">","~","`","*","#","&","!","@","$","%","^","(",")","{","}","[","]"]) > }

QueryExpression parseInput() : 
{/*@bgen(jjtree) parseInput */
        SimpleNode jjtn000 = new SimpleNode(JJTPARSEINPUT);
        boolean jjtc000 = true;
        jjtree.openNodeScope(jjtn000);
/*@egen*/
	QueryExpression qe = null;
}
{/*@bgen(jjtree) parseInput */
        try {
/*@egen*/
   	qe = Query(null) <EOF>/*@bgen(jjtree)*/
        {
          jjtree.closeNodeScope(jjtn000, true);
          jjtc000 = false;
        }
/*@egen*/
   	{ return qe; }/*@bgen(jjtree)*/
        } catch (Throwable jjte000) {
          if (jjtc000) {
            jjtree.clearNodeScope(jjtn000);
            jjtc000 = false;
          } else {
            jjtree.popNode();
          }
          if (jjte000 instanceof RuntimeException) {
            throw (RuntimeException)jjte000;
          }
          if (jjte000 instanceof ParseException) {
            throw (ParseException)jjte000;
          }
          throw (Error)jjte000;
        } finally {
          if (jjtc000) {
            jjtree.closeNodeScope(jjtn000, true);
          }
        }
/*@egen*/
}

QueryExpression Query(Vector<String> bucketNames) : 
{/*@bgen(jjtree) Query */
        SimpleNode jjtn000 = new SimpleNode(JJTQUERY);
        boolean jjtc000 = true;
        jjtree.openNodeScope(jjtn000);
/*@egen*/
	QueryExpression qe1 = null;
	QueryExpression qe2 = null;
	Token operator = null;
}
{/*@bgen(jjtree) Query */
    try {
/*@egen*/
    qe1 = QueryExpression(bucketNames) ( LOOKAHEAD( <AND> | <OR> ) ( operator = <AND> | operator = <OR> ) qe2 = Query(bucketNames) )*/*@bgen(jjtree)*/
    {
      jjtree.closeNodeScope(jjtn000, true);
      jjtc000 = false;
    }
/*@egen*/
    { 
    	if (qe2 == null) {
    		return qe1;
    	}else {
    		QueryLogicalGroup queryLogicalGroup = new QueryLogicalGroup();
    		if (bucketNames != null)
    			queryLogicalGroup.setBucketNames(new HashSet<String>(bucketNames));
    		queryLogicalGroup.setOperator(QueryLogicalGroup.Operator.valueOf(operator.image.trim().toUpperCase()));
    		queryLogicalGroup.addExpression(qe1);
    		queryLogicalGroup.addExpression(qe2);
    		return queryLogicalGroup;
    	}
    }/*@bgen(jjtree)*/
    } catch (Throwable jjte000) {
      if (jjtc000) {
        jjtree.clearNodeScope(jjtn000);
        jjtc000 = false;
      } else {
        jjtree.popNode();
      }
      if (jjte000 instanceof RuntimeException) {
        throw (RuntimeException)jjte000;
      }
      if (jjte000 instanceof ParseException) {
        throw (ParseException)jjte000;
      }
      throw (Error)jjte000;
    } finally {
      if (jjtc000) {
        jjtree.closeNodeScope(jjtn000, true);
      }
    }
/*@egen*/
}

QueryExpression QueryExpression(Vector<String> bucketNames) :
{/*@bgen(jjtree) QueryExpression */
        SimpleNode jjtn000 = new SimpleNode(JJTQUERYEXPRESSION);
        boolean jjtc000 = true;
        jjtree.openNodeScope(jjtn000);
/*@egen*/
	QueryExpression qe = null;
}
{/*@bgen(jjtree) QueryExpression */
    try {
/*@egen*/
    ( 
    	LOOKAHEAD ( <OPEN_PARENS> ) 
    	qe = PriorityQueryExpression(bucketNames)
    | 
    	LOOKAHEAD ( <OPEN_BRACES> (<SPACE>)* <BUCKET_NAME_KEY> ) 
    	qe = StdQueryExpression()
    | 
    	LOOKAHEAD ( <OPEN_BRACES> (<SPACE>)* <CUSTOM_NAME_KEY> ) 
    	qe = CustomQueryExpression(bucketNames)
    | 
        LOOKAHEAD ( <TERM> ) 
    	qe = ComparisonQueryExpression(bucketNames) 
    )/*@bgen(jjtree)*/
    {
      jjtree.closeNodeScope(jjtn000, true);
      jjtc000 = false;
    }
/*@egen*/
    
    { return qe; }/*@bgen(jjtree)*/
    } catch (Throwable jjte000) {
      if (jjtc000) {
        jjtree.clearNodeScope(jjtn000);
        jjtc000 = false;
      } else {
        jjtree.popNode();
      }
      if (jjte000 instanceof RuntimeException) {
        throw (RuntimeException)jjte000;
      }
      if (jjte000 instanceof ParseException) {
        throw (ParseException)jjte000;
      }
      throw (Error)jjte000;
    } finally {
      if (jjtc000) {
        jjtree.closeNodeScope(jjtn000, true);
      }
    }
/*@egen*/
}

QueryExpression StdQueryExpression() : 
{/*@bgen(jjtree) StdQueryExpression */
        SimpleNode jjtn000 = new SimpleNode(JJTSTDQUERYEXPRESSION);
        boolean jjtc000 = true;
        jjtree.openNodeScope(jjtn000);
/*@egen*/
	QueryExpression qe = null;
	Vector<String> bucketNames = new Vector<String>();
}
{/*@bgen(jjtree) StdQueryExpression */
    try {
/*@egen*/
    <OPEN_BRACES> (<SPACE>)* <BUCKET_NAME_KEY> (<SPACE>)* <EQUALS> (<SPACE>)* getValues(bucketNames) (<SPACE>)* [<SEMI_COLON> (<SPACE>)* qe = Query(bucketNames)] (<SPACE>)* <CLOSE_BRACES>/*@bgen(jjtree)*/
    {
      jjtree.closeNodeScope(jjtn000, true);
      jjtc000 = false;
    }
/*@egen*/
    { 
    	if (qe == null) {
    		return new StdQueryExpression(new HashSet<String>(bucketNames));
    	}else {
    		return qe; 
    	}
    }/*@bgen(jjtree)*/
    } catch (Throwable jjte000) {
      if (jjtc000) {
        jjtree.clearNodeScope(jjtn000);
        jjtc000 = false;
      } else {
        jjtree.popNode();
      }
      if (jjte000 instanceof RuntimeException) {
        throw (RuntimeException)jjte000;
      }
      if (jjte000 instanceof ParseException) {
        throw (ParseException)jjte000;
      }
      throw (Error)jjte000;
    } finally {
      if (jjtc000) {
        jjtree.closeNodeScope(jjtn000, true);
      }
    }
/*@egen*/
}

QueryExpression ComparisonQueryExpression(Vector<String> bucketNames) : 
{/*@bgen(jjtree) ComparisonQueryExpression */
        SimpleNode jjtn000 = new SimpleNode(JJTCOMPARISONQUERYEXPRESSION);
        boolean jjtc000 = true;
        jjtree.openNodeScope(jjtn000);
/*@egen*/
	Token termName = null;
	Token operator = null;
	Vector<String> values = new Vector<String>();
}
{/*@bgen(jjtree) ComparisonQueryExpression */
    try {
/*@egen*/
    termName = <TERM> (<SPACE>)* ( operator = <EQ> | operator = <GT> | operator = <GE> | operator = <LT> | operator = <LE> ) (<SPACE>)* getValues(values)/*@bgen(jjtree)*/
    {
      jjtree.closeNodeScope(jjtn000, true);
      jjtc000 = false;
    }
/*@egen*/
    { 
    	Term term = new Term(termName.image);
    	term.setValues(values); //Arrays.asList(termValues.image.split(",")));
    	ComparisonQueryExpression comparisonQueryExpression = new ComparisonQueryExpression();
    	if (bucketNames != null)
    		comparisonQueryExpression.setBucketNames(new HashSet<String>(bucketNames));
    	comparisonQueryExpression.setTerm(term);
    	comparisonQueryExpression.setOperator(ComparisonQueryExpression.Operator.getOperatorBySign(operator.image));
    	return comparisonQueryExpression; 
    }/*@bgen(jjtree)*/
    } catch (Throwable jjte000) {
      if (jjtc000) {
        jjtree.clearNodeScope(jjtn000);
        jjtc000 = false;
      } else {
        jjtree.popNode();
      }
      if (jjte000 instanceof RuntimeException) {
        throw (RuntimeException)jjte000;
      }
      if (jjte000 instanceof ParseException) {
        throw (ParseException)jjte000;
      }
      throw (Error)jjte000;
    } finally {
      if (jjtc000) {
        jjtree.closeNodeScope(jjtn000, true);
      }
    }
/*@egen*/
}

QueryExpression PriorityQueryExpression(Vector<String> bucketNames) :
{/*@bgen(jjtree) PriorityQueryExpression */
        SimpleNode jjtn000 = new SimpleNode(JJTPRIORITYQUERYEXPRESSION);
        boolean jjtc000 = true;
        jjtree.openNodeScope(jjtn000);
/*@egen*/
	QueryExpression qe = null;
}
{/*@bgen(jjtree) PriorityQueryExpression */
    try {
/*@egen*/
    <OPEN_PARENS> qe = Query(bucketNames) <CLOSE_PARENS>/*@bgen(jjtree)*/
    {
      jjtree.closeNodeScope(jjtn000, true);
      jjtc000 = false;
    }
/*@egen*/
    { return qe; }/*@bgen(jjtree)*/
    } catch (Throwable jjte000) {
      if (jjtc000) {
        jjtree.clearNodeScope(jjtn000);
        jjtc000 = false;
      } else {
        jjtree.popNode();
      }
      if (jjte000 instanceof RuntimeException) {
        throw (RuntimeException)jjte000;
      }
      if (jjte000 instanceof ParseException) {
        throw (ParseException)jjte000;
      }
      throw (Error)jjte000;
    } finally {
      if (jjtc000) {
        jjtree.closeNodeScope(jjtn000, true);
      }
    }
/*@egen*/
}

QueryExpression CustomQueryExpression(Vector<String> bucketNames) :
{/*@bgen(jjtree) CustomQueryExpression */
        SimpleNode jjtn000 = new SimpleNode(JJTCUSTOMQUERYEXPRESSION);
        boolean jjtc000 = true;
        jjtree.openNodeScope(jjtn000);
/*@egen*/
	Token customNameToken = null;
	Properties p = new Properties();
}
{/*@bgen(jjtree) CustomQueryExpression */
        try {
/*@egen*/
	<OPEN_BRACES> (<SPACE>)* <CUSTOM_NAME_KEY> (<SPACE>)* <EQUALS> (<SPACE>)* <QUOTE> customNameToken = <TERM> <QUOTE> [ LOOKAHEAD ((<SPACE>)* <SEMI_COLON>) (<SPACE>)* <SEMI_COLON> getProperties(p) ] (<SPACE>)* <CLOSE_BRACES>/*@bgen(jjtree)*/
        {
          jjtree.closeNodeScope(jjtn000, true);
          jjtc000 = false;
        }
/*@egen*/
	{ 
		CustomQueryExpression cqe = new CustomQueryExpression(customNameToken.image, p);
    	if (bucketNames != null)
    		cqe.setBucketNames(new HashSet<String>(bucketNames));
    	return cqe;
	}/*@bgen(jjtree)*/
        } catch (Throwable jjte000) {
          if (jjtc000) {
            jjtree.clearNodeScope(jjtn000);
            jjtc000 = false;
          } else {
            jjtree.popNode();
          }
          if (jjte000 instanceof RuntimeException) {
            throw (RuntimeException)jjte000;
          }
          if (jjte000 instanceof ParseException) {
            throw (ParseException)jjte000;
          }
          throw (Error)jjte000;
        } finally {
          if (jjtc000) {
            jjtree.closeNodeScope(jjtn000, true);
          }
        }
/*@egen*/
}

void getValues(Vector<String> values) : 
{/*@bgen(jjtree) getValues */
        SimpleNode jjtn000 = new SimpleNode(JJTGETVALUES);
        boolean jjtc000 = true;
        jjtree.openNodeScope(jjtn000);
/*@egen*/
	Token value = null;
}
{/*@bgen(jjtree) getValues */
        try {
/*@egen*/
	value = <VALUE> ( LOOKAHEAD (<COMMA>) <COMMA> getValues(values) ) */*@bgen(jjtree)*/
        {
          jjtree.closeNodeScope(jjtn000, true);
          jjtc000 = false;
        }
/*@egen*/
	{ 
		values.add(0, value.image.replaceAll("'", ""));
	}/*@bgen(jjtree)*/
        } catch (Throwable jjte000) {
          if (jjtc000) {
            jjtree.clearNodeScope(jjtn000);
            jjtc000 = false;
          } else {
            jjtree.popNode();
          }
          if (jjte000 instanceof RuntimeException) {
            throw (RuntimeException)jjte000;
          }
          if (jjte000 instanceof ParseException) {
            throw (ParseException)jjte000;
          }
          throw (Error)jjte000;
        } finally {
          if (jjtc000) {
            jjtree.closeNodeScope(jjtn000, true);
          }
        }
/*@egen*/
}

void getProperties(Properties p) : 
{/*@bgen(jjtree) getProperties */
        SimpleNode jjtn000 = new SimpleNode(JJTGETPROPERTIES);
        boolean jjtc000 = true;
        jjtree.openNodeScope(jjtn000);
/*@egen*/
	Token propertyKey = null;
	Token propertyVal = null;
}
{/*@bgen(jjtree) getProperties */
        try {
/*@egen*/
	propertyKey = <P_KEY> (<SPACE>)* <EQUALS> (<SPACE>)* propertyVal = <VALUE> ( LOOKAHEAD (<COMMA>) <COMMA> getProperties(p) ) */*@bgen(jjtree)*/
        {
          jjtree.closeNodeScope(jjtn000, true);
          jjtc000 = false;
        }
/*@egen*/
	{ 
		p.put(propertyKey.image.substring(2), propertyVal.image.replaceAll("'", ""));
	}/*@bgen(jjtree)*/
        } catch (Throwable jjte000) {
          if (jjtc000) {
            jjtree.clearNodeScope(jjtn000);
            jjtc000 = false;
          } else {
            jjtree.popNode();
          }
          if (jjte000 instanceof RuntimeException) {
            throw (RuntimeException)jjte000;
          }
          if (jjte000 instanceof ParseException) {
            throw (ParseException)jjte000;
          }
          throw (Error)jjte000;
        } finally {
          if (jjtc000) {
            jjtree.closeNodeScope(jjtn000, true);
          }
        }
/*@egen*/
}
