Coverage Report - org.apache.ojb.broker.metadata.ConnectionRepository
 
Classes in this File Line Coverage Branch Coverage Complexity
ConnectionRepository
N/A
N/A
2.7
 
 1  
 package org.apache.ojb.broker.metadata;
 2  
 
 3  
 /* Copyright 2002-2005 The Apache Software Foundation
 4  
  *
 5  
  * Licensed under the Apache License, Version 2.0 (the "License");
 6  
  * you may not use this file except in compliance with the License.
 7  
  * You may obtain a copy of the License at
 8  
  *
 9  
  *     http://www.apache.org/licenses/LICENSE-2.0
 10  
  *
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 
 18  
 import org.apache.commons.lang.SerializationUtils;
 19  
 import org.apache.commons.lang.SystemUtils;
 20  
 import org.apache.ojb.broker.PBKey;
 21  
 import org.apache.ojb.broker.util.logging.Logger;
 22  
 import org.apache.ojb.broker.util.logging.LoggerFactory;
 23  
 
 24  
 import java.io.Serializable;
 25  
 import java.util.ArrayList;
 26  
 import java.util.HashMap;
 27  
 import java.util.Hashtable;
 28  
 import java.util.Iterator;
 29  
 import java.util.List;
 30  
 
 31  
 import javax.sql.DataSource;
 32  
 
 33  
 public class ConnectionRepository implements Serializable, XmlCapable
 34  
 {
 35  
         private static final long serialVersionUID = -5581126412817848887L;
 36  
     private static Logger log = LoggerFactory.getLogger(ConnectionRepository.class);
 37  
 
 38  
     private HashMap jcdMap;
 39  
     private Hashtable jcdAliasToPBKeyMap;
 40  
     private JdbcMetadataUtils utils;
 41  
 
 42  
     public ConnectionRepository()
 43  
     {
 44  
         jcdMap             = new HashMap();
 45  
         jcdAliasToPBKeyMap = new Hashtable();
 46  
         utils              = new JdbcMetadataUtils();
 47  
     }
 48  
 
 49  
     /**
 50  
      * Returns the matching {@link JdbcConnectionDescriptor}
 51  
      * or <code>null</code> if no descriptor could be found. The user name
 52  
      * and pass word will be set to match the supplied </code>PBKey</code>
 53  
      * object. If the original user name and pass word are desired, the PBKey
 54  
      * should be obtained with {@link #getStandardPBKeyForJcdAlias(String)}.
 55  
      */ 
 56  
     public JdbcConnectionDescriptor getDescriptor(PBKey pbKey)
 57  
     {
 58  
         JdbcConnectionDescriptor result = (JdbcConnectionDescriptor) jcdMap.get(pbKey);
 59  
         if (result == null)
 60  
         {
 61  
             result = deepCopyOfFirstFound(pbKey.getAlias());
 62  
             if (result != null)
 63  
             {
 64  
                 result.setUserName(pbKey.getUser());
 65  
                 result.setPassWord(pbKey.getPassword());
 66  
                 // this build connection descriptor could not be the default connection
 67  
                 result.setDefaultConnection(false);
 68  
                 log.info("Automatic create of new jdbc-connection-descriptor for PBKey " + pbKey);
 69  
                 addDescriptor(result);
 70  
             }
 71  
             else
 72  
             {
 73  
                 log.info("Could not find " + JdbcConnectionDescriptor.class.getName() + " for PBKey " + pbKey);
 74  
             }
 75  
         }
 76  
         return result;
 77  
     }
 78  
 
 79  
     /**
 80  
      * Returns a deep copy of the first found connection descriptor
 81  
      * with the given <code>jcdAlias</code> name or <code>null</code>
 82  
      * if none found.
 83  
      */
 84  
     private JdbcConnectionDescriptor deepCopyOfFirstFound(String jcdAlias)
 85  
     {
 86  
         Iterator it = jcdMap.values().iterator();
 87  
         JdbcConnectionDescriptor jcd;
 88  
         while (it.hasNext())
 89  
         {
 90  
             jcd = (JdbcConnectionDescriptor) it.next();
 91  
             if (jcdAlias.equals(jcd.getJcdAlias()))
 92  
             {
 93  
                 return (JdbcConnectionDescriptor) SerializationUtils.clone(jcd);
 94  
             }
 95  
         }
 96  
         return null;
 97  
     }
 98  
 
 99  
     /**
 100  
      * Return the matching {@link org.apache.ojb.broker.PBKey} for
 101  
      * the given jcdAlias name, or <code>null</code> if no match
 102  
      * was found.
 103  
      */
 104  
     public PBKey getStandardPBKeyForJcdAlias(String jcdAlias)
 105  
     {
 106  
         return (PBKey) jcdAliasToPBKeyMap.get(jcdAlias);
 107  
     }
 108  
 
 109  
     /**
 110  
      * Add a new {@link JdbcConnectionDescriptor}.
 111  
      */
 112  
     public void addDescriptor(JdbcConnectionDescriptor jcd)
 113  
     {
 114  
         synchronized (jcdMap)
 115  
         {
 116  
             if (jcdMap.containsKey(jcd.getPBKey()))
 117  
             {
 118  
                 throw new MetadataException("Found duplicate connection descriptor using PBKey " +
 119  
                         jcd.getPBKey() + ", remove the old descriptor first, before add the new one. " + jcd);
 120  
             }
 121  
             jcdMap.put(jcd.getPBKey(), jcd);
 122  
             // only if the jcdAlias was not found, put the new PBKey,
 123  
             // because we don't want to replace the original PBKey with
 124  
             // automatic generated descriptors PBKey's - see method getDescriptor(PBKey key)
 125  
             if (!jcdAliasToPBKeyMap.containsKey(jcd.getJcdAlias()))
 126  
             {
 127  
                 jcdAliasToPBKeyMap.put(jcd.getJcdAlias(), jcd.getPBKey());
 128  
             }
 129  
             if (log.isDebugEnabled()) log.debug("New descriptor was added: " + jcd);
 130  
         }
 131  
     }
 132  
 
 133  
     /**
 134  
      * Creates and adds a new connection descriptor for the given JDBC connection url.
 135  
      * This method tries to guess the platform to be used, but it should be checked
 136  
      * afterwards nonetheless using the {@link JdbcConnectionDescriptor#getDbms()} method.
 137  
      * For properties that are not part of the url, the following standard values are
 138  
      * explicitly set:
 139  
      * <ul>
 140  
      * <li>jdbc level = 2.0</li>
 141  
      * </ul>
 142  
      * 
 143  
      * @param jcdAlias          The connection alias for the created connection; if 'default' is used,
 144  
      *                          then the new descriptor will become the default connection descriptor
 145  
      * @param jdbcDriver        The fully qualified jdbc driver name 
 146  
      * @param jdbcConnectionUrl The connection url of the form '[protocol]:[sub protocol]:{database-specific path]'
 147  
      *                          where protocol is usually 'jdbc'
 148  
      * @param username          The user name (can be <code>null</code>) 
 149  
      * @param password          The password (can be <code>null</code>) 
 150  
      * @return The created connection descriptor
 151  
      * @see JdbcConnectionDescriptor#getDbms()
 152  
      */
 153  
     public JdbcConnectionDescriptor addDescriptor(String jcdAlias, String jdbcDriver, String jdbcConnectionUrl, String username, String password)
 154  
     {
 155  
         JdbcConnectionDescriptor jcd   = new JdbcConnectionDescriptor();
 156  
         HashMap                  props = utils.parseConnectionUrl(jdbcConnectionUrl);
 157  
 
 158  
         jcd.setJcdAlias(jcdAlias);
 159  
         jcd.setProtocol((String)props.get(JdbcMetadataUtils.PROPERTY_PROTOCOL));
 160  
         jcd.setSubProtocol((String)props.get(JdbcMetadataUtils.PROPERTY_SUBPROTOCOL));
 161  
         jcd.setDbAlias((String)props.get(JdbcMetadataUtils.PROPERTY_DBALIAS));
 162  
 
 163  
         String platform = utils.findPlatformFor(jcd.getSubProtocol(), jdbcDriver);
 164  
 
 165  
         jcd.setDbms(platform);
 166  
         jcd.setJdbcLevel(2.0);
 167  
         jcd.setDriver(jdbcDriver);
 168  
         if (username != null)
 169  
         {
 170  
            jcd.setUserName(username);
 171  
            jcd.setPassWord(password);
 172  
         }
 173  
         if ("default".equals(jcdAlias))
 174  
         {
 175  
             jcd.setDefaultConnection(true);
 176  
             // arminw: MM will search for the default key
 177  
             // MetadataManager.getInstance().setDefaultPBKey(jcd.getPBKey());
 178  
         }
 179  
 
 180  
         addDescriptor(jcd);
 181  
         return jcd;
 182  
     }
 183  
     
 184  
     /**
 185  
      * Creates and adds a new connection descriptor for the given JDBC data source.
 186  
      * This method tries to guess the platform to be used, but it should be checked
 187  
      * afterwards nonetheless using the {@link JdbcConnectionDescriptor#getDbms()} method.
 188  
      * Note that the descriptor won't have a value for the driver because it is not possible
 189  
      * to retrieve the driver classname from the data source. 
 190  
      * 
 191  
      * @param jcdAlias   The connection alias for the created connection; if 'default' is used,
 192  
      *                   then the new descriptor will become the default connection descriptor
 193  
      * @param dataSource The data source
 194  
      * @param username   The user name (can be <code>null</code>) 
 195  
      * @param password   The password (can be <code>null</code>) 
 196  
      * @return The created connection descriptor
 197  
      * @see JdbcConnectionDescriptor#getDbms()
 198  
      */
 199  
     public JdbcConnectionDescriptor addDescriptor(String jcdAlias, DataSource dataSource, String username, String password)
 200  
     {
 201  
         JdbcConnectionDescriptor jcd = new JdbcConnectionDescriptor();
 202  
 
 203  
         jcd.setJcdAlias(jcdAlias);
 204  
         jcd.setDataSource(dataSource);
 205  
         if (username != null)
 206  
         {
 207  
            jcd.setUserName(username);
 208  
            jcd.setPassWord(password);
 209  
         }
 210  
         utils.fillJCDFromDataSource(jcd, dataSource, username, password);
 211  
         if ("default".equals(jcdAlias))
 212  
         {
 213  
             jcd.setDefaultConnection(true);
 214  
             // arminw: MM will search for the default key
 215  
             // MetadataManager.getInstance().setDefaultPBKey(jcd.getPBKey());
 216  
         }
 217  
         addDescriptor(jcd);
 218  
         return jcd;
 219  
     }
 220  
 
 221  
     /**
 222  
      * Remove a descriptor.
 223  
      * @param validKey  This could be the {@link JdbcConnectionDescriptor}
 224  
      * itself, or the associated {@link JdbcConnectionDescriptor#getPBKey PBKey}.
 225  
      */
 226  
     public void removeDescriptor(Object validKey)
 227  
     {
 228  
         PBKey pbKey;
 229  
         if (validKey instanceof PBKey)
 230  
         {
 231  
             pbKey = (PBKey) validKey;
 232  
         }
 233  
         else if (validKey instanceof JdbcConnectionDescriptor)
 234  
         {
 235  
             pbKey = ((JdbcConnectionDescriptor) validKey).getPBKey();
 236  
         }
 237  
         else
 238  
         {
 239  
             throw new MetadataException("Could not remove descriptor, given object was no vaild key: " +
 240  
                     validKey);
 241  
         }
 242  
         Object removed = null;
 243  
         synchronized (jcdMap)
 244  
         {
 245  
             removed = jcdMap.remove(pbKey);
 246  
             jcdAliasToPBKeyMap.remove(pbKey.getAlias());
 247  
         }
 248  
         log.info("Remove descriptor: " + removed);
 249  
     }
 250  
 
 251  
     /**
 252  
      * Return a deep copy of all managed {@link JdbcConnectionDescriptor}.
 253  
      */
 254  
     public List getAllDescriptor()
 255  
     {
 256  
         return (List) SerializationUtils.clone(new ArrayList(jcdMap.values()));
 257  
     }
 258  
 
 259  
     public String toXML()
 260  
     {
 261  
         String eol = SystemUtils.LINE_SEPARATOR;
 262  
         // use copy to avoid sync problems
 263  
         HashMap map = (HashMap) jcdMap.clone();
 264  
         StringBuffer buf = new StringBuffer();
 265  
         Iterator it = map.values().iterator();
 266  
         while (it.hasNext())
 267  
         {
 268  
             JdbcConnectionDescriptor jcd = (JdbcConnectionDescriptor) it.next();
 269  
             buf.append(jcd.toXML());
 270  
             buf.append(eol);
 271  
         }
 272  
         return buf.toString();
 273  
     }
 274  
 }