FileDocCategorySizeDatePackage
Template.javaAPI DocHibernate 3.2.59608Wed May 10 11:58:10 BST 2006org.hibernate.sql

Template

public final class Template extends Object
Parses SQL fragments specified in mapping documents
author
Gavin King

Fields Summary
private static final Set
KEYWORDS
private static final Set
BEFORE_TABLE_KEYWORDS
private static final Set
FUNCTION_KEYWORDS
public static final String
TEMPLATE
Constructors Summary
private Template()


	  
Methods Summary
private static booleanisFunctionOrKeyword(java.lang.String lcToken, java.lang.String nextToken, org.hibernate.dialect.Dialect dialect, org.hibernate.dialect.function.SQLFunctionRegistry functionRegistry)

		return "(".equals(nextToken) ||
			KEYWORDS.contains(lcToken) ||
			functionRegistry.hasFunction(lcToken) ||
			dialect.getKeywords().contains(lcToken) ||
			FUNCTION_KEYWORDS.contains(lcToken);
	
private static booleanisIdentifier(java.lang.String token, org.hibernate.dialect.Dialect dialect)

		return token.charAt(0)=='`" || ( //allow any identifier quoted with backtick
			Character.isLetter( token.charAt(0) ) && //only recognizes identifiers beginning with a letter
			token.indexOf('.") < 0
		);
	
private static booleanisNamedParameter(java.lang.String token)

		return token.startsWith(":");
	
