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
5 * under the terms of the GNU Lesser General Public License as published
6 * by the Free Software Foundation; either version 2.1 of the License, or
7 * (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; with out even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser General Public License 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,
16 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
17 *
18 * > http://www.gnu.org/copyleft/lesser.html
19 * > http://www.opensource.org/licenses/lgpl-license.php
20 */
21 package net.mlw.vlh.adapter.jdbc.util;
22
23 import java.sql.Connection;
24 import java.sql.PreparedStatement;
25 import java.sql.ResultSet;
26 import java.sql.SQLException;
27 import java.text.ParseException;
28 import java.util.Collections;
29 import java.util.Iterator;
30 import java.util.LinkedList;
31 import java.util.List;
32 import java.util.Map;
33
34 import net.mlw.vlh.adapter.jdbc.util.setter.StringSetter;
35 import net.mlw.vlh.adapter.util.FilterTextManipulator;
36 import net.mlw.vlh.adapter.util.TextManipulator;
37 import net.mlw.vlh.adapter.util.TokenReplaceTextManipulator;
38
39 import org.apache.commons.logging.Log;
40 import org.apache.commons.logging.LogFactory;
41
42 /***
43 * Copyright (c) 2003 held jointly by the individual authors.
44 *
45 * This library is free software; you can redistribute it and/or modify it
46 * under the terms of the GNU Lesser General Public License as published
47 * by the Free Software Foundation; either version 2.1 of the License, or
48 * (at your option) any later version.
49 *
50 * This library is distributed in the hope that it will be useful, but
51 * WITHOUT ANY WARRANTY; with out even the implied warranty of
52 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
53 * GNU Lesser General Public License for more details.
54 *
55 * You should have received a copy of the GNU Lesser General Public License
56 * along with this library; if not, write to the Free Software Foundation,
57 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
58 *
59 * > http://www.gnu.org/copyleft/lesser.html
60 * > http://www.opensource.org/licenses/lgpl-license.php
61 */
62 public class ConfigurableStatementBuilder implements StatementBuilder
63 {
64 /*** Commons logger. */
65 private static final Log LOGGER = LogFactory.getLog(ConfigurableStatementBuilder.class);
66
67 private Map setters;
68
69 private Setter defaultSetter = new StringSetter();
70
71 private List textManipulators;
72
73 private boolean init = false;
74
75 /*** Initialize this bean with default values.
76 */
77 public void init()
78 {
79 if (textManipulators == null)
80 {
81 textManipulators = new LinkedList();
82 textManipulators.add(new FilterTextManipulator());
83 textManipulators.add(new TokenReplaceTextManipulator());
84 }
85 init = true;
86 }
87
88 /***
89 * @see net.mlw.vlh.adapter.jdbc.util.StatementBuilder#generate(java.sql.Connection, java.lang.StringBuffer, java.util.Map, boolean)
90 */
91 public PreparedStatement generate(Connection conn, StringBuffer query, Map whereClause, boolean scrollable) throws SQLException,
92 ParseException
93 {
94 if (!init)
95 {
96 init();
97 }
98
99 if (whereClause == null)
100 {
101 whereClause = Collections.EMPTY_MAP;
102 }
103
104 for (Iterator iter = textManipulators.iterator(); iter.hasNext();)
105 {
106 TextManipulator manipulator = (TextManipulator) iter.next();
107 manipulator.manipulate(query, whereClause);
108 }
109
110 LinkedList arguments = new LinkedList();
111
112
113
114 for (int i = 0, end = 0, start; ((start = query.toString().indexOf('{', end)) >= 0); i++)
115 {
116 end = query.toString().indexOf('}', start);
117
118 String key = query.substring(start + 1, end);
119
120 Object value = whereClause.get(key);
121 if (value == null)
122 {
123 throw new NullPointerException("Property '" + key + "' was not provided.");
124 }
125 arguments.add(new NamedPair(key, value));
126 Setter setter = getSetter(key);
127 query.replace(start, end + 1, setter.getReplacementString(value));
128 end -= (key.length() + 2);
129 }
130
131 PreparedStatement statement = null;
132 if (scrollable)
133 {
134 statement = conn.prepareStatement(query.toString(), ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
135 }
136 else
137 {
138 statement = conn.prepareStatement(query.toString());
139 }
140
141 int index = 1;
142
143 for (Iterator iter = arguments.iterator(); iter.hasNext();)
144 {
145 NamedPair namedPair = (NamedPair) iter.next();
146 Setter setter = getSetter(namedPair.getName());
147 try
148 {
149 index = setter.set(statement, index, namedPair.getValue());
150 }
151 catch (RuntimeException e)
152 {
153 String message = "Cannot set value of " + namedPair.getName() + " (setter = " + setter + ")";
154 LOGGER.error(message, e);
155 throw new RuntimeException(message, e);
156 }
157 }
158
159 return statement;
160 }
161
162 /*** Gets a setter for the given property.
163 *
164 * @param name The name of the property. Also the key in the Map.
165 * @return The setter for the given property.
166 */
167 public Setter getSetter(String name)
168 {
169 Setter setter = ((setters == null) ? defaultSetter : (Setter) setters.get(name));
170 return (setter == null) ? defaultSetter : setter;
171 }
172
173 /***
174 * @param setters The setters to set.
175 */
176 public void setSetters(Map setters)
177 {
178 this.setters = setters;
179 }
180
181 /***
182 * @param defaultSetter The defaultSetter to set.
183 */
184 public void setDefaultSetter(Setter defaultSetter)
185 {
186 this.defaultSetter = defaultSetter;
187 }
188
189 /***
190 * @param textManipulatorList The textManipulatorList to set.
191 */
192 public void setTextManipulators(List textManipulators)
193 {
194 this.textManipulators = textManipulators;
195 }
196 }