~raginggoblin/infolog/infolog

« back to all changes in this revision

Viewing changes to InfologServer/lib/hibernate-distribution-3.3.2.GA/project/core/src/main/java/org/hibernate/hql/QuerySplitter.java

  • Committer: Raging Goblin
  • Date: 2013-11-16 16:51:32 UTC
  • Revision ID: raging_goblin-20131116165132-weujnptzc88uy4ah
Mavenized the project, now using shared project InfologSync

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Hibernate, Relational Persistence for Idiomatic Java
3
 
 *
4
 
 * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
5
 
 * indicated by the @author tags or express copyright attribution
6
 
 * statements applied by the authors.  All third-party contributions are
7
 
 * distributed under license by Red Hat Middleware LLC.
8
 
 *
9
 
 * This copyrighted material is made available to anyone wishing to use, modify,
10
 
 * copy, or redistribute it subject to the terms and conditions of the GNU
11
 
 * Lesser General Public License, as published by the Free Software Foundation.
12
 
 *
13
 
 * This program is distributed in the hope that it will be useful,
14
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15
 
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
16
 
 * for more details.
17
 
 *
18
 
 * You should have received a copy of the GNU Lesser General Public License
19
 
 * along with this distribution; if not, write to:
20
 
 * Free Software Foundation, Inc.
21
 
 * 51 Franklin Street, Fifth Floor
22
 
 * Boston, MA  02110-1301  USA
23
 
 *
24
 
 */
25
 
package org.hibernate.hql;
26
 
 
27
 
import org.slf4j.Logger;
28
 
import org.slf4j.LoggerFactory;
29
 
import org.hibernate.MappingException;
30
 
import org.hibernate.engine.SessionFactoryImplementor;
31
 
import org.hibernate.hql.classic.ParserHelper;
32
 
import org.hibernate.util.StringHelper;
33
 
 
34
 
import java.util.ArrayList;
35
 
import java.util.HashSet;
36
 
import java.util.Set;
37
 
 
38
 
/**
39
 
 * Provides query splitting methods, which were originally in QueryTranslator.
40
 
 * <br>
41
 
 * TODO: This will need to be refactored at some point.
42
 
 *
43
 
 * @author josh
44
 
 */
45
 
public final class QuerySplitter {
46
 
 
47
 
        private static final Logger log = LoggerFactory.getLogger( QuerySplitter.class );
48
 
 
49
 
        private static final Set BEFORE_CLASS_TOKENS = new HashSet();
50
 
        private static final Set NOT_AFTER_CLASS_TOKENS = new HashSet();
51
 
 
52
 
        static {
53
 
                BEFORE_CLASS_TOKENS.add( "from" );
54
 
                BEFORE_CLASS_TOKENS.add( "delete" );
55
 
                BEFORE_CLASS_TOKENS.add( "update" );
56
 
                //beforeClassTokens.add("new"); DEFINITELY DON'T HAVE THIS!!
57
 
                BEFORE_CLASS_TOKENS.add( "," );
58
 
                NOT_AFTER_CLASS_TOKENS.add( "in" );
59
 
                //notAfterClassTokens.add(",");
60
 
                NOT_AFTER_CLASS_TOKENS.add( "from" );
61
 
                NOT_AFTER_CLASS_TOKENS.add( ")" );
62
 
        }
63
 
 
64
 
        /**
65
 
         * Private empty constructor.
66
 
         * (or else checkstyle says: 'warning: Utility classes should not have a public or default constructor.')
67
 
         */
68
 
        private QuerySplitter() {
69
 
        }
70
 
 
71
 
        /**
72
 
         * Handle Hibernate "implicit" polymorphism, by translating the query string into
73
 
         * several "concrete" queries against mapped classes.
74
 
         */
75
 
