You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by mr...@apache.org on 2007/02/28 16:09:29 UTC

svn commit: r512795 [1/4] - in /jackrabbit/trunk/contrib/spi/spi-rmi: ./ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/jackrabbit/ src/main/java/org/apache/jackrabbit/spi/ src/main/java/org/apache/j...

Author: mreutegg
Date: Wed Feb 28 07:09:27 2007
New Revision: 512795

URL: http://svn.apache.org/viewvc?view=rev&rev=512795
Log:
- Initial implementation of SPI-RMI transport layer

Added:
    jackrabbit/trunk/contrib/spi/spi-rmi/   (with props)
    jackrabbit/trunk/contrib/spi/spi-rmi/maven.xml   (with props)
    jackrabbit/trunk/contrib/spi/spi-rmi/project.xml   (with props)
    jackrabbit/trunk/contrib/spi/spi-rmi/src/
    jackrabbit/trunk/contrib/spi/spi-rmi/src/main/
    jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/
    jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/
    jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/
    jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/
    jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/
    jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/
    jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/client/
    jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/client/ClientBatch.java   (with props)
    jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/client/ClientIterator.java   (with props)
    jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/client/ClientQueryInfo.java   (with props)
    jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/client/ClientRepositoryService.java   (with props)
    jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/client/ClientSessionInfo.java   (with props)
    jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/client/RemoteRepositoryException.java   (with props)
    jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/client/RemoteRuntimeException.java   (with props)
    jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/common/
    jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/common/ChildInfoImpl.java   (with props)
    jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/common/ItemInfoImpl.java   (with props)
    jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/common/IteratorHelper.java   (with props)
    jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/common/LockInfoImpl.java   (with props)
    jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/common/NodeInfoImpl.java   (with props)
    jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/common/PropertyInfoImpl.java   (with props)
    jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/common/QItemDefinitionImpl.java   (with props)
    jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/common/QNodeDefinitionImpl.java   (with props)
    jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/common/QNodeTypeDefinitionImpl.java   (with props)
    jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/common/QPropertyDefinitionImpl.java   (with props)
    jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/common/QueryResultRowImpl.java   (with props)
    jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/common/SerializableIdFactory.java   (with props)
    jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/common/SerializableInputStream.java   (with props)
    jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/common/ValueFactoryImpl.java   (with props)
    jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/remote/
    jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/remote/RemoteBatch.java   (with props)
    jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/remote/RemoteIterator.java   (with props)
    jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/remote/RemoteQueryInfo.java   (with props)
    jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/remote/RemoteRepositoryService.java   (with props)
    jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/remote/RemoteSessionInfo.java   (with props)
    jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/server/
    jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/server/ServerBatch.java   (with props)
    jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/server/ServerIterator.java   (with props)
    jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/server/ServerObject.java   (with props)
    jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/server/ServerQueryInfo.java   (with props)
    jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/server/ServerRepositoryService.java   (with props)
    jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/server/ServerSessionInfo.java   (with props)

Propchange: jackrabbit/trunk/contrib/spi/spi-rmi/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Wed Feb 28 07:09:27 2007
@@ -0,0 +1,2 @@
+*.iml
+target

Added: jackrabbit/trunk/contrib/spi/spi-rmi/maven.xml
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/spi-rmi/maven.xml?view=auto&rev=512795
==============================================================================
--- jackrabbit/trunk/contrib/spi/spi-rmi/maven.xml (added)
+++ jackrabbit/trunk/contrib/spi/spi-rmi/maven.xml Wed Feb 28 07:09:27 2007
@@ -0,0 +1,35 @@
+<?xml version="1.0"?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.
+-->
+<project default="jar">
+    <!--
+        the 'clean' goal is already redefined in the maven.xml
+        of the parent project. we need to redefine it here
+        again to 'maven clean' works.
+    -->
+    <goal name="clean">
+        <attainGoal name="clean:clean"/>
+    </goal>
+
+   <!-- Compile the RMI stubs for the JCR-RMI server classes. -->
+   <postGoal name="java:compile">
+      <rmic base="${maven.build.dest}" verify="true"
+            includes="org/apache/jackrabbit/spi/rmi/server/Server*.class"
+            classpathref="maven.dependency.classpath"/>
+   </postGoal>
+
+</project>

Propchange: jackrabbit/trunk/contrib/spi/spi-rmi/maven.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/trunk/contrib/spi/spi-rmi/project.xml
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/spi-rmi/project.xml?view=auto&rev=512795
==============================================================================
--- jackrabbit/trunk/contrib/spi/spi-rmi/project.xml (added)
+++ jackrabbit/trunk/contrib/spi/spi-rmi/project.xml Wed Feb 28 07:09:27 2007
@@ -0,0 +1,83 @@
+<?xml version="1.0"?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.
+-->
+<project>
+    <!-- ====================================================================== -->
+    <!-- P R O J E C T  D E S C R I P T I O N                                   -->
+    <!-- ====================================================================== -->
+    <extend>${basedir}/../project.xml</extend>
+    <artifactId>jackrabbit-spi-rmi</artifactId>
+    <name>SPI-RMI</name>
+    <package>org.apache.jackrabbit.spi.rmi.*</package>
+
+    <!-- ====================================================================== -->
+    <!-- D E P E N D E N C I E S                                                -->
+    <!-- ====================================================================== -->
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.jackrabbit</groupId>
+            <artifactId>jackrabbit-spi</artifactId>
+            <version>${jackrabbit.build.version.spi}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.jackrabbit</groupId>
+            <artifactId>jackrabbit-spi-commons</artifactId>
+            <version>${jackrabbit.build.version.spi}</version>
+        </dependency>
+        <!-- jackrabbit dependencies -->
+        <dependency>
+            <groupId>org.apache.jackrabbit</groupId>
+            <artifactId>jackrabbit-jcr-commons</artifactId>
+            <version>${jackrabbit.build.version.jackrabbit}</version>
+        </dependency>
+
+        <!-- external dependencies -->
+        <dependency>
+            <groupId>jsr170</groupId>
+            <artifactId>jcr</artifactId>
+            <version>${jackrabbit.build.version.jcr}</version>
+            <url>http://jcp.org/en/jsr/detail?id=170</url>
+        </dependency>
+
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-log4j12</artifactId>
+            <version>1.0</version>
+            <url>http://www.slf4j.org/download.html</url>
+        </dependency>
+        
+        <!-- unit tests -->
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>3.8.1</version>
+            <url>http://www.junit.org/</url>
+            <properties>
+                <scope>test</scope>
+            </properties>
+        </dependency>
+    </dependencies>
+
+    <!-- ====================================================================== -->
+    <!-- B U I L D  D E S C R I P T I O N                                       -->
+    <!-- ====================================================================== -->
+    <build>
+        <sourceDirectory>${basedir}/src/main/java</sourceDirectory>
+        <unitTestSourceDirectory>${basedir}/src/test/java</unitTestSourceDirectory>
+    </build>
+
+</project>

