You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by ju...@apache.org on 2005/06/21 22:44:23 UTC
svn commit: r191722 - in /incubator/jackrabbit/trunk/contrib/jcr-rmi: ./
src/java/org/apache/jackrabbit/rmi/client/
src/java/org/apache/jackrabbit/rmi/iterator/
src/java/org/apache/jackrabbit/rmi/observation/
src/java/org/apache/jackrabbit/rmi/remote/ ...
Author: jukka
Date: Tue Jun 21 13:44:22 2005
New Revision: 191722
URL: http://svn.apache.org/viewcvs?rev=191722&view=rev
Log:
JCR-RMI: Added ObservationManager implementation contributed by Felix Meschberger.
Added:
incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/client/ClientObservationManager.java (with props)
incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/iterator/ArrayEventIterator.java (with props)
incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/iterator/ArrayEventListenerIterator.java (with props)
incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/observation/
incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/observation/ClientEventPoll.java (with props)
incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/observation/Queue.java (with props)
incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/observation/ServerEventListenerProxy.java (with props)
incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/observation/package.html (with props)
incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/remote/RemoteEventCollection.java (with props)
incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/remote/RemoteObservationManager.java (with props)
incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/server/ServerEventCollection.java (with props)
incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/server/ServerObservationManager.java (with props)
Modified:
incubator/jackrabbit/trunk/contrib/jcr-rmi/project.xml
incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/client/ClientAdapterFactory.java
incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/client/ClientSession.java
incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/client/ClientWorkspace.java
incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/client/LocalAdapterFactory.java
incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/remote/RemoteWorkspace.java
incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/server/RemoteAdapterFactory.java
incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/server/ServerAdapterFactory.java
incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/server/ServerSession.java
incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/server/ServerWorkspace.java
Modified: incubator/jackrabbit/trunk/contrib/jcr-rmi/project.xml
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-rmi/project.xml?rev=191722&r1=191721&r2=191722&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-rmi/project.xml (original)
+++ incubator/jackrabbit/trunk/contrib/jcr-rmi/project.xml Tue Jun 21 13:44:22 2005
@@ -76,6 +76,10 @@
<id>junit</id>
<version>3.8.1</version>
</dependency>
+ <dependency>
+ <id>commons-logging</id>
+ <version>1.0</version>
+ </dependency>
</dependencies>
<build>
Modified: incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/client/ClientAdapterFactory.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/client/ClientAdapterFactory.java?rev=191722&r1=191721&r2=191722&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/client/ClientAdapterFactory.java (original)
+++ incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/client/ClientAdapterFactory.java Tue Jun 21 13:44:22 2005
@@ -29,6 +29,7 @@
import javax.jcr.nodetype.ItemDefinition;
import javax.jcr.nodetype.NodeDefinition;
import javax.jcr.nodetype.PropertyDefinition;
+import javax.jcr.observation.ObservationManager;
import javax.jcr.query.Query;
import javax.jcr.query.QueryManager;
import javax.jcr.query.QueryResult;
@@ -44,6 +45,7 @@
import org.apache.jackrabbit.rmi.remote.RemoteNodeDefinition;
import org.apache.jackrabbit.rmi.remote.RemoteNodeType;
import org.apache.jackrabbit.rmi.remote.RemoteNodeTypeManager;
+import org.apache.jackrabbit.rmi.remote.RemoteObservationManager;
import org.apache.jackrabbit.rmi.remote.RemoteProperty;
import org.apache.jackrabbit.rmi.remote.RemotePropertyDefinition;
import org.apache.jackrabbit.rmi.remote.RemoteQuery;
@@ -97,6 +99,17 @@
return new ClientWorkspace(session, remote, this);
}
+ /**
+ * Creates and returns a
+ * {@link ClientObservationManager ClientObservationManager} instance.
+ *
+ * {@inheritDoc}
+ */
+ public ObservationManager getObservationManager(
+ RemoteObservationManager remote) {
+ return new ClientObservationManager(remote);
+ }
+
/**
* Creates and returns a
* {@link ClientNamespaceRegistry ClientClientNamespaceRegistry} instance.
Added: incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/client/ClientObservationManager.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/client/ClientObservationManager.java?rev=191722&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/client/ClientObservationManager.java (added)
+++ incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/client/ClientObservationManager.java Tue Jun 21 13:44:22 2005
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.rmi.client;
+
+import java.rmi.RemoteException;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.observation.EventListener;
+import javax.jcr.observation.EventListenerIterator;
+import javax.jcr.observation.ObservationManager;
+
+import org.apache.jackrabbit.rmi.iterator.ArrayEventListenerIterator;
+import org.apache.jackrabbit.rmi.observation.ClientEventPoll;
+import org.apache.jackrabbit.rmi.remote.RemoteObservationManager;
+
+/**
+ * The <code>ClientObservationManager</code> class
+ * <p>
+ * This class uses an instance of the
+ * {@link org.apache.jackrabbit.rmi.observation.ClientEventPoll} class for the
+ * actual registration and event dispatching.
+ * <p>
+ * This class does not require the
+ * {@link org.apache.jackrabbit.rmi.client.LocalAdapterFactory} and consequently
+ * calls the base class constructor with a <code>null</code> factory.
+ * <p>
+ * See the <a href="../observation/package.html><code>observation</code></a>
+ * package comment for a description on how event listener registration and
+ * notification is implemented.
+ *
+ * @author Felix Meschberger
+ *
+ * @see org.apache.jackrabbit.rmi.observation.ClientEventPoll
+ */
+public class ClientObservationManager extends ClientObject implements
+ ObservationManager {
+
+ /** The remote observation manager */
+ private final RemoteObservationManager remote;
+
+ /** The ClientEventPoll class internally used for event dispatching */
+ private ClientEventPoll poller;
+
+ /**
+ * Creates an instance of this class talking to the given remote observation
+ * manager.
+ *
+ * @param remote The {@link RemoteObservationManager} backing this
+ * client-side observation manager.
+ */
+ public ClientObservationManager(RemoteObservationManager remote) {
+ super(null);
+ this.remote = remote;
+ }
+
+ /** {@inheritDoc} */
+ public void addEventListener(EventListener listener, int eventTypes,
+ String absPath, boolean isDeep, String[] uuid,
+ String[] nodeTypeName, boolean noLocal)
+ throws RepositoryException {
+ try {
+ long listenerId = getClientEventPoll().addListener(listener);
+ remote.addEventListener(listenerId, eventTypes, absPath,
+ isDeep, uuid, nodeTypeName, noLocal);
+ } catch (RemoteException ex) {
+ throw new RemoteRepositoryException(ex);
+ }
+ }
+
+ /** {@inheritDoc} */
+ public void removeEventListener(EventListener listener)
+ throws RepositoryException {
+ try {
+ long id = getClientEventPoll().removeListener(listener);
+ remote.removeEventListener(id);
+ } catch (RemoteException ex) {
+ throw new RemoteRepositoryException(ex);
+ }
+ }
+
+ /** {@inheritDoc} */
+ public EventListenerIterator getRegisteredEventListeners() {
+ return new ArrayEventListenerIterator(poller.getListeners());
+ }
+
+ //---------- internal ------------------------------------------------------
+
+ /**
+ * Returns the {@link ClientEventPoll} instance used by this (client-side)
+ * observation manager. This method creates the instance on the first call
+ * and starts the poller thread to wait for remote events.
+ */
+ private synchronized ClientEventPoll getClientEventPoll() {
+ if (poller == null) {
+ poller = new ClientEventPoll(remote);
+ poller.start();
+ }
+ return poller;
+ }
+}
Propchange: incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/client/ClientObservationManager.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/client/ClientSession.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/client/ClientSession.java?rev=191722&r1=191721&r2=191722&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/client/ClientSession.java (original)
+++ incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/client/ClientSession.java Tue Jun 21 13:44:22 2005
@@ -64,6 +64,15 @@
/** The adapted remote session. */
private RemoteSession remote;
+
+ /**
+ * The adapted workspace of this session. This field is set on the first
+ * call to the {@link #getWorkspace()} method assuming, that a workspace
+ * instance is not changing during the lifetime of a session, that is,
+ * each call to the server-side <code>Session.getWorkspace()</code> allways
+ * returns the same object.
+ */
+ private Workspace workspace;
/**
* Creates a client adapter for the given remote session.
@@ -117,11 +126,16 @@
/** {@inheritDoc} */
public Workspace getWorkspace() {
- try {
- return getFactory().getWorkspace(this, remote.getWorkspace());
- } catch (RemoteException ex) {
- throw new RemoteRuntimeException(ex);
+ if (workspace == null) {
+ try {
+ workspace =
+ getFactory().getWorkspace(this, remote.getWorkspace());
+ } catch (RemoteException ex) {
+ throw new RemoteRuntimeException(ex);
+ }
}
+
+ return workspace;
}
/** {@inheritDoc} */
Modified: incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/client/ClientWorkspace.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/client/ClientWorkspace.java?rev=191722&r1=191721&r2=191722&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/client/ClientWorkspace.java (original)
+++ incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/client/ClientWorkspace.java Tue Jun 21 13:44:22 2005
@@ -57,6 +57,16 @@
private RemoteWorkspace remote;
/**
+ * The adapted observation manager of this workspace. This field is set on
+ * the first call to the {@link #getObservationManager()()} method assuming,
+ * that the observation manager instance is not changing during the lifetime
+ * of a workspace instance, that is, each call to the server-side
+ * <code>Workspace.getObservationManager()</code> allways returns the same
+ * object.
+ */
+ private ObservationManager observationManager;
+
+ /**
* Creates a client adapter for the given remote workspace.
*
* @param session current session
@@ -150,9 +160,17 @@
/** {@inheritDoc} */
public ObservationManager getObservationManager()
throws RepositoryException {
- // TODO Auto-generated method stub
- // return null;
- throw new UnsupportedRepositoryOperationException();
+ if (observationManager == null) {
+ try {
+ observationManager =
+ getFactory().
+ getObservationManager(remote.getObservationManager());
+ } catch (RemoteException ex) {
+ throw new RemoteRepositoryException(ex);
+ }
+ }
+
+ return observationManager;
}
/** {@inheritDoc} */
Modified: incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/client/LocalAdapterFactory.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/client/LocalAdapterFactory.java?rev=191722&r1=191721&r2=191722&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/client/LocalAdapterFactory.java (original)
+++ incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/client/LocalAdapterFactory.java Tue Jun 21 13:44:22 2005
@@ -24,11 +24,12 @@
import javax.jcr.Session;
import javax.jcr.Workspace;
import javax.jcr.lock.Lock;
-import javax.jcr.nodetype.NodeType;
-import javax.jcr.nodetype.NodeTypeManager;
import javax.jcr.nodetype.ItemDefinition;
import javax.jcr.nodetype.NodeDefinition;
+import javax.jcr.nodetype.NodeType;
+import javax.jcr.nodetype.NodeTypeManager;
import javax.jcr.nodetype.PropertyDefinition;
+import javax.jcr.observation.ObservationManager;
import javax.jcr.query.Query;
import javax.jcr.query.QueryManager;
import javax.jcr.query.QueryResult;
@@ -44,6 +45,7 @@
import org.apache.jackrabbit.rmi.remote.RemoteNodeDefinition;
import org.apache.jackrabbit.rmi.remote.RemoteNodeType;
import org.apache.jackrabbit.rmi.remote.RemoteNodeTypeManager;
+import org.apache.jackrabbit.rmi.remote.RemoteObservationManager;
import org.apache.jackrabbit.rmi.remote.RemoteProperty;
import org.apache.jackrabbit.rmi.remote.RemotePropertyDefinition;
import org.apache.jackrabbit.rmi.remote.RemoteQuery;
@@ -102,6 +104,15 @@
* @return local workspace adapter
*/
Workspace getWorkspace(Session session, RemoteWorkspace remote);
+
+ /**
+ * Factory method for creating a local adapter for a remote observation
+ * manager.
+ *
+ * @param remote remote observation manager
+ * @return local observation manager adapter
+ */
+ ObservationManager getObservationManager(RemoteObservationManager remote);
/**
* Factory method for creating a local adapter for a remote namespace
Added: incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/iterator/ArrayEventIterator.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/iterator/ArrayEventIterator.java?rev=191722&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/iterator/ArrayEventIterator.java (added)
+++ incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/iterator/ArrayEventIterator.java Tue Jun 21 13:44:22 2005
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.rmi.iterator;
+
+import javax.jcr.observation.Event;
+import javax.jcr.observation.EventIterator;
+
+/**
+ * Array implementation of the JCR
+ * {@link javax.jcr.EventIterator EventIterator} interface.
+ * This class is used by the JCR-RMI client adapters to convert
+ * node arrays to iterators.
+ *
+ * @author Felix Meschberger
+ */
+public class ArrayEventIterator extends ArrayIterator implements EventIterator {
+
+ /**
+ * Creates an iterator for the given array of events.
+ *
+ * @param nodes the nodes to iterate
+ */
+ public ArrayEventIterator(Event[] nodes) {
+ super(nodes);
+ }
+
+ /** {@inheritDoc} */
+ public Event nextEvent() {
+ return (Event) next();
+ }
+
+}
Propchange: incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/iterator/ArrayEventIterator.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/iterator/ArrayEventListenerIterator.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/iterator/ArrayEventListenerIterator.java?rev=191722&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/iterator/ArrayEventListenerIterator.java (added)
+++ incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/iterator/ArrayEventListenerIterator.java Tue Jun 21 13:44:22 2005
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.rmi.iterator;
+
+import javax.jcr.observation.Event;
+import javax.jcr.observation.EventIterator;
+import javax.jcr.observation.EventListener;
+import javax.jcr.observation.EventListenerIterator;
+
+/**
+ * Array implementation of the JCR
+ * {@link javax.jcr.EventListenerIterator EventListenerIterator} interface.
+ * This class is used by the JCR-RMI client adapters to convert
+ * listener arrays to iterators.
+ *
+ * @author Felix Meschberger
+ */
+public class ArrayEventListenerIterator extends ArrayIterator
+ implements EventListenerIterator {
+
+ /**
+ * Creates an iterator for the given array of listeners.
+ *
+ * @param listeners the listeners to iterate
+ */
+ public ArrayEventListenerIterator(EventListener[] listeners) {
+ super(listeners);
+ }
+
+ /** {@inheritDoc} */
+ public EventListener nextEventListener() {
+ return (EventListener) next();
+ }
+
+}
Propchange: incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/iterator/ArrayEventListenerIterator.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/observation/ClientEventPoll.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/observation/ClientEventPoll.java?rev=191722&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/observation/ClientEventPoll.java (added)
+++ incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/observation/ClientEventPoll.java Tue Jun 21 13:44:22 2005
@@ -0,0 +1,279 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.rmi.observation;
+
+import java.rmi.RemoteException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.jcr.observation.Event;
+import javax.jcr.observation.EventIterator;
+import javax.jcr.observation.EventListener;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jackrabbit.rmi.iterator.ArrayEventIterator;
+import org.apache.jackrabbit.rmi.remote.RemoteEventCollection;
+import org.apache.jackrabbit.rmi.remote.RemoteObservationManager;
+
+/**
+ * The <code>ClientEventPoll</code> class is the registry for client-side
+ * event listeners on behalf of the
+ * {@link org.apache.jackrabbit.rmi.client.ClientObservationManager} class. In
+ * addition this class extends the <code>java.lang.Thread</code> class able
+ * to be run in a separate thread to constantly poll the server-side observation
+ * manager for new events.
+ * <p>
+ * Notes:
+ * <ol>
+ * <li>Only one instance of this class should be instantiated for each instance
+ * of a {@link org.apache.jackrabbit.rmi.remote.RemoteObservationManager} class.
+ * <li><code>EventListener</code>s registered with this class must properly
+ * implement the <code>Object.hashCode()</code> and <code>Object.equals()</code>
+ * contracts for them to be handled correctly by this class.
+ * </ol>
+ *
+ * @author Felix Meschberger
+ * @see #run()
+ */
+public class ClientEventPoll extends Thread {
+
+ /** logger */
+ private static final Log log = LogFactory.getLog(ClientEventPoll.class);
+
+ /**
+ * The time in milliseconds the {@link #run()} method should be waiting
+ * for remote events.
+ * @see #run()
+ */
+ private static final long POLL_TIMEOUT = 5000;
+
+ /** The thread name */
+ private static final String THREAD_NAME = "Client Event Poller";
+
+ /** The primitive unique identifier generator. */
+ private static long counter = 0;
+
+ /** The {@link RemoteObservationManager} called for the new events. */
+ private final RemoteObservationManager remote;
+
+ /** The map of locally registered listeners indexed by the unique identifier */
+ private Map listenerMap = new HashMap();
+
+ /** The map of unique identifieres indexed by the registered listeners */
+ private Map idMap = new HashMap();
+
+ /**
+ * Flag indicating whether the {@link #run()} method should terminate.
+ * @see #run()
+ */
+ private boolean running = true;
+
+ /**
+ * Creates an instance of this class talking to the given
+ * {@link RemoteObservationManager}.
+ *
+ * @param remote The remote observation manager which is asked for new
+ * events. This must not be <code>null</code>.
+ *
+ * @throws NullPointerException if <code>remote</code> is <code>null</code>.
+ */
+ public ClientEventPoll(RemoteObservationManager remote) {
+ super(THREAD_NAME);
+
+ // check remote and assign
+ if (remote == null) {
+ throw new NullPointerException("remote");
+ }
+ this.remote = remote;
+ }
+
+ /**
+ * Registers the given local listener with this instance and returns the
+ * unique identifier assigned to it.
+ *
+ * @param listener The <code>EventListener</code> to register.
+ *
+ * @return The unique identifier assigned to the newly registered event
+ * listener.
+ */
+ public synchronized long addListener(EventListener listener) {
+ Long id = new Long(counter++);
+ listenerMap.put(id, listener);
+ idMap.put(listener, id);
+ return id.longValue();
+ }
+
+ /**
+ * Unregisters the given local listener from this instance and returns the
+ * unique identifier assigned to it.
+ *
+ * @param listener The <code>EventListener</code> to unregister.
+ *
+ * @return The unique identifier assigned to the unregistered event listener
+ * or <code>-1</code> if the listener was not registered.
+ */
+ public synchronized long removeListener(EventListener listener) {
+ Long key = (Long) idMap.remove(listener);
+ if (key != null) {
+ listenerMap.remove(key);
+ return key.longValue();
+ }
+
+ return -1;
+ }
+
+ /**
+ * Returns an array of the registered event listeners.
+ */
+ public synchronized EventListener[] getListeners() {
+ return (EventListener[]) listenerMap.values().toArray(
+ new EventListener[(listenerMap.size())]);
+ }
+
+ /**
+ * Indicates to the {@link #run()} method, that asking for events should
+ * be terminated.
+ *
+ * @see #run()
+ */
+ public void terminate() {
+ this.running = false;
+ }
+
+ //---------- Thread overwrite ---------------------------------------------
+
+ /**
+ * Checks for remote events and dispatches them to the locally registered
+ * event listeners. This is how this method works:
+ * <ol>
+ * <li>Continue with next step if {@link #terminate()} has not been called
+ * yet.
+ * <li>Call the {@link RemoteObservationManager#getNextEvent(long)} method
+ * waiting for a specified time (5 seconds).
+ * <li>If no event was received in the specified time go back to step #1.
+ * <li>Extract the unique listener identifier from the remote event and
+ * find it in the list of locally registered event listeners. Go back to
+ * step #1 if no such listener exists.
+ * <li>Convert the remote event list to an <code>EventIterator</code> and
+ * call the <code>EventListener.onEvent()</code> method.
+ * <li>Go back to step #1.
+ * </ol>
+ */
+ public void run() {
+ while (running) {
+ try {
+ // ask for an event waiting at most POLL_TIMEOUT milliseconds
+ RemoteEventCollection remoteEvent = remote.getNextEvent(POLL_TIMEOUT);
+
+ // poll time out, check running and ask again
+ if (remoteEvent == null) {
+ continue;
+ }
+
+ // extract the listener id from the remote event and find
+ // the locally registered event listener
+ Long id = new Long(remoteEvent.getListenerId());
+ EventListener listener = (EventListener) listenerMap.get(id);
+
+ // if the listener is not registered (anymore), the event is
+ // silently ignored, running is checked and the server asked again
+ if (listener == null) {
+ continue;
+ }
+
+ // otherwise convert the remote events into an EventIterator
+ // and the listener is called
+ RemoteEventCollection.RemoteEvent[] remoteEvents = remoteEvent.getEvents();
+ EventIterator events = toEvents(remoteEvents);
+ try {
+ listener.onEvent(events);
+ } catch (Exception e) {
+ log.error("Unexpected failure of Listener " + listener, e);
+ }
+
+ } catch (RemoteException re) {
+ log.error("Problem handling event. Looking for next one.", re);
+ }
+ }
+ }
+
+ //---------- internal -----------------------------------------------------
+
+ /**
+ * Converts an array of {@link RemoteEventCollection.RemoteEvent} instances to an
+ * instance of <code>EventIterator</code> suitable to be sent to the
+ * event listener.
+ */
+ private EventIterator toEvents(RemoteEventCollection.RemoteEvent[] remoteEvents)
+ throws RemoteException {
+ Event[] events = new Event[remoteEvents.length];
+ for (int i=0; i < events.length; i++) {
+ events[i] = new JCREvent(remoteEvents[i]);
+ }
+ return new ArrayEventIterator(events);
+ }
+
+ /**
+ * The <code>JCREvent</code> class is a simple implementation of the JCR
+ * <code>Event</code> interface to be sent to the locally registered
+ * event listeners.
+ *
+ * @author Felix Meschberger
+ */
+ private static class JCREvent implements Event {
+
+ /** The event type */
+ private final int type;
+
+ /** The path of the repository item underlying the event */
+ private final String path;
+
+ /** The user id of the session originating the event */
+ private final String userID;
+
+ /**
+ * Creates an instance of this class from the contents of the given
+ * <code>remoteEvent</code>.
+ *
+ * @param remoteEvent The {@link RemoteEventCollection.RemoteEvent} instance
+ * providing the data for this event.
+ *
+ * @throws RemoteException if an RMI error occurrs.
+ */
+ private JCREvent(RemoteEventCollection.RemoteEvent remoteEvent) throws RemoteException {
+ type = remoteEvent.getType();
+ path = remoteEvent.getPath();
+ userID = remoteEvent.getUserID();
+ }
+
+ /** @inheritDoc */
+ public int getType() {
+ return type;
+ }
+
+ /** @inheritDoc */
+ public String getPath() {
+ return path;
+ }
+
+ /** @inheritDoc */
+ public String getUserID() {
+ return userID;
+ }
+ }
+}
Propchange: incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/observation/ClientEventPoll.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/observation/Queue.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/observation/Queue.java?rev=191722&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/observation/Queue.java (added)
+++ incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/observation/Queue.java Tue Jun 21 13:44:22 2005
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.rmi.observation;
+
+import java.util.LinkedList;
+
+/**
+ * The <code>Queue</code> class is a very simple queue assuming that there is
+ * at least one consumer and potentially multiple producers. This class poses
+ * no restrictions on the size of the queue.
+ *
+ * @author Felix Meschberger
+ */
+public class Queue {
+
+ /** The linked list implementing the queue of data */
+ private final LinkedList queue;
+
+ /**
+ * Creates an instance of this queue.
+ */
+ public Queue() {
+ queue = new LinkedList();
+ }
+
+ /**
+ * Appends the given <code>object</code> to the end of the queue.
+ * <p>
+ * After appending the element, the queue is notified such that threads
+ * waiting to retrieve an element from the queue are woken up.
+ */
+ public void put(Object object) {
+ synchronized (queue) {
+ queue.addLast(object);
+ queue.notifyAll();
+ }
+ }
+
+ /**
+ * Returns the first element from the queue. If the queue is currently empty
+ * the method waits at most the given number of milliseconds.
+ *
+ * @param timeout The maximum number of milliseconds to wait for an entry in
+ * the queue if the queue is empty. If zero, the method waits forever
+ * for an element.
+ *
+ * @return The first element of the queue or <code>null</code> if the method
+ * timed out waiting for an entry.
+ *
+ * @throws InterruptedException Is thrown if the current thread is
+ * interrupted while waiting for the queue to get at least one entry.
+ */
+ public Object get(long timeout) throws InterruptedException {
+ synchronized (queue) {
+ // wait for data if the queue is empty
+ if (queue.isEmpty()) {
+ queue.wait(timeout);
+ }
+
+ // return null if queue is (still) empty
+ if (queue.isEmpty()) {
+ return null;
+ }
+
+ // return first if queue has content now
+ return queue.removeFirst();
+ }
+ }
+}
Propchange: incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/observation/Queue.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/observation/ServerEventListenerProxy.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/observation/ServerEventListenerProxy.java?rev=191722&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/observation/ServerEventListenerProxy.java (added)
+++ incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/observation/ServerEventListenerProxy.java Tue Jun 21 13:44:22 2005
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.rmi.observation;
+
+import java.rmi.RemoteException;
+
+import javax.jcr.observation.EventIterator;
+import javax.jcr.observation.EventListener;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jackrabbit.rmi.remote.RemoteEventCollection;
+import org.apache.jackrabbit.rmi.server.RemoteAdapterFactory;
+
+/**
+ * The <code>ServerEventListenerProxy</code> class is the server-side event
+ * listener proxy registered on behalf of a client-side event listener identified
+ * with the unique identifier.
+ * <p>
+ * The term <i>Server</i> in this class indicates, that this is a server-side
+ * class. In contrast to the classes in the
+ * {@link org.apache.jackrabbit.rmi.server} package, this class neither extends
+ * the {@link org.apache.jackrabbit.rmi.server.ServerObject} class nor does it
+ * implement any of the remote interfaces in the
+ * {@link org.apache.jackrabbit.rmi.remote} package because it only is
+ * instantiated to be used on the server side.
+ * <p>
+ * See the package overview for an explanation of the mechanisms implemented for
+ * event dispatching.
+ *
+ * @author Felix Meschberger
+ */
+public class ServerEventListenerProxy implements EventListener {
+
+ /** logger */
+ private static final Log log =
+ LogFactory.getLog(ServerEventListenerProxy.class);
+
+ /** The factory used to convert event iterators to remote events */
+ private final RemoteAdapterFactory factory;
+
+ /**
+ * The unique indentifier of the client-side event listener on whose
+ * behalf this listener proxy is registered.
+ */
+ private final long listenerId;
+
+ /**
+ * The queue to which remote events are queue for them to be picked up
+ * by calls to the
+ * {@link org.apache.jackrabbit.rmi.remote.RemoteObservationManager#getNextEvent(long)}
+ * method.
+ */
+ private final Queue queue;
+
+ /**
+ * Creates a new instance of this listener proxy.
+ *
+ * @param factory The {@link RemoteAdapterFactory} used to convert the
+ * {@link EventIterator} instances to {@link RemoteEventCollection} objects.
+ * @param listenerId The unique identifier of the client-side event listener
+ * on whose behalf this proxy works.
+ * @param queue The sink to which events to be dispatched to the client are
+ * queued to be picked up.
+ */
+ public ServerEventListenerProxy(RemoteAdapterFactory factory,
+ long listenerId, Queue queue) {
+ this.factory = factory;
+ this.listenerId = listenerId;
+ this.queue = queue;
+ }
+
+ /**
+ * Converts the {@link javax.jcr.observation.Event} instances in the given
+ * iterator to an instance of {@link RemoteEventCollection} for them to be dispatched
+ * to the client-side event listener.
+ *
+ * @param events The {@link javax.jcr.observation.Event Events} to be
+ * dispatched.
+ */
+ public void onEvent(EventIterator events) {
+ try {
+ RemoteEventCollection remoteEvent = factory.getRemoteEvent(listenerId, events);
+ queue.put(remoteEvent);
+ } catch (RemoteException re) {
+ Throwable t = (re.getCause() == null) ? re : re.getCause();
+ log.error("Problem creating remote event for " + listenerId, t);
+ }
+ }
+
+ //---------- Object overwrite ----------------------------------------------
+
+ /**
+ * Returns the client-side listener identifier as its hash code.
+ */
+ public int hashCode() {
+ return (int) listenerId;
+ }
+
+ /**
+ * Returns <code>true</code> if <code>obj</code> is either the same as this
+ * or a proxy for the same client-side listener, which is identicated by the
+ * same listener identifier.
+ *
+ * @param obj The object to compare to.
+ *
+ * @return <code>true</code> if <code>obj</code> is the same or a proxy for
+ * the same client-side listener.
+ */
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ } else if (obj instanceof ServerEventListenerProxy) {
+ return listenerId == ((ServerEventListenerProxy) obj).listenerId;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Returns the a string representation of this instance, which is an
+ * indication of this class's name and the unique identifier of the real
+ * event listener.
+ */
+ public String toString() {
+ return "EventListenerProxy: listenerId=" + listenerId;
+ }
+}
Propchange: incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/observation/ServerEventListenerProxy.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/observation/package.html
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/observation/package.html?rev=191722&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/observation/package.html (added)
+++ incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/observation/package.html Tue Jun 21 13:44:22 2005
@@ -0,0 +1,67 @@
+<body>
+
+<p>
+Helper class used by the observation manager classes.
+</p>
+
+<p>
+The JCR observation framework defines a notification mechanism where an
+<code>EventListener</code> is registered with the observation manager
+to receive certain events during the lifetime of the registration. For
+the remote case, where the repository and the application run in different
+Java VMs on possibly different hosts, there are issues related to the
+observation framework.
+
+<p>
+The listener mechanism is a call-back mechanism where the server calls
+code in the client application. The client application code most probably
+hooks into other parts of that application. Therefore it is not practically
+feasible to just require the client listener to be serializable to be sent
+to the server for several reasons:
+
+<ul>
+<li>The RMI server cannot call any method on the RMI client. To support such
+call-back situations, the client side application would have to register
+another server, which the server side would have to call.
+<li>When trying to "transfer" the listener to the server side, the listener
+class would have to be available to the server side - either locally in the
+class path or through RMI class loading mechanisms.
+<ul>
+
+<p>
+To circumvent these issues and still be able to register event listeners,
+support for observation events is implemented in a manner similar to the Java
+Management Extensions Remote API 1.0 (JSR 160) as laid out in Chapter 2.4,
+Adding Remote Listeners:
+
+<p>
+The ObservationManager interface is not implemented in the RMI layer like
+other interfaces, which just forward calls to the API to the corresponding
+remote object by means of the RMI framework. Instead the client-side
+ObservationManager manages its own list of registered event listeners. Each
+listener registered with an ObservationManager is assigned a unique
+identifier.
+
+<p>
+The unique identifier along with the filter configuration (event type,
+path, depth flag, uuid list, node type list, local flag) is sent to the
+server-side remote observation manager. This latter instantiates a proxy
+event listener representing the client side event listener contains the
+unique identifier as a ilnk to the client side event listener. The proxy
+event listener is the registered to the repository's ObservationManager
+with the configuration received from the client side.
+
+<p>
+When an event arrives at the event listener proxy, the proxy creates a
+new RemoteEvent instance, which contains the client-side event listener
+identifier along with the Event objects from the EventIterator. This
+RemoteEvent instance is added to a server-side queue, which may be
+retrieved from the client-side.
+
+<p>
+The client-side ObservationManager has a helper class ClientEventPoll,
+which works in the background asking the server for the RemoteEvents from
+the event queue. Each such event is then dispatched to the client-side
+event listener by calling the EventListener.onEvent() method.
+
+</body
\ No newline at end of file
Propchange: incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/observation/package.html
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/remote/RemoteEventCollection.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/remote/RemoteEventCollection.java?rev=191722&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/remote/RemoteEventCollection.java (added)
+++ incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/remote/RemoteEventCollection.java Tue Jun 21 13:44:22 2005
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.rmi.remote;
+
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+
+import javax.jcr.observation.Event;
+
+/**
+ * The <code>RemoteEventCollection</code> class serves as a container for
+ * notifications sent to registered event listeners. Instances of this class are
+ * created by the server-side event listener proxies and sent to the client-side
+ * event poller. On the client-side the enclosed list of events is then sent to
+ * the listener identified by the contained listener identifier.
+ *
+ * @author Felix Meschberger
+ */
+public interface RemoteEventCollection extends Remote {
+
+ /**
+ * Returns unique identifier of the client-side listener to which the
+ * enclosed events should be sent.
+ * @throws RemoteException on RMI errors
+ */
+ long getListenerId() throws RemoteException;
+
+ /**
+ * Returns the list of events to be sent to the client-side listener
+ * identified by {@link #getListenerId()}.
+ * @throws RemoteException on RMI errors
+ */
+ RemoteEvent[] getEvents() throws RemoteException;
+
+ /**
+ * The <code>RemoteEvent</code> class provides an encapsulation of single
+ * events in an event list sent to a registered listener.
+ */
+ public static interface RemoteEvent extends Remote {
+ /**
+ * Returns the event type.
+ * @throws RemoteException on RMI errors
+ */
+ int getType() throws RemoteException;
+
+ /**
+ * Returns the absolute path of the underlying item.
+ * @throws RemoteException on RMI errors
+ */
+ String getPath() throws RemoteException;
+
+ /**
+ * Returns the userID of the session causing this event.
+ * @throws RemoteException on RMI errors
+ */
+ String getUserID() throws RemoteException;
+ }
+
+}
Propchange: incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/remote/RemoteEventCollection.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/remote/RemoteObservationManager.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/remote/RemoteObservationManager.java?rev=191722&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/remote/RemoteObservationManager.java (added)
+++ incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/remote/RemoteObservationManager.java Tue Jun 21 13:44:22 2005
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.rmi.remote;
+
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.observation.EventListener;
+import javax.jcr.observation.EventListenerIterator;
+
+import org.apache.jackrabbit.rmi.client.RemoteRepositoryException;
+
+/**
+ * Remote version of the JCR {@link javax.jcr.observation.ObservationManager ObservationManager}
+ * interface. Used by the
+ * {@link org.apache.jackrabbit.rmi.server.ServerObservationManager ServerObservationManager}
+ * and
+ * {@link org.apache.jackrabbit.rmi.client.ClientObservationManager ClientObservationManager}
+ * adapter base classes to provide transparent RMI access to remote observation
+ * managers.
+ * <p>
+ * See the <a href="../observation/package.html><code>observation</code></a>
+ * package comment for a description on how event listener registration and
+ * notification is implemented.
+ *
+ * @author Felix Meschberger
+ *
+ * @see javax.jcr.observation.ObservationManager
+ * @see org.apache.jackrabbit.rmi.client.ClientObservationManager
+ * @see org.apache.jackrabbit.rmi.server.ServerObservationManager
+ */
+public interface RemoteObservationManager extends Remote {
+
+ /**
+ * Remote version of the
+ * {@link javax.jcr.observation.ObservationManager#addEventListener(javax.jcr.observation.EventListener, int, java.lang.String, boolean, java.lang.String[], java.lang.String[], boolean) ObservationManager.addEventListener()}
+ * method. See class comment for an explanation on how the
+ * <code>listenerId</code> is used.
+ *
+ * @param listenerId The identification of the listener on the client
+ * side to which events will be directed.
+ * @param eventTypes The mask of event types to be sent to this listener.
+ * @param absPath The root item defining a subtree for which events are to
+ * be delivered.
+ * @param isDeep <code>true</code> if the events from the complete subtree
+ * rooted at <code>absPath</code> are to be sent or only for the item
+ * at the given path.
+ * @param uuid An optional list of node UUIDs for which events are to be
+ * sent. If <code>null</code> this parameter is ignored.
+ * @param nodeTypeName An optional list of node type names for which events
+ * are to be sent. If <code>null</code> this parameter is ignored.
+ * @param noLocal <code>true</code> if only events are to be sent which do
+ * not originate from the session to which this instance belongs.
+ *
+ * @throws RepositoryException on repository errors
+ * @throws RemoteException on RMI errors
+ */
+ public void addEventListener(long listenerId, int eventTypes,
+ String absPath, boolean isDeep, String[] uuid,
+ String[] nodeTypeName, boolean noLocal)
+ throws RepositoryException, RemoteException;
+
+ /**
+ * Remote version of the
+ * {@link javax.jcr.observation.ObservationManager#removeEventListener(javax.jcr.observation.EventListener) ObservationManager.removeEventListener()}
+ * method. See class comment for an explanation on how the
+ * <code>listenerId</code> is used.
+ *
+ * @param listenerId The identification of the listener on the client
+ * side to which events will be directed.
+ *
+ * @throws RepositoryException on repository errors
+ * @throws RemoteException on RMI errors
+ */
+ public void removeEventListener(long listenerId)
+ throws RepositoryException, RemoteException;
+
+ /**
+ * Returns the next event to be dispatched to registered event listeners. If
+ * no event is available, this method blocks until one is available or until
+ * the given timeout expires.
+ *
+ * @param timeout The time in milliseconds to wait for the next event
+ * available to be dispatched. If negative or zero, this method waits
+ * for ever.
+ *
+ * @return The {@link RemoteEventCollection} to be dispatched. <code>null</code> is
+ * returned if the method timed out waiting for an event to be
+ * dispatched.
+ *
+ * @throws RemoteException on RMI errors
+ */
+ public RemoteEventCollection getNextEvent(long timeout)
+ throws RemoteException;
+}
Propchange: incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/remote/RemoteObservationManager.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/remote/RemoteWorkspace.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/remote/RemoteWorkspace.java?rev=191722&r1=191721&r2=191722&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/remote/RemoteWorkspace.java (original)
+++ incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/remote/RemoteWorkspace.java Tue Jun 21 13:44:22 2005
@@ -147,6 +147,18 @@
/**
* Remote version of the
+ * {@link javax.jcr.Workspace#getObservationManager() Workspace.getObservationManager()}
+ * method.
+ *
+ * @return observation manager
+ * @throws RepositoryException on repository errors
+ * @throws RemoteException on RMI errors
+ */
+ RemoteObservationManager getObservationManager()
+ throws RepositoryException, RemoteException;
+
+ /**
+ * Remote version of the
* {@link javax.jcr.Workspace#getAccessibleWorkspaceNames() Workspace.getAccessibleWorkspaceNames()}
* method.
*
Modified: incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/server/RemoteAdapterFactory.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/server/RemoteAdapterFactory.java?rev=191722&r1=191721&r2=191722&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/server/RemoteAdapterFactory.java (original)
+++ incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/server/RemoteAdapterFactory.java Tue Jun 21 13:44:22 2005
@@ -31,6 +31,8 @@
import javax.jcr.nodetype.NodeDefinition;
import javax.jcr.nodetype.PropertyDefinition;
import javax.jcr.nodetype.ItemDefinition;
+import javax.jcr.observation.EventIterator;
+import javax.jcr.observation.ObservationManager;
import javax.jcr.query.Query;
import javax.jcr.query.QueryManager;
import javax.jcr.query.QueryResult;
@@ -38,6 +40,7 @@
import javax.jcr.version.Version;
import javax.jcr.version.VersionHistory;
+import org.apache.jackrabbit.rmi.remote.RemoteEventCollection;
import org.apache.jackrabbit.rmi.remote.RemoteItem;
import org.apache.jackrabbit.rmi.remote.RemoteItemDefinition;
import org.apache.jackrabbit.rmi.remote.RemoteLock;
@@ -46,6 +49,7 @@
import org.apache.jackrabbit.rmi.remote.RemoteNodeDefinition;
import org.apache.jackrabbit.rmi.remote.RemoteNodeType;
import org.apache.jackrabbit.rmi.remote.RemoteNodeTypeManager;
+import org.apache.jackrabbit.rmi.remote.RemoteObservationManager;
import org.apache.jackrabbit.rmi.remote.RemoteProperty;
import org.apache.jackrabbit.rmi.remote.RemotePropertyDefinition;
import org.apache.jackrabbit.rmi.remote.RemoteQuery;
@@ -108,6 +112,17 @@
throws RemoteException;
/**
+ * Returns a remote adapter for the given local observation manager.
+ *
+ * @param observationManager local observation manager
+ * @return remote observation manager adapter
+ * @throws RemoteException on RMI errors
+ */
+ RemoteObservationManager getRemoteObservationManager(
+ ObservationManager observationManager)
+ throws RemoteException;
+
+ /**
* Returns a remote adapter for the given local namespace registry.
*
* @param registry local namespace registry
@@ -268,4 +283,15 @@
*/
RemoteRow getRemoteRow(Row row) throws RemoteException;
+ /**
+ * Returns a remote adapter for the given local events.
+ *
+ * @param listenerId The listener identifier to which the events are to be
+ * dispatched.
+ * @param event the local events
+ * @return remote event iterator adapter
+ * @throws RemoteException on RMI errors
+ */
+ RemoteEventCollection getRemoteEvent(long listenerId, EventIterator events)
+ throws RemoteException;
}
Modified: incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/server/ServerAdapterFactory.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/server/ServerAdapterFactory.java?rev=191722&r1=191721&r2=191722&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/server/ServerAdapterFactory.java (original)
+++ incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/server/ServerAdapterFactory.java Tue Jun 21 13:44:22 2005
@@ -17,20 +17,26 @@
package org.apache.jackrabbit.rmi.server;
import java.rmi.RemoteException;
+import java.util.ArrayList;
+import java.util.List;
import javax.jcr.Item;
import javax.jcr.NamespaceRegistry;
import javax.jcr.Node;
import javax.jcr.Property;
import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.Workspace;
import javax.jcr.lock.Lock;
-import javax.jcr.nodetype.NodeType;
-import javax.jcr.nodetype.NodeTypeManager;
import javax.jcr.nodetype.ItemDefinition;
import javax.jcr.nodetype.NodeDefinition;
+import javax.jcr.nodetype.NodeType;
+import javax.jcr.nodetype.NodeTypeManager;
import javax.jcr.nodetype.PropertyDefinition;
+import javax.jcr.observation.Event;
+import javax.jcr.observation.EventIterator;
+import javax.jcr.observation.ObservationManager;
import javax.jcr.query.Query;
import javax.jcr.query.QueryManager;
import javax.jcr.query.QueryResult;
@@ -38,6 +44,7 @@
import javax.jcr.version.Version;
import javax.jcr.version.VersionHistory;
+import org.apache.jackrabbit.rmi.remote.RemoteEventCollection;
import org.apache.jackrabbit.rmi.remote.RemoteItem;
import org.apache.jackrabbit.rmi.remote.RemoteItemDefinition;
import org.apache.jackrabbit.rmi.remote.RemoteLock;
@@ -46,6 +53,7 @@
import org.apache.jackrabbit.rmi.remote.RemoteNodeDefinition;
import org.apache.jackrabbit.rmi.remote.RemoteNodeType;
import org.apache.jackrabbit.rmi.remote.RemoteNodeTypeManager;
+import org.apache.jackrabbit.rmi.remote.RemoteObservationManager;
import org.apache.jackrabbit.rmi.remote.RemoteProperty;
import org.apache.jackrabbit.rmi.remote.RemotePropertyDefinition;
import org.apache.jackrabbit.rmi.remote.RemoteQuery;
@@ -98,6 +106,16 @@
}
/**
+ * Creates a {@link ServerObservationManager ServerObservationManager}
+ * instance.
+ * {@inheritDoc}
+ */
+ public RemoteObservationManager getRemoteObservationManager(
+ ObservationManager observationManager) throws RemoteException {
+ return new ServerObservationManager(observationManager, this);
+ }
+
+ /**
* Creates a {@link ServerNamespaceRegistry ServerNamespaceRegistry}
* instance.
* {@inheritDoc}
@@ -238,4 +256,31 @@
return new ServerRow(row, this);
}
+ /**
+ * Creates a {@link ServerEventCollection ServerEventCollection} instances.
+ * {@inheritDoc}
+ */
+ public RemoteEventCollection getRemoteEvent(long listenerId, EventIterator events)
+ throws RemoteException {
+ RemoteEventCollection.RemoteEvent[] remoteEvents;
+ if (events != null) {
+ List eventList = new ArrayList();
+ for (int i=0; events.hasNext(); i++) {
+ Event event = events.nextEvent();
+ try {
+ eventList.add(new ServerEventCollection.ServerEvent(event.getType(),
+ event.getPath(), event.getUserID()));
+ } catch (RepositoryException re) {
+ throw new RemoteException(re.getMessage(), re);
+ }
+ }
+ remoteEvents = new RemoteEventCollection.RemoteEvent[eventList.size()];
+ eventList.toArray(remoteEvents);
+
+ } else {
+ remoteEvents = new RemoteEventCollection.RemoteEvent[0]; // for safety
+ }
+
+ return new ServerEventCollection(listenerId, remoteEvents);
+ }
}
Added: incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/server/ServerEventCollection.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/server/ServerEventCollection.java?rev=191722&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/server/ServerEventCollection.java (added)
+++ incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/server/ServerEventCollection.java Tue Jun 21 13:44:22 2005
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.rmi.server;
+
+import java.rmi.RemoteException;
+
+import org.apache.jackrabbit.rmi.remote.RemoteEventCollection;
+import org.apache.jackrabbit.rmi.remote.RemoteEventCollection.RemoteEvent;
+
+/**
+ * The <code>ServerEventCollection</code> class implemnts the
+ * {@link org.apache.jackrabbit.rmi.remote.RemoteEventCollection}event to
+ * actually sent the server-side event to the client.
+ * <p>
+ * This class does not directly relate to any JCR class because beside the list
+ * of events the unique identifier of the client-side listener has to be
+ * provided such that the receiving listener may be identified on the
+ * client-side.
+ * <p>
+ * This class does not require the
+ * {@link org.apache.jackrabbit.rmi.server.RemoteAdapterFactory}and
+ * consequently calls the base class constructor with a <code>null</code>
+ * factory.
+ *
+ * @author Felix Meschberger
+ */
+public class ServerEventCollection extends ServerObject implements
+ RemoteEventCollection {
+
+ /** The unique identifier of the receiving listener */
+ private final long listenerId;
+
+ /**
+ * The list of
+ * {@link org.apache.jackrabbit.rmi.remote.RemoteEventCollection.RemoteEvent}.
+ */
+ private final RemoteEvent[] events;
+
+ /**
+ * Creates an instance of this class.
+ *
+ * @param listenerId The unique identifier of the client-side listener to
+ * which the events should be sent.
+ * @param events The list of {@link RemoteEvent remote events}.
+ *
+ * @throws RemoteException on RMI errors
+ */
+ ServerEventCollection(long listenerId, RemoteEvent[] events)
+ throws RemoteException {
+ super(null);
+
+ this.listenerId = listenerId;
+ this.events = events;
+ }
+
+ /** {@inheritDoc} */
+ public long getListenerId() {
+ return listenerId;
+ }
+
+ /** {@inheritDoc} */
+ public RemoteEvent[] getEvents() {
+ return events;
+ }
+
+ /**
+ * Server side implementation of the {@link RemoteEvent} interface.
+ *
+ * {@inheritDoc}
+ */
+ public static class ServerEvent extends ServerObject implements RemoteEvent {
+
+ private final int type;
+ private final String path;
+ private final String userID;
+
+ /**
+ * Creates an instance of this class.
+ * @param type The event type.
+ * @param path The absolute path to the underlying item.
+ * @param userId The userID of the originating session.
+ *
+ * @throws RemoteException declared because of the declaration in the
+ * base class constructor called. In fact this exception is never
+ * thrown.
+ */
+ ServerEvent(int type, String path, String userId) throws RemoteException {
+ super(null);
+ this.type = type;
+ this.path = path;
+ this.userID = userId;
+ }
+
+ /** {@inheritDoc} */
+ public String getPath() {
+ return path;
+ }
+
+ /** {@inheritDoc} */
+ public int getType() {
+ return type;
+ }
+
+ /** {@inheritDoc} */
+ public String getUserID() {
+ return userID;
+ }
+ }
+}
Propchange: incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/server/ServerEventCollection.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/server/ServerObservationManager.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/server/ServerObservationManager.java?rev=191722&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/server/ServerObservationManager.java (added)
+++ incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/server/ServerObservationManager.java Tue Jun 21 13:44:22 2005
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.rmi.server;
+
+import java.rmi.RemoteException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.observation.ObservationManager;
+
+import org.apache.jackrabbit.rmi.observation.Queue;
+import org.apache.jackrabbit.rmi.observation.ServerEventListenerProxy;
+import org.apache.jackrabbit.rmi.remote.RemoteEventCollection;
+import org.apache.jackrabbit.rmi.remote.RemoteObservationManager;
+
+/**
+ * The <code>ServerObservationManager</code> class
+ *
+ * @author Felix Meschberger
+ */
+/**
+ * Remote adapter for the JCR
+ * {@link javax.jcr.observation.ObservationManager ObservationManager} interface.
+ * This class makes a local item available as an RMI service using
+ * the {@link org.apache.jackrabbit.rmi.remote.RemoteObservationManager RemoteObservationManager}
+ * interface.
+ * <p>
+ * This class works in conjunction with the
+ * {@link org.apache.jackrabbit.rmi.client.ClientObservationManager} class to
+ * implement the distributed the event listener registration described in
+ * <a href="../observation/package.html><code>observation</code></a> package
+ * comment.
+ *
+ * @author Felix Meschberger
+ * @see javax.jcr.observation.ObservationManager
+ * @see org.apache.jackrabbit.rmi.remote.RemoteObservationManager
+ */
+public class ServerObservationManager extends ServerObject implements
+ RemoteObservationManager {
+
+ /** The adapted local observation manager. */
+ private ObservationManager observationManager;
+
+ /**
+ * The map of event listener proxies indexed by the unique identifier.
+ */
+ private Map proxyMap;
+
+ /**
+ * The queue to which event listener proxies post events to be reported
+ * by the {@link #getNextEvent(long)} method.
+ */
+ private Queue queue;
+
+ /**
+ * Creates a remote adapter for the given local workspace.
+ *
+ * @param observationManager local observation manager
+ * @param factory remote adapter factory
+ * @throws RemoteException on RMI errors
+ */
+ public ServerObservationManager(ObservationManager observationManager,
+ RemoteAdapterFactory factory)
+ throws RemoteException {
+ super(factory);
+ this.observationManager = observationManager;
+ }
+
+ /** {@inheritDoc} */
+ public void addEventListener(long listenerId, int eventTypes,
+ String absPath, boolean isDeep, String[] uuid, String[] nodeTypeName,
+ boolean noLocal) throws RepositoryException, RemoteException {
+
+ // find the proxy or create one
+ ServerEventListenerProxy proxy;
+ synchronized (this) {
+ if (proxyMap == null) {
+ proxyMap = new HashMap();
+ }
+
+ Long id = new Long(listenerId);
+ proxy = (ServerEventListenerProxy) proxyMap.get(id);
+ if (proxy == null) {
+ proxy = new ServerEventListenerProxy(getFactory(), listenerId,
+ getQueue());
+ proxyMap.put(id, proxy);
+ }
+ }
+
+ // register the proxy with the observation manager
+ observationManager.addEventListener(proxy, eventTypes, absPath,
+ isDeep, uuid, nodeTypeName, noLocal);
+ }
+
+ /** {@inheritDoc} */
+ public void removeEventListener(long listenerId)
+ throws RepositoryException, RemoteException {
+
+ // try to find the proxy in the map
+ ServerEventListenerProxy proxy;
+ synchronized (this) {
+ if (proxyMap == null) {
+ return;
+ }
+
+ Long id = new Long(listenerId);
+ proxy = (ServerEventListenerProxy) proxyMap.remove(id);
+ if (proxy == null) {
+ return;
+ }
+ }
+
+ // register the proxy with the observation manager
+ observationManager.removeEventListener(proxy);
+ }
+
+ /** {@inheritDoc} */
+ public RemoteEventCollection getNextEvent(long timeout) throws RemoteException {
+ // need the queue
+ checkQueue();
+
+ try {
+ if (timeout < 0) timeout = 0;
+ return (RemoteEventCollection) queue.get(timeout);
+ } catch (InterruptedException ie) {
+ // don't retry, but log
+ }
+
+ // did not get anything, fall back to nothing
+ return null;
+ }
+
+ //---------- internal ------------------------------------------------------
+
+ /**
+ * Makes sure, the {@link #queue} field is assigned a value.
+ */
+ private synchronized void checkQueue() {
+ if (queue == null) {
+ queue = new Queue();
+ }
+ }
+
+ /**
+ * Returns the <code>Channel</code> allocating it if required.
+ */
+ private Queue getQueue() {
+ checkQueue();
+ return queue;
+ }
+}
Propchange: incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/server/ServerObservationManager.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/server/ServerSession.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/server/ServerSession.java?rev=191722&r1=191721&r2=191722&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/server/ServerSession.java (original)
+++ incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/server/ServerSession.java Tue Jun 21 13:44:22 2005
@@ -45,6 +45,15 @@
/** The adapted local session. */
private Session session;
+
+ /**
+ * The server workspace for this session. This field is assigned on demand
+ * by the first call to {@link #getWorkspace()}. The assumption is that
+ * there is only one workspace instance per session and that each call to
+ * the <code>Session.getWorkspace()</code> method of a single session will
+ * allways return the same object.
+ */
+ private RemoteWorkspace remoteWorkspace;
/**
* Creates a remote adapter for the given local session.
@@ -87,7 +96,12 @@
/** {@inheritDoc} */
public RemoteWorkspace getWorkspace() throws RemoteException {
- return getFactory().getRemoteWorkspace(session.getWorkspace());
+ if (remoteWorkspace == null) {
+ remoteWorkspace =
+ getFactory().getRemoteWorkspace(session.getWorkspace());
+ }
+
+ return remoteWorkspace;
}
/** {@inheritDoc} */
Modified: incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/server/ServerWorkspace.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/server/ServerWorkspace.java?rev=191722&r1=191721&r2=191722&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/server/ServerWorkspace.java (original)
+++ incubator/jackrabbit/trunk/contrib/jcr-rmi/src/java/org/apache/jackrabbit/rmi/server/ServerWorkspace.java Tue Jun 21 13:44:22 2005
@@ -24,10 +24,12 @@
import javax.jcr.RepositoryException;
import javax.jcr.Workspace;
import javax.jcr.nodetype.NodeTypeManager;
+import javax.jcr.observation.ObservationManager;
import javax.jcr.query.QueryManager;
import org.apache.jackrabbit.rmi.remote.RemoteNamespaceRegistry;
import org.apache.jackrabbit.rmi.remote.RemoteNodeTypeManager;
+import org.apache.jackrabbit.rmi.remote.RemoteObservationManager;
import org.apache.jackrabbit.rmi.remote.RemoteQueryManager;
import org.apache.jackrabbit.rmi.remote.RemoteWorkspace;
@@ -45,6 +47,16 @@
private Workspace workspace;
/**
+ * The remote observation manager for this workspace. This field is assigned
+ * on demand by the first call to {@link #getObservationManager()}. The
+ * assumption is that there is only one observation manager instance per
+ * workspace and that each call to the
+ * <code>Workspace.getObservationManager()</code> method of a single
+ * workspace will allways return the same object.
+ */
+ private RemoteObservationManager remoteObservationManager;
+
+ /**
* Creates a remote adapter for the given local workspace.
*
* @param workspace local workspace
@@ -136,6 +148,22 @@
}
}
+ /** {@inheritDoc} */
+ public RemoteObservationManager getObservationManager()
+ throws RepositoryException, RemoteException {
+ try {
+ if (remoteObservationManager == null) {
+ ObservationManager observationManager =
+ workspace.getObservationManager();
+ remoteObservationManager =
+ getFactory().getRemoteObservationManager(observationManager);
+ }
+ return remoteObservationManager;
+ } catch (RepositoryException ex) {
+ throw getRepositoryException(ex);
+ }
+ }
+
/** {@inheritDoc} */
public String[] getAccessibleWorkspaceNames()
throws RepositoryException, RemoteException {