db-ojb-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bri...@apache.org
Subject cvs commit: db-ojb/src/test/org/apache/ojb/broker/dirty DirtyTest.java
Date Tue, 06 Jul 2004 12:45:44 GMT
brianm      2004/07/06 05:45:44

  Added:       src/java/org/apache/ojb/broker/dirty
                        DirtyPersistenceBrokerFactory.java Entry.java
                        LifeCycleListener.java StateListener.java
                        Tracker.java
               src/test/org/apache/ojb/broker/dirty DirtyTest.java
  Log:
  Initial checkin of persistence broker auto-dirty system. Not optimized yet, and not fully
tested, but it should work for majority of cases.
  
  Revision  Changes    Path
  1.1                  db-ojb/src/java/org/apache/ojb/broker/dirty/DirtyPersistenceBrokerFactory.java
  
  Index: DirtyPersistenceBrokerFactory.java
  ===================================================================
  /* Copyright 2004-2004 The Apache Software Foundation
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package org.apache.ojb.broker.dirty;
  
  import org.apache.ojb.broker.PBFactoryException;
  import org.apache.ojb.broker.PBKey;
  import org.apache.ojb.broker.PersistenceBroker;
  import org.apache.ojb.broker.PersistenceBrokerFactory;
  import org.apache.ojb.broker.core.PersistenceBrokerFactoryFactory;
  import org.apache.ojb.broker.metadata.MetadataManager;
  import org.apache.ojb.broker.util.configuration.Configurator;
  import org.apache.ojb.broker.util.configuration.impl.OjbConfigurator;
  
  /**
   * Provides PersistenceBroker instances configured to do
   * dirty checking on commit.
   * <p>
   * Behavior is iffy on rollback, but database will be clean
   */
  public class DirtyPersistenceBrokerFactory
  {
      private static final PersistenceBroker wrap(PersistenceBroker broker)
      {
          Tracker t = new Tracker();
  
          broker.addListener(new LifeCycleListener(t));
          broker.addListener(new StateListener(t));
  
          return broker;
      }
  
      public static PersistenceBroker defaultPersistenceBroker()
      {
          return wrap(PersistenceBrokerFactory.defaultPersistenceBroker());
      }
  
      /**
       * Returns the {@link org.apache.ojb.broker.util.configuration.Configurator}
       * object.
       *
       * @return the configurator
       */
      public static Configurator getConfigurator()
      {
          return OjbConfigurator.getInstance();
      }
  
      /**
       * @see org.apache.ojb.broker.core.PersistenceBrokerFactoryIF#setDefaultKey
       */
      public static void setDefaultKey(PBKey key)
      {
          MetadataManager.getInstance().setDefaultPBKey(key);
      }
  
      /**
       * @see org.apache.ojb.broker.core.PersistenceBrokerFactoryIF#getDefaultKey
       */
      public static PBKey getDefaultKey()
      {
          return MetadataManager.getInstance().getDefaultPBKey();
      }
  
      /**
       * @see org.apache.ojb.broker.core.PersistenceBrokerFactoryIF#createPersistenceBroker(java.lang.String,
java.lang.String, java.lang.String)
       */
      public static PersistenceBroker createPersistenceBroker(String jcdAlias,
                                                              String user, String password)
              throws PBFactoryException
      {
          return wrap(PersistenceBrokerFactoryFactory.instance().
                  createPersistenceBroker(jcdAlias, user, password));
      }
  
      /**
       * @see org.apache.ojb.broker.core.PersistenceBrokerFactoryIF#createPersistenceBroker(org.apache.ojb.broker.PBKey)
       */
      public static PersistenceBroker createPersistenceBroker(PBKey key)
              throws PBFactoryException
      {
          return wrap(PersistenceBrokerFactoryFactory.instance().createPersistenceBroker(key));
      }
  
      /**
       * @see org.apache.ojb.broker.core.PersistenceBrokerFactoryIF#releaseAllInstances
       */
      public static void releaseAllInstances()
      {
          PersistenceBrokerFactoryFactory.instance().releaseAllInstances();
      }
  }
  
  
  
  1.1                  db-ojb/src/java/org/apache/ojb/broker/dirty/Entry.java
  
  Index: Entry.java
  ===================================================================
  /* Copyright 2004-2004 The Apache Software Foundation
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package org.apache.ojb.broker.dirty;
  
  import org.apache.ojb.otm.states.State;
  import org.apache.ojb.broker.metadata.MetadataManager;
  import org.apache.ojb.broker.metadata.ClassDescriptor;
  import org.apache.ojb.broker.metadata.FieldDescriptor;
  import org.apache.ojb.broker.metadata.fieldaccess.PersistentField;
  
  public class Entry
  {
      private State state;
      private Object[] fields;
  
      public Entry(Object original, State state)
      {
  
          MetadataManager man = MetadataManager.getInstance();
          ClassDescriptor cd = man.getRepository().getDescriptorFor(original.getClass());
          FieldDescriptor[] fds = cd.getFieldDescriptions();
          fields = new Object[fds.length];
          for (int i = 0; i < fds.length; i++)
          {
              FieldDescriptor fd = fds[i];
              PersistentField pd = fd.getPersistentField();
              fields[i] = pd.get(original);
          }
          this.state = state;
      }
  
      public boolean changed(Object key)
      {
          MetadataManager man = MetadataManager.getInstance();
          ClassDescriptor cd = man.getRepository().getDescriptorFor(key.getClass());
          FieldDescriptor[] fds = cd.getFieldDescriptions();
          for (int i = 0; i < fds.length; i++)
          {
              FieldDescriptor fd = fds[i];
              PersistentField pd = fd.getPersistentField();
              if (fields[i] == null && pd.get(key) == null) continue;
              if (fields[i] == null && pd.get(key) != null) return true;
              if (!fields[i].equals(pd.get(key))
                  && ( this.state == State.PERSISTENT_CLEAN || this.state == State.PERSISTENT_NEW))
return true;
          }
          return false;
      }
  
      public void restore(Object key)
      {
          MetadataManager man = MetadataManager.getInstance();
          ClassDescriptor cd = man.getRepository().getDescriptorFor(key.getClass());
          FieldDescriptor[] fds = cd.getFieldDescriptions();
          for (int i = 0; i < fds.length; i++)
          {
              FieldDescriptor fd = fds[i];
              PersistentField pd = fd.getPersistentField();
              if (fields[i] == null && pd.get(key) == null) continue;
              if (fields[i] == null && pd.get(key) != null)
              {
                  pd.set(key, null);
              }
              if (!fields[i].equals(pd.get(key)))
              {
                  pd.set(key, fields[i]);
              }
          }
      }
  }
  
  
  
  1.1                  db-ojb/src/java/org/apache/ojb/broker/dirty/LifeCycleListener.java
  
  Index: LifeCycleListener.java
  ===================================================================
  /* Copyright 2004-2004 The Apache Software Foundation
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package org.apache.ojb.broker.dirty;
  
  import org.apache.ojb.broker.PBLifeCycleListener;
  import org.apache.ojb.broker.PBLifeCycleEvent;
  import org.apache.ojb.broker.PersistenceBrokerException;
  
  public class LifeCycleListener implements PBLifeCycleListener
  {
      private Tracker tracker;
  
      LifeCycleListener(Tracker t)
      {
          tracker = t;
      }
  
      public void beforeInsert(PBLifeCycleEvent event) throws PersistenceBrokerException
      {
      }
  
      public void afterInsert(PBLifeCycleEvent event) throws PersistenceBrokerException
      {
          tracker.inserted(event.getTarget());
      }
  
      public void beforeUpdate(PBLifeCycleEvent event) throws PersistenceBrokerException
      {
      }
  
  
      public void afterUpdate(PBLifeCycleEvent event) throws PersistenceBrokerException
      {
          tracker.flushed(event.getTarget());
      }
  
      public void beforeDelete(PBLifeCycleEvent event) throws PersistenceBrokerException
      {
      }
  
      public void afterDelete(PBLifeCycleEvent event) throws PersistenceBrokerException
      {
          tracker.deleted(event.getTarget());
      }
  
      public void afterLookup(PBLifeCycleEvent event) throws PersistenceBrokerException
      {
          tracker.fetched(event.getTarget());
      }
  }
  
  
  
  1.1                  db-ojb/src/java/org/apache/ojb/broker/dirty/StateListener.java
  
  Index: StateListener.java
  ===================================================================
  /* Copyright 2004-2004 The Apache Software Foundation
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package org.apache.ojb.broker.dirty;
  
  import org.apache.ojb.broker.PBStateListener;
  import org.apache.ojb.broker.PBStateEvent;
  
  public class StateListener implements PBStateListener
  {
      private Tracker tracker;
  
      StateListener(Tracker t)
      {
          tracker = t;
      }
  
      public void afterOpen(PBStateEvent event)
      {
      }
  
  
      public void beforeBegin(PBStateEvent event)
      {
      }
  
      /**
       * Called after a <tt>PersistenceBroker transaction</tt> was started.
       */
      public void afterBegin(PBStateEvent event)
      {
          tracker.begin();
      }
  
      /**
       * Called before a <tt>PersistenceBroker commit</tt> was called.
       */
      public void beforeCommit(PBStateEvent event)
      {
          tracker.commit(event.getTriggeringBroker());
      }
  
      /**
       * Called after a <tt>PersistenceBroker commit</tt> was called.
       */
      public void afterCommit(PBStateEvent event)
      {
      }
  
      /**
       * Called before a <tt>PersistenceBroker rollback</tt> was called.
       */
      public void beforeRollback(PBStateEvent event)
      {
      }
  
      /**
       * Called after a <tt>PersistenceBroker rollback</tt> was called.
       */
      public void afterRollback(PBStateEvent event)
      {
      }
  
      /**
       * Called before the {@link org.apache.ojb.broker.PersistenceBroker}
       * instance was returned to pool.
       */
      public void beforeClose(PBStateEvent event)
      {
      }
  }
  
  
  
  1.1                  db-ojb/src/java/org/apache/ojb/broker/dirty/Tracker.java
  
  Index: Tracker.java
  ===================================================================
  /* Copyright 2004-2004 The Apache Software Foundation
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package org.apache.ojb.broker.dirty;
  
  import org.apache.ojb.broker.PersistenceBroker;
  import org.apache.ojb.broker.core.proxy.ProxyHelper;
  import org.apache.ojb.otm.states.State;
  
  import java.util.Iterator;
  import java.util.Map;
  import java.util.IdentityHashMap;
  
  public class Tracker
  {
      private final IdentityHashMap map = new IdentityHashMap();
      private boolean flushing = false;
      private boolean transactional = true;
  
      /**
       * transaction started, begin tracking changes
       */
      public void begin()
      {
          map.clear();
          flushing = false;
          transactional = true;
      }
  
      public void rollback()
      {
          for (Iterator iterator = map.entrySet().iterator(); iterator.hasNext();)
          {
              Map.Entry map_entry = (Map.Entry) iterator.next();
              Object key = map_entry.getKey();
              Entry entry = (Entry) map_entry.getValue();
              entry.restore(key);
          }
          map.clear();
          transactional = false;
      }
  
      /**
       * About to commit, flush dirty objects!
       */
      public void commit(PersistenceBroker broker)
      {
          flushing = true;
          for (Iterator iterator = map.entrySet().iterator(); iterator.hasNext();)
          {
              Map.Entry map_entry = (Map.Entry) iterator.next();
              Object key = map_entry.getKey();
              Entry entry = (Entry) map_entry.getValue();
              if (entry.changed(key))
              {
                  broker.store(key);
              }
          }
          map.clear();
          flushing = false;
          transactional = false;
      }
  
      /**
       * Called on explicit update. Set target as the
       * current instance in entity map, and make it
       * persistentclean
       */
      public void flushed(Object target)
      {
          if (flushing || !transactional) return;
          map.put(target, new Entry(target, State.PERSISTENT_CLEAN));
      }
  
      /**
       * inserted during trasnacton, add as persistent clean
       */
      public void inserted(Object source)
      {
          if (!transactional) return;
          map.put(source, new Entry(source, State.PERSISTENT_NEW));
      }
  
      /**
       * Deleted in transaction, add as persistent-deleted
       */
      public void deleted(Object source)
      {
          if (!transactional) return;
          map.put(source, new Entry(source, State.PERSISTENT_DELETED));
      }
  
      /**
       * fetched during transaction, add as persistent clean
       */
      public void fetched(Object source)
      {
          if (!transactional) return;
          if (ProxyHelper.isProxy(source)) return;
          map.put(source, new Entry(source, State.PERSISTENT_CLEAN));
      }
  }
  
  
  
  1.1                  db-ojb/src/test/org/apache/ojb/broker/dirty/DirtyTest.java
  
  Index: DirtyTest.java
  ===================================================================
  package org.apache.ojb.broker.dirty;
  
  import junit.framework.TestCase;
  import org.apache.ojb.broker.Article;
  import org.apache.ojb.broker.Identity;
  import org.apache.ojb.broker.InterfaceArticle;
  import org.apache.ojb.broker.PersistenceBroker;
  import org.apache.ojb.broker.Person;
  import org.apache.ojb.broker.ProductGroupWithCollectionProxy;
  import org.apache.ojb.broker.core.proxy.CollectionProxy;
  import org.apache.ojb.broker.core.proxy.ProxyHelper;
  
  import java.util.List;
  
  public class DirtyTest extends TestCase
  {
      public void testSimpleInsert() throws Exception
      {
          Person p = new Person();
          p.setFirstname("brian");
          PersistenceBroker pb = DirtyPersistenceBrokerFactory.defaultPersistenceBroker();
          pb.beginTransaction();
          pb.store(p);
          pb.commitTransaction();
  
          pb.clearCache();
  
          Identity id = new Identity(p, pb);
          Person same = (Person) pb.getObjectByIdentity(id);
          assertEquals("brian", same.getFirstname());
  
          pb.close();
      }
  
      public void testSimpleUpdate() throws Exception
      {
          Person p = new Person();
          p.setFirstname("brian");
          PersistenceBroker pb = DirtyPersistenceBrokerFactory.defaultPersistenceBroker();
          pb.beginTransaction();
          pb.store(p);
          pb.commitTransaction();
  
          pb.clearCache();
  
          pb.beginTransaction();
          Identity id = new Identity(p, pb);
          Person same = (Person) pb.getObjectByIdentity(id);
          same.setFirstname("george");
          pb.commitTransaction();
  
          pb.clearCache();
  
          same = (Person) pb.getObjectByIdentity(id);
          assertEquals("george", same.getFirstname());
  
          pb.close();
      }
  
      public void testProxyWorks() throws Exception
      {
          ProductGroupWithCollectionProxy pg = new ProductGroupWithCollectionProxy();
          pg.setGroupName("groupName");
          InterfaceArticle a = Article.createInstance();
          a.setProductGroup(pg);
          a.setArticleName("name");
          pg.add(a);
  
          PersistenceBroker pb = DirtyPersistenceBrokerFactory.defaultPersistenceBroker();
          pb.beginTransaction();
          pb.store(pg);
          pb.store(a);
          pb.commitTransaction();
  
          pb.clearCache();
  
          pb.beginTransaction();
          pg = (ProductGroupWithCollectionProxy) pb.getObjectByIdentity(new Identity(pg, pb));
          List articles = pg.getAllArticlesInGroup();
          assertTrue(ProxyHelper.isCollectionProxy(articles));
          CollectionProxy proxy = (CollectionProxy)articles;
          assertFalse(proxy.isLoaded());
          a = (InterfaceArticle) articles.get(0);
          a.setArticleName("new name");
          pb.commitTransaction();
  
          pb.clearCache();
  
          a = (Article) pb.getObjectByIdentity(new Identity(a, pb));
          assertEquals("new name", a.getArticleName());
  
          pb.close();
      }
  }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org


Mime
View raw message