Parses an ADQL query thanks to the {@link ADQLParser#Query()} function.
*
*
This parser is able, thanks to a {@link QueryChecker} object, to check each ADQLQuery just after its generation.
* It could be used to check the consistency between the ADQL query to parse and the "database" on which the query must be executed.
* By default, there is no {@link QueryChecker}. Thus you must extend {@link QueryChecker} to check semantically all generated ADQLQuery objects.
*
*
To create an object representation of the given ADQL query, this parser uses a {@link ADQLQueryFactory} object. So if you want customize some object (ie. CONTAINS) of this representation
* you just have to extend the corresponding default object (ie. ContainsFunction) and to extend the corresponding function of {@link ADQLQueryFactory} (ie. createContains(...)).
*
*
WARNING: To modify this class it's strongly encouraged to modify the .jj file in the section between PARSER_BEGIN and PARSER_END and to re-compile it with JavaCC.
*
* @see QueryChecker
* @see ADQLQueryFactory
*
* @author Grégory Mantelet (CDS) - gregory.mantelet@astro.unistra.fr
* @version January 2012
*/
public class ADQLParser {
/** Tools to build the object representation of the ADQL query. */
private ADQLQueryFactory queryFactory = new ADQLQueryFactory();
/** The stack of queries (because there may be some sub-queries). */
private Stack stackQuery = new Stack();
/** The object representation of the ADQL query to parse. (ONLY USED DURING THE PARSING, else it is always null). */
private ADQLQuery query = null;
/** Checks each ADQLQuery (sub-query or not) just after their generation. */
private QueryChecker queryChecker = null;
/** The first token of a table/column name. This token is extracted by {@link #Identifier()}. */
private Token currentIdentifierToken = null;
/** List of all allowed coordinate systems. */
private ArrayList allowedCoordSys = new ArrayList();
/**
* Builds an ADQL parser without a query to parse.
*/
public ADQLParser(){
this(new java.io.ByteArrayInputStream("".getBytes()));
}
/**
* Builds an ADQL parser without a query to parse but with a QueryChecker and a ADQLQueryFactory.
*
* @param checker The object to use to check each ADQLQuery.
* @param factory The object to use to build an object representation of the given ADQL query.
*/
public ADQLParser(QueryChecker checker, ADQLQueryFactory factory) {
this();
queryChecker = checker;
if (factory != null)
queryFactory = factory;
}
/**
* Builds an ADQL parser without a query to parse but with a QueryChecker.
*
* @param checker The object to use to check each ADQLQuery.
*/
public ADQLParser(QueryChecker checker) {
this(checker, null);
}
/**
* Builds an ADQL parser without a query to parse but with a ADQLQueryFactory.
*
* @param factory The object to use to build an object representation of the given ADQL query.
*/
public ADQLParser(ADQLQueryFactory factory) {
this((QueryChecker)null, factory);
}
/**
* Builds a parser with a stream containing the query to parse.
*
* @param stream The stream in which the ADQL query to parse is given.
* @param checker The object to use to check each ADQLQuery.
* @param factory The object to use to build an object representation of the given ADQL query.
*/
public ADQLParser(java.io.InputStream stream, QueryChecker checker, ADQLQueryFactory factory) {
this(stream);
queryChecker = checker;
if (factory != null)
queryFactory = factory;
}
/**
* Builds a parser with a stream containing the query to parse.
*
* @param stream The stream in which the ADQL query to parse is given.
* @param checker The object to use to check each ADQLQuery.
*/
public ADQLParser(java.io.InputStream stream, QueryChecker checker) {
this(stream, checker, null);
}
/**
* Builds a parser with a stream containing the query to parse.
*
* @param stream The stream in which the ADQL query to parse is given.
* @param factory The object to use to build an object representation of the given ADQL query.
*/
public ADQLParser(java.io.InputStream stream, ADQLQueryFactory factory) {
this(stream, (QueryChecker)null, factory);
}
/**
* Builds a parser with a stream containing the query to parse.
*
* @param stream The stream in which the ADQL query to parse is given.
* @param encoding The supplied encoding.
* @param checker The object to use to check each ADQLQuery.
* @param factory The object to use to build an object representation of the given ADQL query.
*/
public ADQLParser(java.io.InputStream stream, String encoding, QueryChecker checker, ADQLQueryFactory factory) {
this(stream, encoding);
queryChecker = checker;
if (factory != null)
queryFactory = factory;
}
/**
* Builds a parser with a stream containing the query to parse.
*
* @param stream The stream in which the ADQL query to parse is given.
* @param encoding The supplied encoding.
* @param checker The object to use to check each ADQLQuery.
*/
public ADQLParser(java.io.InputStream stream, String encoding, QueryChecker checker) {
this(stream, encoding, checker, null);
}
/**
* Builds a parser with a stream containing the query to parse.
*
* @param stream The stream in which the ADQL query to parse is given.
* @param encoding The supplied encoding.
* @param factory The object to use to build an object representation of the given ADQL query.
*/
public ADQLParser(java.io.InputStream stream, String encoding, ADQLQueryFactory factory) {
this(stream, encoding, null, factory);
}
/**
* Builds a parser with a reader containing the query to parse.
*
* @param reader The reader in which the ADQL query to parse is given.
* @param checker The object to use to check each ADQLQuery.
* @param factory The object to use to build an object representation of the given ADQL query.
*/
public ADQLParser(java.io.Reader reader, QueryChecker checker, ADQLQueryFactory factory) {
this(reader);
queryChecker = checker;
if (factory != null)
queryFactory = factory;
}
/**
* Builds a parser with a reader containing the query to parse.
*
* @param reader The reader in which the ADQL query to parse is given.
* @param checker The object to use to check each ADQLQuery.
*/
public ADQLParser(java.io.Reader reader, QueryChecker checker) {
this(reader, checker, null);
}
/**
* Builds a parser with a reader containing the query to parse.
*
* @param reader The reader in which the ADQL query to parse is given.
* @param factory The object to use to build an object representation of the given ADQL query.
*/
public ADQLParser(java.io.Reader reader, ADQLQueryFactory factory) {
this(reader, null, factory);
}
/**
* Builds a parser with another token manager.
*
* @param tm The manager which associates a token to a numeric code.
* @param checker The object to use to check each ADQLQuery.
* @param factory The object to use to build an object representation of the given ADQL query.
*/
public ADQLParser(ADQLParserTokenManager tm, QueryChecker checker, ADQLQueryFactory factory) {
this(tm);
queryChecker = checker;
if (factory != null)
queryFactory = factory;
}
/**
* Builds a parser with another token manager.
*
* @param tm The manager which associates a token to a numeric code.
* @param checker The object to use to check each ADQLQuery.
*/
public ADQLParser(ADQLParserTokenManager tm, QueryChecker checker) {
this(tm, checker, null);
}
/**
* Builds a parser with another token manager.
*
* @param tm The manager which associates a token to a numeric code.
* @param factory The object to use to build an object representation of the given ADQL query.
*/
public ADQLParser(ADQLParserTokenManager tm, ADQLQueryFactory factory) {
this(tm, null, factory);
}
/**
* Parses the query given at the creation of this parser or in the ReInit functions.
*
* @return The object representation of the given ADQL query.
* @throws ParseException If there is at least one syntactic error.
*
* @see ADQLParser#Query()
*/
public final ADQLQuery parseQuery() throws ParseException {
stackQuery.clear();
query = null;
return Query();
}
/**
* Parses the query given in parameter.
*
* @param q The ADQL query to parse.
* @return The object representation of the given ADQL query.
* @throws ParseException If there is at least one syntactic error.
*
* @see ADQLParser#ReInit(java.io.InputStream)
* @see ADQLParser#setDebug(boolean)
* @see ADQLParser#Query()
*/
public final ADQLQuery parseQuery(String q) throws ParseException {
stackQuery.clear();
query = null;
ReInit(new java.io.ByteArrayInputStream(q.getBytes()));
return Query();
}
/**
* Parses the query contained in the stream given in parameter.
*
* @param stream The stream which contains the ADQL query to parse.
* @return The object representation of the given ADQL query.
* @throws ParseException If there is at least one syntactic error.
*
* @see ADQLParser#ReInit(java.io.InputStream)
* @see ADQLParser#setDebug(boolean)
* @see ADQLParser#Query()
*/
public final ADQLQuery parseQuery(java.io.InputStream stream) throws ParseException {
stackQuery.clear();
query = null;
ReInit(stream);
return Query();
}
public final void addCoordinateSystem(final String coordSys){
allowedCoordSys.add(coordSys);
}
public final void setCoordinateSystems(final Collection coordSys){
allowedCoordSys.clear();
if (coordSys != null)
allowedCoordSys.addAll(coordSys);
}
public final boolean isAllowedCoordSys(final String coordSys) {
for(String cs : allowedCoordSys){
if (cs.equalsIgnoreCase(coordSys))
return true;
}
return false;
}
public final void setDebug(boolean debug){
if (debug) enable_tracing();
else disable_tracing();
}
public final QueryChecker getQueryChecker(){
return queryChecker;
}
public final void setQueryChecker(QueryChecker checker){
queryChecker = checker;
}
public final ADQLQueryFactory getQueryFactory(){
return queryFactory;
}
public final void setQueryFactory(ADQLQueryFactory factory){
queryFactory = (factory!=null)?factory:(new ADQLQueryFactory());
}
private final ParseException generateParseException(Exception ex){
if (!(ex instanceof ParseException)){
ParseException pex = new ParseException("["+ex.getClass().getName()+"] "+ex.getMessage());
pex.setStackTrace(ex.getStackTrace());
return pex;
}else
return (ParseException)ex;
}
/**
*
Gets the specified ADQL query and parses the given ADQL query. The SQL translation is then printed if the syntax is correct.
*
ONLY the syntax is checked: the query is NOT EXECUTED !