1 package org.apache.torque.dsfactory;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57 import java.util.Hashtable;
58 import java.util.Iterator;
59 import java.util.Map;
60 import java.util.StringTokenizer;
61
62 import javax.naming.Context;
63 import javax.naming.InitialContext;
64 import javax.naming.NameAlreadyBoundException;
65 import javax.naming.NamingException;
66 import javax.sql.DataSource;
67
68 import org.apache.commons.configuration.Configuration;
69
70 import org.apache.commons.logging.Log;
71 import org.apache.commons.logging.LogFactory;
72
73 import org.apache.torque.TorqueException;
74
75 /***
76 * A factory that looks up the DataSource from JNDI. It is also able
77 * to deploy the DataSource based on properties found in the
78 * configuration.
79 *
80 * @author <a href="mailto:jmcnally@apache.org">John McNally</a>
81 * @version $Id: JndiDataSourceFactory.java,v 1.6 2003/05/14 19:38:04 mpoeschl Exp $
82 */
83 public class JndiDataSourceFactory
84 extends AbstractDataSourceFactory
85 implements DataSourceFactory
86 {
87
88 /*** The log. */
89 private static Log log = LogFactory.getLog(JndiDataSourceFactory.class);
90
91 /*** The path to get the resource from. */
92 private String path;
93 /*** The context to get the resource from. */
94 private Context ctx;
95
96 /***
97 * @see org.apache.torque.dsfactory.DataSourceFactory#getDataSource
98 */
99 public DataSource getDataSource() throws TorqueException
100 {
101 DataSource ds = null;
102 try
103 {
104 ds = ((DataSource) ctx.lookup(path));
105 }
106 catch (Exception e)
107 {
108 throw new TorqueException(e);
109 }
110 return ds;
111 }
112
113 /***
114 * @see org.apache.torque.dsfactory.DataSourceFactory#initialize
115 */
116 public void initialize(Configuration configuration) throws TorqueException
117 {
118 if (configuration == null)
119 {
120 throw new TorqueException(
121 "Torque cannot be initialized without "
122 + "a valid configuration. Please check the log files "
123 + "for further details.");
124 }
125 initJNDI(configuration);
126 initDataSource(configuration);
127 }
128
129 /***
130 * Initializes JNDI.
131 *
132 * @param configuration where to read the settings from
133 * @throws TorqueException if a property set fails
134 */
135 private void initJNDI(Configuration configuration) throws TorqueException
136 {
137 log.debug("Starting initJNDI");
138 Hashtable env = null;
139 Configuration c = configuration.subset("jndi");
140 if (c == null)
141 {
142 throw new TorqueException(
143 "JndiDataSourceFactory requires a jndi "
144 + "path property to lookup the DataSource in JNDI.");
145 }
146 try
147 {
148 Iterator i = c.getKeys();
149 while (i.hasNext())
150 {
151 String key = (String) i.next();
152 if (key.equals("path"))
153 {
154 path = c.getString(key);
155 log.debug("JNDI path: " + path);
156 }
157 else
158 {
159 if (env == null)
160 {
161 env = new Hashtable();
162 }
163 String value = c.getString(key);
164 env.put(key, value);
165 log.debug("Set jndi property: " + key + "=" + value);
166 }
167 }
168 if (env == null)
169 {
170 ctx = new InitialContext();
171 }
172 else
173 {
174 ctx = new InitialContext(env);
175 }
176 log.debug("Created new InitialContext");
177 debugCtx(ctx);
178 }
179 catch (Exception e)
180 {
181 log.error("", e);
182 throw new TorqueException(e);
183 }
184 }
185
186 /***
187 * Initializes the DataSource.
188 *
189 * @param configuration where to read the settings from
190 * @throws TorqueException if a property set fails
191 */
192 private void initDataSource(Configuration configuration)
193 throws TorqueException
194 {
195 log.debug("Starting initDataSources");
196 Configuration c = configuration.subset("datasource");
197 try
198 {
199 if (c != null)
200 {
201 Object ds = null;
202 Iterator i = c.getKeys();
203 while (i.hasNext())
204 {
205 String key = (String) i.next();
206 if (key.equals("classname"))
207 {
208 String classname = c.getString(key);
209 log.debug("Datasource class: " + classname);
210
211 Class dsClass = Class.forName(classname);
212 ds = dsClass.newInstance();
213 }
214 else
215 {
216 log.debug("Setting datasource property: " + key);
217 setProperty(key, c, ds);
218 }
219 }
220
221 bindDStoJndi(ctx, path, ds);
222 }
223 }
224 catch (Exception e)
225 {
226 log.error("", e);
227 throw new TorqueException(e);
228 }
229 }
230
231 /***
232 *
233 * @param ctx the context
234 * @throws NamingException
235 */
236 private void debugCtx(Context ctx) throws NamingException
237 {
238 log.debug("InitialContext -------------------------------");
239 Map env = ctx.getEnvironment();
240 Iterator qw = env.keySet().iterator();
241 log.debug("Environment properties:" + env.size());
242 while (qw.hasNext())
243 {
244 Object prop = qw.next();
245 log.debug(" " + prop + ": " + env.get(prop));
246 }
247 log.debug("----------------------------------------------");
248 }
249
250 /***
251 *
252 * @param ctx
253 * @param path
254 * @param ds
255 * @throws Exception
256 */
257 private void bindDStoJndi(Context ctx, String path, Object ds)
258 throws Exception
259 {
260 debugCtx(ctx);
261
262
263 int start = path.indexOf(':') + 1;
264 if (start > 0)
265 {
266 path = path.substring(start);
267 }
268 StringTokenizer st = new StringTokenizer(path, "/");
269 while (st.hasMoreTokens())
270 {
271 String subctx = st.nextToken();
272 if (st.hasMoreTokens())
273 {
274 try
275 {
276 ctx.createSubcontext(subctx);
277 log.debug("Added sub context: " + subctx);
278 }
279 catch (NameAlreadyBoundException nabe)
280 {
281
282 }
283 catch (NamingException ne)
284 {
285
286
287
288
289
290
291
292
293
294
295 }
296 ctx = (Context) ctx.lookup(subctx);
297 }
298 else
299 {
300
301 ctx.bind(subctx, ds);
302 }
303 }
304 }
305 }