Index: src/main/java/org/apache/jackrabbit/rmi/server/ServerAdapterFactory.java =================================================================== --- src/main/java/org/apache/jackrabbit/rmi/server/ServerAdapterFactory.java (revision 1377741) +++ src/main/java/org/apache/jackrabbit/rmi/server/ServerAdapterFactory.java (working copy) @@ -16,6 +16,7 @@ */ package org.apache.jackrabbit.rmi.server; +import java.rmi.Remote; import java.rmi.RemoteException; import java.security.Principal; import java.security.acl.Group; @@ -60,6 +61,8 @@ import javax.jcr.version.VersionManager; import javax.transaction.xa.XAResource; +import org.apache.commons.collections.map.ReferenceIdentityMap; +import org.apache.commons.collections.map.ReferenceMap; import org.apache.jackrabbit.rmi.remote.ArrayIterator; import org.apache.jackrabbit.rmi.remote.BufferIterator; import org.apache.jackrabbit.rmi.remote.RemoteEventCollection; @@ -124,6 +127,14 @@ /** The buffer size of iterators created by this factory. */ private int bufferSize = DEFAULT_BUFFER_SIZE; + /** A cache mapping local JCR Objects to Remote Stubs. */ + private ReferenceIdentityMap remoteCache = + new ReferenceIdentityMap(ReferenceMap.WEAK, ReferenceMap.WEAK); + + /** A cache mapping Remote Stubs to local JCR Objects. */ + private ReferenceMap localCache = + new ReferenceMap(ReferenceMap.WEAK, ReferenceMap.WEAK); + /** * The port number for server objects. Initializes to the value of the * org.apache.jackrabbit.rmi.port system property, or to 0 if @@ -175,7 +186,13 @@ */ public RemoteRepository getRemoteRepository(Repository repository) throws RemoteException { - return new ServerRepository(repository, this); + ServerRepository remote = + (ServerRepository) getRemoteObject(repository); + if (remote == null) { + remote = new ServerRepository(repository, this); + addToCache(repository, remote); + } + return remote; } /** @@ -186,11 +203,17 @@ */ public RemoteSession getRemoteSession(Session session) throws RemoteException { - if (session instanceof XAResource) { - return new ServerXASession(session, (XAResource) session, this); - } else { - return new ServerSession(session, this); + ServerSession remote = (ServerSession) getRemoteObject(session); + if (remote == null) { + if (session instanceof XAResource) { + remote = new ServerXASession(session, (XAResource) session, + this); + } else { + remote = new ServerSession(session, this); + } + addToCache(session, remote); } + return remote; } /** @@ -198,7 +221,12 @@ */ public RemoteWorkspace getRemoteWorkspace(Workspace workspace) throws RemoteException { - return new ServerWorkspace(workspace, this); + ServerWorkspace remote = (ServerWorkspace) getRemoteObject(workspace); + if (remote == null) { + remote = new ServerWorkspace(workspace, this); + addToCache(workspace, remote); + } + return remote; } /** @@ -207,7 +235,13 @@ */ public RemoteObservationManager getRemoteObservationManager( ObservationManager observationManager) throws RemoteException { - return new ServerObservationManager(observationManager, this); + ServerObservationManager remote = + (ServerObservationManager) getRemoteObject(observationManager); + if (remote == null) { + remote = new ServerObservationManager(observationManager, this); + addToCache(observationManager, remote); + } + return remote; } /** @@ -216,7 +250,13 @@ */ public RemoteNamespaceRegistry getRemoteNamespaceRegistry( NamespaceRegistry registry) throws RemoteException { - return new ServerNamespaceRegistry(registry, this); + ServerNamespaceRegistry remote = + (ServerNamespaceRegistry) getRemoteObject(registry); + if (remote == null) { + remote = new ServerNamespaceRegistry(registry, this); + addToCache(registry, remote); + } + return remote; } /** @@ -225,14 +265,25 @@ */ public RemoteNodeTypeManager getRemoteNodeTypeManager( NodeTypeManager manager) throws RemoteException { - return new ServerNodeTypeManager(manager, this); + ServerNodeTypeManager remote = + (ServerNodeTypeManager) getRemoteObject(manager); + if (remote == null) { + remote = new ServerNodeTypeManager(manager, this); + addToCache(manager, remote); + } + return remote; } /** * Creates a {@link ServerItem ServerItem} instance. {@inheritDoc} */ public RemoteItem getRemoteItem(Item item) throws RemoteException { - return new ServerItem(item, this); + ServerItem remote = (ServerItem) getRemoteObject(item); + if (remote == null) { + remote = new ServerItem(item, this); + addToCache(item, remote); + } + return remote; } /** @@ -240,14 +291,24 @@ */ public RemoteProperty getRemoteProperty(Property property) throws RemoteException { - return new ServerProperty(property, this); + ServerProperty remote = (ServerProperty) getRemoteObject(property); + if (remote == null) { + remote = new ServerProperty(property, this); + addToCache(property, remote); + } + return remote; } /** * Creates a {@link ServerNode ServerNode} instance. {@inheritDoc} */ public RemoteNode getRemoteNode(Node node) throws RemoteException { - return new ServerNode(node, this); + ServerNode remote = (ServerNode) getRemoteObject(node); + if (remote == null) { + remote = new ServerNode(node, this); + addToCache(node, remote); + } + return remote; } /** @@ -255,7 +316,12 @@ */ public RemoteVersion getRemoteVersion(Version version) throws RemoteException { - return new ServerVersion(version, this); + ServerVersion remote = (ServerVersion) getRemoteObject(version); + if (remote == null) { + remote = new ServerVersion(version, this); + addToCache(version, remote); + } + return remote; } /** @@ -264,7 +330,13 @@ */ public RemoteVersionHistory getRemoteVersionHistory( VersionHistory versionHistory) throws RemoteException { - return new ServerVersionHistory(versionHistory, this); + ServerVersionHistory remote = + (ServerVersionHistory) getRemoteObject(versionHistory); + if (remote == null) { + remote = new ServerVersionHistory(versionHistory, this); + addToCache(versionHistory, remote); + } + return remote; } /** @@ -272,7 +344,12 @@ */ public RemoteNodeType getRemoteNodeType(NodeType type) throws RemoteException { - return new ServerNodeType(type, this); + ServerNodeType remote = (ServerNodeType) getRemoteObject(type); + if (remote == null) { + remote = new ServerNodeType(type, this); + addToCache(type, remote); + } + return remote; } /** @@ -281,7 +358,13 @@ */ public RemoteItemDefinition getRemoteItemDefinition(ItemDefinition def) throws RemoteException { - return new ServerItemDefinition(def, this); + ServerItemDefinition remote = + (ServerItemDefinition) getRemoteObject(def); + if (remote == null) { + remote = new ServerItemDefinition(def, this); + addToCache(def, remote); + } + return remote; } /** @@ -290,7 +373,13 @@ */ public RemoteNodeDefinition getRemoteNodeDefinition(NodeDefinition def) throws RemoteException { - return new ServerNodeDefinition(def, this); + ServerNodeDefinition remote = + (ServerNodeDefinition) getRemoteObject(def); + if (remote == null) { + remote = new ServerNodeDefinition(def, this); + addToCache(def, remote); + } + return remote; } /** @@ -299,14 +388,25 @@ */ public RemotePropertyDefinition getRemotePropertyDefinition( PropertyDefinition def) throws RemoteException { - return new ServerPropertyDefinition(def, this); + ServerPropertyDefinition remote = + (ServerPropertyDefinition) getRemoteObject(def); + if (remote == null) { + remote = new ServerPropertyDefinition(def, this); + addToCache(def, remote); + } + return remote; } /** * Creates a {@link ServerLock ServerLock} instance. {@inheritDoc} */ public RemoteLock getRemoteLock(Lock lock) throws RemoteException { - return new ServerLock(lock, this); + ServerLock remote = (ServerLock) getRemoteObject(lock); + if (remote == null) { + remote = new ServerLock(lock, this); + addToCache(lock, remote); + } + return remote; } /** @@ -315,14 +415,25 @@ */ public RemoteQueryManager getRemoteQueryManager(Session session, QueryManager manager) throws RemoteException { - return new ServerQueryManager(session, manager, this); + ServerQueryManager remote = + (ServerQueryManager) getRemoteObject(manager); + if (remote == null) { + remote = new ServerQueryManager(session, manager, this); + addToCache(manager, remote); + } + return remote; } /** * Creates a {@link ServerQuery ServerQuery} instance. {@inheritDoc} */ public RemoteQuery getRemoteQuery(Query query) throws RemoteException { - return new ServerQuery(query, this); + ServerQuery remote = (ServerQuery) getRemoteObject(query); + if (remote == null) { + remote = new ServerQuery(query, this); + addToCache(query, remote); + } + return remote; } /** @@ -331,7 +442,12 @@ */ public RemoteQueryResult getRemoteQueryResult(QueryResult result) throws RemoteException { - return new ServerQueryResult(result, this); + ServerQueryResult remote = (ServerQueryResult) getRemoteObject(result); + if (remote == null) { + remote = new ServerQueryResult(result, this); + addToCache(result, remote); + } + return remote; } /** @@ -339,7 +455,12 @@ * {@inheritDoc} */ public RemoteRow getRemoteRow(Row row) throws RemoteException { - return new ServerRow(row, this); + ServerRow remote = (ServerRow) getRemoteObject(row); + if (remote == null) { + remote = new ServerRow(row, this); + addToCache(row, remote); + } + return remote; } /** @@ -441,12 +562,24 @@ public RemoteLockManager getRemoteLockManager(LockManager lockManager) throws RemoteException { - return new ServerLockManager(lockManager, this); + ServerLockManager remote = + (ServerLockManager) getRemoteObject(lockManager); + if (remote == null) { + remote = new ServerLockManager(lockManager, this); + addToCache(lockManager, remote); + } + return remote; } public RemoteVersionManager getRemoteVersionManager(Session session, VersionManager versionManager) throws RemoteException { - return new ServerVersionManager(session, versionManager, this); + ServerVersionManager remote = + (ServerVersionManager) getRemoteObject(versionManager); + if (remote == null) { + remote = new ServerVersionManager(session, versionManager, this); + addToCache(versionManager, remote); + } + return remote; } /** @@ -456,12 +589,22 @@ */ public RemoteAccessControlManager getRemoteAccessControlManager( AccessControlManager acm) throws RemoteException { - return new ServerAccessControlManager(acm, this); + ServerAccessControlManager remote = (ServerAccessControlManager) getRemoteObject(acm); + if (remote == null) { + remote = new ServerAccessControlManager(acm, this); + addToCache(acm, remote); + } + return remote; } public RemotePrivilege getRemotePrivilege(final Privilege local) throws RemoteException { - return new ServerPrivilege(local, this); + ServerPrivilege remote = (ServerPrivilege) getRemoteObject(local); + if (remote == null) { + remote = new ServerPrivilege(local, this); + addToCache(local, remote); + } + return remote; } public RemotePrivilege[] getRemotePrivilege(final Privilege[] local) @@ -475,10 +618,18 @@ public RemoteAccessControlPolicy getRemoteAccessControlPolicy( final AccessControlPolicy local) throws RemoteException { - if (local instanceof AccessControlList) { - return new ServerAccessControlList((AccessControlList) local, this); + ServerAccessControlPolicy remote = + (ServerAccessControlPolicy) getRemoteObject(local); + if (remote == null) { + if (local instanceof AccessControlList) { + remote = new ServerAccessControlList( + (AccessControlList) local, this); + } else { + remote = new ServerAccessControlPolicy(local, this); + } + addToCache(local, remote); } - return new ServerAccessControlPolicy(local, this); + return remote; } public RemoteAccessControlPolicy[] getRemoteAccessControlPolicy( @@ -501,7 +652,13 @@ public RemoteAccessControlEntry getRemoteAccessControlEntry( final AccessControlEntry local) throws RemoteException { - return new ServerAccessControlEntry(local, this); + ServerAccessControlEntry remote = + (ServerAccessControlEntry) getRemoteObject(local); + if (remote == null) { + remote = new ServerAccessControlEntry(local, this); + addToCache(local, remote); + } + return remote; } public RemoteAccessControlEntry[] getRemoteAccessControlEntry( @@ -527,4 +684,25 @@ bufferSize)); } + /** {@inheritDoc} */ + public Object getJcrObject(Remote stub) { + return localCache.get(stub); + } + + /** {@inheritDoc} */ + public Remote getRemoteObject(Object jcrObject) { + return (Remote) remoteCache.get(jcrObject); + } + + /** + * Convenience method to put remote stubs and jcr objects into the hashmaps. + * TODO Check for synchronization needs. + * @param jcrObject local JCR object + * @param remote remote wrapper of the JCR object + */ + private void addToCache(Object jcrObject, Remote stub) { + remoteCache.put(jcrObject, stub); + localCache.put(stub, jcrObject); + } + } Index: src/main/java/org/apache/jackrabbit/rmi/server/RemoteAdapterFactory.java =================================================================== --- src/main/java/org/apache/jackrabbit/rmi/server/RemoteAdapterFactory.java (revision 1377741) +++ src/main/java/org/apache/jackrabbit/rmi/server/RemoteAdapterFactory.java (working copy) @@ -16,6 +16,7 @@ */ package org.apache.jackrabbit.rmi.server; +import java.rmi.Remote; import java.rmi.RemoteException; import java.security.Principal; import java.util.Iterator; @@ -483,4 +484,21 @@ public RemoteIterator getRemotePrincipalIterator( final Iterator principals) throws RemoteException; + /** + * Returns the local jcr object represented by the given remote stub or + * serializable object. + * + * @param stub remote stub + * @return local jcr object or null + */ + Object getJcrObject(Remote stub); + + /** + * Returns a remote stub for the given jcr object. + * + * @param jcrObject a jcr object (Node, Item, etc.) + * @return remote stub for the given jcr object or null + */ + Remote getRemoteObject(Object jcrObject); + } Index: src/main/java/org/apache/jackrabbit/rmi/client/ClientAdapterFactory.java =================================================================== --- src/main/java/org/apache/jackrabbit/rmi/client/ClientAdapterFactory.java (revision 1377741) +++ src/main/java/org/apache/jackrabbit/rmi/client/ClientAdapterFactory.java (working copy) @@ -16,6 +16,7 @@ */ package org.apache.jackrabbit.rmi.client; +import java.rmi.Remote; import java.security.Principal; import java.util.Iterator; @@ -52,6 +53,8 @@ import javax.jcr.version.VersionIterator; import javax.jcr.version.VersionManager; +import org.apache.commons.collections.map.ReferenceIdentityMap; +import org.apache.commons.collections.map.ReferenceMap; import org.apache.jackrabbit.rmi.client.iterator.ClientNodeIterator; import org.apache.jackrabbit.rmi.client.iterator.ClientNodeTypeIterator; import org.apache.jackrabbit.rmi.client.iterator.ClientPropertyIterator; @@ -108,6 +111,14 @@ */ public class ClientAdapterFactory implements LocalAdapterFactory { + /** A cache mapping Client JCR Objects to Remote Stubs. */ + private ReferenceIdentityMap remoteCache = + new ReferenceIdentityMap(ReferenceMap.WEAK, ReferenceMap.WEAK); + + /** A cache mapping Remote Stubs to local Client JCR Objects. */ + private ReferenceMap localCache = + new ReferenceMap(ReferenceMap.WEAK, ReferenceMap.WEAK); + /** * Creates and returns a {@link ClientRepository ClientRepository} * instance. @@ -115,7 +126,12 @@ * {@inheritDoc} */ public Repository getRepository(RemoteRepository remote) { - return new ClientRepository(remote, this); + ClientRepository local = (ClientRepository) getClientObject(remote); + if (local == null) { + local = new ClientRepository(remote, this); + addToCache(local, remote); + } + return local; } /** @@ -126,12 +142,17 @@ * {@inheritDoc} */ public Session getSession(Repository repository, RemoteSession remote) { - if (remote instanceof RemoteXASession) { - return new ClientXASession( - repository, (RemoteXASession) remote, this); - } else { - return new ClientSession(repository, remote, this); + ClientSession local = (ClientSession) getClientObject(remote); + if (local == null) { + if (remote instanceof RemoteXASession) { + local = new ClientXASession(repository, + (RemoteXASession) remote, this); + } else { + local = new ClientSession(repository, remote, this); + } + addToCache(local, remote); } + return local; } /** @@ -140,7 +161,12 @@ * {@inheritDoc} */ public Workspace getWorkspace(Session session, RemoteWorkspace remote) { - return new ClientWorkspace(session, remote, this); + ClientWorkspace local = (ClientWorkspace) getClientObject(remote); + if (local == null) { + local = new ClientWorkspace(session, remote, this); + addToCache(local, remote); + } + return local; } /** @@ -151,7 +177,13 @@ */ public ObservationManager getObservationManager(Workspace workspace, RemoteObservationManager remote) { - return new ClientObservationManager(workspace, remote); + ClientObservationManager local = + (ClientObservationManager) getClientObject(remote); + if (local == null) { + local = new ClientObservationManager(workspace, remote); + addToCache(local, remote); + } + return local; } /** @@ -162,7 +194,13 @@ */ public NamespaceRegistry getNamespaceRegistry( RemoteNamespaceRegistry remote) { - return new ClientNamespaceRegistry(remote, this); + ClientNamespaceRegistry local = + (ClientNamespaceRegistry) getClientObject(remote); + if (local == null) { + local = new ClientNamespaceRegistry(remote, this); + addToCache(local, remote); + } + return local; } /** @@ -172,7 +210,13 @@ * {@inheritDoc} */ public NodeTypeManager getNodeTypeManager(RemoteNodeTypeManager remote) { - return new ClientNodeTypeManager(remote, this); + ClientNodeTypeManager local = + (ClientNodeTypeManager) getClientObject(remote); + if (local == null) { + local = new ClientNodeTypeManager(remote, this); + addToCache(local, remote); + } + return local; } /** @@ -181,7 +225,12 @@ * {@inheritDoc} */ public Item getItem(Session session, RemoteItem remote) { - return new ClientItem(session, remote, this); + ClientItem local = (ClientItem) getClientObject(remote); + if (local == null) { + local = new ClientItem(session, remote, this); + addToCache(local, remote); + } + return local; } /** @@ -190,7 +239,12 @@ * {@inheritDoc} */ public Property getProperty(Session session, RemoteProperty remote) { - return new ClientProperty(session, remote, this); + ClientProperty local = (ClientProperty) getClientObject(remote); + if (local == null) { + local = new ClientProperty(session, remote, this); + addToCache(local, remote); + } + return local; } /** @@ -199,7 +253,12 @@ * {@inheritDoc} */ public Node getNode(Session session, RemoteNode remote) { - return new ClientNode(session, remote, this); + ClientNode local = (ClientNode) getClientObject(remote); + if (local == null) { + local = new ClientNode(session, remote, this); + addToCache(local, remote); + } + return local; } /** @@ -208,7 +267,12 @@ * {@inheritDoc} */ public Version getVersion(Session session, RemoteVersion remote) { - return new ClientVersion(session, remote, this); + ClientVersion local = (ClientVersion) getClientObject(remote); + if (local == null) { + local = new ClientVersion(session, remote, this); + addToCache(local, remote); + } + return local; } /** @@ -218,7 +282,13 @@ * {@inheritDoc} */ public VersionHistory getVersionHistory(Session session, RemoteVersionHistory remote) { - return new ClientVersionHistory(session, remote, this); + ClientVersionHistory local = + (ClientVersionHistory) getClientObject(remote); + if (local == null) { + local = new ClientVersionHistory(session, remote, this); + addToCache(local, remote); + } + return local; } /** @@ -227,7 +297,12 @@ * {@inheritDoc} */ public NodeType getNodeType(RemoteNodeType remote) { - return new ClientNodeType(remote, this); + ClientNodeType local = (ClientNodeType) getClientObject(remote); + if (local == null) { + local = new ClientNodeType(remote, this); + addToCache(local, remote); + } + return local; } /** @@ -236,7 +311,13 @@ * {@inheritDoc} */ public ItemDefinition getItemDef(RemoteItemDefinition remote) { - return new ClientItemDefinition(remote, this); + ClientItemDefinition local = + (ClientItemDefinition) getClientObject(remote); + if (local == null) { + local = new ClientItemDefinition(remote, this); + addToCache(local, remote); + } + return local; } /** @@ -245,7 +326,13 @@ * {@inheritDoc} */ public NodeDefinition getNodeDef(RemoteNodeDefinition remote) { - return new ClientNodeDefinition(remote, this); + ClientNodeDefinition local = + (ClientNodeDefinition) getClientObject(remote); + if (local == null) { + local = new ClientNodeDefinition(remote, this); + addToCache(local, remote); + } + return local; } /** @@ -255,7 +342,13 @@ * {@inheritDoc} */ public PropertyDefinition getPropertyDef(RemotePropertyDefinition remote) { - return new ClientPropertyDefinition(remote, this); + ClientPropertyDefinition local = + (ClientPropertyDefinition) getClientObject(remote); + if (local == null) { + local = new ClientPropertyDefinition(remote, this); + addToCache(local, remote); + } + return local; } /** @@ -264,7 +357,12 @@ * {@inheritDoc} */ public Lock getLock(Session session, RemoteLock remote) { - return new ClientLock(session, remote, this); + ClientLock local = (ClientLock) getClientObject(remote); + if (local == null) { + local = new ClientLock(session, remote, this); + addToCache(local, remote); + } + return local; } /** @@ -274,7 +372,12 @@ */ public QueryManager getQueryManager( Session session, RemoteQueryManager remote) { - return new ClientQueryManager(session, remote, this); + ClientQueryManager local = (ClientQueryManager) getClientObject(remote); + if (local == null) { + local = new ClientQueryManager(session, remote, this); + addToCache(local, remote); + } + return local; } /** @@ -283,7 +386,12 @@ * {@inheritDoc} */ public Query getQuery(Session session, RemoteQuery remote) { - return new ClientQuery(session, remote, this); + ClientQuery local = (ClientQuery) getClientObject(remote); + if (local == null) { + local = new ClientQuery(session, remote, this); + addToCache(local, remote); + } + return local; } /** @@ -293,7 +401,12 @@ */ public QueryResult getQueryResult( Session session, RemoteQueryResult remote) { - return new ClientQueryResult(session, remote, this); + ClientQueryResult local = (ClientQueryResult) getClientObject(remote); + if (local == null) { + local = new ClientQueryResult(session, remote, this); + addToCache(local, remote); + } + return local; } /** @@ -302,7 +415,12 @@ * {@inheritDoc} */ public Row getRow(Session session, RemoteRow remote) { - return new ClientRow(session, remote, this); + ClientRow local = (ClientRow) getClientObject(remote); + if (local == null) { + local = new ClientRow(session, remote, this); + addToCache(local, remote); + } + return local; } /** @@ -350,12 +468,23 @@ public LockManager getLockManager( Session session, RemoteLockManager remote) { - return new ClientLockManager(session, remote, this); + ClientLockManager local = (ClientLockManager) getClientObject(remote); + if (local == null) { + local = new ClientLockManager(session, remote, this); + addToCache(local, remote); + } + return local; } public VersionManager getVersionManager( Session session, RemoteVersionManager remote) { - return new ClientVersionManager(session, remote, this); + ClientVersionManager local = + (ClientVersionManager) getClientObject(remote); + if (local == null) { + local = new ClientVersionManager(session, remote, this); + addToCache(local, remote); + } + return local; } /** @@ -363,7 +492,13 @@ */ public AccessControlManager getAccessControlManager( RemoteAccessControlManager remote) { - return new ClientAccessControlManager(remote, this); + ClientAccessControlManager local = + (ClientAccessControlManager) getClientObject(remote); + if (local == null) { + local = new ClientAccessControlManager(remote, this); + addToCache(local, remote); + } + return local; } /** @@ -371,11 +506,18 @@ */ public AccessControlPolicy getAccessControlPolicy( RemoteAccessControlPolicy remote) { - if (remote instanceof RemoteAccessControlList) { - return new ClientAccessControlList( - (RemoteAccessControlList) remote, this); + ClientAccessControlPolicy local = + (ClientAccessControlPolicy) getClientObject(remote); + if (local == null) { + if (remote instanceof RemoteAccessControlList) { + local = new ClientAccessControlList( + (RemoteAccessControlList) remote, this); + } else { + local = new ClientAccessControlPolicy(remote, this); + } + addToCache(local, remote); } - return new ClientAccessControlPolicy(remote, this); + return local; } /** @@ -403,7 +545,13 @@ */ public AccessControlEntry getAccessControlEntry( RemoteAccessControlEntry remote) { - return new ClientAccessControlEntry(remote, this); + ClientAccessControlEntry local = + (ClientAccessControlEntry) getClientObject(remote); + if (local == null) { + local = new ClientAccessControlEntry(remote, this); + addToCache(local, remote); + } + return local; } /** @@ -440,7 +588,12 @@ * {@inheritDoc} */ public Privilege getPrivilege(RemotePrivilege remote) { - return new ClientPrivilege(remote, this); + ClientPrivilege local = (ClientPrivilege) getClientObject(remote); + if (local == null) { + local = new ClientPrivilege(remote, this); + addToCache(local, remote); + } + return local; } /** @@ -454,4 +607,25 @@ return local; } + /** {@inheritDoc} */ + public final Remote getRemoteObject(final Object clientObject) { + return (Remote) remoteCache.get(clientObject); + } + + /** {@inheritDoc} */ + public final Object getClientObject(final Remote stub) { + return localCache.get(stub); + } + + /** + * Convenience method to put remote stubs and jcr objects into the hashmaps. + * TODO Check for synchronization needs. + * @param jcrObject local JCR object + * @param remote remote wrapper of the JCR object + */ + private void addToCache(final Object jcrObject, final Remote remote) { + remoteCache.put(jcrObject, remote); + localCache.put(remote, jcrObject); + } + } Index: src/main/java/org/apache/jackrabbit/rmi/client/LocalAdapterFactory.java =================================================================== --- src/main/java/org/apache/jackrabbit/rmi/client/LocalAdapterFactory.java (revision 1377741) +++ src/main/java/org/apache/jackrabbit/rmi/client/LocalAdapterFactory.java (working copy) @@ -16,6 +16,7 @@ */ package org.apache.jackrabbit.rmi.client; +import java.rmi.Remote; import java.security.Principal; import java.util.Iterator; @@ -442,4 +443,20 @@ */ Privilege[] getPrivilege(RemotePrivilege[] remote); + /** + * Method for getting a remote adapter for a client object from cache. + * + * @param clientObject a local client object + * @return remote stub or null + */ + Remote getRemoteObject(Object clientObject); + + /** + * Method for getting a local adapter for a remote object from cache. + * + * @param stub a remote stub + * @return local client object or null + */ + Object getClientObject(Remote stub); + } Index: pom.xml =================================================================== --- pom.xml (revision 1387204) +++ pom.xml (working copy) @@ -541,6 +541,10 @@ org.slf4j slf4j-api + + commons-collections + commons-collections +