FileDocCategorySizeDatePackage
ParameterParser.javaAPI DocHibernate 3.2.53766Sat Nov 25 07:22:26 GMT 2006org.hibernate.engine.query

ParameterParser

public class ParameterParser extends Object
The single available method {@link #parse} is responsible for parsing a query string and recognizing tokens in relation to parameters (either named, JPA-style, or ordinal) and providing callbacks about such recognitions.
author
Steve Ebersole

Fields Summary
Constructors Summary
private ParameterParser()

		// disallow instantiation
	
Methods Summary
public static voidparse(java.lang.String sqlString, org.hibernate.engine.query.ParameterParser$Recognizer recognizer)
Performs the actual parsing and tokenizing of the query string making appropriate callbacks to the given recognizer upon recognition of the various tokens.

Note that currently, this only knows how to deal with a single output parameter (for callable statements). If we later add support for multiple output params, this, obviously, needs to change.

param
sqlString The string to be parsed/tokenized.
param
recognizer The thing which handles recognition events.
throws
QueryException

		boolean hasMainOutputParameter = sqlString.indexOf( "call" ) > 0 &&
		                                 sqlString.indexOf( "?" ) < sqlString.indexOf( "call" ) &&
		                                 sqlString.indexOf( "=" ) < sqlString.indexOf( "call" );
		boolean foundMainOutputParam = false;

		int stringLength = sqlString.length();
		boolean inQuote = false;
		for ( int indx = 0; indx < stringLength; indx++ ) {
			char c = sqlString.charAt( indx );
			if ( inQuote ) {
				if ( '\'" == c ) {
					inQuote = false;
				}
				recognizer.other( c );
			}
			else if ( '\'" == c ) {
				inQuote = true;
				recognizer.other( c );
			}
			else {
				if ( c == ':" ) {
					// named parameter
					int right = StringHelper.firstIndexOfChar( sqlString, ParserHelper.HQL_SEPARATORS, indx + 1 );
					int chopLocation = right < 0 ? sqlString.length() : right;
					String param = sqlString.substring( indx + 1, chopLocation );
					if ( StringHelper.isEmpty( param ) ) {
						throw new QueryException("Space is not allowed after parameter prefix ':' '"
								+ sqlString + "'");
					}
					recognizer.namedParameter( param, indx );
					indx = chopLocation - 1;
				}
				else if ( c == '?" ) {
					// could be either an ordinal or JPA-positional parameter
					if ( indx < stringLength - 1 && Character.isDigit( sqlString.charAt( indx + 1 ) ) ) {
						// a peek ahead showed this as an JPA-positional parameter
						int right = StringHelper.firstIndexOfChar( sqlString, ParserHelper.HQL_SEPARATORS, indx + 1 );
						int chopLocation = right < 0 ? sqlString.length() : right;
						String param = sqlString.substring( indx + 1, chopLocation );
						// make sure this "name" is an integral
						try {
							new Integer( param );
						}
						catch( NumberFormatException e ) {
							throw new QueryException( "JPA-style positional param was not an integral ordinal" );
						}
						recognizer.jpaPositionalParameter( param, indx );
						indx = chopLocation - 1;
					}
					else {
						if ( hasMainOutputParameter && !foundMainOutputParam ) {
							foundMainOutputParam = true;
							recognizer.outParameter( indx );
						}
						else {
							recognizer.ordinalParameter( indx );
						}
					}
				}
				else {
					recognizer.other( c );
				}
			}
		}