Templatepublic final class Template extends Object Parses SQL fragments specified in mapping documents |
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 boolean | isFunctionOrKeyword(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 boolean | isIdentifier(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 boolean | isNamedParameter(java.lang.String token)
return token.startsWith(":");
| public static java.lang.String | renderOrderByStringTemplate(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.String | renderWhereStringTemplate(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.String | renderWhereStringTemplate(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.
return renderWhereStringTemplate( sqlWhereString, placeholder, dialect, new SQLFunctionRegistry( dialect, java.util.Collections.EMPTY_MAP ) );
| public static java.lang.String | renderWhereStringTemplate(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.
//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();
|
|