You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by ju...@apache.org on 2008/07/30 15:52:55 UTC

svn commit: r681031 - in /jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/jndi: BindableRepository.java BindableRepositoryFactory.java RegistryHelper.java

Author: jukka
Date: Wed Jul 30 06:52:52 2008
New Revision: 681031

URL: http://svn.apache.org/viewvc?rev=681031&view=rev
Log:
JCR-1664: JNDI Referencable Issues

Avoid issues with the ordering of the JNDI configuration options by
including the entire Reference instance within BindableRepository.

Also, streamlined the JNDI classes a bit by using the AbstractRepository base class and the JackrabbitRepository interface, and by inlining many of the static methods that weren't being used outside the jndi package.

Modified:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/jndi/BindableRepository.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/jndi/BindableRepositoryFactory.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/jndi/RegistryHelper.java

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/jndi/BindableRepository.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/jndi/BindableRepository.java?rev=681031&r1=681030&r2=681031&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/jndi/BindableRepository.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/jndi/BindableRepository.java Wed Jul 30 06:52:52 2008
@@ -16,24 +16,22 @@
  */
 package org.apache.jackrabbit.core.jndi;
 
+import org.apache.jackrabbit.api.JackrabbitRepository;
+import org.apache.jackrabbit.commons.AbstractRepository;
 import org.apache.jackrabbit.core.RepositoryImpl;
-import org.apache.jackrabbit.core.config.ConfigurationException;
 import org.apache.jackrabbit.core.config.RepositoryConfig;
 
 import java.io.IOException;
 import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
 import java.io.Serializable;
 
 import javax.jcr.Credentials;
 import javax.jcr.LoginException;
 import javax.jcr.NoSuchWorkspaceException;
-import javax.jcr.Repository;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 import javax.naming.Reference;
 import javax.naming.Referenceable;
-import javax.naming.StringRefAddr;
 
 /**
  * A referenceable and serializable content repository proxy.
@@ -60,36 +58,35 @@
  * method should be used to explicitly close the repository if
  * needed.
  */
