db-ojb-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From arm...@apache.org
Subject cvs commit: db-ojb/src/java/org/apache/ojb/broker/metadata MetadataManager.java
Date Sat, 24 May 2003 00:56:38 GMT
arminw      2003/05/23 17:56:38

  Modified:    src/test/org/apache/ojb/broker/metadata MetadataTest.java
               src/java/org/apache/ojb/broker/metadata MetadataManager.java
  Log:
  add some new methods, tests, doc
  
  Revision  Changes    Path
  1.8       +78 -12    db-ojb/src/test/org/apache/ojb/broker/metadata/MetadataTest.java
  
  Index: MetadataTest.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/test/org/apache/ojb/broker/metadata/MetadataTest.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- MetadataTest.java	22 May 2003 19:39:42 -0000	1.7
  +++ MetadataTest.java	24 May 2003 00:56:38 -0000	1.8
  @@ -5,6 +5,8 @@
   import org.apache.ojb.broker.PersistenceBroker;
   import org.apache.ojb.broker.PersistenceBrokerFactory;
   import org.apache.ojb.broker.TestHelper;
  +import org.apache.ojb.broker.Identity;
  +import org.apache.ojb.broker.PersistenceBrokerException;
   import org.apache.ojb.broker.query.Criteria;
   import org.apache.ojb.broker.query.Query;
   import org.apache.ojb.broker.query.QueryFactory;
  @@ -39,29 +41,93 @@
           junit.textui.TestRunner.main(arr);
       }
   
  -    /**
  -     * Insert the method's description here.
  -     * Creation date: (24.12.2000 00:33:40)
  -     */
       public MetadataTest(String name)
       {
           super(name);
       }
   
  -    /**
  -     * Insert the method's description here.
  -     * Creation date: (06.12.2000 21:58:53)
  -     */
       public void setUp()
       {
       }
   
  -    /**
  -     * Insert the method's description here.
  -     * Creation date: (06.12.2000 21:59:14)
  -     */
       public void tearDown()
       {
  +
  +    }
  +
  +    public void testLoadingProfiles() throws Exception
  +    {
  +        PersistenceBroker broker = null;
  +        MetadataManager mm = MetadataManager.getInstance();
  +        try
  +        {
  +            mm.setEnablePerThreadChanges(true);
  +            DescriptorRepository dr_1 = mm.readDescriptorRepository(TEST_CLASS_DESCRIPTOR);
  +            // add some profiles
  +            mm.addProfile("global", mm.getGlobalRepository());
  +            mm.addProfile("test", dr_1);
  +
  +            // now load a specific profile
  +            mm.loadProfile("test");
  +            broker = PersistenceBrokerFactory.defaultPersistenceBroker();
  +            CldTestObject obj = new CldTestObject();
  +            obj.setName("testLoadingProfiles");
  +            try
  +            {
  +                broker.store(obj);
  +                try
  +                {
  +                    // try to find persistent object, only available in global
  +                    // repository profile
  +                    Class clazz = broker.getClassDescriptor(testClass).getClassOfObject();
  +                    fail("We should not found this class-descriptor in profile");
  +                }
  +                catch (PersistenceBrokerException e)
  +                {
  +                }
  +            }
  +            finally
  +            {
  +                broker.close();
  +            }
  +
  +            //***************************************
  +            mm.removeProfile("test");
  +            try
  +            {
  +                mm.loadProfile("test");
  +                fail("Loading of profile should fail, but doesn't");
  +            }
  +            catch (Exception e)
  +            {
  +            }
  +            // now we load copy of global DescriptorRepository
  +            mm.loadProfile("global");
  +            broker = PersistenceBrokerFactory.defaultPersistenceBroker();
  +            Class clazz = broker.getClassDescriptor(testClass).getClassOfObject();
  +            broker.close();
  +            assertEquals(testClass, clazz);
  +            mm.removeAllProfiles();
  +            try
  +            {
  +                mm.loadProfile("global");
  +                fail("Loading of profile should fail, but doesn't");
  +            }
  +            catch (Exception e)
  +            {
  +            }
  +
  +            broker = PersistenceBrokerFactory.defaultPersistenceBroker();
  +            clazz = broker.getClassDescriptor(testClass).getClassOfObject();
  +            broker.close();
  +            assertEquals(testClass, clazz);
  +        }
  +        finally
  +        {
  +            mm.setEnablePerThreadChanges(false);
  +            if(broker != null) broker.close();
  +        }
  +
   
       }
   
  
  
  
  1.10      +224 -56   db-ojb/src/java/org/apache/ojb/broker/metadata/MetadataManager.java
  
  Index: MetadataManager.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/metadata/MetadataManager.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- MetadataManager.java	26 Apr 2003 23:18:24 -0000	1.9
  +++ MetadataManager.java	24 May 2003 00:56:38 -0000	1.10
  @@ -1,58 +1,100 @@
   package org.apache.ojb.broker.metadata;
   
  -import java.util.Iterator;
  -import java.util.List;
  -
   import org.apache.commons.lang.SerializationUtils;
   import org.apache.ojb.broker.core.PersistenceBrokerConfiguration;
   import org.apache.ojb.broker.util.configuration.impl.OjbConfigurator;
   import org.apache.ojb.broker.util.logging.Logger;
   import org.apache.ojb.broker.util.logging.LoggerFactory;
   
  +import java.io.InputStream;
  +import java.util.Hashtable;
  +import java.util.Iterator;
  +import java.util.List;
  +
   /**
  - * Central class for metadata operations - manages all OJB's
  - * {@link org.apache.ojb.broker.metadata.DescriptorRepository} and
  - * {@link org.apache.ojb.broker.metadata.ConnectionRepository} instances.
  - * <br>
  - * Allow a bunch of different repository handling possibilities -
  - * allows a transparent flexible metadata manipulation at runtime.
  - * <p>
  + * Central class for metadata operations/manipulations - manages OJB's
  + * metadata objects, in particular:
  + * <ul>
  + * <li>{@link org.apache.ojb.broker.metadata.DescriptorRepository} contains
  + * metadata of persistent objects</li>
  + * <li>{@link org.apache.ojb.broker.metadata.ConnectionRepository} contains
  + * all connection metadata information</li>
  + * </ul>
    *
  + * This class allows transparent flexible metadata loading/manipulation at runtime.
    *
  - * TODO: Is this a really useful feature?
  + * <p>
  + * <b>How to read/merge metadata</b><br/>
  + * Per default OJB loads default {@link org.apache.ojb.broker.metadata.DescriptorRepository}
  + * and {@link org.apache.ojb.broker.metadata.ConnectionRepository} instances, by reading
the
  + * specified repository file. This is done first time the <code>MetadataManager</code>
instance
  + * was used.
  + * <br/>
  + * To read metadata information at runtime use
  + * {@link #readDescriptorRepository readDescriptorRepository} and
  + * {@link #readConnectionRepository readConnectionRepository}
  + * methods.
  + * <br/>
  + * It is also possible to merge different repositories using
  + * {@link #mergeDescriptorRepository mergeDescriptorRepository}
  + * and {@link #mergeConnectionRepository mergeConnectionRepository}
    *
  + * </p>
    *
    * <a name="perThread"/>
  - * <b>Per thread handling of metadata</b>
  - * <br/>
  + * <h3>Per thread handling of metadata</h3>
  + * <p>
    * Per default the manager handle one global {@link org.apache.ojb.broker.metadata.DescriptorRepository}
  - * for all calling threads, but it is ditto possible to change metadata only per thread.
When the thread
  - * dies all made changes were rejected.
  - * <br/>
  - * To use this feature do something similar:
  + * for all calling threads, but it is ditto possible to use different metadata <i>profiles</i>
in a per thread
  + * manner - <i>profiles</i> means different copies of {@link org.apache.ojb.broker.metadata.DescriptorRepository}
  + * objects.
  + * <p/>
  + *
  + * <p>
  + * <a name="enablePerThreadMode"/>
  + * <b>Enable the per thread mode</b><br/>
  + * To enable the 'per thread' mode for {@link org.apache.ojb.broker.metadata.DescriptorRepository}
  + * instances:
    * <pre>
    *   MetadataManager mm = MetadataManager.getInstance();
    *   // tell the manager to use per thread mode
    *   mm.setEnablePerThreadChanges(true);
  - *
  + *   ...
  + * </pre>
  + * This could be done e.g. at start up.<br/>
  + * Now it's possible to use dedicated <code>DescriptorRepository</code> instances
  + * per thread:
  + *  <pre>
    *   // e.g we get a coppy of the global repository
    *   DescriptorRepository dr = mm.copyOfGlobalRepository();
  - *   // now we can manipulate the metadata of the copy
  + *   // now we can manipulate the persistent object metadata of the copy
    *   ......
    *
    *   // set the changed repository for this thread
  - *   mm.setPerThreadDescriptor(dr);
  + *   mm.setDescriptor(dr);
    *
  - *   // now this thread could lookup a PB with the modified metadata
  + *   // now this thread could lookup a PersistenceBroker instance
  + *   // with the modified metadata
    *   // all other threads use the global metadata
    *   PersistenceBroker broker = Persis......
    * </pre>
  - * First do {@link #setEnablePerThreadChanges enable the per thread mode}
  - * handling. This could be done e.g. at setup. Now each thread could use
  - * its own metadata, but you have
  - * <br/>a) explicit to set the new repository per thread
  - * <br/>b) do this BEFORE you lookup the {@link PersistenceBroker} for
  - * the thread, because the metadata was bound to the PB at lookup.
  + * Note: Change metadata <i>before</i> lookup the {@link org.apache.ojb.broker.PersistenceBroker}
  + * instance for current thread, because the metadata was bound to the PB at lookup.
  + * </p>
  + *
  + * <p>
  + * <b>How to use different metadata profiles</b><br/>
  + * MetadataManager was shipped with a simple mechanism to
  + * add, remove and load different persistent objects metadata
  + * profiles (different {@link org.apache.ojb.broker.metadata.DescriptorRepository}
  + * instances) in a per thread manner. Use
  + * <ul>
  + * <li>{@link #addProfile addProfile} add different persistent object metadata profiles</li>
  + * <li>{@link #removeProfile removeProfile} remove a persistent object metadata profiles</li>
  + * <li>{@link #loadProfile loadProfile} load a profile for the current thread</li>
  + * </ul>
  + * Note: This only works if the <a href="#enablePerThreadMode">per thread mode</a>
is
  + * enabled.
    * </p>
    *
    *
  @@ -66,6 +108,7 @@
       private static ThreadLocal threadedRepository = new ThreadLocal();
       private static MetadataManager singleton = new MetadataManager();
   
  +    private Hashtable metadataProfiles;
       private DescriptorRepository globalRepository;
       private ConnectionRepository connectionRepository;
       private boolean enablePerThreadChanges;
  @@ -78,8 +121,9 @@
   
       private void init()
       {
  +        metadataProfiles = new Hashtable();
           String repository = ((PersistenceBrokerConfiguration) OjbConfigurator.getInstance()
  -                    .getConfigurationFor(null)).getRepositoryFilename();
  +                .getConfigurationFor(null)).getRepositoryFilename();
           try
           {
               globalRepository = new RepositoryPersistor().readDescriptorRepository(repository);
  @@ -87,7 +131,7 @@
           catch (Exception e)
           {
               throw new MetadataException(
  -                    "Could not read repository class descriptor data, using repository:
"+repository,e);
  +                    "Could not read repository class descriptor data, using repository:
" + repository, e);
           }
           try
           {
  @@ -96,7 +140,7 @@
           catch (Exception e)
           {
               throw new MetadataException(
  -                    "Could not read jdbc-connection-descriptor data, using repository:
"+repository,e);
  +                    "Could not read jdbc-connection-descriptor data, using repository:
" + repository, e);
           }
       }
   
  @@ -114,8 +158,8 @@
        * {@link org.apache.ojb.broker.metadata.DescriptorRepository}.
        * <br>
        * When {@link #isEnablePerThreadChanges per thread descriptor handling}  is enabled
  -     * we first search for a {@link org.apache.ojb.broker.metadata.DescriptorRepository}
  -     * for the calling thread, if not found the global descriptor was returned.
  +     * we first search for a specific {@link org.apache.ojb.broker.metadata.DescriptorRepository}
  +     * for the calling thread, if none could be found the global descriptor was returned.
        *
        * @see MetadataManager#getGlobalRepository
        * @see MetadataManager#copyOfGlobalRepository
  @@ -126,11 +170,9 @@
           if (enablePerThreadChanges)
           {
               repository = (DescriptorRepository) threadedRepository.get();
  -            if(repository == null)
  +            if (repository == null)
               {
                   repository = getGlobalRepository();
  -//                repository = copyOfGlobalRepository();
  -//                threadedRepository.set(repository);
               }
               return repository;
           }
  @@ -161,23 +203,40 @@
       }
   
       /**
  -     * Merge the given {@link ConnectionRepository} with the
  -     * existing one.
  +     * Merge the given {@link ConnectionRepository} (make deep copy of containing objects)
  +     * with the existing one.
        */
       public void mergeConnectionRepository(ConnectionRepository repository)
       {
  -        List list = repository.getAllDescriptor();
  +        mergeConnectionRepository(connectionRepository(), repository, true);
  +    }
  +
  +    /**
  +     * Merge the given source {@link ConnectionRepository} with the
  +     * existing target. If parameter
  +     * <tt>deep</tt> is set <code>true</code> deep copies of source
objects were made.
  +     */
  +    public void mergeConnectionRepository(
  +            ConnectionRepository targetRepository, ConnectionRepository sourceRepository,
boolean deep)
  +    {
  +        List list = sourceRepository.getAllDescriptor();
           for (Iterator iterator = list.iterator(); iterator.hasNext();)
           {
               JdbcConnectionDescriptor jcd = (JdbcConnectionDescriptor) iterator.next();
  -            connectionRepository().addDescriptor(jcd);
  +            if (deep)
  +            {
  +                //TODO: adopt copy/clone methods for metadata classes?
  +                jcd = (JdbcConnectionDescriptor) SerializationUtils.clone(jcd);
  +            }
  +            targetRepository.addDescriptor(jcd);
           }
       }
   
       /**
        * Merge the given {@link org.apache.ojb.broker.metadata.DescriptorRepository}
  -     * with the existing one - keep in mind if running in
  -     * <a href="#perThread">per thread mode</a>
  +     * (make deep copy of containing objects) with the global one, returned
  +     * by method {@link #getRepository()} - keep
  +     * in mind if running in <a href="#perThread">per thread mode</a>
        * merge maybe only takes effect on current thread.
        *
        * @see #isEnablePerThreadChanges
  @@ -185,18 +244,33 @@
        */
       public void mergeDescriptorRepository(DescriptorRepository repository)
       {
  -        DescriptorRepository targetRepository = getRepository();
  -        Iterator it = repository.iterator();
  +        mergeDescriptorRepository(getRepository(), repository, true);
  +    }
  +
  +    /**
  +     * Merge the given {@link org.apache.ojb.broker.metadata.DescriptorRepository}
  +     * files, the source objects will be pushed to the target repository. If parameter
  +     * <tt>deep</tt> is set <code>true</code> deep copies of source
objects were made.
  +     */
  +    public void mergeDescriptorRepository(
  +            DescriptorRepository targetRepository, DescriptorRepository sourceRepository,
boolean deep)
  +    {
  +        Iterator it = sourceRepository.iterator();
           while (it.hasNext())
           {
               ClassDescriptor cld = (ClassDescriptor) it.next();
  -            cld.setRepository(targetRepository);
  +            if (deep)
  +            {
  +                //TODO: adopt copy/clone methods for metadata classes?
  +                cld = (ClassDescriptor) SerializationUtils.clone(cld);
  +            }
               targetRepository.put(cld.getClassOfObject(), cld);
  +            cld.setRepository(targetRepository);
           }
       }
   
       /**
  -     * Read all ClassDescriptors from the given repository file.
  +     * Read ClassDescriptors from the given repository file.
        * @see #mergeDescriptorRepository
        */
       public DescriptorRepository readDescriptorRepository(String fileName)
  @@ -208,14 +282,32 @@
           }
           catch (Exception e)
           {
  -            throw new MetadataException("Could not read repository "+fileName, e);
  +            throw new MetadataException("Could not read repository " + fileName, e);
           }
       }
   
  -   /**
  -    * Read all JdbcConnectionDescriptors from the given repository file.
  -    * @see #mergeConnectionRepository
  -    */
  +    /**
  +     * Read ClassDescriptors from the given InputStream.
  +     * @see #mergeDescriptorRepository
  +     */
  +    public DescriptorRepository readDescriptorRepository(InputStream inst)
  +    {
  +        try
  +        {
  +            RepositoryPersistor persistor = new RepositoryPersistor();
  +            return persistor.readDescriptorRepository(inst);
  +        }
  +        catch (Exception e)
  +        {
  +            throw new MetadataException("Could not read repository " + inst, e);
  +        }
  +    }
  +
  +    /**
  +     * Read JdbcConnectionDescriptors from the given repository file.
  +     *
  +     * @see #mergeConnectionRepository
  +     */
       public ConnectionRepository readConnectionRepository(String fileName)
       {
           try
  @@ -225,7 +317,25 @@
           }
           catch (Exception e)
           {
  -            throw new MetadataException("Could not read repository "+fileName, e);
  +            throw new MetadataException("Could not read repository " + fileName, e);
  +        }
  +    }
  +
  +    /**
  +     * Read JdbcConnectionDescriptors from this InputStream.
  +     *
  +     * @see #mergeConnectionRepository
  +     */
  +    public ConnectionRepository readConnectionRepository(InputStream inst)
  +    {
  +        try
  +        {
  +            RepositoryPersistor persistor = new RepositoryPersistor();
  +            return persistor.readConnectionRepository(inst);
  +        }
  +        catch (Exception e)
  +        {
  +            throw new MetadataException("Could not read repository from " + inst, e);
           }
       }
   
  @@ -239,21 +349,32 @@
        */
       public void setDescriptor(DescriptorRepository repository, boolean global)
       {
  -        if(global)
  +        if (global)
           {
  -            if(log.isDebugEnabled()) log.debug("Set new global repository: "+repository);
  +            if (log.isDebugEnabled()) log.debug("Set new global repository: " + repository);
               globalRepository = repository;
           }
           else
           {
  -            if(log.isDebugEnabled()) log.debug("Set new threaded repository: "+repository);
  +            if (log.isDebugEnabled()) log.debug("Set new threaded repository: " + repository);
               threadedRepository.set(repository);
           }
       }
   
       /**
  +     * Set {@link DescriptorRepository} for the current thread.
  +     * Convenience method for
  +     * {@link #setDescriptor(DescriptorRepository repository, boolean global) setDescriptor(repository,
false)}.
  +     */
  +    public void setDescriptor(DescriptorRepository repository)
  +    {
  +        setDescriptor(repository, false);
  +    }
  +
  +    /**
        * Convenience method for
        * {@link #setDescriptor setDescriptor(repository, false)}.
  +     * @deprecated use {@link #setDescriptor}
        */
       public void setPerThreadDescriptor(DescriptorRepository repository)
       {
  @@ -279,7 +400,7 @@
        * repository file if set, or the global if no threaded was found.
        * <br>
        * If returns <i>false</i> the {@link #getRepository} method return
  -     * always the {@link getGlobalRepository global} repository.
  +     * always the {@link #getGlobalRepository() global} repository.
        *
        * @see #setEnablePerThreadChanges
        */
  @@ -299,8 +420,55 @@
           this.enablePerThreadChanges = enablePerThreadChanges;
       }
   
  +    /**
  +     * Add a metadata profile.
  +     * @see #loadProfile
  +     */
  +    public void addProfile(Object key, DescriptorRepository repository)
  +    {
  +        if(metadataProfiles.contains(key))
  +        {
  +            throw new MetadataException("Duplicate profile key. Key '"+key+"' already exists.");
  +        }
  +        metadataProfiles.put(key, repository);
  +    }
  +
  +    /**
  +     * Load the given metadata profile for the current thread.
  +     *
  +     */
  +    public void loadProfile(Object key)
  +    {
  +        if (!isEnablePerThreadChanges())
  +        {
  +            throw new MetadataException("Could not load profile with disabled per thread
mode");
  +        }
  +        DescriptorRepository rep = (DescriptorRepository) metadataProfiles.get(key);
  +        if (rep == null)
  +        {
  +            throw new MetadataException("Could not find profile for key '" + key+"'");
  +        }
  +        setDescriptor(rep);
  +    }
   
  +    /**
  +     * Remove the given metadata profile.
  +     */
  +    public DescriptorRepository removeProfile(Object key)
  +    {
  +        return (DescriptorRepository) metadataProfiles.remove(key);
  +    }
   
  +    /**
  +     * Remove all profiles
  +     *
  +     * @see #removeProfile
  +     * @see #addProfile
  +     */
  +    public void removeAllProfiles()
  +    {
  +        metadataProfiles.clear();
  +    }
   
   //    /**
   //     * Returns a new {@link ClassDescriptor} instance.
  
  
  

Mime
View raw message