View Javadoc

1   /***
2    * Copyright (c) 2003 held jointly by the individual authors.
3    * 
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    * 
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
11   * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
12   * for more details.
13   * 
14   * You should have received a copy of the GNU Lesser General Public License
15   * along with this library; if not, write to the Free Software Foundation, Inc.,
16   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
17   *  > http://www.gnu.org/copyleft/lesser.html >
18   * http://www.opensource.org/licenses/lgpl-license.php
19   */
20  package net.mlw.vlh.adapter.hibernate3.util;
21  
22  import java.text.ParseException;
23  import java.util.Collections;
24  import java.util.HashMap;
25  import java.util.Iterator;
26  import java.util.List;
27  import java.util.Map;
28  
29  import net.mlw.vlh.adapter.hibernate3.util.setter.DefaultSetter;
30  
31  import org.apache.commons.logging.Log;
32  import org.apache.commons.logging.LogFactory;
33  import org.hibernate.HibernateException;
34  import org.hibernate.Query;
35  import org.hibernate.Session;
36  
37  /***
38   * Utility for working with hibernate.
39   * 
40   * @author Matthew L. Wilson, Andrej Zachar
41   * @version $Revision: 1.2 $ $Date: 2005/12/16 15:40:09 $
42   */
43  public class StatementBuilder
44  {
45     /*** Commons Logger */
46     private static final Log LOGGER = LogFactory.getFactory().getInstance(StatementBuilder.class);
47  
48     private Map setters;
49  
50     private Setter defaultSetter = new DefaultSetter();
51  
52     /***
53      * Usage of filters: {key} -> :keyName add to query's parameter map keyValue
54      * [key] -> keyValue
55      * 
56      * @param hql
57      * @param whereClause
58      * @return Query for ordinary list
59      * @throws HibernateException
60      * @throws ParseException
61      */
62     public Query generate(Session session, StringBuffer hql, Map whereClause, boolean isRemoveEmptyStrings) throws HibernateException,
63           ParseException
64     {
65        if (whereClause == null)
66        {
67           whereClause = Collections.EMPTY_MAP;
68        }
69  
70        Map arguments = new HashMap();
71  
72        // Include or exclude the filters.
73        for (int i = 0, end = 0, start; ((start = hql.toString().indexOf("/~", end)) >= 0); i++)
74        {
75           end = hql.toString().indexOf("~/", start);
76           String key = hql.substring(start + 2, hql.indexOf(":", start));
77  
78           Object value = whereClause.get(key);
79           if (isValuePopulated(value, isRemoveEmptyStrings))
80           {
81              if (LOGGER.isDebugEnabled())
82              {
83                 LOGGER.debug("The filter key=[" + key + "] with the value=[" + value + "] is accepted by the hql preprocesor");
84              }
85              hql.replace(start, end + 2, hql.substring(hql.indexOf(":", start) + 1, end));
86           }
87           else
88           {
89              if (LOGGER.isInfoEnabled())
90              {
91                 LOGGER.info("The filter key=[" + key + "] is removed from the query by the hql preprocesor.");
92              }
93              hql.replace(start, end + 2, "");
94  
95           }
96           end -= start;
97        }
98  
99        // Replace any [key] with the value in the whereClause Map.
100       for (int i = 0, end = 0, start; ((start = hql.toString().indexOf('[', end)) >= 0); i++)
101       {
102          end = hql.toString().indexOf(']', start);
103          String key = hql.substring(start + 1, end);
104 
105          Object value = whereClause.get(key);
106          hql.replace(start, end + 1, (value == null) ? "" : value.toString());
107          end -= (key.length() + 2);
108       }
109 
110       // Replace any "{key}" with the value in the whereClause Map,
111       // then placing the value in the partameters list.
112       for (int i = 0, end = 0, start; ((start = hql.toString().indexOf('{', end)) >= 0); i++)
113       {
114          end = hql.toString().indexOf('}', start);
115 
116          String key = hql.substring(start + 1, end);
117 
118          Object value = whereClause.get(key);
119          if (value == null)
120          {
121             throw new NullPointerException("Property '" + key + "' was not provided.");
122          }
123          arguments.put(key, value);
124          hql.replace(start, end + 1, ":" + key);
125          end -= (key.length() + 2);
126       }
127       if (LOGGER.isDebugEnabled())
128       {
129          LOGGER.debug("The final query is " + hql);
130       }
131       Query query = session.createQuery(hql.toString());
132       // Now set all the patameters on the statement.
133 
134       if (setters == null)
135       {
136          for (Iterator keys = arguments.keySet().iterator(); keys.hasNext();)
137          {
138             String key = (String) keys.next();
139             Object value = arguments.get(key);
140             if (value instanceof List)
141             {
142                if (LOGGER.isDebugEnabled())
143                {
144                   LOGGER.debug("Setting a paremeterList to the query.");
145                }
146                query.setParameterList(key, ((List) value).toArray());
147             }
148             else
149             {
150                if (LOGGER.isDebugEnabled())
151                {
152                   LOGGER.debug("Using the default setter for key=[" + key + "] with the value=[" + value + "]");
153                }
154                getDefaultSetter().set(query, key, value);
155             }
156          }
157       }
158       else
159       {
160          for (Iterator keys = arguments.keySet().iterator(); keys.hasNext();)
161          {
162             String key = (String) keys.next();
163             Object value = arguments.get(key);
164             getSetter(key).set(query, key, value);
165          }
166       }
167 
168       return query;
169    }
170 
171    /***
172     * @param value
173     * @param isRemoveEmptyStrings Enable/Disable String length checking
174     * @return true - When is it not null and for instances of String is lenght >
175     *         0 as well. false - When is null, or String is ""
176     */
177    private boolean isValuePopulated(Object value, boolean isRemoveEmptyStrings)
178    {
179       if (value == null)
180       {
181          return false;
182       }
183       else
184       {
185          if (isRemoveEmptyStrings && value instanceof String)
186          {
187             return ((String) value).length() > 0;
188          }
189          else
190          {
191             return true;
192          }
193       }
194 
195    }
196 
197    /***
198     * Generete optimalized query for focusing large amount of data.
199     * 
200     * @param session
201     * @param hql
202     * @param whereClause
203     * @param isRemoveEmptyStrings
204     * @param defaultFocusPropertyObjectAlias
205     * @param focusProperty
206     * @return
207     * @throws HibernateException
208     * @throws ParseException
209     */
210    public Query generateForFocus(Session session, StringBuffer hql, Map whereClause, boolean isRemoveEmptyStrings,
211          String defaultFocusPropertyObjectAlias, String focusProperty) throws HibernateException, ParseException
212    {
213       StringBuffer hsqlFocus = new StringBuffer("SELECT ");
214       hsqlFocus.append(defaultFocusPropertyObjectAlias);
215       hsqlFocus.append(focusProperty);
216 
217       int indexOfTextFrom = hql.toString().toLowerCase().indexOf(" from ");
218       if (indexOfTextFrom < 0)
219       {
220          indexOfTextFrom = hql.toString().toLowerCase().indexOf("from ");
221          hsqlFocus.append(" ");
222       }
223       if (indexOfTextFrom > -1)
224       {
225          hsqlFocus.append(hql.substring(indexOfTextFrom));
226          return generate(session, hsqlFocus, whereClause, isRemoveEmptyStrings);
227       }
228       else
229       {
230          LOGGER.error("HQL hasn't command FROM!!");
231          return null;
232       }
233    }
234 
235    /***
236     * @param setters The setters to set.
237     */
238    public void setSetters(Map setters)
239    {
240       this.setters = setters;
241    }
242 
243    public Setter getSetter(String key)
244    {
245       Setter setter = null;
246       if (setters != null)
247       {
248          if (LOGGER.isDebugEnabled())
249          {
250             LOGGER.debug("Using custom setters for key=[" + key + "]");
251          }
252          setter = (Setter) setters.get(key);
253       }
254       else
255       {
256          if (LOGGER.isDebugEnabled())
257          {
258             LOGGER.debug("Using default setter for key=[" + key + "]");
259          }
260       }
261 
262       return (setter == null) ? defaultSetter : setter;
263 
264    }
265 
266    /***
267     * @return Returns the defaultSetter.
268     */
269    public Setter getDefaultSetter()
270    {
271       return defaultSetter;
272    }
273 
274    /***
275     * @param defaultSetter The defaultSetter to set.
276     */
277    public void setDefaultSetter(Setter defaultSetter)
278    {
279       this.defaultSetter = defaultSetter;
280    }
281 }