-public class BindableRepository implements Repository, Referenceable, Serializable {
+public class BindableRepository extends AbstractRepository
+        implements JackrabbitRepository, Referenceable, Serializable {
 
     /**
      * The serialization UID of this class.
      */
-    static final long serialVersionUID = -2298220550793843166L;
+    private static final long serialVersionUID = 8864716577016297651L;
 
     /**
-     * The repository configuration file path.
+     * type of <code>configFilePath</code> reference address
+     * @see Reference#get(String)
      */
-    private final String configFilePath;
+    public static final String CONFIGFILEPATH_ADDRTYPE = "configFilePath";
 
     /**
-     * The repository home directory path.
+     * type of <code>repHomeDir</code> reference address
+     * @see Reference#get(String)
      */
-    private final String repHomeDir;
+    public static final String REPHOMEDIR_ADDRTYPE = "repHomeDir";
 
     /**
-     * type of <code>configFilePath</code> reference address (@see <code>{@link Reference#get(String)}</code>
-     */
-    public static final String CONFIGFILEPATH_ADDRTYPE = "configFilePath";
-    /**
-     * type of <code>repHomeDir</code> reference address (@see <code>{@link Reference#get(String)}</code>
+     * The repository reference
      */
-    public static final String REPHOMEDIR_ADDRTYPE = "repHomeDir";
+    private final Reference reference;
 
     /**
      * The delegate repository instance. Created by {@link #init() init}.
      */
-    protected transient Repository delegatee;
+    private transient JackrabbitRepository delegatee;
 
     /**
      * Thread that is registered as shutdown hook after {@link #init} has been
@@ -104,26 +101,9 @@
      * @param configFilePath repository configuration file path
      * @param repHomeDir     repository home directory path
      */
-    protected BindableRepository(String configFilePath, String repHomeDir) {
-        this.configFilePath = configFilePath;
-        this.repHomeDir = repHomeDir;
-        delegatee = null;
-    }
-
-    /**
-     * Creates an initialized BindableRepository instance using the given
-     * configuration information.
-     *
-     * @param configFilePath repository configuration file path
-     * @param repHomeDir     repository home directory path
-     * @return initialized repository instance
-     * @throws RepositoryException if the repository cannot be created
-     */
-    static BindableRepository create(String configFilePath, String repHomeDir)
-            throws RepositoryException {
-        BindableRepository rep = new BindableRepository(configFilePath, repHomeDir);
-        rep.init();
-        return rep;
+    public BindableRepository(Reference reference) throws RepositoryException {
+        this.reference = reference;
+        init();
     }
 
     /**
@@ -134,43 +114,29 @@
      * @throws RepositoryException if the repository cannot be created
      */
     protected void init() throws RepositoryException {
-        RepositoryConfig config = createRepositoryConfig(configFilePath, repHomeDir);
-        delegatee = createRepository(config);
+        delegatee = getRepository(reference);
         hook = new Thread() {
             public void run() {
                 shutdown();
             }
         };
-
         Runtime.getRuntime().addShutdownHook(hook);
     }
 
     /**
-     * Creates a repository configuration from a path to the repository.xml file
-     * and the repository home directory.
-     *
-     * @param configFilePath path to the repository.xml file.
-     * @param repHomeDir     the repository home directory.
-     * @return the repository configuration.
-     * @throws ConfigurationException on configuration error.
-     */
-    protected RepositoryConfig createRepositoryConfig(String configFilePath,
-                                                      String repHomeDir)
-            throws ConfigurationException {
-        return RepositoryConfig.create(configFilePath, repHomeDir);
-    }
-
-    /**
-     * Creates a plain repository instance from a repository
-     * <code>config</code>.
-     *
-     * @param config the repository configuration.
-     * @return the repository instance.
-     * @throws RepositoryException if an error occurs while creating the
-     *                             repository instance.
+     * Creates a repository instance based on the given reference. Can be
+     * overridden by subclasses to return different repositories. The default
+     * implementation returns a {@link RepositoryImpl} instance.
+     *
+     * @param reference repository reference
+     * @return repository instance
+     * @throws RepositoryException if the repository could not be created
      */
-    protected Repository createRepository(RepositoryConfig config)
+    protected JackrabbitRepository getRepository(Reference reference)
             throws RepositoryException {
+        RepositoryConfig config = RepositoryConfig.create(
+                reference.get(CONFIGFILEPATH_ADDRTYPE).getContent().toString(),
+                reference.get(REPHOMEDIR_ADDRTYPE).getContent().toString());
         return RepositoryImpl.create(config);
     }
 
@@ -189,32 +155,6 @@
      * Delegated to the underlying repository instance.
      * {@inheritDoc}
      */
-    public Session login(String workspaceName)
-            throws LoginException, NoSuchWorkspaceException, RepositoryException {
-        return delegatee.login(workspaceName);
-    }
-
-    /**
-     * Delegated to the underlying repository instance.
-     * {@inheritDoc}
-     */
-    public Session login() throws LoginException, RepositoryException {
-        return delegatee.login();
-    }
-
-    /**
-     * Delegated to the underlying repository instance.
-     * {@inheritDoc}
-     */
-    public Session login(Credentials credentials)
-            throws LoginException, RepositoryException {
-        return delegatee.login(credentials);
-    }
-
-    /**
-     * Delegated to the underlying repository instance.
-     * {@inheritDoc}
-     */
     public String getDescriptor(String key) {
         return delegatee.getDescriptor(key);
     }
@@ -230,38 +170,19 @@
     //--------------------------------------------------------< Referenceable >
 
     /**
-     * Creates a JNDI reference for this content repository. The returned
+     * Returns the JNDI reference for this content repository. The returned
      * reference holds the configuration information required to create a
      * copy of this instance.
      *
-     * @return the created JNDI reference
+     * @return the JNDI reference
      */
     public Reference getReference() {
-        Reference ref = new Reference(BindableRepository.class.getName(),
-                BindableRepositoryFactory.class.getName(),
-                null); // no classpath defined
-        ref.add(new StringRefAddr(CONFIGFILEPATH_ADDRTYPE, configFilePath));
-        ref.add(new StringRefAddr(REPHOMEDIR_ADDRTYPE, repHomeDir));
-        return ref;
+        return reference;
     }
 
     //-------------------------------------------------< Serializable support >
 
     /**
-     * Serializes the repository configuration. The default serialization
-     * mechanism is used, as the underlying delegate repository is referenced
-     * using a transient variable.
-     *
-     * @param out the serialization stream
-     * @throws IOException on IO errors
-     * @see Serializable
-     */
-    private void writeObject(ObjectOutputStream out) throws IOException {
-        // delegate to default implementation
-        out.defaultWriteObject();
-    }
-
-    /**
      * Deserializes a repository instance. The repository configuration
      * is deserialized using the standard deserialization mechanism, and
      * the underlying delegate repository is created using the
@@ -279,21 +200,24 @@
         // initialize reconstructed instance
         try {
             init();
-        } catch (RepositoryException re) {
+        } catch (RepositoryException e) {
             // failed to reinstantiate repository
-            throw new IOException(re.getMessage());
+            IOException exception = new IOException(e.getMessage());
+            exception.initCause(e);
+            throw exception;
         }
     }
 
     /**
      * Delegated to the underlying repository instance.
      */
-    void shutdown() {
-        ((RepositoryImpl) delegatee).shutdown();
+    public void shutdown() {
+        delegatee.shutdown();
         try {
             Runtime.getRuntime().removeShutdownHook(hook);
         } catch (IllegalStateException e) {
             // ignore. exception is thrown when hook itself calls shutdown
         }
     }
+
 }

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/jndi/BindableRepositoryFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/jndi/BindableRepositoryFactory.java?rev=681031&r1=681030&r2=681031&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/jndi/BindableRepositoryFactory.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/jndi/BindableRepositoryFactory.java Wed Jul 30 06:52:52 2008
@@ -37,51 +37,22 @@
      * cache using <code>java.naming.Reference</code> objects as keys and
      * storing soft references to <code>BindableRepository</code> instances
      */
-    private static Map cache = new ReferenceMap(ReferenceMap.HARD, ReferenceMap.SOFT);
+    private static Map cache = new ReferenceMap();
 
     /**
-     * empty default constructor
-     */
-    public BindableRepositoryFactory() {
-    }
-
-    /**
-     * Creates an initialized BindableRepository instance using the given
-     * configuration information and puts it in {@link #cache}.
-     *
-     * @param configFilePath repository configuration file path
-     * @param repHomeDir     repository home directory path
-     * @return initialized repository instance
-     * @throws RepositoryException if the repository cannot be created
-     */
-    static BindableRepository createInstance(String configFilePath, String repHomeDir)
-            throws RepositoryException {
-        BindableRepository rep = BindableRepository.create(configFilePath, repHomeDir);
-        cache.put(rep.getReference(), rep);
-        return rep;
-    }
-
-    //--------------------------------------------------------< ObjectFactory >
-    /**
      * {@inheritDoc}
      */
-    public Object getObjectInstance(Object obj, Name name, Context nameCtx,
-                                    Hashtable environment)
-            throws Exception {
-        if (obj instanceof Reference) {
-            Reference ref = (Reference) obj;
-            synchronized (cache) {
-                if (cache.containsKey(ref)) {
-                    return cache.get(ref);
-                } else {
-                    String configFilePath =
-                            (String) ref.get(BindableRepository.CONFIGFILEPATH_ADDRTYPE).getContent();
-                    String repHomeDir =
-                            (String) ref.get(BindableRepository.REPHOMEDIR_ADDRTYPE).getContent();
-                    return createInstance(configFilePath, repHomeDir);
-                }
+    public synchronized Object getObjectInstance(
+            Object obj, Name name, Context nameCtx, Hashtable environment)
+            throws RepositoryException {
+        synchronized (cache) {
+            Object instance = cache.get(obj);
+            if (instance == null && obj instanceof Reference) {
+                instance = new BindableRepository((Reference) obj);
+                cache.put(obj, instance);
             }
+            return instance;
         }
-        return null;
     }
+
 }

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/jndi/RegistryHelper.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/jndi/RegistryHelper.java?rev=681031&r1=681030&r2=681031&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/jndi/RegistryHelper.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/jndi/RegistryHelper.java Wed Jul 30 06:52:52 2008
@@ -16,13 +16,18 @@
  */
 package org.apache.jackrabbit.core.jndi;
 
+import javax.jcr.Repository;
 import javax.jcr.RepositoryException;
 import javax.naming.Context;
 import javax.naming.NamingException;
+import javax.naming.Reference;
+import javax.naming.StringRefAddr;
+
+import org.apache.jackrabbit.api.JackrabbitRepository;
 
 /**
  * JNDI helper functionality. This class contains static utility
- * methods for binding and unbinding Jackarbbit repositories to and
+ * methods for binding and unbinding Jackrabbit repositories to and
  * from a JNDI context.
  */
 public class RegistryHelper {
@@ -54,10 +59,20 @@
                                           String repHomeDir,
                                           boolean overwrite)
             throws NamingException, RepositoryException {
+        Reference reference = new Reference(
+                Repository.class.getName(),
+                BindableRepositoryFactory.class.getName(),
+                null); // no classpath defined
+        reference.add(new StringRefAddr(
+                BindableRepository.CONFIGFILEPATH_ADDRTYPE, configFilePath));
+        reference.add(new StringRefAddr(
+                BindableRepository.REPHOMEDIR_ADDRTYPE, repHomeDir));
+
         // always create instance by using BindableRepositoryFactory
         // which maintains an instance cache;
         // see http://issues.apache.org/jira/browse/JCR-411 for details
-        Object obj = BindableRepositoryFactory.createInstance(configFilePath, repHomeDir);
+        Object obj = new BindableRepositoryFactory().getObjectInstance(
+                reference, null, null, null);
         if (overwrite) {
             ctx.rebind(name, obj);
         } else {
@@ -76,7 +91,8 @@
      */
     public static void unregisterRepository(Context ctx, String name)
             throws NamingException {
-        ((BindableRepository) ctx.lookup(name)).shutdown();
+        ((JackrabbitRepository) ctx.lookup(name)).shutdown();
         ctx.unbind(name);
     }
+
 }