Propchange: jackrabbit/trunk/contrib/spi/spi-rmi/project.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/client/ClientBatch.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/client/ClientBatch.java?view=auto&rev=512795
==============================================================================
--- jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/client/ClientBatch.java (added)
+++ jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/client/ClientBatch.java Wed Feb 28 07:09:27 2007
@@ -0,0 +1,171 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.jackrabbit.spi.rmi.client;
+
+import org.apache.jackrabbit.spi.Batch;
+import org.apache.jackrabbit.spi.NodeId;
+import org.apache.jackrabbit.spi.QValue;
+import org.apache.jackrabbit.spi.PropertyId;
+import org.apache.jackrabbit.spi.ItemId;
+import org.apache.jackrabbit.spi.rmi.remote.RemoteBatch;
+import org.apache.jackrabbit.name.QName;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.ValueFormatException;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.ItemExistsException;
+import javax.jcr.AccessDeniedException;
+import javax.jcr.UnsupportedRepositoryOperationException;
+import javax.jcr.nodetype.ConstraintViolationException;
+import javax.jcr.lock.LockException;
+import javax.jcr.version.VersionException;
+import java.rmi.RemoteException;
+
+/**
+ * <code>ClientBatch</code> implements a SPI {@link Batch} which wraps a remote
+ * batch.
+ */
+class ClientBatch implements Batch {
+
+    /**
+     * The remote batch.
+     */
+    private final RemoteBatch remoteBatch;
+
+    ClientBatch(RemoteBatch remoteBatch) {
+        this.remoteBatch = remoteBatch;
+    }
+
+    /**
+     * @return the wrapped remote batch.
+     */
+    RemoteBatch getRemoteBatch() {
+        return remoteBatch;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void addNode(NodeId parentId,
+                        QName nodeName,
+                        QName nodetypeName,
+                        String uuid) throws RepositoryException {
+        try {
+            remoteBatch.addNode(parentId, nodeName, nodetypeName, uuid);
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void addProperty(NodeId parentId, QName propertyName, QValue value)
+            throws ValueFormatException, VersionException, LockException, ConstraintViolationException, PathNotFoundException, ItemExistsException, AccessDeniedException, UnsupportedRepositoryOperationException, RepositoryException {
+        try {
+            remoteBatch.addProperty(parentId, propertyName, value);
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void addProperty(NodeId parentId,
+                            QName propertyName,
+                            QValue[] values) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, PathNotFoundException, ItemExistsException, AccessDeniedException, UnsupportedRepositoryOperationException, RepositoryException {
+        try {
+            remoteBatch.addProperty(parentId, propertyName, values);
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void setValue(PropertyId propertyId, QValue value)
+            throws RepositoryException {
+        try {
+            remoteBatch.setValue(propertyId, value);
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void setValue(PropertyId propertyId, QValue[] values)
+            throws RepositoryException {
+        try {
+            remoteBatch.setValue(propertyId, values);
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void remove(ItemId itemId) throws RepositoryException {
+        try {
+            remoteBatch.remove(itemId);
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void reorderNodes(NodeId parentId,
+                             NodeId srcNodeId,
+                             NodeId beforeNodeId) throws RepositoryException {
+        try {
+            remoteBatch.reorderNodes(parentId, srcNodeId, beforeNodeId);
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void setMixins(NodeId nodeId, QName[] mixinNodeTypeIds)
+            throws RepositoryException {
+        try {
+            remoteBatch.setMixins(nodeId, mixinNodeTypeIds);
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void move(NodeId srcNodeId,
+                     NodeId destParentNodeId,
+                     QName destName) throws RepositoryException {
+        try {
+            remoteBatch.move(srcNodeId, destParentNodeId, destName);
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+}

Propchange: jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/client/ClientBatch.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/client/ClientIterator.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/client/ClientIterator.java?view=auto&rev=512795
==============================================================================
--- jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/client/ClientIterator.java (added)
+++ jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/client/ClientIterator.java Wed Feb 28 07:09:27 2007
@@ -0,0 +1,224 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.jackrabbit.spi.rmi.client;
+
+import java.rmi.RemoteException;
+import java.util.NoSuchElementException;
+
+import javax.jcr.RangeIterator;
+
+import org.apache.jackrabbit.spi.rmi.remote.RemoteIterator;
+import org.apache.jackrabbit.spi.IdIterator;
+import org.apache.jackrabbit.spi.ItemId;
+import org.apache.jackrabbit.spi.QueryResultRowIterator;
+import org.apache.jackrabbit.spi.QueryResultRow;
+
+/**
+ * A buffering local adapter for the {@link RemoteIterator}
+ * interface. This class makes the remote iterator locally available
+ * using the JCR {@link RangeIterator} interface. The element arrays
+ * returned by the remote iterator are buffered locally.
+ */
+class ClientIterator implements RangeIterator, IdIterator, QueryResultRowIterator {
+
+    /** The adapted remote iterator. */
+    private final RemoteIterator remote;
+
+    /**
+     * The cached number of elements in the iterator, -1 if the iterator
+     * size is unknown, or -2 if the size has not been retrieved from the
+     * remote iterator.
+     */
+    private long size;
+
+    /** The position of the buffer within the iteration. */
+    private long positionOfBuffer;
+
+    /** The position within the buffer of the iteration. */
+    private int positionInBuffer;
+
+    /**
+     * The element buffer. Set to <code>null</code> when the end of the
+     * iteration has been reached.
+     */
+    private Object[] buffer;
+
+    /**
+     * Creates a local adapter for the given remote iterator. The element buffer
+     * is initially empty.
+     *
+     * @param remote remote iterator
+     */
+    public ClientIterator(RemoteIterator remote) {
+        this.remote = remote;
+        this.size = -2;
+        this.positionOfBuffer = 0;
+        this.positionInBuffer = 0;
+        this.buffer = new Object[0];
+    }
+
+    /**
+     * Returns the current position within the iterator.
+     *
+     * @return current position
+     * @see RangeIterator#getPosition()
+     */
+    public long getPosition() {
+        return positionOfBuffer + positionInBuffer;
+    }
+
+    /**
+     * Returns the size (the total number of elements) of this iteration.
+     * Returns <code>-1</code> if the size is unknown.
+     * <p>
+     * To minimize the number of remote method calls, the size is retrieved
+     * when this method is first called and cached for subsequent invocations.
+     *
+     * @return number of elements in the iteration, or <code>-1</code>
+     * @throws RemoteRuntimeException on RMI errors
+     * @see RangeIterator#getSize()
+     */
+    public long getSize() throws RemoteRuntimeException {
+        if (size == -2) {
+            try {
+                size = remote.getSize();
+            } catch (RemoteException e) {
+                throw new RemoteRuntimeException(e);
+            }
+        }
+        return size;
+    }
+
+    /**
+     * Skips the given number of elements in this iteration.
+     * <p>
+     * The elements in the local element buffer are skipped first, and
+     * a remote skip method call is made only if more elements are being
+     * skipped than remain in the local buffer.
+     *
+     * @param skipNum the number of elements to skip
+     * @throws NoSuchElementException if skipped past the last element
+     * @throws RemoteRuntimeException on RMI errors
+     * @see RangeIterator#skip(long)
+     */
+    public void skip(long skipNum)
+            throws NoSuchElementException, RemoteRuntimeException {
+        if (skipNum < 0) {
+            throw new IllegalArgumentException("Negative skip is not allowed");
+        } else if (buffer == null && skipNum > 0) {
+            throw new NoSuchElementException("Skipped past the last element");
+        } else if (positionInBuffer + skipNum < buffer.length) {
+            positionInBuffer += skipNum;
+        } else {
+            try {
+                skipNum -= buffer.length - positionInBuffer;
+                remote.skip(skipNum);
+                positionInBuffer = buffer.length;
+                positionOfBuffer += skipNum;
+            } catch (RemoteException e) {
+                throw new RemoteRuntimeException(e);
+            } catch (NoSuchElementException e) {
+                buffer = null; // End of iterator reached
+                throw e;
+            }
+        }
+    }
+
+    /**
+     * Advances the element buffer if there are no more elements in it. The
+     * element buffer is set to <code>null</code> if the end of the iteration
+     * has been reached.
+     *
+     * @throws RemoteException on RMI errors
+     */
+    private void advance() throws RemoteException {
+        if (buffer != null && positionInBuffer == buffer.length) {
+            positionOfBuffer += buffer.length;
+            positionInBuffer = 0;
+            buffer = remote.nextObjects();
+            if (buffer == null) {
+                size = positionOfBuffer;
+            }
+        }
+    }
+
+    /**
+     * Checks if there are more elements in this iteration.
+     *
+     * @return <code>true</code> if there are more elements,
+     *         <code>false</code> otherwise
+     * @throws RemoteRuntimeException on RMI errors
+     * @see java.util.Iterator#hasNext()
+     */
+    public boolean hasNext() throws RemoteRuntimeException {
+        try {
+            advance();
+            return buffer != null;
+        } catch (RemoteException e) {
+            throw new RemoteRuntimeException(e);
+        }
+    }
+
+    /**
+     * Returns the next element in this iteration.
+     *
+     * @return next element
+     * @throws NoSuchElementException if there are no more elements
+     * @throws RemoteRuntimeException on RMI errors
+     * @see java.util.Iterator#next()
+     */
+    public Object next() throws NoSuchElementException, RemoteRuntimeException {
+        try {
+            advance();
+            if (buffer == null) {
+                throw new NoSuchElementException("End of iterator reached");
+            } else {
+                return buffer[positionInBuffer++];
+            }
+        } catch (RemoteException e) {
+            throw new RemoteRuntimeException(e);
+        }
+    }
+
+    /**
+     * Not supported.
+     *
+     * @throws UnsupportedOperationException always thrown
+     * @see java.util.Iterator#remove()
+     */
+    public void remove() throws UnsupportedOperationException {
+        throw new UnsupportedOperationException();
+    }
+
+    //------------------------------< IdIterator >------------------------------
+
+    /**
+     * @return returns the next <code>ItemId</code> in this iterator.
+     */
+    public ItemId nextId() {
+        return (ItemId) next();
+    }
+
+    //-----------------------< QueryResultRowIterator >-------------------------
+
+    /**
+     * @return returns the next <code>QueryResultRow</code> in this iterator.
+     */
+    public QueryResultRow nextQueryResultRow() {
+        return (QueryResultRow) next();
+    }
+}

Propchange: jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/client/ClientIterator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/client/ClientQueryInfo.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/client/ClientQueryInfo.java?view=auto&rev=512795
==============================================================================
--- jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/client/ClientQueryInfo.java (added)
+++ jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/client/ClientQueryInfo.java Wed Feb 28 07:09:27 2007
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.jackrabbit.spi.rmi.client;
+
+import org.apache.jackrabbit.spi.QueryInfo;
+import org.apache.jackrabbit.spi.QueryResultRowIterator;
+import org.apache.jackrabbit.spi.rmi.remote.RemoteQueryInfo;
+import org.apache.jackrabbit.name.QName;
+
+import java.rmi.RemoteException;
+
+/**
+ * <code>ClientQueryInfo</code> wraps a remote query info and exposes it as a
+ * SPI query info.
+ */
+class ClientQueryInfo implements QueryInfo {
+
+    /**
+     * The remote query info.
+     */
+    private final RemoteQueryInfo queryInfo;
+
+    /**
+     * Creates a new client query info wrapping a remote query info.
+     *
+     * @param queryInfo the remote query info.
+     */
+    ClientQueryInfo(RemoteQueryInfo queryInfo) {
+        this.queryInfo = queryInfo;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public QueryResultRowIterator getRows() {
+        try {
+            return new ClientIterator(queryInfo.getRows());
+        } catch (RemoteException e) {
+            throw new RemoteRuntimeException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public QName[] getColumnNames() {
+        try {
+            return queryInfo.getColumnNames();
+        } catch (RemoteException e) {
+            throw new RemoteRuntimeException(e);
+        }
+    }
+}

Propchange: jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/client/ClientQueryInfo.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/client/ClientRepositoryService.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/client/ClientRepositoryService.java?view=auto&rev=512795
==============================================================================
--- jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/client/ClientRepositoryService.java (added)
+++ jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/client/ClientRepositoryService.java Wed Feb 28 07:09:27 2007
@@ -0,0 +1,751 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.jackrabbit.spi.rmi.client;
+
+import org.apache.jackrabbit.spi.RepositoryService;
+import org.apache.jackrabbit.spi.IdFactory;
+import org.apache.jackrabbit.spi.QValueFactory;
+import org.apache.jackrabbit.spi.SessionInfo;
+import org.apache.jackrabbit.spi.ItemId;
+import org.apache.jackrabbit.spi.NodeId;
+import org.apache.jackrabbit.spi.QNodeDefinition;
+import org.apache.jackrabbit.spi.QPropertyDefinition;
+import org.apache.jackrabbit.spi.PropertyId;
+import org.apache.jackrabbit.spi.NodeInfo;
+import org.apache.jackrabbit.spi.PropertyInfo;
+import org.apache.jackrabbit.spi.Batch;
+import org.apache.jackrabbit.spi.LockInfo;
+import org.apache.jackrabbit.spi.IdIterator;
+import org.apache.jackrabbit.spi.QueryInfo;
+import org.apache.jackrabbit.spi.EventFilter;
+import org.apache.jackrabbit.spi.EventBundle;
+import org.apache.jackrabbit.spi.QNodeTypeDefinitionIterator;
+import org.apache.jackrabbit.spi.QNodeTypeDefinition;
+import org.apache.jackrabbit.spi.rmi.remote.RemoteRepositoryService;
+import org.apache.jackrabbit.spi.rmi.remote.RemoteSessionInfo;
+import org.apache.jackrabbit.spi.rmi.remote.RemoteIterator;
+import org.apache.jackrabbit.spi.rmi.remote.RemoteQueryInfo;
+import org.apache.jackrabbit.spi.rmi.common.SerializableIdFactory;
+import org.apache.jackrabbit.spi.rmi.common.SerializableInputStream;
+import org.apache.jackrabbit.spi.rmi.common.IteratorHelper;
+import org.apache.jackrabbit.name.QName;
+import org.apache.jackrabbit.name.Path;
+import org.apache.jackrabbit.value.QValueFactoryImpl;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Credentials;
+import javax.jcr.LoginException;
+import javax.jcr.NoSuchWorkspaceException;
+import javax.jcr.ItemNotFoundException;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.ValueFormatException;
+import javax.jcr.AccessDeniedException;
+import javax.jcr.UnsupportedRepositoryOperationException;
+import javax.jcr.ItemExistsException;
+import javax.jcr.InvalidItemStateException;
+import javax.jcr.ReferentialIntegrityException;
+import javax.jcr.MergeException;
+import javax.jcr.NamespaceException;
+import javax.jcr.query.InvalidQueryException;
+import javax.jcr.lock.LockException;
+import javax.jcr.version.VersionException;
+import javax.jcr.nodetype.NoSuchNodeTypeException;
+import javax.jcr.nodetype.ConstraintViolationException;
+import java.util.Map;
+import java.util.Iterator;
+import java.util.HashMap;
+import java.util.Arrays;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.rmi.RemoteException;
+
+/**
+ * <code>ClientRepositoryService</code> implements a SPI repository service
+ * which is backed by a remote repository service.
+ */
+public class ClientRepositoryService implements RepositoryService {
+
+    /**
+     * The remote repository service.
+     */
+    private final RemoteRepositoryService remoteService;
+
+    /**
+     * The id factory.
+     */
+    private final SerializableIdFactory idFactory = SerializableIdFactory.getInstance();
+
+    /**
+     * The QValue factory.
+     */
+    private final QValueFactory qValueFactory = QValueFactoryImpl.getInstance();
+
+    /**
+     * Creates a new client repository service.
+     *
+     * @param remoteService the remote repository service to expose.
+     */
+    public ClientRepositoryService(RemoteRepositoryService remoteService) {
+        this.remoteService = remoteService;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public IdFactory getIdFactory() {
+        return idFactory;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public QValueFactory getQValueFactory() {
+        return qValueFactory;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Map getRepositoryDescriptors() throws RepositoryException {
+        try {
+            return remoteService.getRepositoryDescriptors();
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public SessionInfo obtain(Credentials credentials, String workspaceName)
+            throws LoginException, NoSuchWorkspaceException, RepositoryException {
+        try {
+            return new ClientSessionInfo(remoteService.obtain(credentials, workspaceName));
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public SessionInfo obtain(SessionInfo sessionInfo, String workspaceName)
+            throws LoginException, NoSuchWorkspaceException, RepositoryException {
+        try {
+            return new ClientSessionInfo(remoteService.obtain(
+                    getRemoteSessionInfo(sessionInfo), workspaceName));
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void dispose(SessionInfo sessionInfo) throws RepositoryException {
+        try {
+            remoteService.dispose(getRemoteSessionInfo(sessionInfo));
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String[] getWorkspaceNames(SessionInfo sessionInfo)
+            throws RepositoryException {
+        try {
+            return remoteService.getWorkspaceNames(
+                    getRemoteSessionInfo(sessionInfo));
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean isGranted(SessionInfo sessionInfo,
+                             ItemId itemId,
+                             String[] actions) throws RepositoryException {
+        try {
+            return remoteService.isGranted(
+                    getRemoteSessionInfo(sessionInfo), itemId, actions);
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public NodeId getRootId(SessionInfo sessionInfo)
+            throws RepositoryException {
+        try {
+            return remoteService.getRootId(getRemoteSessionInfo(sessionInfo));
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public QNodeDefinition getNodeDefinition(SessionInfo sessionInfo,
+                                             NodeId nodeId)
+            throws RepositoryException {
+        try {
+            return remoteService.getNodeDefinition(
+                    getRemoteSessionInfo(sessionInfo), nodeId);
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+    /**
+     * {@inheritDoc}
+     */
+    public QPropertyDefinition getPropertyDefinition(SessionInfo sessionInfo,
+                                                     PropertyId propertyId)
+            throws RepositoryException {
+        try {
+            return remoteService.getPropertyDefinition(
+                    getRemoteSessionInfo(sessionInfo), propertyId);
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean exists(SessionInfo sessionInfo, ItemId itemId)
+            throws RepositoryException {
+        try {
+            return remoteService.exists(
+                    getRemoteSessionInfo(sessionInfo), itemId);
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public NodeInfo getNodeInfo(SessionInfo sessionInfo, NodeId nodeId)
+            throws ItemNotFoundException, RepositoryException {
+        try {
+            return remoteService.getNodeInfo(getRemoteSessionInfo(sessionInfo), nodeId);
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Iterator getChildInfos(SessionInfo sessionInfo, NodeId parentId)
+            throws ItemNotFoundException, RepositoryException {
+        try {
+            RemoteIterator it = remoteService.getChildInfos(
+                    getRemoteSessionInfo(sessionInfo), parentId);
+            return new ClientIterator(it);
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public PropertyInfo getPropertyInfo(SessionInfo sessionInfo,
+                                        PropertyId propertyId)
+            throws ItemNotFoundException, RepositoryException {
+        try {
+            return remoteService.getPropertyInfo(getRemoteSessionInfo(sessionInfo), propertyId);
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Batch createBatch(ItemId itemId, SessionInfo sessionInfo)
+            throws RepositoryException {
+        try {
+            return new ClientBatch(remoteService.createBatch(
+                    itemId, getRemoteSessionInfo(sessionInfo)));
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void submit(Batch batch) throws PathNotFoundException, ItemNotFoundException, NoSuchNodeTypeException, ValueFormatException, VersionException, LockException, ConstraintViolationException, AccessDeniedException, UnsupportedRepositoryOperationException, RepositoryException {
+        if (batch instanceof ClientBatch) {
+            try {
+                remoteService.submit(((ClientBatch) batch).getRemoteBatch());
+            } catch (RemoteException e) {
+                throw new RemoteRepositoryException(e);
+            }
+        } else {
+            throw new RepositoryException("Unknown Batch implementation: " +
+                    batch.getClass().getName());
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void importXml(SessionInfo sessionInfo,
+                          NodeId parentId,
+                          InputStream xmlStream,
+                          int uuidBehaviour) throws ItemExistsException, PathNotFoundException, VersionException, ConstraintViolationException, LockException, AccessDeniedException, UnsupportedRepositoryOperationException, RepositoryException {
+        try {
+            remoteService.importXml(getRemoteSessionInfo(sessionInfo), parentId,
+                    new SerializableInputStream(xmlStream), uuidBehaviour);
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void move(SessionInfo sessionInfo,
+                     NodeId srcNodeId,
+                     NodeId destParentNodeId,
+                     QName destName) throws ItemExistsException, PathNotFoundException, VersionException, ConstraintViolationException, LockException, AccessDeniedException, UnsupportedRepositoryOperationException, RepositoryException {
+        try {
+            remoteService.move(getRemoteSessionInfo(sessionInfo), srcNodeId,
+                    destParentNodeId, destName);
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void copy(SessionInfo sessionInfo,
+                     String srcWorkspaceName,
+                     NodeId srcNodeId,
+                     NodeId destParentNodeId,
+                     QName destName) throws NoSuchWorkspaceException, ConstraintViolationException, VersionException, AccessDeniedException, PathNotFoundException, ItemExistsException, LockException, UnsupportedRepositoryOperationException, RepositoryException {
+        try {
+            remoteService.copy(getRemoteSessionInfo(sessionInfo),
+                    srcWorkspaceName, srcNodeId, destParentNodeId, destName);
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void update(SessionInfo sessionInfo,
+                       NodeId nodeId,
+                       String srcWorkspaceName)
+            throws NoSuchWorkspaceException, AccessDeniedException, LockException, InvalidItemStateException, RepositoryException {
+        try {
+            remoteService.update(getRemoteSessionInfo(sessionInfo),
+                    nodeId, srcWorkspaceName);
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void clone(SessionInfo sessionInfo,
+                      String srcWorkspaceName,
+                      NodeId srcNodeId,
+                      NodeId destParentNodeId,
+                      QName destName,
+                      boolean removeExisting) throws NoSuchWorkspaceException, ConstraintViolationException, VersionException, AccessDeniedException, PathNotFoundException, ItemExistsException, LockException, UnsupportedRepositoryOperationException, RepositoryException {
+        try {
+            remoteService.clone(getRemoteSessionInfo(sessionInfo),
+                    srcWorkspaceName, srcNodeId, destParentNodeId,
+                    destName, removeExisting);
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public LockInfo getLockInfo(SessionInfo sessionInfo, NodeId nodeId)
+            throws LockException, RepositoryException {
+        try {
+            return remoteService.getLockInfo(
+                    getRemoteSessionInfo(sessionInfo), nodeId);
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public LockInfo lock(SessionInfo sessionInfo,
+                         NodeId nodeId,
+                         boolean deep,
+                         boolean sessionScoped)
+            throws UnsupportedRepositoryOperationException, LockException, AccessDeniedException, InvalidItemStateException, RepositoryException {
+        try {
+            return remoteService.lock(getRemoteSessionInfo(sessionInfo),
+                    nodeId, deep, sessionScoped);
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void refreshLock(SessionInfo sessionInfo, NodeId nodeId)
+            throws LockException, RepositoryException {
+        try {
+            remoteService.refreshLock(getRemoteSessionInfo(sessionInfo), nodeId);
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void unlock(SessionInfo sessionInfo, NodeId nodeId)
+            throws UnsupportedRepositoryOperationException, LockException, AccessDeniedException, InvalidItemStateException, RepositoryException {
+        try {
+            remoteService.unlock(getRemoteSessionInfo(sessionInfo), nodeId);
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void checkin(SessionInfo sessionInfo, NodeId nodeId)
+            throws VersionException, UnsupportedRepositoryOperationException, InvalidItemStateException, LockException, RepositoryException {
+        try {
+            remoteService.checkin(getRemoteSessionInfo(sessionInfo), nodeId);
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void checkout(SessionInfo sessionInfo, NodeId nodeId)
+            throws UnsupportedRepositoryOperationException, LockException, RepositoryException {
+        try {
+            remoteService.checkout(getRemoteSessionInfo(sessionInfo), nodeId);
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void removeVersion(SessionInfo sessionInfo,
+                              NodeId versionHistoryId,
+                              NodeId versionId)
+            throws ReferentialIntegrityException, AccessDeniedException, UnsupportedRepositoryOperationException, VersionException, RepositoryException {
+        try {
+            remoteService.removeVersion(getRemoteSessionInfo(sessionInfo), versionHistoryId, versionId);
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void restore(SessionInfo sessionInfo,
+                        NodeId nodeId,
+                        NodeId versionId,
+                        boolean removeExisting) throws VersionException, PathNotFoundException, ItemExistsException, UnsupportedRepositoryOperationException, LockException, InvalidItemStateException, RepositoryException {
+        try {
+            remoteService.restore(getRemoteSessionInfo(sessionInfo), nodeId, versionId, removeExisting);
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void restore(SessionInfo sessionInfo,
+                        NodeId[] versionIds,
+                        boolean removeExisting) throws ItemExistsException, UnsupportedRepositoryOperationException, VersionException, LockException, InvalidItemStateException, RepositoryException {
+        try {
+            remoteService.restore(getRemoteSessionInfo(sessionInfo), versionIds, removeExisting);
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public IdIterator merge(SessionInfo sessionInfo,
+                            NodeId nodeId,
+                            String srcWorkspaceName,
+                            boolean bestEffort)
+            throws NoSuchWorkspaceException, AccessDeniedException, MergeException, LockException, InvalidItemStateException, RepositoryException {
+        try {
+            RemoteIterator it = remoteService.merge(
+                    getRemoteSessionInfo(sessionInfo), nodeId,
+                    srcWorkspaceName, bestEffort);
+            return new ClientIterator(it);
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void resolveMergeConflict(SessionInfo sessionInfo,
+                                     NodeId nodeId,
+                                     NodeId[] mergeFailedIds,
+                                     NodeId[] predecessorIds)
+            throws VersionException, InvalidItemStateException, UnsupportedRepositoryOperationException, RepositoryException {
+        try {
+            remoteService.resolveMergeConflict(getRemoteSessionInfo(sessionInfo),
+                    nodeId, mergeFailedIds, predecessorIds);
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void addVersionLabel(SessionInfo sessionInfo,
+                                NodeId versionHistoryId,
+                                NodeId versionId,
+                                QName label,
+                                boolean moveLabel) throws VersionException, RepositoryException {
+        try {
+            remoteService.addVersionLabel(getRemoteSessionInfo(sessionInfo),
+                    versionHistoryId, versionId, label, moveLabel);
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void removeVersionLabel(SessionInfo sessionInfo,
+                                   NodeId versionHistoryId,
+                                   NodeId versionId,
+                                   QName label) throws VersionException, RepositoryException {
+        try {
+            remoteService.removeVersionLabel(getRemoteSessionInfo(sessionInfo), versionHistoryId, versionId, label);
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String[] getSupportedQueryLanguages(SessionInfo sessionInfo)
+            throws RepositoryException {
+        try {
+            return remoteService.getSupportedQueryLanguages(getRemoteSessionInfo(sessionInfo));
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void checkQueryStatement(SessionInfo sessionInfo,
+                                    String statement,
+                                    String language,
+                                    Map namespaces)
+            throws InvalidQueryException, RepositoryException {
+        if (!(namespaces instanceof Serializable)) {
+            namespaces = new HashMap(namespaces);
+        }
+        try {
+            remoteService.checkQueryStatement(getRemoteSessionInfo(sessionInfo),
+                    statement, language, namespaces);
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public QueryInfo executeQuery(SessionInfo sessionInfo,
+                                  String statement,
+                                  String language,
+                                  Map namespaces) throws RepositoryException {
+        if (!(namespaces instanceof Serializable)) {
+            namespaces = new HashMap(namespaces);
+        }
+        try {
+            RemoteQueryInfo remoteQueryInfo = remoteService.executeQuery(
+                    getRemoteSessionInfo(sessionInfo), statement,
+                    language, namespaces);
+            return new ClientQueryInfo(remoteQueryInfo);
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public EventFilter createEventFilter(SessionInfo sessionInfo,
+                                         int eventTypes,
+                                         Path absPath,
+                                         boolean isDeep,
+                                         String[] uuid,
+                                         QName[] nodeTypeName,
+                                         boolean noLocal)
+            throws UnsupportedRepositoryOperationException, RepositoryException {
+        try {
+            return remoteService.createEventFilter(
+                    getRemoteSessionInfo(sessionInfo), eventTypes, absPath,
+                    isDeep, uuid, nodeTypeName, noLocal);
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public EventBundle[] getEvents(SessionInfo sessionInfo,
+                                   long timeout,
+                                   EventFilter[] filters)
+            throws RepositoryException, UnsupportedRepositoryOperationException, InterruptedException {
+        try {
+            return remoteService.getEvents(getRemoteSessionInfo(sessionInfo),
+                    timeout, filters);
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Map getRegisteredNamespaces(SessionInfo sessionInfo)
+            throws RepositoryException {
+        try {
+            return remoteService.getRegisteredNamespaces(
+                    getRemoteSessionInfo(sessionInfo));
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getNamespaceURI(SessionInfo sessionInfo, String prefix)
+            throws NamespaceException, RepositoryException {
+        try {
+            return remoteService.getNamespaceURI(
+                    getRemoteSessionInfo(sessionInfo), prefix);
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getNamespacePrefix(SessionInfo sessionInfo, String uri)
+            throws NamespaceException, RepositoryException {
+        try {
+            return remoteService.getNamespacePrefix(
+                    getRemoteSessionInfo(sessionInfo), uri);
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void registerNamespace(SessionInfo sessionInfo,
+                                  String prefix,
+                                  String uri) throws NamespaceException, UnsupportedRepositoryOperationException, AccessDeniedException, RepositoryException {
+        try {
+            remoteService.registerNamespace(getRemoteSessionInfo(sessionInfo),
+                    prefix, uri);
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void unregisterNamespace(SessionInfo sessionInfo, String uri)
+            throws NamespaceException, UnsupportedRepositoryOperationException, AccessDeniedException, RepositoryException {
+        try {
+            remoteService.unregisterNamespace(getRemoteSessionInfo(sessionInfo), uri);
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public QNodeTypeDefinitionIterator getNodeTypeDefinitions(
+            SessionInfo sessionInfo) throws RepositoryException {
+        try {
+            QNodeTypeDefinition[] ntDefs = remoteService.getNodeTypeDefinitions(
+                    getRemoteSessionInfo(sessionInfo));
+            return new IteratorHelper(Arrays.asList(ntDefs));
+        } catch (RemoteException e) {
+            throw new RemoteRepositoryException(e);
+        }
+    }
+
+    //------------------------------< internal >--------------------------------
+
+    private RemoteSessionInfo getRemoteSessionInfo(SessionInfo sessionInfo)
+            throws RepositoryException {
+        if (sessionInfo instanceof ClientSessionInfo) {
+            return ((ClientSessionInfo) sessionInfo).getRemoteSessionInfo();
+        } else {
+            throw new RepositoryException("Unknown SessionInfo implementation: " +
+                    sessionInfo.getClass().getName());
+        }
+    }
+}

Propchange: jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/client/ClientRepositoryService.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/client/ClientSessionInfo.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/client/ClientSessionInfo.java?view=auto&rev=512795
==============================================================================
--- jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/client/ClientSessionInfo.java (added)
+++ jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/client/ClientSessionInfo.java Wed Feb 28 07:09:27 2007
@@ -0,0 +1,134 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.jackrabbit.spi.rmi.client;
+
+import org.apache.jackrabbit.spi.SessionInfo;
+import org.apache.jackrabbit.spi.rmi.remote.RemoteSessionInfo;
+
+import java.rmi.RemoteException;
+
+/**
+ * <code>ClientSessionInfo</code> wraps a remote session info and exposes it
+ * as a SPI {@link org.apache.jackrabbit.spi.SessionInfo}.
+ */
+class ClientSessionInfo implements SessionInfo {
+
+    /**
+     * The underlying remote session info.
+     */
+    private final RemoteSessionInfo remoteSessionInfo;
+
+    /**
+     * Creates a new session info based on a remote session info.
+     *
+     * @param remoteSessionInfo the remote session info.
+     */
+    public ClientSessionInfo(RemoteSessionInfo remoteSessionInfo) {
+        this.remoteSessionInfo = remoteSessionInfo;
+    }
+
+    /**
+     * @return the underlying remote session info.
+     */
+    RemoteSessionInfo getRemoteSessionInfo() {
+        return remoteSessionInfo;
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws RemoteRuntimeException if an RMI error occurs.
+     */
+    public String getUserID() {
+        try {
+            return remoteSessionInfo.getUserID();
+        } catch (RemoteException e) {
+            throw new RemoteRuntimeException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws RemoteRuntimeException if an RMI error occurs.
+     */
+    public String getWorkspaceName() {
+        try {
+            return remoteSessionInfo.getWorkspaceName();
+        } catch (RemoteException e) {
+            throw new RemoteRuntimeException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws RemoteRuntimeException if an RMI error occurs.
+     */
+    public String[] getLockTokens() {
+        try {
+            return remoteSessionInfo.getLockTokens();
+        } catch (RemoteException e) {
+            throw new RemoteRuntimeException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws RemoteRuntimeException if an RMI error occurs.
+     */
+    public void addLockToken(String lockToken) {
+        try {
+            remoteSessionInfo.addLockToken(lockToken);
+        } catch (RemoteException e) {
+            throw new RemoteRuntimeException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws RemoteRuntimeException if an RMI error occurs.
+     */
+    public void removeLockToken(String lockToken) {
+        try {
+            remoteSessionInfo.removeLockToken(lockToken);
+        } catch (RemoteException e) {
+            throw new RemoteRuntimeException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws RemoteRuntimeException if an RMI error occurs.
+     */
+    public String getLastEventBundleId() {
+        try {
+            return remoteSessionInfo.getLastEventBundleId();
+        } catch (RemoteException e) {
+            throw new RemoteRuntimeException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     * @throws RemoteRuntimeException if an RMI error occurs.
+     */
+    public void setLastEventBundleId(String eventBundleId) {
+        try {
+            remoteSessionInfo.setLastEventBundleId(eventBundleId);
+        } catch (RemoteException e) {
+            throw new RemoteRuntimeException(e);
+        }
+    }
+}

Propchange: jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/client/ClientSessionInfo.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/client/RemoteRepositoryException.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/client/RemoteRepositoryException.java?view=auto&rev=512795
==============================================================================
--- jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/client/RemoteRepositoryException.java (added)
+++ jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/client/RemoteRepositoryException.java Wed Feb 28 07:09:27 2007
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.jackrabbit.spi.rmi.client;
+
+import javax.jcr.RepositoryException;
+import java.rmi.RemoteException;
+
+/**
+ * <code>RemoteRepositoryException</code> is thrown if a
+ * {@link java.rmi.RemoteException} is thrown by one of the RMI methods.
+ */
+public class RemoteRepositoryException extends RepositoryException {
+
+    public RemoteRepositoryException(RemoteException e) {
+        super(e);
+    }
+}

Propchange: jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/client/RemoteRepositoryException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/client/RemoteRuntimeException.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/client/RemoteRuntimeException.java?view=auto&rev=512795
==============================================================================
--- jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/client/RemoteRuntimeException.java (added)
+++ jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/client/RemoteRuntimeException.java Wed Feb 28 07:09:27 2007
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.jackrabbit.spi.rmi.client;
+
+import java.rmi.RemoteException;
+
+/**
+ * Wraps a remote exception with a runtime exception.
+ */
+public class RemoteRuntimeException extends RuntimeException {
+
+    /**
+     * Creates a RemoteRuntimeException based on the given RemoteException.
+     *
+     * @param ex the remote exception
+     */
+    public RemoteRuntimeException(RemoteException ex) {
+        super(ex);
+    }
+}

Propchange: jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/client/RemoteRuntimeException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/common/ChildInfoImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/common/ChildInfoImpl.java?view=auto&rev=512795
==============================================================================
--- jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/common/ChildInfoImpl.java (added)
+++ jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/common/ChildInfoImpl.java Wed Feb 28 07:09:27 2007
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.jackrabbit.spi.rmi.common;
+
+import org.apache.jackrabbit.spi.ChildInfo;
+import org.apache.jackrabbit.name.QName;
+
+import java.io.Serializable;
+
+/**
+ * <code>ChildInfoImpl</code> implements a serializable <code>ChildInfo</code>.
+ */
+public class ChildInfoImpl implements ChildInfo, Serializable {
+
+    /**
+     * The name of this child info.
+     */
+    private final QName name;
+
+    /**
+     * The unique id for this child info or <code>null</code> if it does not
+     * have a unique id.
+     */
+    private final String uniqueId;
+
+    /**
+     * 1-based index of this child info.
+     */
+    private final int index;
+
+    /**
+     * Creates a new serializable <code>ChildInfoImpl</code>.
+     *
+     * @param name     the name of the child node.
+     * @param uniqueId the unique id of the child node or <code>null</code>.
+     * @param index    the index of the child node.
+     */
+    public ChildInfoImpl(QName name, String uniqueId, int index) {
+        this.name = name;
+        this.uniqueId = uniqueId;
+        this.index = index;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public QName getName() {
+        return name;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getUniqueID() {
+        return uniqueId;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public int getIndex() {
+        return index;
+    }
+}

Propchange: jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/common/ChildInfoImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/common/ItemInfoImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/common/ItemInfoImpl.java?view=auto&rev=512795
==============================================================================
--- jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/common/ItemInfoImpl.java (added)
+++ jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/common/ItemInfoImpl.java Wed Feb 28 07:09:27 2007
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.jackrabbit.spi.rmi.common;
+
+import org.apache.jackrabbit.spi.ItemInfo;
+import org.apache.jackrabbit.spi.NodeId;
+import org.apache.jackrabbit.name.QName;
+import org.apache.jackrabbit.name.Path;
+
+import java.io.Serializable;
+
+/**
+ * <code>ItemInfoImpl</code> is a base class for <code>ItemInfo</code>
+ * implementations.
+ */
+abstract class ItemInfoImpl implements ItemInfo, Serializable {
+
+    /**
+     * The parent node id of this item or <code>null</code> if this item
+     * represents the root node info.
+     */
+    private final NodeId parentId;
+
+    /**
+     * The name of this item info.
+     */
+    private final QName name;
+
+    /**
+     * The path of this item info.
+     */
+    private final Path path;
+
+    /**
+     * Flag indicating whether this is a node or a property info.
+     */
+    private final boolean isNode;
+
+    /**
+     * Creates a new serializable item info for the given qualified
+     * <code>item</code> info.
+     *
+     * @param parentId the parent id.
+     * @param name     the name of this item.
+     * @param path     the path to this item.
+     * @param isNode   if this item is a node.
+     */
+    public ItemInfoImpl(NodeId parentId, QName name, Path path, boolean isNode) {
+        this.parentId = parentId;
+        this.name = name;
+        this.path = path;
+        this.isNode = isNode;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public NodeId getParentId() {
+        return parentId;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public QName getQName() {
+        return name;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean denotesNode() {
+        return isNode;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Path getPath() {
+        return path;
+    }
+}

Propchange: jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/common/ItemInfoImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/common/IteratorHelper.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/common/IteratorHelper.java?view=auto&rev=512795
==============================================================================
--- jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/common/IteratorHelper.java (added)
+++ jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/common/IteratorHelper.java Wed Feb 28 07:09:27 2007
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.jackrabbit.spi.rmi.common;
+
+import org.apache.jackrabbit.spi.IdIterator;
+import org.apache.jackrabbit.spi.QNodeTypeDefinitionIterator;
+import org.apache.jackrabbit.spi.ItemId;
+import org.apache.jackrabbit.spi.QNodeTypeDefinition;
+import org.apache.jackrabbit.spi.Event;
+import org.apache.jackrabbit.spi.EventIterator;
+import org.apache.jackrabbit.spi.QueryResultRow;
+import org.apache.jackrabbit.spi.QueryResultRowIterator;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.ArrayList;
+
+/**
+ * <code>org.apache.jackrabbit.spi.rmi.common.IteratorHelper</code>...
+ * TODO: move to spi-commons
+ */
+public class IteratorHelper extends org.apache.jackrabbit.util.IteratorHelper
+    implements IdIterator, QueryResultRowIterator, QNodeTypeDefinitionIterator, EventIterator {
+
+    public static final IteratorHelper EMPTY = new IteratorHelper(new ArrayList(0));
+
+    public IteratorHelper(Collection c) {
+        super(c);
+    }
+
+    public IteratorHelper(Iterator iter) {
+        super(iter);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public ItemId nextId() {
+        return (ItemId) next();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public QNodeTypeDefinition nextDefinition() {
+        return (QNodeTypeDefinition) next();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public QueryResultRow nextQueryResultRow() {
+        return (QueryResultRow)super.next();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Event nextEvent() {
+        return (Event) next();
+    }
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/common/IteratorHelper.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/common/LockInfoImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/common/LockInfoImpl.java?view=auto&rev=512795
==============================================================================
--- jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/common/LockInfoImpl.java (added)
+++ jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/common/LockInfoImpl.java Wed Feb 28 07:09:27 2007
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.jackrabbit.spi.rmi.common;
+
+import org.apache.jackrabbit.spi.LockInfo;
+import org.apache.jackrabbit.spi.NodeId;
+
+import java.io.Serializable;
+
+/**
+ * <code>LockInfoImpl</code> implements a serializable <code>LockInfo</code>
+ * based on another lock info.
+ */
+public class LockInfoImpl implements LockInfo, Serializable {
+
+    /**
+     * The lock token for this lock info.
+     */
+    private final String lockToken;
+
+    /**
+     * The owner of the lock.
+     */
+    private final String lockOwner;
+
+    /**
+     * The isDeep flag.
+     */
+    private final boolean isDeep;
+
+    /**
+     * The isSessionScoped flag.
+     */
+    private final boolean isSessionScoped;
+
+    /**
+     * The <code>NodeId</code> of the locked node.
+     */
+    private final NodeId nodeId;
+
+    /**
+     * Creates a new lock info for the given <code>lock</code> info.
+     *
+     * @param lockToken the lock token
+     * @param lockOwner the lock owner
+     * @param isDeep whether this lock is deep or not
+     * @param isSessionScoped whether this lock is session scoped or not
+     * @param nodeId the node id of the locked node.
+     */
+    public LockInfoImpl(String lockToken, String lockOwner, boolean isDeep,
+                        boolean isSessionScoped, NodeId nodeId) {
+        this.lockToken = lockToken;
+        this.lockOwner = lockOwner;
+        this.isDeep = isDeep;
+        this.isSessionScoped = isSessionScoped;
+        this.nodeId = nodeId;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getLockToken() {
+        return lockToken;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getOwner() {
+        return lockOwner;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean isDeep() {
+        return isDeep;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean isSessionScoped() {
+        return isSessionScoped;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public NodeId getNodeId() {
+        return nodeId;
+    }
+}

Propchange: jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/common/LockInfoImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/common/NodeInfoImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/common/NodeInfoImpl.java?view=auto&rev=512795
==============================================================================
--- jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/common/NodeInfoImpl.java (added)
+++ jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/common/NodeInfoImpl.java Wed Feb 28 07:09:27 2007
@@ -0,0 +1,140 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.jackrabbit.spi.rmi.common;
+
+import org.apache.jackrabbit.spi.NodeInfo;
+import org.apache.jackrabbit.spi.NodeId;
+import org.apache.jackrabbit.spi.PropertyId;
+import org.apache.jackrabbit.spi.IdIterator;
+import org.apache.jackrabbit.name.QName;
+import org.apache.jackrabbit.name.Path;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+/**
+ * <code>NodeInfoImpl</code> implements a serializable <code>NodeInfo</code>
+ * based on another node info.
+ */
+public class NodeInfoImpl extends ItemInfoImpl implements NodeInfo {
+
+    /**
+     * The node id of the underlying node.
+     */
+    private final NodeId id;
+
+    /**
+     * 1-based index of the underlying node.
+     */
+    private final int index;
+
+    /**
+     * The name of the primary node type.
+     */
+    private final QName primaryTypeName;
+
+    /**
+     * The names of assigned mixins.
+     */
+    private final QName[] mixinNames;
+
+    /**
+     * The list of {@link PropertyId}s that reference this node info.
+     */
+    private final List references;
+
+    /**
+     * The list of {@link PropertyId}s of this node info.
+     */
+    private final List propertyIds;
+
+    /**
+     * Creates a new serializable node info for the given <code>node</code>
+     * info.
+     *
+     * @param parentId        the parent id.
+     * @param name            the name of this item.
+     * @param path            the path to this item.
+     * @param id              the id of this item.
+     * @param index           the index of this item.
+     * @param primaryTypeName the name of the primary node type.
+     * @param mixinNames      the names of the assigned mixins.
+     * @param references      the references to this node.
+     * @param propertyIds     the properties of this node.
+     */
+    public NodeInfoImpl(NodeId parentId, QName name, Path path, NodeId id,
+                        int index, QName primaryTypeName, QName[] mixinNames,
+                        PropertyId[] references, IdIterator propertyIds) {
+        super(parentId, name, path, true);
+        this.id = id;
+        this.index = index;
+        this.primaryTypeName = primaryTypeName;
+        this.mixinNames = mixinNames;
+        this.references = Arrays.asList(references);
+        this.propertyIds = new ArrayList();
+        while (propertyIds.hasNext()) {
+            this.propertyIds.add(propertyIds.nextId());
+        }
+    }
+
+    //-------------------------------< NodeInfo >-------------------------------
+
+    /**
+     * {@inheritDoc}
+     */
+    public NodeId getId() {
+        return id;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public int getIndex() {
+        return index;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public QName getNodetype() {
+        return primaryTypeName;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public QName[] getMixins() {
+        QName[] ret = new QName[mixinNames.length];
+        System.arraycopy(mixinNames, 0, ret, 0, mixinNames.length);
+        return ret;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public PropertyId[] getReferences() {
+        return (PropertyId[]) references.toArray(new PropertyId[references.size()]);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public IdIterator getPropertyIds() {
+        return new IteratorHelper(propertyIds);
+    }
+}

Propchange: jackrabbit/trunk/contrib/spi/spi-rmi/src/main/java/org/apache/jackrabbit/spi/rmi/common/NodeInfoImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native