Coverage report

  %line %branch
org.apache.torque.dsfactory.JndiDataSourceFactory
0% 
0% 

 1  
 package org.apache.torque.dsfactory;
 2  
 
 3  
 /*
 4  
  * Copyright 2001-2004 The Apache Software Foundation.
 5  
  *
 6  
  * Licensed under the Apache License, Version 2.0 (the "License")
 7  
  * you may not use this file except in compliance with the License.
 8  
  * You may obtain a copy of the License at
 9  
  *
 10  
  *     http://www.apache.org/licenses/LICENSE-2.0
 11  
  *
 12  
  * Unless required by applicable law or agreed to in writing, software
 13  
  * distributed under the License is distributed on an "AS IS" BASIS,
 14  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15  
  * See the License for the specific language governing permissions and
 16  
  * limitations under the License.
 17  
  */
 18  
 
 19  
 import java.util.Hashtable;
 20  
 import java.util.Iterator;
 21  
 import java.util.Map;
 22  
 import java.util.StringTokenizer;
 23  
 
 24  
 import javax.naming.Context;
 25  
 import javax.naming.InitialContext;
 26  
 import javax.naming.NameAlreadyBoundException;
 27  
 import javax.naming.NamingException;
 28  
 import javax.sql.DataSource;
 29  
 
 30  
 import org.apache.commons.configuration.Configuration;
 31  
 
 32  
 import org.apache.commons.logging.Log;
 33  
 import org.apache.commons.logging.LogFactory;
 34  
 
 35  
 import org.apache.torque.TorqueException;
 36  
 
 37  
 /**
 38  
  * A factory that looks up the DataSource from JNDI.  It is also able
 39  
  * to deploy the DataSource based on properties found in the
 40  
  * configuration.
 41  
  *
 42  
  * This factory tries to avoid excessive context lookups to improve speed.
 43  
  * The time between two lookups can be configured. The default is 0 (no cache).
 44  
  *
 45  
  * @author <a href="mailto:jmcnally@apache.org">John McNally</a>
 46  
  * @author <a href="mailto:thomas@vandahl.org">Thomas Vandahl</a>
 47  
  * @version $Id: JndiDataSourceFactory.java,v 1.6.2.3 2004/10/20 14:13:58 henning Exp $
 48  
  */
 49  0
 public class JndiDataSourceFactory
 50  
     extends AbstractDataSourceFactory
 51  
     implements DataSourceFactory
 52  
 {
 53  
 
 54  
     /** The log. */
 55  0
     private static Log log = LogFactory.getLog(JndiDataSourceFactory.class);
 56  
 
 57  
     /** The path to get the resource from. */
 58  
     private String path;
 59  
     /** The context to get the resource from. */
 60  
     private Context ctx;
 61  
 
 62  
     /** A locally cached copy of the DataSource */
 63  0
     private DataSource ds = null;
 64  
 
 65  
     /** Time of last actual lookup action */
 66  0
     private long lastLookup = 0;
 67  
 
 68  
     /** Time between two lookups */
 69  0
     private long ttl = 0; // ms
 70  
 
 71  
     /**
 72  
      * @see org.apache.torque.dsfactory.DataSourceFactory#getDataSource
 73  
      */
 74  
     public DataSource getDataSource() throws TorqueException
 75  
     {
 76  0
     	long time = System.currentTimeMillis();
 77  
     	
 78  0
     	if (ds == null || time - lastLookup > ttl)
 79  
     	{
 80  
             try
 81  
             {
 82  0
                 ds = ((DataSource) ctx.lookup(path));
 83  0
 	        lastLookup = time;
 84  
             }
 85  0
             catch (Exception e)
 86  
             {
 87  0
                 throw new TorqueException(e);
 88  0
             }
 89  
     	}
 90  
 
 91  0
    	return ds;
 92  
     }
 93  
 
 94  
     /**
 95  
      * @see org.apache.torque.dsfactory.DataSourceFactory#initialize
 96  
      */
 97  
     public void initialize(Configuration configuration) throws TorqueException
 98  
     {
 99  0
         if (configuration == null)
 100  
         {
 101  0
             throw new TorqueException(
 102  
                 "Torque cannot be initialized without "
 103  
                     + "a valid configuration. Please check the log files "
 104  
                     + "for further details.");
 105  
         }
 106  0
         initJNDI(configuration);
 107  0
         initDataSource(configuration);
 108  0
     }
 109  
 
 110  
     /**
 111  
      * Initializes JNDI.
 112  
      *
 113  
      * @param configuration where to read the settings from
 114  
      * @throws TorqueException if a property set fails
 115  
      */
 116  
     private void initJNDI(Configuration configuration) throws TorqueException
 117  
     {
 118  0
         log.debug("Starting initJNDI");
 119  0
         Hashtable env = null;
 120  0
         Configuration c = configuration.subset("jndi");
 121  0
         if (c == null)
 122  
         {
 123  0
             throw new TorqueException(
 124  
                 "JndiDataSourceFactory requires a jndi "
 125  
                     + "path property to lookup the DataSource in JNDI.");
 126  
         }
 127  
         try
 128  
         {
 129  0
             Iterator i = c.getKeys();
 130  0
             while (i.hasNext())
 131  
             {
 132  0
                 String key = (String) i.next();
 133  0
                 if (key.equals("path"))
 134  
                 {
 135  0
                     path = c.getString(key);
 136  0
                     log.debug("JNDI path: " + path);
 137  
                 }
 138  0
                 else if (key.equals("ttl"))
 139  
 		{
 140  0
 		    ttl = c.getLong(key, ttl);
 141  0
                     log.debug("Time between context lookups: " + ttl);
 142  
 		}
 143  
                 else
 144  
                 {
 145  0
                     if (env == null)
 146  
                     {
 147  0
                         env = new Hashtable();
 148  
                     }
 149  0
                     String value = c.getString(key);
 150  0
                     env.put(key, value);
 151  0
                     log.debug("Set jndi property: " + key + "=" + value);
 152  
                 }
 153  
             }
 154  0
             if (env == null)
 155  
             {
 156  0
                 ctx = new InitialContext();
 157  
             }
 158  
             else
 159  
             {
 160  0
                 ctx = new InitialContext(env);
 161  
             }
 162  0
             log.debug("Created new InitialContext");
 163  0
             debugCtx(ctx);
 164  
         }
 165  0
         catch (Exception e)
 166  
         {
 167  0
             log.error("", e);
 168  0
             throw new TorqueException(e);
 169  0
         }
 170  0
     }
 171  
 
 172  
     /**
 173  
      * Initializes the DataSource.
 174  
      *
 175  
      * @param configuration where to read the settings from
 176  
      * @throws TorqueException if a property set fails
 177  
      */
 178  
     private void initDataSource(Configuration configuration)
 179  
         throws TorqueException
 180  
     {
 181  0
         log.debug("Starting initDataSources");
 182  0
         Configuration c = configuration.subset("datasource");
 183  
         try
 184  
         {
 185  0
             if (c != null)
 186  
             {
 187  0
                 Object ds = null;
 188  0
                 Iterator i = c.getKeys();
 189  0
                 while (i.hasNext())
 190  
                 {
 191  0
                     String key = (String) i.next();
 192  0
                     if (key.equals("classname"))
 193  
                     {
 194  0
                         String classname = c.getString(key);
 195  0
                         log.debug("Datasource class: " + classname);
 196  
 
 197  0
                         Class dsClass = Class.forName(classname);
 198  0
                         ds = dsClass.newInstance();
 199  
                     }
 200  
                     else
 201  
                     {
 202  0
                         log.debug("Setting datasource property: " + key);
 203  0
                         setProperty(key, c, ds);
 204  
                     }
 205  
                 }
 206  
 
 207  0
                 bindDStoJndi(ctx, path, ds);
 208  
             }
 209  
         }
 210  0
         catch (Exception e)
 211  
         {
 212  0
             log.error("", e);
 213  0
             throw new TorqueException(e);
 214  0
         }
 215  0
     }
 216  
 
 217  
     /**
 218  
      *
 219  
      * @param ctx the context
 220  
      * @throws NamingException
 221  
      */
 222  
     private void debugCtx(Context ctx) throws NamingException
 223  
     {
 224  0
         log.debug("InitialContext -------------------------------");
 225  0
         Map env = ctx.getEnvironment();
 226  0
         Iterator qw = env.keySet().iterator();
 227  0
         log.debug("Environment properties:" + env.size());
 228  0
         while (qw.hasNext())
 229  
         {
 230  0
             Object prop = qw.next();
 231  0
             log.debug("    " + prop + ": " + env.get(prop));
 232  
         }
 233  0
         log.debug("----------------------------------------------");
 234  0
     }
 235  
 
 236  
     /**
 237  
      *
 238  
      * @param ctx
 239  
      * @param path
 240  
      * @param ds
 241  
      * @throws Exception
 242  
      */
 243  
     private void bindDStoJndi(Context ctx, String path, Object ds)
 244  
         throws Exception
 245  
     {
 246  0
         debugCtx(ctx);
 247  
 
 248  
         // add subcontexts, if not added already
 249  0
         int start = path.indexOf(':') + 1;
 250  0
         if (start > 0)
 251  
         {
 252  0
             path = path.substring(start);
 253  
         }
 254  0
         StringTokenizer st = new StringTokenizer(path, "/");
 255  0
         while (st.hasMoreTokens())
 256  
         {
 257  0
             String subctx = st.nextToken();
 258  0
             if (st.hasMoreTokens())
 259  
             {
 260  
                 try
 261  
                 {
 262  0
                     ctx.createSubcontext(subctx);
 263  0
                     log.debug("Added sub context: " + subctx);
 264  
                 }
 265  0
                 catch (NameAlreadyBoundException nabe)
 266  
                 {
 267  
                     // ignore
 268  
                 }
 269  0
                 catch (NamingException ne)
 270  
                 {
 271  
                     // even though there is a specific exception
 272  
                     // for this condition, some implementations
 273  
                     // throw the more general one.
 274  
                     /*
 275  
                       if (ne.getMessage().indexOf("already bound") == -1 )
 276  
                       {
 277  
                       throw ne;
 278  
                       }
 279  
                     */
 280  
                     // ignore
 281  0
                 }
 282  0
                 ctx = (Context) ctx.lookup(subctx);
 283  
             }
 284  
             else
 285  
             {
 286  
                 // not really a subctx, it is the ds name
 287  0
                 ctx.bind(subctx, ds);
 288  
             }
 289  
         }
 290  0
     }
 291  
 }

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.