        public static String[] concreteQueries(String query, SessionFactoryImplementor factory) throws MappingException {
76
 
 
77
 
                //scan the query string for class names appearing in the from clause and replace
78
 
                //with all persistent implementors of the class/interface, returning multiple
79
 
                //query strings (make sure we don't pick up a class in the select clause!)
80
 
 
81
 
                //TODO: this is one of the ugliest and most fragile pieces of code in Hibernate....
82
 
 
83
 
                String[] tokens = StringHelper.split( StringHelper.WHITESPACE + "(),", query, true );
84
 
                if ( tokens.length == 0 ) return new String[]{query}; // just especially for the trivial collection filter
85
 
                ArrayList placeholders = new ArrayList();
86
 
                ArrayList replacements = new ArrayList();
87
 
                StringBuffer templateQuery = new StringBuffer( 40 );
88
 
                int count = 0;
89
 
                String last = null;
90
 
                int nextIndex = 0;
91
 
                String next = null;
92
 
                boolean isSelectClause = false;
93
 
 
94
 
                templateQuery.append( tokens[0] );
95
 
                if ( "select".equals( tokens[0].toLowerCase() ) ) isSelectClause = true;
96
 
        
97
 
                for ( int i = 1; i < tokens.length; i++ ) {
98
 
 
99
 
                        //update last non-whitespace token, if necessary
100
 
                        if ( !ParserHelper.isWhitespace( tokens[i - 1] ) ) last = tokens[i - 1].toLowerCase();
101
 
 
102
 
                        // select-range is terminated by declaration of "from"
103
 
                        if ( "from".equals( tokens[i].toLowerCase() ) ) isSelectClause = false;
104
 
 
105
 
                        String token = tokens[i];
106
 
                        if ( !ParserHelper.isWhitespace( token ) || last == null ) {
107
 
 
108
 
                                //scan for next non-whitespace token
109
 
                                if ( nextIndex <= i ) {
110
 
                                        for ( nextIndex = i + 1; nextIndex < tokens.length; nextIndex++ ) {
111
 
                                                next = tokens[nextIndex].toLowerCase();
112
 
                                                if ( !ParserHelper.isWhitespace( next ) ) break;
113
 
                                        }
114
 
                                }
115
 
 
116
 
                                boolean process = !isSelectClause && 
117
 
                                                isJavaIdentifier( token ) && 
118
 
                                                isPossiblyClassName( last, next );
119
 
                                                
120
 
                                if (process) {
121
 
                                        String importedClassName = getImportedClass( token, factory );
122
 
                                        if ( importedClassName != null ) {
123
 
                                                String[] implementors = factory.getImplementors( importedClassName );
124
 
                                                String placeholder = "$clazz" + count++ + "$";
125
 
                                                if ( implementors != null ) {
126
 
                                                        placeholders.add( placeholder );
127
 
                                                        replacements.add( implementors );
128
 
                                                }
129
 
                                                token = placeholder; // Note this!!
130
 
                                        }
131
 
                                }
132
 
 
133
 
                        }
134
 
 
135
 
                        templateQuery.append( token );
136
 
 
137
 
                }
138
 
                String[] results = StringHelper.multiply( templateQuery.toString(), placeholders.iterator(), replacements.iterator() );
139
 
                if ( results.length == 0 ) log.warn( "no persistent classes found for query class: " + query );
140
 
                return results;
141
 
        }
142
 
 
143
 
        private static boolean isPossiblyClassName(String last, String next) {
144
 
                return "class".equals( last ) || ( 
145
 
                                BEFORE_CLASS_TOKENS.contains( last ) && 
146
 
                                !NOT_AFTER_CLASS_TOKENS.contains( next ) 
147
 
                        );
148
 
        }
149
 
 
150
 
        private static boolean isJavaIdentifier(String token) {
151
 
                return Character.isJavaIdentifierStart( token.charAt( 0 ) );
152
 
        }
153
 
 
154
 
        public static String getImportedClass(String name, SessionFactoryImplementor factory) {
155
 
                return factory.getImportedClassName( name );
156
 
        }
157
 
}