Coverage Report - org.apache.ojb.odmg.DatabaseImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
DatabaseImpl
N/A
N/A
4.909
 
 1  
 package org.apache.ojb.odmg;
 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.ojb.broker.PBFactoryException;
 19  
 import org.apache.ojb.broker.PBKey;
 20  
 import org.apache.ojb.broker.PersistenceBroker;
 21  
 import org.apache.ojb.broker.PersistenceBrokerFactory;
 22  
 import org.apache.ojb.broker.util.BrokerHelper;
 23  
 import org.apache.ojb.broker.util.logging.Logger;
 24  
 import org.apache.ojb.broker.util.logging.LoggerFactory;
 25  
 import org.odmg.DatabaseClosedException;
 26  
 import org.odmg.DatabaseNotFoundException;
 27  
 import org.odmg.DatabaseOpenException;
 28  
 import org.odmg.ODMGException;
 29  
 import org.odmg.ObjectNameNotFoundException;
 30  
 import org.odmg.ObjectNameNotUniqueException;
 31  
 import org.odmg.TransactionInProgressException;
 32  
 import org.odmg.TransactionNotInProgressException;
 33  
 
 34  
 /**
 35  
  * Implementation class of the {@link org.odmg.Database} interface.
 36  
  * 
 37  
  * @author <a href="mailto:thma@apache.org">Thomas Mahler<a>
 38  
  * @author <a href="mailto:mattbaird@yahoo.com">Matthew Baird</a>
 39  
  * @author <a href="mailto:armin@codeAuLait.de">Armin Waibel</a>
 40  
  * @version $Id: DatabaseImpl.java,v 1.1 2007-08-24 22:17:37 ewestfal Exp $
 41  
  */
 42  
 public class DatabaseImpl implements org.odmg.Database
 43  
 {
 44  
     private Logger log = LoggerFactory.getLogger(DatabaseImpl.class);
 45  
 
 46  
     private PBKey pbKey;
 47  
     private boolean isOpen;
 48  
     private ImplementationImpl odmg;
 49  
 
 50  
     public DatabaseImpl(ImplementationImpl ojb)
 51  
     {
 52  
         isOpen = false;
 53  
         this.odmg = ojb;
 54  
     }
 55  
 
 56  
     private TransactionImpl getTransaction()
 57  
     {
 58  
         Object result = odmg.currentTransaction();
 59  
         // TODO: remove this workaround
 60  
         // In managed environments only wrapped tx are returned, so
 61  
         // we have to extract the real tx first
 62  
         if(result instanceof NarrowTransaction)
 63  
         {
 64  
             return ((NarrowTransaction) result).getRealTransaction();
 65  
         }
 66  
         return (TransactionImpl) result;
 67  
     }
 68  
 
 69  
     /**
 70  
      * Return the {@link org.apache.ojb.broker.PBKey} associated with this Database.
 71  
      */
 72  
     public PBKey getPBKey()
 73  
     {
 74  
         if (pbKey == null)
 75  
         {
 76  
             log.error("## PBKey not set, Database isOpen=" + isOpen + " ##");
 77  
             if (!isOpen) throw new DatabaseClosedException("Database is not open");
 78  
         }
 79  
         return pbKey;
 80  
     }
 81  
 
 82  
     public boolean isOpen()
 83  
     {
 84  
         return this.isOpen;
 85  
     }
 86  
 
 87  
     /**
 88  
      * Open the named database with the specified access mode.
 89  
      * Attempts to open a database when it has already been opened will result in
 90  
      * the throwing of the exception <code>DatabaseOpenException</code>.
 91  
      * A <code>DatabaseNotFoundException</code> is thrown if the database does not exist.
 92  
      * Some implementations may throw additional exceptions that are also derived from
 93  
      * <code>ODMGException</code>.
 94  
      * @param name The name of the database.
 95  
      * @param accessMode The access mode, which should be one of the static fields:
 96  
      * <code>OPEN_READ_ONLY</code>, <code>OPEN_READ_WRITE</code>,
 97  
      * or <code>OPEN_EXCLUSIVE</code>.
 98  
      * @exception ODMGException The database could not be opened.
 99  
      */
 100  
     public synchronized void open(String name, int accessMode) throws ODMGException
 101  
     {
 102  
         if (isOpen())
 103  
         {
 104  
             throw new DatabaseOpenException("Database is already open");
 105  
         }
 106  
         PersistenceBroker broker = null;
 107  
         try
 108  
         {
 109  
             if (name == null)
 110  
             {
 111  
                 log.info("Given argument was 'null', open default database");
 112  
                 broker = PersistenceBrokerFactory.defaultPersistenceBroker();
 113  
             }
 114  
             else
 115  
             {
 116  
                 broker = PersistenceBrokerFactory.createPersistenceBroker(
 117  
                         BrokerHelper.extractAllTokens(name));
 118  
             }
 119  
             pbKey = broker.getPBKey();
 120  
             isOpen = true;
 121  
             //register opened database
 122  
             odmg.registerOpenDatabase(this);
 123  
             if (log.isDebugEnabled()) log.debug("Open database using PBKey " + pbKey);
 124  
         }
 125  
         catch (PBFactoryException ex)
 126  
         {
 127  
             log.error("Open database failed: " + ex.getMessage(), ex);
 128  
             throw new DatabaseNotFoundException(
 129  
                     "OJB can't open database " + name + "\n" + ex.getMessage());
 130  
         }
 131  
         finally
 132  
         {
 133  
             // broker must be immediately closed
 134  
             if (broker != null)
 135  
             {
 136  
                 broker.close();
 137  
             }
 138  
         }
 139  
     }
 140  
 
 141  
     /**
 142  
      * Close the database.
 143  
      * After you have closed a database, further attempts to access objects in the
 144  
      * database will cause the exception <code>DatabaseClosedException</code> to be thrown.
 145  
      * Some implementations may throw additional exceptions that are also derived
 146  
      * from <code>ODMGException</code>.
 147  
      * @exception ODMGException Unable to close the database.
 148  
      */
 149  
     public void close() throws ODMGException
 150  
     {
 151  
         /**
 152  
          * is the DB open? ODMG 3.0 says we can't close an already open database.
 153  
          */
 154  
         if (!isOpen())
 155  
         {
 156  
             throw new DatabaseClosedException("Database is not Open. Must have an open DB to call close.");
 157  
         }
 158  
         /**
 159  
          * is the associated Tx open? ODMG 3.0 says we can't close the database with an open Tx pending.
 160  
          * check if a tx was found, the tx was associated with database
 161  
          */
 162  
         if (odmg.hasOpenTransaction() &&
 163  
                 getTransaction().getAssociatedDatabase().equals(this))
 164  
         {
 165  
             String msg = "Database cannot be closed, associated Tx is still open." +
 166  
                     " Transaction status is '" + TxUtil.getStatusString(getTransaction().getStatus()) + "'." +
 167  
                     " Used PBKey was "+getTransaction().getBroker().getPBKey();
 168  
             log.error(msg);
 169  
             throw new TransactionInProgressException(msg);
 170  
         }
 171  
         isOpen = false;
 172  
         // remove the current PBKey
 173  
         pbKey = null;
 174  
         // if we close current database, we have to notify implementation instance
 175  
         if (this == odmg.getCurrentDatabase())
 176  
         {
 177  
             odmg.setCurrentDatabase(null);
 178  
         }
 179  
     }
 180  
 
 181  
     /**
 182  
      * Associate a name with an object and make it persistent.
 183  
      * An object instance may be bound to more than one name.
 184  
      * Binding a previously transient object to a name makes that object persistent.
 185  
      * @param object The object to be named.
 186  
      * @param name The name to be given to the object.
 187  
      * @exception org.odmg.ObjectNameNotUniqueException
 188  
      * If an attempt is made to bind a name to an object and that name is already bound
 189  
      * to an object.
 190  
      */
 191  
     public void bind(Object object, String name)
 192  
             throws ObjectNameNotUniqueException
 193  
     {
 194  
         /**
 195  
          * Is DB open? ODMG 3.0 says it has to be to call bind.
 196  
          */
 197  
         if (!this.isOpen())
 198  
         {
 199  
             throw new DatabaseClosedException("Database is not open. Must have an open DB to call bind.");
 200  
         }
 201  
         /**
 202  
          * Is Tx open? ODMG 3.0 says it has to be to call bind.
 203  
          */
 204  
         TransactionImpl tx = getTransaction();
 205  
         if (tx == null || !tx.isOpen())
 206  
         {
 207  
             throw new TransactionNotInProgressException("Tx is not open. Must have an open TX to call bind.");
 208  
         }
 209  
 
 210  
         tx.getNamedRootsMap().bind(object, name);
 211  
     }
 212  
 
 213  
     /**
 214  
      * Lookup an object via its name.
 215  
      * @param name The name of an object.
 216  
      * @return The object with that name.
 217  
      * @exception ObjectNameNotFoundException There is no object with the specified name.
 218  
      * ObjectNameNotFoundException
 219  
      */
 220  
     public Object lookup(String name) throws ObjectNameNotFoundException
 221  
     {
 222  
         /**
 223  
          * Is DB open? ODMG 3.0 says it has to be to call bind.
 224  
          */
 225  
         if (!this.isOpen())
 226  
         {
 227  
             throw new DatabaseClosedException("Database is not open. Must have an open DB to call lookup");
 228  
         }
 229  
         /**
 230  
          * Is Tx open? ODMG 3.0 says it has to be to call bind.
 231  
          */
 232  
         TransactionImpl tx = getTransaction();
 233  
         if (tx == null || !tx.isOpen())
 234  
         {
 235  
             throw new TransactionNotInProgressException("Tx is not open. Must have an open TX to call lookup.");
 236  
         }
 237  
 
 238  
         return tx.getNamedRootsMap().lookup(name);
 239  
     }
 240  
 
 241  
     /**
 242  
      * Disassociate a name with an object
 243  
      * @param name The name of an object.
 244  
      * @exception ObjectNameNotFoundException No object exists in the database with that name.
 245  
      */
 246  
     public void unbind(String name) throws ObjectNameNotFoundException
 247  
     {
 248  
         /**
 249  
          * Is DB open? ODMG 3.0 says it has to be to call unbind.
 250  
          */
 251  
         if (!this.isOpen())
 252  
         {
 253  
             throw new DatabaseClosedException("Database is not open. Must have an open DB to call unbind");
 254  
         }
 255  
         TransactionImpl tx = getTransaction();
 256  
         if (tx == null || !tx.isOpen())
 257  
         {
 258  
             throw new TransactionNotInProgressException("Tx is not open. Must have an open TX to call lookup.");
 259  
         }
 260  
 
 261  
         tx.getNamedRootsMap().unbind(name);
 262  
     }
 263  
 
 264  
     /**
 265  
      * Make a transient object durable in the database.
 266  
      * It must be executed in the context of an open transaction.
 267  
      * If the transaction in which this method is executed commits,
 268  
      * then the object is made durable.
 269  
      * If the transaction aborts,
 270  
      * then the makePersistent operation is considered not to have been executed,
 271  
      * and the target object is again transient.
 272  
      * ClassNotPersistenceCapableException is thrown if the implementation cannot make
 273  
      * the object persistent because of the type of the object.
 274  
      * @param        object        The object to make persistent.
 275  
      * @throws TransactionNotInProgressException if there is no current transaction.
 276  
      */
 277  
     public void makePersistent(Object object)
 278  
     {
 279  
         /**
 280  
          * Is DB open? ODMG 3.0 says it has to be to call makePersistent.
 281  
          */
 282  
         if (!this.isOpen())
 283  
         {
 284  
             throw new DatabaseClosedException("Database is not open");
 285  
         }
 286  
         /**
 287  
          * Is Tx open? ODMG 3.0 says it has to be to call makePersistent.
 288  
          */
 289  
         TransactionImpl tx = getTransaction();
 290  
         if (tx == null || !tx.isOpen())
 291  
         {
 292  
             throw new TransactionNotInProgressException("No transaction in progress, cannot persist");
 293  
         }
 294  
         RuntimeObject rt = new RuntimeObject(object, getTransaction());
 295  
         tx.makePersistent(rt);
 296  
 //        tx.moveToLastInOrderList(rt.getIdentity());
 297  
     }
 298  
 
 299  
     /**
 300  
      * Deletes an object from the database.
 301  
      * It must be executed in the context of an open transaction.
 302  
      * If the object is not persistent, then ObjectNotPersistent is thrown.
 303  
      * If the transaction in which this method is executed commits,
 304  
      * then the object is removed from the database.
 305  
      * If the transaction aborts,
 306  
      * then the deletePersistent operation is considered not to have been executed,
 307  
      * and the target object is again in the database.
 308  
      * @param        object        The object to delete.
 309  
      */
 310  
     public void deletePersistent(Object object)
 311  
     {
 312  
         if (!this.isOpen())
 313  
         {
 314  
             throw new DatabaseClosedException("Database is not open");
 315  
         }
 316  
         TransactionImpl tx = getTransaction();
 317  
         if (tx == null || !tx.isOpen())
 318  
         {
 319  
             throw new TransactionNotInProgressException("No transaction in progress, cannot delete persistent");
 320  
         }
 321  
         RuntimeObject rt = new RuntimeObject(object, tx);
 322  
         tx.deletePersistent(rt);
 323  
 //        tx.moveToLastInOrderList(rt.getIdentity());
 324  
     }
 325  
 }