public static java.lang.StringrenderOrderByStringTemplate(java.lang.String sqlOrderByString, org.hibernate.dialect.Dialect dialect, org.hibernate.dialect.function.SQLFunctionRegistry functionRegistry)
Takes order by clause provided in the mapping attribute and interpolates the alias. Handles asc, desc, SQL functions, quoted identifiers.

		//TODO: make this a bit nicer
		String symbols = new StringBuffer()
			.append("=><!+-*/()',|&`")
			.append(StringHelper.WHITESPACE)
			.append( dialect.openQuote() )
			.append( dialect.closeQuote() )
			.toString();
		StringTokenizer tokens = new StringTokenizer(sqlOrderByString, symbols, true);
		
		StringBuffer result = new StringBuffer();
		boolean quoted = false;
		boolean quotedIdentifier = false;
		
		boolean hasMore = tokens.hasMoreTokens();
		String nextToken = hasMore ? tokens.nextToken() : null;
		while (hasMore) {
			String token = nextToken;
			String lcToken = token.toLowerCase();
			hasMore = tokens.hasMoreTokens();
			nextToken = hasMore ? tokens.nextToken() : null;
			
			boolean isQuoteCharacter = false;
			
			if ( !quotedIdentifier && "'".equals(token) ) {
				quoted = !quoted;
				isQuoteCharacter = true;
			}
			
			if ( !quoted ) {
				
				boolean isOpenQuote;
				if ( "`".equals(token) ) {
					isOpenQuote = !quotedIdentifier;
					token = lcToken = isOpenQuote ? 
						new Character( dialect.openQuote() ).toString() :
						new Character( dialect.closeQuote() ).toString();
					quotedIdentifier = isOpenQuote;	
					isQuoteCharacter = true;
				}
				else if ( !quotedIdentifier && ( dialect.openQuote()==token.charAt(0) ) ) {
					isOpenQuote = true;
					quotedIdentifier = true;	
					isQuoteCharacter = true;
				}
				else if ( quotedIdentifier && ( dialect.closeQuote()==token.charAt(0) ) ) {
					quotedIdentifier = false;
					isQuoteCharacter = true;
					isOpenQuote = false;
				}
				else {
					isOpenQuote = false;
				}
				
				if (isOpenQuote) {
					result.append(TEMPLATE).append('.");
				}
				
			}
	
			boolean quotedOrWhitespace = quoted || 
				quotedIdentifier || 
				isQuoteCharacter || 
				Character.isWhitespace( token.charAt(0) );
			
			if (quotedOrWhitespace) {
				result.append(token);
			}
			else if (
				isIdentifier(token, dialect) &&
				!isFunctionOrKeyword(lcToken, nextToken, dialect, functionRegistry)
			) {
				result.append(TEMPLATE)
					.append('.")
					.append( dialect.quote(token) );
			}
			else {
				result.append(token);
			}
		}
		return result.toString();
	
public static java.lang.StringrenderWhereStringTemplate(java.lang.String sqlWhereString, org.hibernate.dialect.Dialect dialect, org.hibernate.dialect.function.SQLFunctionRegistry functionRegistry)

		return renderWhereStringTemplate(sqlWhereString, TEMPLATE, dialect, functionRegistry);
	
public static java.lang.StringrenderWhereStringTemplate(java.lang.String sqlWhereString, java.lang.String placeholder, org.hibernate.dialect.Dialect dialect)
Same functionality as {@link #renderWhereStringTemplate(String, String, Dialect, SQLFunctionRegistry)}, except that a SQLFunctionRegistry is not provided (i.e., only the dialect-defined functions are considered). This is only intended for use by the annotations project until the many-to-many/map-key-from-target-table feature is pulled into core.

deprecated
Only intended for annotations usage; use {@link #renderWhereStringTemplate(String, String, Dialect, SQLFunctionRegistry)} instead

		return renderWhereStringTemplate( sqlWhereString, placeholder, dialect, new SQLFunctionRegistry( dialect, java.util.Collections.EMPTY_MAP ) );
	
public static java.lang.StringrenderWhereStringTemplate(java.lang.String sqlWhereString, java.lang.String placeholder, org.hibernate.dialect.Dialect dialect, org.hibernate.dialect.function.SQLFunctionRegistry functionRegistry)
Takes the where condition provided in the mapping attribute and interpolates the alias. Handles subselects, quoted identifiers, quoted strings, expressions, SQL functions, named parameters.

param
sqlWhereString The string into which to interpolate the placeholder value
param
placeholder The value to be interpolated into the the sqlWhereString
param
dialect The dialect to apply
param
functionRegistry The registry of all sql functions
return
The rendered sql fragment

		//TODO: make this a bit nicer
		String symbols = new StringBuffer()
			.append("=><!+-*/()',|&`")
			.append(StringHelper.WHITESPACE)
			.append( dialect.openQuote() )
			.append( dialect.closeQuote() )
			.toString();
		StringTokenizer tokens = new StringTokenizer(sqlWhereString, symbols, true);
		
		StringBuffer result = new StringBuffer();
		boolean quoted = false;
		boolean quotedIdentifier = false;
		boolean beforeTable = false;
		boolean inFromClause = false;
		boolean afterFromTable = false;
		
		boolean hasMore = tokens.hasMoreTokens();
		String nextToken = hasMore ? tokens.nextToken() : null;
		while (hasMore) {
			String token = nextToken;
			String lcToken = token.toLowerCase();
			hasMore = tokens.hasMoreTokens();
			nextToken = hasMore ? tokens.nextToken() : null;
			
			boolean isQuoteCharacter = false;
			
			if ( !quotedIdentifier && "'".equals(token) ) {
				quoted = !quoted;
				isQuoteCharacter = true;
			}
			
			if ( !quoted ) {
				
				boolean isOpenQuote;
				if ( "`".equals(token) ) {
					isOpenQuote = !quotedIdentifier;
					token = lcToken = isOpenQuote ? 
						new Character( dialect.openQuote() ).toString() :
						new Character( dialect.closeQuote() ).toString();
					quotedIdentifier = isOpenQuote;	
					isQuoteCharacter = true;
				}
				else if ( !quotedIdentifier && ( dialect.openQuote()==token.charAt(0) ) ) {
					isOpenQuote = true;
					quotedIdentifier = true;	
					isQuoteCharacter = true;
				}
				else if ( quotedIdentifier && ( dialect.closeQuote()==token.charAt(0) ) ) {
					quotedIdentifier = false;
					isQuoteCharacter = true;
					isOpenQuote = false;
				}
				else {
					isOpenQuote = false;
				}
				
				if (isOpenQuote) {
					result.append(placeholder).append('.");
				}
				
			}
	
			boolean quotedOrWhitespace = quoted || 
				quotedIdentifier || 
				isQuoteCharacter || 
				Character.isWhitespace( token.charAt(0) );
			
			if (quotedOrWhitespace) {
				result.append(token);
			}
			else if (beforeTable) {
				result.append(token);
				beforeTable = false;
				afterFromTable = true;
			}
			else if (afterFromTable) {
				if ( !"as".equals(lcToken) ) afterFromTable = false;
				result.append(token);
			}
			else if ( isNamedParameter(token) ) {
				result.append(token);
			}
			else if (
				isIdentifier(token, dialect) &&
				!isFunctionOrKeyword(lcToken, nextToken, dialect , functionRegistry)
			) {
				result.append(placeholder)
					.append('.")
					.append( dialect.quote(token) );
			}
			else {
				if ( BEFORE_TABLE_KEYWORDS.contains(lcToken) ) {
					beforeTable = true;
					inFromClause = true;
				}
				else if ( inFromClause && ",".equals(lcToken) ) {
					beforeTable = true;
				}
				result.append(token);
			}
			
			if ( //Yuck:
					inFromClause && 
					KEYWORDS.contains(lcToken) && //"as" is not in KEYWORDS
					!BEFORE_TABLE_KEYWORDS.contains(lcToken)
			) { 
				inFromClause = false;
			}

		}
		return result.toString();