📄 querysplitter.java
字号:
//$Id: QuerySplitter.java,v 1.3 2004/12/08 00:22:06 oneovthafew Exp $package org.hibernate.hql;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.hibernate.MappingException;import org.hibernate.engine.SessionFactoryImplementor;import org.hibernate.hql.classic.ParserHelper;import org.hibernate.util.StringHelper;import java.util.ArrayList;import java.util.HashSet;import java.util.Set;/** * Provides query splitting methods, which were originally in QueryTranslator. * <br> * TODO: This will need to be refactored at some point. * * @author josh Mar 14, 2004 10:50:23 AM */public final class QuerySplitter { private static final Log log = LogFactory.getLog( QuerySplitter.class ); private static final Set BEFORE_CLASS_TOKENS = new HashSet(); private static final Set NOT_AFTER_CLASS_TOKENS = new HashSet(); static { BEFORE_CLASS_TOKENS.add( "from" ); //beforeClassTokens.add("new"); DEFINITELY DON'T HAVE THIS!! BEFORE_CLASS_TOKENS.add( "," ); NOT_AFTER_CLASS_TOKENS.add( "in" ); //notAfterClassTokens.add(","); NOT_AFTER_CLASS_TOKENS.add( "from" ); NOT_AFTER_CLASS_TOKENS.add( ")" ); } /** * Private empty constructor. * (or else checkstyle says: 'warning: Utility classes should not have a public or default constructor.') */ private QuerySplitter() { } /** * Handle Hibernate "implicit" polymorphism, by translating the query string into * several "concrete" queries against mapped classes. */ public static String[] concreteQueries(String query, SessionFactoryImplementor factory) throws MappingException { //scan the query string for class names appearing in the from clause and replace //with all persistent implementors of the class/interface, returning multiple //query strings (make sure we don't pick up a class in the select clause!) //TODO: this is one of the ugliest and most fragile pieces of code in Hibernate.... String[] tokens = StringHelper.split( ParserHelper.WHITESPACE + "(),", query, true ); if ( tokens.length == 0 ) return new String[]{query}; // just especially for the trivial collection filter ArrayList placeholders = new ArrayList(); ArrayList replacements = new ArrayList(); StringBuffer templateQuery = new StringBuffer( 40 ); int count = 0; String last = null; int nextIndex = 0; String next = null; templateQuery.append( tokens[0] ); for ( int i = 1; i < tokens.length; i++ ) { //update last non-whitespace token, if necessary if ( !ParserHelper.isWhitespace( tokens[i - 1] ) ) last = tokens[i - 1].toLowerCase(); String token = tokens[i]; if ( !ParserHelper.isWhitespace( token ) || last == null ) { //scan for next non-whitespace token if ( nextIndex <= i ) { for ( nextIndex = i + 1; nextIndex < tokens.length; nextIndex++ ) { next = tokens[nextIndex].toLowerCase(); if ( !ParserHelper.isWhitespace( next ) ) break; } } if ( Character.isJavaIdentifierStart( token.charAt( 0 ) ) && ( ( BEFORE_CLASS_TOKENS.contains( last ) && !NOT_AFTER_CLASS_TOKENS.contains( next ) ) || "class".equals( last ) ) ) { String importedClassName = getImportedClass( token, factory ); if ( importedClassName != null ) { String[] implementors = factory.getImplementors( importedClassName ); String placeholder = "$clazz" + count++ + "$"; if ( implementors != null ) { placeholders.add( placeholder ); replacements.add( implementors ); } token = placeholder; // Note this!! } } } templateQuery.append( token ); } String[] results = StringHelper.multiply( templateQuery.toString(), placeholders.iterator(), replacements.iterator() ); if ( results.length == 0 ) log.warn( "no persistent classes found for query class: " + query ); return results; } public static String getImportedClass(String name, SessionFactoryImplementor factory) { return factory.getImportedClassName( name ); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -