KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > jdo > castor > CastorJDOImpl


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.jdo.castor;
23
24 import java.io.PrintWriter JavaDoc;
25 import java.io.Serializable JavaDoc;
26 import java.io.FileNotFoundException JavaDoc;
27
28 import java.lang.reflect.Method JavaDoc;
29
30 import java.util.HashMap JavaDoc;
31 import java.util.Hashtable JavaDoc;
32
33 import java.util.Enumeration JavaDoc;
34 import java.net.URL JavaDoc;
35
36 import javax.management.*;
37 import javax.naming.spi.ObjectFactory JavaDoc;
38 import javax.naming.Referenceable JavaDoc;
39 import javax.naming.Reference JavaDoc;
40 import javax.naming.Context JavaDoc;
41 import javax.naming.InitialContext JavaDoc;
42 import javax.naming.Name JavaDoc;
43 import javax.naming.NamingException JavaDoc;
44 import javax.naming.NameNotFoundException JavaDoc;
45
46 import org.xml.sax.EntityResolver JavaDoc;
47 import org.xml.sax.InputSource JavaDoc;
48
49 import org.exolab.castor.jdo.Database;
50 import org.exolab.castor.jdo.DataObjects;
51 import org.exolab.castor.jdo.JDO;
52 import org.exolab.castor.jdo.DatabaseNotFoundException;
53 import org.exolab.castor.jdo.PersistenceException;
54 import org.exolab.castor.persist.spi.LogInterceptor;
55 import org.exolab.castor.xml.Unmarshaller;
56
57 import org.jboss.logging.util.LoggerPluginWriter;
58
59 import org.jboss.system.ServiceMBeanSupport;
60
61
62 /**
63  * Castor JDO support.
64  *
65  * @jmx:mbean name="jboss:type=Service,service=JDO,flavor=Castor"
66  * extends="org.jboss.system.ServiceMBean"
67  *
68  * @version <tt>$Revision: 37459 $</tt>
69  * @author Oleg Nitz (on@ibis.odessa.ua)
70  */

71 public class CastorJDOImpl
72    extends ServiceMBeanSupport
73    implements DataObjects, ObjectFactory JavaDoc, Referenceable JavaDoc, Serializable JavaDoc,
74               CastorJDOImplMBean, MBeanRegistration, LogInterceptor
75 {
76
77    private String JavaDoc _jndiName;
78
79    private String JavaDoc _dbConf;
80
81    private String JavaDoc _dbUrl;
82
83    private JDO _jdo = new JDO();
84
85    private String JavaDoc _dataSourceName;
86
87    private static HashMap JavaDoc _instances = new HashMap JavaDoc();
88
89    private transient PrintWriter JavaDoc writer;
90
91    /**
92     * Do JDO classes should be loader by the global class loader
93     * (the same class loader as Castor classes)?
94     */

95    private boolean _commonClassPath;
96
97    /*
98     * True if user prefer all reachable object to be stored automatically.
99     * False (default) if user want only dependent object to be stored.
100     */

101    private boolean _autoStore = false;
102
103    /*
104     * True if user prefers application-server database pooling.
105     * False (default) if user wants a new connection for each invocation of
106     * getDatabase().
107     */

108    private boolean _dbPooling = false;
109
110    public CastorJDOImpl() {
111    }
112
113    protected ObjectName getObjectName(MBeanServer server, ObjectName name)
114       throws javax.management.MalformedObjectNameException JavaDoc
115    {
116       if (name == null) {
117          return new ObjectName(OBJECT_NAME+",name="+_jndiName);
118       }
119       
120       return name;
121    }
122
123    protected void startService() throws Exception JavaDoc
124    {
125       org.exolab.castor.jdo.conf.Database database;
126       Unmarshaller unm;
127       int pos;
128       Method JavaDoc m;
129
130       boolean debug = log.isDebugEnabled();
131
132       // Bind in JNDI
133
bind(new InitialContext JavaDoc(), "java:/" + _jndiName, this);
134
135         // Determine complete URL to _dbConf file. It is likely a relative path.
136
URL JavaDoc confUrl = Thread.currentThread().getContextClassLoader().getResource( _dbConf );
137
138         if ( null == confUrl )
139             {
140             FileNotFoundException JavaDoc e = new FileNotFoundException JavaDoc(
141                 "CastorJDOImpl.startService(): Unable to resolve Configuration attribute to URL = "
142                 + _dbConf );
143             log.error( "CastorJDOImpl.startService(): Unable to find " + _dbConf + " file.", e );
144             }
145
146         _dbUrl = confUrl.toString();
147     
148       _jdo.setTransactionManager("java:/TransactionManager");
149       _jdo.setConfiguration( _dbUrl );
150       unm = new Unmarshaller(org.exolab.castor.jdo.conf.Database.class);
151       database = (org.exolab.castor.jdo.conf.Database) unm.unmarshal(new InputSource JavaDoc( _dbUrl ));
152       _jdo.setDatabaseName(database.getName());
153       if (database.getJndi() != null) {
154          _dataSourceName = database.getJndi().getName();
155       }
156       // Older Castor versions older don't have these methods,
157
// we'll use reflection for backward compatibility
158
//_jdo.setAutoStore(_autoStore);
159
//_jdo.setDatabasePooling(_dbpooling);
160
try {
161          // 0.9.4
162
m = _jdo.getClass().getMethod("setAutoStore",
163                                        new Class JavaDoc[] {boolean.class});
164          m.invoke(_jdo, new Object JavaDoc[] {new Boolean JavaDoc(_autoStore)});
165       } catch (Exception JavaDoc ex) {
166          if (debug)
167             log.debug("couldn't invoke setAutoStore()");
168       }
169
170       try {
171          // 0.9.3
172
m = _jdo.getClass().getMethod("setDatabasePooling",
173                                        new Class JavaDoc[] {boolean.class});
174          m.invoke(_jdo, new Object JavaDoc[] {new Boolean JavaDoc(_dbPooling)});
175       } catch (Exception JavaDoc ex) {
176          if (debug)
177             log.debug("couldn't invoke setDatabasePooling()");
178       }
179       _instances.put(_jndiName, this);
180       if (debug)
181          log.debug("DataObjects factory for " + _dataSourceName + " bound to " + _jndiName);
182    }
183
184    protected void stopService() throws Exception JavaDoc
185    {
186       // Unbind from JNDI
187
InitialContext JavaDoc ctx = new InitialContext JavaDoc();
188       try {
189          ctx.unbind("java:/" + _jndiName);
190       }
191       finally {
192          ctx.close();
193       }
194    }
195
196
197     /**
198         * Copied from Jetty.java. Used to find resource within .sar.
199     */

200     public URL JavaDoc findResourceInJar( String JavaDoc name )
201     {
202         URL JavaDoc url = null;
203
204         try
205             {
206             url = getClass().getClassLoader().getResource( name );
207             }
208         catch ( Exception JavaDoc e )
209             {
210             log.error( "Could not find resource: " + name, e );
211             }
212
213         return url;
214     }
215
216
217    // CastorJDOImplMBean implementation ---------------------------
218

219    /**
220     * @jmx:managed-attribute
221     */

222    public void setJndiName(String JavaDoc jndiName) {
223       _jndiName = jndiName;
224    }
225
226    /**
227     * @jmx:managed-attribute
228     */

229    public String JavaDoc getJndiName() {
230       return _jndiName;
231    }
232
233    /**
234     * @jmx:managed-attribute
235     */

236    public void setConfiguration(String JavaDoc dbConf) {
237       _dbConf = dbConf;
238    }
239
240    /**
241     * @jmx:managed-attribute
242     */

243    public String JavaDoc getConfiguration() {
244       return _dbConf;
245    }
246
247    /**
248     * @jmx:managed-attribute
249     */

250    public String JavaDoc getConfigurationURL() {
251       return _dbUrl;
252    }
253
254    /**
255     * @jmx:managed-attribute
256     */

257    public void setLockTimeout(int lockTimeout) {
258       _jdo.setLockTimeout(lockTimeout);
259    }
260
261    /**
262     * @jmx:managed-attribute
263     */

264    public int getLockTimeout() {
265       return _jdo.getLockTimeout();
266    }
267
268    /**
269     * @jmx:managed-attribute
270     */

271    public void setLoggingEnabled(boolean loggingEnabled) {
272       _jdo.setLogInterceptor(loggingEnabled ? this : null);
273    }
274
275    /**
276     * @jmx:managed-attribute
277     */

278    public boolean getLoggingEnabled() {
279       return (_jdo.getLogInterceptor() != null);
280    }
281
282    /**
283     * @jmx:managed-attribute
284     */

285    public void setCommonClassPath(boolean commonClassPath) {
286       _commonClassPath = commonClassPath;
287    }
288
289    /**
290     * @jmx:managed-attribute
291     */

292    public boolean getCommonClassPath() {
293       return _commonClassPath;
294    }
295
296    /**
297     * @jmx:managed-attribute
298     *
299     * @param autoStore True if user prefer all reachable object to be stored automatically.
300     * False if user want only dependent object to be stored.
301     */

302    public void setAutoStore( boolean autoStore ) {
303       _autoStore = autoStore;
304    }
305
306    /**
307     * @jmx:managed-attribute
308     *
309     * @return if the next Database instance will be set to autoStore.
310     */

311    public boolean isAutoStore() {
312       return _autoStore;
313    }
314
315    /**
316     * True if user prefers to use application server database pools.
317     * False if user wants a new connection for each call to getDatabase().
318     *
319     * @jmx:managed-attribute
320     */

321    public void setDatabasePooling(boolean dbPooling) {
322       _dbPooling = dbPooling;
323    }
324
325    /**
326     * Return true if the Database instance uses the application server pooling.
327     *
328     * @jmx:managed-attribute
329     */

330    public boolean isDatabasePooling() {
331       return _dbPooling;
332    }
333
334    
335    // DataObjects implementation ----------------------------------
336

337    public Database getDatabase()
338       throws DatabaseNotFoundException, PersistenceException
339    {
340       Method JavaDoc m;
341
342       if (_commonClassPath) {
343          _jdo.setClassLoader(null);
344       } else {
345          _jdo.setClassLoader(Thread.currentThread().getContextClassLoader());
346       }
347       return _jdo.getDatabase();
348    }
349
350    public void setDescription(String JavaDoc description) {
351       _jdo.setDescription(description);
352    }
353
354    public String JavaDoc getDescription() {
355       return _jdo.getDescription();
356    }
357
358    
359    // Referenceable implementation ----------------------------------
360

361    public Reference JavaDoc getReference() {
362       return new Reference JavaDoc(getClass().getName(), getClass().getName(), null);
363    }
364
365    
366    // ObjectFactory implementation ----------------------------------
367

368    public Object JavaDoc getObjectInstance(Object JavaDoc obj,
369                                    Name JavaDoc name,
370                                    Context JavaDoc nameCtx,
371                                    Hashtable JavaDoc environment)
372       throws Exception JavaDoc
373    {
374       return _instances.get(name.toString());
375    }
376
377    
378    // Private -------------------------------------------------------
379

380    private void bind(Context JavaDoc ctx, String JavaDoc name, Object JavaDoc val)
381       throws NamingException JavaDoc
382    {
383       // Bind val to name in ctx, and make sure that all intermediate contexts exist
384

385       Name JavaDoc n = ctx.getNameParser("").parse(name);
386       while (n.size() > 1)
387          {
388             String JavaDoc ctxName = n.get(0);
389             try
390                {
391                   ctx = (Context JavaDoc)ctx.lookup(ctxName);
392                } catch (NameNotFoundException JavaDoc e)
393                   {
394                      ctx = ctx.createSubcontext(ctxName);
395                   }
396             n = n.getSuffix(1);
397          }
398
399       ctx.bind(n.get(0), val);
400    }
401
402    
403    // LogInterceptor implementation for Castor 0.8 ----------------------
404

405    public void loading(Class JavaDoc objClass, Object JavaDoc identity) {
406       if (log.isDebugEnabled())
407          log.debug( "Loading " + objClass.getName() + " (" + identity + ")" );
408    }
409
410    public void creating(Class JavaDoc objClass, Object JavaDoc identity) {
411       if (log.isDebugEnabled())
412          log.debug( "Creating " + objClass.getName() + " (" + identity + ")" );
413    }
414
415    public void removing(Class JavaDoc objClass, Object JavaDoc identity) {
416       if (log.isDebugEnabled())
417          log.debug( "Removing " + objClass.getName() + " (" + identity + ")" );
418    }
419
420
421    public void storing(Class JavaDoc objClass, Object JavaDoc identity) {
422       if (log.isDebugEnabled())
423          log.debug( "Storing " + objClass.getName() + " (" + identity + ")" );
424    }
425
426
427    // LogInterceptor implementation for Castor 0.9 ----------------------
428

429    public void loading(Object JavaDoc objClass, Object JavaDoc identity) {
430       if (log.isDebugEnabled())
431          log.debug( "Loading " + objClass + " (" + identity + ")" );
432    }
433
434    public void creating(Object JavaDoc objClass, Object JavaDoc identity) {
435       if (log.isDebugEnabled())
436          log.debug( "Creating " + objClass + " (" + identity + ")" );
437    }
438
439    public void removing(Object JavaDoc objClass, Object JavaDoc identity) {
440       if (log.isDebugEnabled())
441          log.debug( "Removing " + objClass + " (" + identity + ")" );
442    }
443
444    public void storing(Object JavaDoc objClass, Object JavaDoc identity) {
445       if (log.isDebugEnabled())
446          log.debug( "Storing " + objClass + " (" + identity + ")" );
447    }
448
449    // LogInterceptor implementation - the rest part --------------------
450

451    public void storeStatement(String JavaDoc statement) {
452       log.debug(statement);
453    }
454
455    public void queryStatement(String JavaDoc statement) {
456       log.debug(statement);
457    }
458
459    public void message(String JavaDoc message) {
460       log.debug(message);
461    }
462
463    public void exception(Exception JavaDoc except) {
464       log.error("Exception", except);
465    }
466
467    public PrintWriter JavaDoc getPrintWriter()
468    {
469       if (writer == null)
470       {
471          writer = new LoggerPluginWriter(log.getLoggerPlugin ());
472       }
473
474       return writer;
475    }
476 }
477
478
Popular Tags