[jboss-remoting-commits] JBoss Remoting SVN: r5572 - in remoting3/trunk: jboss-remoting/src/main/java/org/jboss/remoting3 and 3 other directories.

jboss-remoting-commits at lists.jboss.org jboss-remoting-commits at lists.jboss.org
Tue Oct 27 21:44:11 EDT 2009


Author: david.lloyd at jboss.com
Date: 2009-10-27 21:44:11 -0400 (Tue, 27 Oct 2009)
New Revision: 5572

Added:
   remoting3/trunk/taglet/src/main/java/org/jboss/remoting3/taglet/RemotingNonBlockingTaglet.java
Removed:
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/BasicMarshallingProtocol.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/FutureResult.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/LocalServiceConfiguration.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/MarshallingProtocol.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/Result.java
Modified:
   remoting3/trunk/jboss-remoting/pom.xml
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/ClientConnectorImpl.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Endpoint.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/EndpointImpl.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/FutureReplyImpl.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/LocalRequestHandler.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Options.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Remoting.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/ConnectionContext.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/ConnectionHandler.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/ConnectionProvider.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/RemotingServiceDescriptor.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/RequestHandlerConnector.java
   remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/simple/LocalBasicExample2Main.java
   remoting3/trunk/taglet/src/main/java/org/jboss/remoting3/taglet/RemotingTypeTaglet.java
Log:
Commit the changes I was just talking about

Modified: remoting3/trunk/jboss-remoting/pom.xml
===================================================================
--- remoting3/trunk/jboss-remoting/pom.xml	2009-10-24 22:49:32 UTC (rev 5571)
+++ remoting3/trunk/jboss-remoting/pom.xml	2009-10-28 01:44:11 UTC (rev 5572)
@@ -37,13 +37,13 @@
         <dependency>
             <groupId>org.jboss.xnio</groupId>
             <artifactId>xnio-api</artifactId>
-            <version>2.0.0.CR3</version>
+            <version>2.0.0.CR4-SNAPSHOT</version>
             <scope>compile</scope>
         </dependency>
         <dependency>
             <groupId>org.jboss.marshalling</groupId>
             <artifactId>marshalling-api</artifactId>
-            <version>1.1.0.GA</version>
+            <version>1.2.0.CR5-SNAPSHOT</version>
             <scope>compile</scope>
         </dependency>
         <dependency>
@@ -95,14 +95,14 @@
                     <docletArtifact>
                         <groupId>org.jboss.apiviz</groupId>
                         <artifactId>apiviz</artifactId>
-                        <version>1.2.5.GA</version>
+                        <version>1.3.0.GA</version>
                     </docletArtifact>
                     <doctitle><![CDATA[JBoss Remoting ]]>${version}</doctitle>
                     <header><![CDATA[JBoss Remoting ]]>${version}</header>
                     <footer><![CDATA[JBoss Remoting ]]>${version}</footer>
                     <bottom><![CDATA[<i>Copyright &#169; 2009 JBoss, a division of Red Hat, Inc.</i>]]></bottom>
                     <links>
-                        <link>http://java.sun.com/j2se/1.5.0/docs/api/</link>
+                        <link>http://java.sun.com/javase/6/docs/</link>
                     </links>
                 </configuration>
             </plugin>

Deleted: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/BasicMarshallingProtocol.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/BasicMarshallingProtocol.java	2009-10-24 22:49:32 UTC (rev 5571)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/BasicMarshallingProtocol.java	2009-10-28 01:44:11 UTC (rev 5572)
@@ -1,122 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2009, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.jboss.remoting3;
-
-import org.jboss.remoting3.spi.MarshallingProtocol;
-import org.jboss.marshalling.Unmarshaller;
-import org.jboss.marshalling.Marshaller;
-import org.jboss.marshalling.MarshallerFactory;
-import org.jboss.marshalling.MarshallingConfiguration;
-import org.jboss.marshalling.Marshalling;
-import org.jboss.marshalling.reflect.SunReflectiveCreator;
-import org.jboss.xnio.Pool;
-import org.jboss.xnio.OptionMap;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.io.IOException;
-
-/**
- * A marshalling protocol which wraps a {@link org.jboss.marshalling.MarshallerFactory}.
- */
-public final class BasicMarshallingProtocol implements MarshallingProtocol {
-
-    private final MarshallerFactory marshallerFactory;
-    private final int version;
-
-    private static final SunReflectiveCreator creator = AccessController.doPrivileged(new PrivilegedAction<SunReflectiveCreator>() {
-        public SunReflectiveCreator run() {
-            return new SunReflectiveCreator();
-        }
-    });
-
-    /**
-     * Construct a new instance.
-     *
-     * @param marshallerFactory the marshaller factory to use
-     * @param version the wire protocol version to specify
-     */
-    public BasicMarshallingProtocol(final MarshallerFactory marshallerFactory, final int version) {
-        // todo: security check?
-        this.marshallerFactory = marshallerFactory;
-        this.version = version;
-    }
-
-    /** {@inheritDoc} */
-    public Pool<Unmarshaller> getUnmarshallerPool(final Configuration configuration) {
-        final MarshallingConfiguration config = buildConfig(configuration);
-        return new Pool<Unmarshaller>() {
-            public Unmarshaller allocate() {
-                try {
-                    return marshallerFactory.createUnmarshaller(config);
-                } catch (IOException e) {
-                    // todo log
-                    return null;
-                }
-            }
-
-            public void free(final Unmarshaller resource) throws IllegalArgumentException {
-            }
-
-            public void discard(final Unmarshaller resource) {
-            }
-        };
-    }
-
-    /** {@inheritDoc} */
-    public Pool<Marshaller> getMarshallerPool(final Configuration configuration) {
-        final MarshallingConfiguration config = buildConfig(configuration);
-        return new Pool<Marshaller>() {
-            public Marshaller allocate() {
-                try {
-                    return marshallerFactory.createMarshaller(config);
-                } catch (IOException e) {
-                    // todo log
-                    return null;
-                }
-            }
-
-            public void free(final Marshaller resource) throws IllegalArgumentException {
-            }
-
-            public void discard(final Marshaller resource) {
-            }
-        };
-    }
-
-    private MarshallingConfiguration buildConfig(final Configuration configuration) {
-        final MarshallingConfiguration config = new MarshallingConfiguration();
-        config.setCreator(creator);
-        config.setStreamHeader(Marshalling.nullStreamHeader());
-        config.setClassExternalizerFactory(configuration.getUserExternalizerFactory());
-        config.setClassTable(configuration.getUserClassTable());
-        config.setClassResolver(configuration.getUserClassResolver());
-        config.setObjectResolver(configuration.getUserObjectResolver());
-        config.setObjectTable(configuration.getUserObjectTable());
-        final OptionMap optionMap = configuration.getOptionMap();
-        config.setBufferSize(optionMap.get(Options.BUFFER_SIZE, 512));
-        config.setClassCount(optionMap.get(Options.CLASS_COUNT, 64));
-        config.setInstanceCount(optionMap.get(Options.INSTANCE_COUNT, 256));
-        config.setVersion(version);
-        return config;
-    }
-}

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/ClientConnectorImpl.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/ClientConnectorImpl.java	2009-10-24 22:49:32 UTC (rev 5571)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/ClientConnectorImpl.java	2009-10-28 01:44:11 UTC (rev 5572)
@@ -22,10 +22,11 @@
 
 package org.jboss.remoting3;
 
-import org.jboss.xnio.IoFuture;
 import org.jboss.remoting3.spi.RequestHandlerConnector;
 import org.jboss.remoting3.spi.RequestHandler;
-import org.jboss.xnio.Cancellable;
+import org.jboss.xnio.FutureResult;
+import org.jboss.xnio.IoFuture;
+import org.jboss.xnio.TranslatingResult;
 import java.io.Serializable;
 import java.io.IOException;
 
@@ -52,18 +53,13 @@
         if (clientContext != null) {
             throw new SecurityException("Connector has not been sent");
         }
-        return new FutureResult<Client<I, O>, RequestHandler>() {
-            private final Cancellable cancellable = requestHandlerConnector.createRequestHandler(getResult());
-
-            protected Client<I, O> translate(final RequestHandler result) throws IOException {
-                return endpoint.createClient(result, requestClass, replyClass);
+        final FutureResult<Client<I, O>> futureResult = new FutureResult<Client<I, O>>();
+        requestHandlerConnector.createRequestHandler(new TranslatingResult<RequestHandler, Client<I, O>>(futureResult) {
+            protected Client<I, O> translate(final RequestHandler input) throws IOException {
+                return endpoint.createClient(input, requestClass, replyClass);
             }
-
-            public IoFuture<Client<I, O>> cancel() {
-                cancellable.cancel();
-                return super.cancel();
-            }
-        };
+        });
+        return futureResult.getIoFuture();
     }
 
     public ClientContext getClientContext() {

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Endpoint.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Endpoint.java	2009-10-24 22:49:32 UTC (rev 5571)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Endpoint.java	2009-10-28 01:44:11 UTC (rev 5572)
@@ -6,7 +6,6 @@
 import org.jboss.remoting3.spi.ConnectionProviderFactory;
 import org.jboss.remoting3.spi.RequestHandler;
 import org.jboss.remoting3.spi.ConnectionProviderRegistration;
-import org.jboss.remoting3.spi.MarshallingProtocol;
 import org.jboss.xnio.IoFuture;
 import org.jboss.xnio.OptionMap;
 import org.jboss.marshalling.ClassTable;
@@ -14,6 +13,7 @@
 import org.jboss.marshalling.ClassExternalizerFactory;
 import org.jboss.marshalling.ClassResolver;
 import org.jboss.marshalling.ObjectResolver;
+import org.jboss.marshalling.MarshallerFactory;
 
 /**
  * A potential participant in a JBoss Remoting communications relationship.
@@ -45,19 +45,105 @@
      * @return the request handler
      * @throws IOException if an error occurs
      */
-    <I, O> RequestHandler createLocalRequestHandler(RequestListener<I, O> requestListener, final Class<I> requestClass, final Class<O> replyClass) throws IOException;
+    <I, O> RequestHandler createLocalRequestHandler(RequestListener<? super I, ? extends O> requestListener, Class<I> requestClass, Class<O> replyClass) throws IOException;
 
     /**
-     * Create a request handler source that can be used to acquire clients associated with a request listener on this endpoint.
-     * <p/>
-     * You must have the {@link org.jboss.remoting3.EndpointPermission registerService EndpointPermission} to invoke this method.
+     * Get a new service builder which can be used to register a service.
      *
-     * @param configuration the configuration to use
-     * @throws IOException if an error occurs
+     * @return a new service builder
      */
-    <I, O> Registration registerService(LocalServiceConfiguration<I, O> configuration) throws IOException;
+    ServiceBuilder<?, ?> serviceBuilder();
 
     /**
+     * A service builder for new service registration.
+     *
+     * @param <I> the request type
+     * @param <O> the reply type
+     */
+    interface ServiceBuilder<I, O> {
+
+        /**
+         * Set the group name.
+         * @param groupName the group name
+         * @return this builder
+         */
+        ServiceBuilder<I, O> setGroupName(String groupName);
+
+        /**
+         * Set the service type string, which should follow the convention for package names (reversed domain names).
+         *
+         * @param serviceType the service type
+         * @return this builder
+         */
+        ServiceBuilder<I, O> setServiceType(String serviceType);
+
+        /**
+         * Clear the configured client listener and set a new request type.
+         *
+         * @param newRequestType the new request type's class
+         * @param <N> the new request type
+         * @return this builder, cast to include the new request type
+         */
+        <N> ServiceBuilder<N, O> setRequestType(Class<N> newRequestType);
+
+        /**
+         * Clear the configured client listener and set a new reply type.
+         *
+         * @param newReplyType the new reply type's class
+         * @param <N> the new reply type
+         * @return this builder, cast to include the new reply type
+         */
+        <N> ServiceBuilder<I, N> setReplyType(Class<N> newReplyType);
+
+        /**
+         * Set the request listener.  The given listener may be configured to accept a superclass of the given
+         * request type, or a subclass of the given reply type, since they are compatible.
+         *
+         * @param clientListener the request listener
+         * @return this builder
+         */
+        ServiceBuilder<I, O> setClientListener(ClientListener<? super I, ? extends O> clientListener);
+
+        /**
+         * Set the option map for the service.  The options may include, but are not limited to:
+         * <ul>
+         * <li>{@link Options#BUFFER_SIZE} - the recommended buffer size for marshallers to use for this service</li>
+         * <li>{@link Options#CLASS_COUNT} - the recommended class count for marshallers to use for this service</li>
+         * <li>{@link Options#INSTANCE_COUNT} - the recommended instance count for marshallers to use for this service</li>
+         * <li>{@link Options#METRIC} - the relative desirability or "distance" of this service</li>
+         * <li>{@link Options#MARSHALLING_PROTOCOLS} - the marshalling protocols which are allowed for this service,
+         *          in order of decreasing preference; if none is given, all registered protocols will
+         *          be made available</li>
+         * <li>{@link Options#MARSHALLING_CLASS_RESOLVERS} - the class resolvers which are allowed for this service,
+         *          in order of decreasing preference; if none is given, the default class resolver is used</li>
+         * <li>{@link Options#MARSHALLING_CLASS_TABLES} - the class tables which are allowed for this service, in order
+         *          of decreasing preference</li>
+         * <li>{@link Options#MARSHALLING_EXTERNALIZER_FACTORIES} - the class externalizer factories which are allowed
+         *          for this service, in order of decreasing preference</li>
+         * <li>{@link Options#REMOTELY_VISIBLE} - {@code true} if this service should be remotely accessible,
+         *          {@code false} otherwise (defaults to {@code true})</li>
+         * <li>{@link Options#REQUIRE_SECURE} - {@code true} if this service may only be accessed over a secure/encrypted
+         *          channel; defaults to {@code false}, however this should be set to {@code true} if sensitive data (e.g.
+         *          passwords) may be transmitted as part of a payload</li>
+         * </ul>
+         *
+         * @param optionMap the option map
+         * @return this builder
+         */
+        ServiceBuilder<I, O> setOptionMap(OptionMap optionMap);
+
+        /**
+         * Register the service.
+         * <p/>
+         * You must have the {@link org.jboss.remoting3.EndpointPermission registerService EndpointPermission} to invoke this method.
+         *
+         * @return a registration handle
+         * @throws IOException if a problem occurs with registration
+         */
+        Registration register() throws IOException;
+    }
+
+    /**
      * Add a service registration listener which is called whenever a local service is registered.
      * <p/>
      * You must have the {@link org.jboss.remoting3.EndpointPermission addServiceListener EndpointPermission} to invoke this method.
@@ -81,7 +167,7 @@
      * @return the client
      * @throws IOException if an error occurs
      */
-    <I, O> Client<I, O> createClient(RequestHandler handler, Class<I> requestClass,  Class<O> replyClass) throws IOException;
+    <I, O> Client<I, O> createClient(RequestHandler handler, Class<I> requestClass, Class<O> replyClass) throws IOException;
 
     /**
      * Open a connection with a peer.  Returns a future connection which may be used to cancel the connection attempt.
@@ -115,11 +201,11 @@
      * You must have the {@link org.jboss.remoting3.EndpointPermission addMarshallingProtocol EndpointPermission} to invoke this method.
      *
      * @param name the protocol name
-     * @param marshallingProtocol the implementation
+     * @param marshallerFactory the implementation
      * @return a handle which may be used to remove the registration
      * @throws DuplicateRegistrationException if there is already a protocol registered to that name
      */
-    Registration addMarshallingProtocol(String name, MarshallingProtocol marshallingProtocol) throws DuplicateRegistrationException;
+    Registration addMarshallingProtocol(String name, MarshallerFactory marshallerFactory) throws DuplicateRegistrationException;
 
     /**
      * Register a named class table for marshalling.

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/EndpointImpl.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/EndpointImpl.java	2009-10-24 22:49:32 UTC (rev 5571)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/EndpointImpl.java	2009-10-28 01:44:11 UTC (rev 5572)
@@ -45,31 +45,31 @@
 import org.jboss.remoting3.spi.ConnectionProviderFactory;
 import org.jboss.remoting3.spi.RequestHandler;
 import org.jboss.remoting3.spi.RequestHandlerConnector;
-import org.jboss.remoting3.spi.Result;
 import org.jboss.remoting3.spi.ConnectionProviderRegistration;
-import org.jboss.remoting3.spi.MarshallingProtocol;
 import org.jboss.remoting3.spi.ConnectionContext;
+import org.jboss.xnio.log.Logger;
 import org.jboss.xnio.Cancellable;
+import org.jboss.xnio.FailedIoFuture;
+import org.jboss.xnio.FinishedIoFuture;
+import org.jboss.xnio.FutureResult;
 import org.jboss.xnio.IoFuture;
 import org.jboss.xnio.IoUtils;
+import org.jboss.xnio.OptionMap;
+import org.jboss.xnio.Result;
+import org.jboss.xnio.TranslatingResult;
 import org.jboss.xnio.WeakCloseable;
-import org.jboss.xnio.OptionMap;
-import org.jboss.xnio.FinishedIoFuture;
-import org.jboss.xnio.FailedIoFuture;
-import org.jboss.xnio.log.Logger;
 import org.jboss.marshalling.ClassTable;
 import org.jboss.marshalling.ObjectTable;
 import org.jboss.marshalling.ClassExternalizerFactory;
 import org.jboss.marshalling.ClassResolver;
 import org.jboss.marshalling.ObjectResolver;
+import org.jboss.marshalling.MarshallerFactory;
 
 /**
  *
  */
 final class EndpointImpl extends AbstractHandleableCloseable<Endpoint> implements Endpoint {
 
-    private static final NullCancellable NULL_CANCELLABLE = new NullCancellable();
-
     static {
         // Print Remoting "greeting" message
         Logger.getLogger("org.jboss.remoting").info("JBoss Remoting version %s", Version.VERSION);
@@ -121,7 +121,7 @@
     private final ConcurrentMap<String, ConcurrentMap<String, ServiceRegistration>> registeredLocalServices = concurrentMap(serviceRegistrationLock);
 
     private final ConcurrentMap<String, ConnectionProvider<?>> connectionProviders = concurrentMap();
-    private final ConcurrentMap<String, MarshallingProtocol> marshallingProtocols = concurrentMap();
+    private final ConcurrentMap<String, MarshallerFactory> marshallerFactories = concurrentMap();
     private final ConcurrentMap<String, ClassTable> classTables = concurrentMap();
     private final ConcurrentMap<String, ObjectTable> objectTables = concurrentMap();
     private final ConcurrentMap<String, ClassExternalizerFactory> classExternalizerFactories = concurrentMap();
@@ -164,15 +164,14 @@
         return name;
     }
 
-    public <I, O> RequestHandler createLocalRequestHandler(final RequestListener<I, O> requestListener, final Class<I> requestClass, final Class<O> replyClass) throws IOException {
+    public <I, O> RequestHandler createLocalRequestHandler(final RequestListener<? super I, ? extends O> requestListener, final Class<I> requestClass, final Class<O> replyClass) throws IOException {
         SecurityManager sm = System.getSecurityManager();
         if (sm != null) {
             sm.checkPermission(CREATE_REQUEST_HANDLER_PERM);
         }
         checkOpen();
         final ClientContextImpl clientContext = new ClientContextImpl(executor, loopbackConnection);
-        final LocalRequestHandler<I, O> localRequestHandler = new LocalRequestHandler<I, O>(executor,
-                requestListener, clientContext, requestClass, replyClass);
+        final LocalRequestHandler<I, O> localRequestHandler = new LocalRequestHandler<I, O>(executor, requestListener, clientContext, requestClass, replyClass);
         final WeakCloseable lrhCloseable = new WeakCloseable(localRequestHandler);
         clientContext.addCloseHandler(new CloseHandler<ClientContext>() {
             public void handleClose(final ClientContext closed) {
@@ -192,37 +191,161 @@
         return localRequestHandler;
     }
 
-    public <I, O> Registration registerService(final LocalServiceConfiguration<I, O> configuration) throws IOException {
-        SecurityManager sm = System.getSecurityManager();
-        if (sm != null) {
-            sm.checkPermission(REGISTER_SERVICE_PERM);
+    public ServiceBuilder<?, ?> serviceBuilder() {
+        return new ServiceBuilderImpl<Void, Void>();
+    }
+
+    private final class ServiceBuilderImpl<I, O> implements ServiceBuilder<I, O> {
+        private String groupName;
+        private String serviceType;
+        private Class<I> requestType;
+        private Class<O> replyType;
+        private ClientListener<? super I, ? extends O> clientListener;
+        private OptionMap optionMap = OptionMap.EMPTY;
+
+        public ServiceBuilder<I, O> setGroupName(final String groupName) {
+            this.groupName = groupName;
+            return this;
         }
-        if (configuration == null) {
-            throw new NullPointerException("configuration is null");
+
+        public ServiceBuilder<I, O> setServiceType(final String serviceType) {
+            this.serviceType = serviceType;
+            return this;
         }
-        final String serviceType = configuration.getServiceType();
-        final String groupName = configuration.getGroupName();
-        final OptionMap optionMap = configuration.getOptionMap();
-        final Integer metric = optionMap.get(Options.METRIC);
-        if (metric != null && metric.intValue() < 0) {
-            throw new IllegalArgumentException("metric must be greater than or equal to zero");
+
+        @SuppressWarnings({ "unchecked" })
+        public <N> ServiceBuilder<N, O> setRequestType(final Class<N> newRequestType) {
+            if (newRequestType == null) {
+                throw new NullPointerException("newRequestType is null");
+            }
+            clientListener = null;
+            ServiceBuilderImpl<N, O> castBuilder = (ServiceBuilderImpl<N, O>) this;
+            castBuilder.requestType = newRequestType;
+            return castBuilder;
         }
-        ServiceURI.validateServiceType(serviceType);
-        ServiceURI.validateGroupName(groupName);
-        checkOpen();
-        final String canonServiceType = serviceType.toLowerCase();
-        final String canonGroupName = groupName.toLowerCase();
-        final Class<I> requestClass = configuration.getRequestClass();
-        final Class<O> replyClass = configuration.getReplyClass();
-        final ClientListener<I, O> clientListener = configuration.getClientListener();
-        final Executor executor = this.executor;
-        final ConcurrentMap<String, ConcurrentMap<String, ServiceRegistration>> registeredLocalServices = this.registeredLocalServices;
-        final RequestHandlerConnector requestHandlerConnector = new RequestHandlerConnector() {
+
+        @SuppressWarnings({ "unchecked" })
+        public <N> ServiceBuilder<I, N> setReplyType(final Class<N> newReplyType) {
+            if (newReplyType == null) {
+                throw new NullPointerException("newReplyType is null");
+            }
+            clientListener = null;
+            ServiceBuilderImpl<I, N> castBuilder = (ServiceBuilderImpl<I, N>) this;
+            castBuilder.replyType = newReplyType;
+            return castBuilder;
+        }
+
+        public ServiceBuilder<I, O> setClientListener(final ClientListener<? super I, ? extends O> clientListener) {
+            if (requestType == null || replyType == null) {
+                throw new IllegalArgumentException("Must configure both request and reply type before setting the client listener");
+            }
+            this.clientListener = clientListener;
+            return this;
+        }
+
+        public ServiceBuilder<I, O> setOptionMap(final OptionMap optionMap) {
+            if (optionMap == null) {
+                throw new NullPointerException("optionMap is null");
+            }
+            this.optionMap = optionMap;
+            return this;
+        }
+
+        public Registration register() throws IOException {
+            SecurityManager sm = System.getSecurityManager();
+            if (sm != null) {
+                sm.checkPermission(REGISTER_SERVICE_PERM);
+            }
+            if (groupName == null) {
+                throw new NullPointerException("groupName is null");
+            }
+            if (serviceType == null) {
+                throw new NullPointerException("serviceType is null");
+            }
+            if (requestType == null) {
+                throw new NullPointerException("requestType is null");
+            }
+            if (replyType == null) {
+                throw new NullPointerException("replyType is null");
+            }
+            if (clientListener == null) {
+                throw new NullPointerException("clientListener is null");
+            }
+            final Integer metric = optionMap.get(Options.METRIC);
+            if (metric != null && metric.intValue() < 0) {
+                throw new IllegalArgumentException("metric must be greater than or equal to zero");
+            }
+            ServiceURI.validateServiceType(serviceType);
+            ServiceURI.validateGroupName(groupName);
+            checkOpen();
+            final String canonServiceType = serviceType.toLowerCase();
+            final String canonGroupName = groupName.toLowerCase();
+            final Executor executor = EndpointImpl.this.executor;
+            final ConcurrentMap<String, ConcurrentMap<String, ServiceRegistration>> registeredLocalServices = EndpointImpl.this.registeredLocalServices;
+            final RequestHandlerConnector requestHandlerConnector = new Connector();
+            final ServiceRegistration registration = new ServiceRegistration(serviceType, groupName, name, optionMap, requestHandlerConnector);
+            // this handle is used to remove the service registration
+            final Registration handle = new Registration() {
+                public void close() {
+                    synchronized (serviceRegistrationLock) {
+                        final ConcurrentMap<String, ServiceRegistration> submap = registeredLocalServices.get(serviceType);
+                        if (submap != null) {
+                            submap.remove(groupName, registration);
+                        }
+                    }
+                }
+            };
+            registration.setHandle(handle);
+            final Iterator<Map.Entry<Registration,ServiceRegistrationListener>> serviceListenerRegistrations;
+            final Object lock = serviceRegistrationLock;
+            synchronized (lock) {
+                // actually register the service, and while we have the lock, snag a copy of the registration listener list
+                final ConcurrentMap<String, ServiceRegistration> submap;
+                if (registeredLocalServices.containsKey(canonServiceType)) {
+                    submap = registeredLocalServices.get(canonServiceType);
+                    if (submap.containsKey(canonGroupName)) {
+                        throw new ServiceRegistrationException("ListenerRegistration of service of type \"" + serviceType + "\" in group \"" + groupName + "\" duplicates an already-registered service's specification");
+                    }
+                } else {
+                    submap = concurrentMap(lock);
+                    registeredLocalServices.put(canonServiceType, submap);
+                }
+                submap.put(canonGroupName, registration);
+                // snapshot
+                serviceListenerRegistrations = EndpointImpl.this.serviceListenerRegistrations.entrySet().iterator();
+            }
+            // notify all service listener registrations that were registered at the time the service was created
+            final ServiceRegistrationListener.ServiceInfo serviceInfo = new ServiceRegistrationListener.ServiceInfo();
+            serviceInfo.setGroupName(groupName);
+            serviceInfo.setServiceType(serviceType);
+            serviceInfo.setOptionMap(optionMap);
+            serviceInfo.setRegistrationHandle(handle);
+            serviceInfo.setRequestHandlerConnector(requestHandlerConnector);
+            executor.execute(new Runnable() {
+                public void run() {
+                    final Iterator<Map.Entry<Registration,ServiceRegistrationListener>> iter = serviceListenerRegistrations;
+                    while (iter.hasNext()) {
+                        final Map.Entry<Registration,ServiceRegistrationListener> slr = iter.next();
+                        try {
+                            slr.getValue().serviceRegistered(slr.getKey(), serviceInfo.clone());
+                        } catch (Throwable t) {
+                            logListenerError(t);
+                        }
+                    }
+                }
+            });
+            return handle;
+        }
+
+        private class Connector implements RequestHandlerConnector {
+
+            Connector() {
+            }
+
             public Cancellable createRequestHandler(final Result<RequestHandler> result) throws SecurityException {
                 try {
                     final ClientContextImpl clientContext = new ClientContextImpl(executor, loopbackConnection);
-                    final RequestListener<I, O> requestListener = clientListener.handleClientOpen(clientContext);
-                    final RequestHandler localRequestHandler = createLocalRequestHandler(requestListener, requestClass, replyClass);
+                    final RequestHandler localRequestHandler = createLocalRequestHandler(clientListener.handleClientOpen(clientContext), requestType, replyType);
                     clientContext.addCloseHandler(new CloseHandler<ClientContext>() {
                         public void handleClose(final ClientContext closed) {
                             IoUtils.safeClose(localRequestHandler);
@@ -232,61 +355,9 @@
                 } catch (IOException e) {
                     result.setException(e);
                 }
-                return NULL_CANCELLABLE;
+                return IoUtils.nullCancellable();
             }
-        };
-        final ServiceRegistration registration = new ServiceRegistration(serviceType, groupName, name, optionMap, requestHandlerConnector);
-        // this handle is used to remove the service registration
-        final Registration handle = new Registration() {
-            public void close() {
-                synchronized (serviceRegistrationLock) {
-                    final ConcurrentMap<String, ServiceRegistration> submap = registeredLocalServices.get(serviceType);
-                    if (submap != null) {
-                        submap.remove(groupName, registration);
-                    }
-                }
-            }
-        };
-        registration.setHandle(handle);
-        final Iterator<Map.Entry<Registration,ServiceRegistrationListener>> serviceListenerRegistrations;
-        final Object lock = serviceRegistrationLock;
-        synchronized (lock) {
-            // actually register the service, and while we have the lock, snag a copy of the registration listener list
-            final ConcurrentMap<String, ServiceRegistration> submap;
-            if (registeredLocalServices.containsKey(canonServiceType)) {
-                submap = registeredLocalServices.get(canonServiceType);
-                if (submap.containsKey(canonGroupName)) {
-                    throw new ServiceRegistrationException("ListenerRegistration of service of type \"" + serviceType + "\" in group \"" + groupName + "\" duplicates an already-registered service's specification");
-                }
-            } else {
-                submap = concurrentMap(lock);
-                registeredLocalServices.put(canonServiceType, submap);
-            }
-            submap.put(canonGroupName, registration);
-            // snapshot
-            serviceListenerRegistrations = this.serviceListenerRegistrations.entrySet().iterator();
         }
-        // notify all service listener registrations that were registered at the time the service was created
-        final ServiceRegistrationListener.ServiceInfo serviceInfo = new ServiceRegistrationListener.ServiceInfo();
-        serviceInfo.setGroupName(groupName);
-        serviceInfo.setServiceType(serviceType);
-        serviceInfo.setOptionMap(optionMap);
-        serviceInfo.setRegistrationHandle(handle);
-        serviceInfo.setRequestHandlerConnector(requestHandlerConnector);
-        executor.execute(new Runnable() {
-            public void run() {
-                final Iterator<Map.Entry<Registration,ServiceRegistrationListener>> iter = serviceListenerRegistrations;
-                while (iter.hasNext()) {
-                    final Map.Entry<Registration,ServiceRegistrationListener> slr = iter.next();
-                    try {
-                        slr.getValue().serviceRegistered(slr.getKey(), serviceInfo.clone());
-                    } catch (Throwable t) {
-                        logListenerError(t);
-                    }
-                }
-            }
-        });
-        return handle;
     }
 
     private static void logListenerError(final Throwable t) {
@@ -383,13 +454,13 @@
         if (connectionProvider == null) {
             throw new UnknownURISchemeException("No connection provider for URI scheme \"" + scheme + "\" is installed");
         }
-        final FutureResult<Connection, ConnectionHandlerFactory> futureResult = new FutureResult<Connection, ConnectionHandlerFactory>() {
-            protected Connection translate(final ConnectionHandlerFactory result) {
-                return new ConnectionImpl(result);
+        final FutureResult<Connection> futureResult = new FutureResult<Connection>(executor);
+        futureResult.addCancelHandler(connectionProvider.connect(destination, connectOptions, new TranslatingResult<ConnectionHandlerFactory, Connection>(futureResult) {
+            protected Connection translate(final ConnectionHandlerFactory input) {
+                return new ConnectionImpl(input);
             }
-        };
-        connectionProvider.connect(destination, connectOptions, futureResult.getResult());
-        return futureResult;
+        }));
+        return futureResult.getIoFuture();
     }
 
     public <T> ConnectionProviderRegistration<T> addConnectionProvider(final String uriScheme, final ConnectionProviderFactory<T> providerFactory) {
@@ -439,8 +510,8 @@
         return new MapRegistration<T>(map, name, target);
     }
 
-    public Registration addMarshallingProtocol(final String name, final MarshallingProtocol marshallingProtocol) throws DuplicateRegistrationException {
-        return addMarshallingRegistration(name, marshallingProtocol, marshallingProtocols, "Marshalling protocol");
+    public Registration addMarshallingProtocol(final String name, final MarshallerFactory marshallerFactory) throws DuplicateRegistrationException {
+        return addMarshallingRegistration(name, marshallerFactory, marshallerFactories, "Marshalling protocol factory");
     }
 
     public Registration addUserClassTable(final String name, final ClassTable classTable) throws DuplicateRegistrationException {
@@ -467,16 +538,6 @@
         return "endpoint \"" + name + "\" <" + Integer.toHexString(hashCode()) + ">";
     }
 
-    private <I, O> IoFuture<? extends Client<I, O>> doOpenClient(final ConnectionHandler connectionHandler, final String serviceType, final String groupName, final Class<I> requestClass, final Class<O> replyClass) {
-        final FutureResult<Client<I, O>, RequestHandler> futureResult = new FutureResult<Client<I, O>, RequestHandler>() {
-            protected Client<I, O> translate(final RequestHandler result) throws IOException {
-                return createClient(result, requestClass, replyClass);
-            }
-        };
-        connectionHandler.open(serviceType, groupName, futureResult.getResult());
-        return futureResult;
-    }
-
     private static class MapRegistration<T> implements Registration {
         private static final class Info<T> {
             private final ConcurrentMap<String, T> map;
@@ -504,7 +565,12 @@
     }
 
     private final class LocalConnectionContext implements ConnectionContext {
+        private final Connection connection;
 
+        LocalConnectionContext(final Connection connection) {
+            this.connection = connection;
+        }
+
         public void openService(final String serviceType, final String groupName, final OptionMap optionMap, final ServiceResult serviceResult) {
             final String canonServiceType = serviceType.toLowerCase();
             final String canonGroupName = groupName.toLowerCase();
@@ -529,21 +595,28 @@
                 }
             }
             registration.getRequestHandlerConnector().createRequestHandler(new Result<RequestHandler>() {
-                public void setResult(final RequestHandler result) {
+                public boolean setResult(final RequestHandler result) {
                     serviceResult.opened(result, registration.getOptionMap());
+                    return true;
                 }
 
-                public void setException(final IOException exception) {
+                public boolean setException(final IOException exception) {
                     log.warn(exception, "Unexpected exception on service lookup");
                     serviceResult.notFound();
+                    return true;
                 }
 
-                public void setCancelled() {
+                public boolean setCancelled() {
                     log.warn("Unexpected cancellation on service lookup");
                     serviceResult.notFound();
+                    return true;
                 }
             });
         }
+
+        public void remoteClosed() {
+            IoUtils.safeClose(connection);
+        }
     }
 
     private class ConnectionImpl extends AbstractHandleableCloseable<Connection> implements Connection {
@@ -551,7 +624,7 @@
 
         private ConnectionImpl(final ConnectionHandlerFactory connectionHandlerFactory) {
             super(EndpointImpl.this.executor);
-            connectionHandler = connectionHandlerFactory.createInstance(localConnectionContext);
+            connectionHandler = connectionHandlerFactory.createInstance(new LocalConnectionContext(this));
         }
 
         protected void closeAction() throws IOException {
@@ -559,7 +632,13 @@
         }
 
         public <I, O> IoFuture<? extends Client<I, O>> openClient(final String serviceType, final String groupName, final Class<I> requestClass, final Class<O> replyClass) {
-            return doOpenClient(connectionHandler, serviceType, groupName, requestClass, replyClass);
+            final FutureResult<Client<I, O>> futureResult = new FutureResult<Client<I, O>>();
+            futureResult.addCancelHandler(connectionHandler.open(serviceType, groupName, new TranslatingResult<RequestHandler, Client<I, O>>(futureResult) {
+                protected Client<I, O> translate(final RequestHandler input) throws IOException {
+                    return createClient(input, requestClass, replyClass);
+                }
+            }));
+            return futureResult.getIoFuture();
         }
 
         public <I, O> ClientConnector<I, O> createClientConnector(final RequestListener<I, O> listener, final Class<I> requestClass, final Class<O> replyClass) throws IOException {
@@ -586,17 +665,10 @@
         }
     }
 
-    private final ConnectionContext localConnectionContext = new LocalConnectionContext();
     private final ConnectionHandler loopbackConnectionHandler = new LoopbackConnectionHandler();
     private final Connection loopbackConnection = new LoopbackConnection();
+    private final ConnectionContext localConnectionContext = new LocalConnectionContext(loopbackConnection);
 
-    // todo - move this into XNIO IoUtils
-    private static class NullCancellable implements Cancellable {
-        public Cancellable cancel() {
-            return this;
-        }
-    }
-
     private final class LocalConnectionProvider implements ConnectionProvider<Void> {
 
         public Cancellable connect(final URI uri, final OptionMap connectOptions, final Result<ConnectionHandlerFactory> result) throws IllegalArgumentException {
@@ -604,9 +676,8 @@
                 public ConnectionHandler createInstance(final ConnectionContext context) {
                     return loopbackConnectionHandler;
                 }
-
             });
-            return NULL_CANCELLABLE;
+            return IoUtils.nullCancellable();
         }
 
         public Void getProviderInterface() {
@@ -617,21 +688,13 @@
     private class LoopbackConnection implements Connection {
 
         public <I, O> IoFuture<? extends Client<I, O>> openClient(final String serviceType, final String groupName, final Class<I> requestClass, final Class<O> replyClass) {
-            final IoFuture.Manager<Client<I, O>> mgr = new IoFuture.Manager<Client<I, O>>();
-            mgr.addCancelHandler(loopbackConnectionHandler.open(serviceType, groupName, new Result<RequestHandler>() {
-                public void setResult(final RequestHandler result) {
-                    mgr.setResult(ClientImpl.create(result, executor, requestClass, replyClass));
+            final FutureResult<Client<I,O>> futureResult = new FutureResult<Client<I, O>>(executor);
+            futureResult.addCancelHandler(loopbackConnectionHandler.open(serviceType, groupName, new TranslatingResult<RequestHandler, Client<I, O>>(futureResult) {
+                protected Client<I, O> translate(final RequestHandler input) throws IOException {
+                    return ClientImpl.create(input, executor, requestClass, replyClass);
                 }
-
-                public void setException(final IOException exception) {
-                    mgr.setException(exception);
-                }
-
-                public void setCancelled() {
-                    mgr.finishCancel();
-                }
             }));
-            return mgr.getIoFuture();
+            return futureResult.getIoFuture();
         }
 
         public <I, O> ClientConnector<I, O> createClientConnector(final RequestListener<I, O> listener, final Class<I> requestClass, final Class<O> replyClass) {
@@ -684,7 +747,7 @@
 
     private class LoopbackConnectionHandler implements ConnectionHandler {
 
-        public Cancellable open(final String serviceType, final String groupName, final Result<RequestHandler> result) {
+        public Cancellable open(final String serviceType, final String groupName, final org.jboss.xnio.Result<RequestHandler> result) {
             localConnectionContext.openService(serviceType, groupName, OptionMap.EMPTY, new ConnectionContext.ServiceResult() {
                 public void opened(final RequestHandler requestHandler, final OptionMap optionMap) {
                     result.setResult(requestHandler);
@@ -694,15 +757,15 @@
                     result.setException(new ServiceNotFoundException(ServiceURI.create(serviceType, groupName, name), "No such service located"));
                 }
             });
-            return NULL_CANCELLABLE;
+            return IoUtils.nullCancellable();
         }
 
         public RequestHandlerConnector createConnector(final RequestHandler localHandler) {
             // the loopback connection just returns the local handler directly as no forwarding is involved
             return new RequestHandlerConnector() {
-                public Cancellable createRequestHandler(final Result<RequestHandler> result) throws SecurityException {
+                public Cancellable createRequestHandler(final org.jboss.xnio.Result<RequestHandler> result) throws SecurityException {
                     result.setResult(localHandler);
-                    return NULL_CANCELLABLE;
+                    return IoUtils.nullCancellable();
                 }
             };
         }

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/FutureReplyImpl.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/FutureReplyImpl.java	2009-10-24 22:49:32 UTC (rev 5571)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/FutureReplyImpl.java	2009-10-28 01:44:11 UTC (rev 5572)
@@ -91,7 +91,7 @@
         }
 
         public void handleCancellation() {
-            finishCancel();
+            setCancelled();
         }
     }
 }

Deleted: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/FutureResult.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/FutureResult.java	2009-10-24 22:49:32 UTC (rev 5571)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/FutureResult.java	2009-10-28 01:44:11 UTC (rev 5572)
@@ -1,65 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2009, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.jboss.remoting3;
-
-import org.jboss.xnio.AbstractIoFuture;
-import org.jboss.remoting3.spi.Result;
-import java.io.IOException;
-
-abstract class FutureResult<T, X> extends AbstractIoFuture<T> {
-    private final Result<X> result = new Result<X>() {
-        public void setResult(final X result) {
-            try {
-                FutureResult.this.setResult(translate(result));
-            } catch (IOException e) {
-                FutureResult.this.setException(e);
-            }
-        }
-
-        public void setException(final IOException exception) {
-            FutureResult.this.setException(exception);
-        }
-
-        public void setCancelled() {
-            finishCancel();
-        }
-    };
-
-    abstract protected T translate(X result) throws IOException;
-
-    Result<X> getResult() {
-        return result;
-    }
-
-    protected boolean setException(final IOException exception) {
-        return super.setException(exception);
-    }
-
-    protected boolean setResult(final T result) {
-        return super.setResult(result);
-    }
-
-    protected boolean finishCancel() {
-        return super.finishCancel();
-    }
-}

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/LocalRequestHandler.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/LocalRequestHandler.java	2009-10-24 22:49:32 UTC (rev 5571)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/LocalRequestHandler.java	2009-10-28 01:44:11 UTC (rev 5572)
@@ -44,9 +44,10 @@
 
     private static final Logger log = Logger.getLogger("org.jboss.remoting.listener");
 
-    LocalRequestHandler(final Executor executor, final RequestListener<I, O> requestListener, final ClientContextImpl clientContext, final Class<I> requestClass, final Class<O> replyClass) {
+    @SuppressWarnings({ "unchecked" })
+    LocalRequestHandler(final Executor executor, final RequestListener<? super I, ? extends O> requestListener, final ClientContextImpl clientContext, final Class<I> requestClass, final Class<O> replyClass) {
         super(executor);
-        this.requestListener = requestListener;
+        this.requestListener = (RequestListener<I, O>) requestListener;
         this.clientContext = clientContext;
         this.requestClass = requestClass;
         this.replyClass = replyClass;

Deleted: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/LocalServiceConfiguration.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/LocalServiceConfiguration.java	2009-10-24 22:49:32 UTC (rev 5571)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/LocalServiceConfiguration.java	2009-10-28 01:44:11 UTC (rev 5572)
@@ -1,153 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2008, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.jboss.remoting3;
-
-import org.jboss.xnio.OptionMap;
-
-/**
- * A configuration for a service to be deployed into the endpoint.
- *
- * @apiviz.exclude
- *
- * @param <I> the request type
- * @param <O> the reply type
- */
-public final class LocalServiceConfiguration<I, O> {
-    private final ClientListener<I, O> clientListener;
-    private final Class<I> requestClass;
-    private final Class<O> replyClass;
-    private String serviceType;
-    private String groupName;
-    private OptionMap optionMap = OptionMap.EMPTY;
-
-    /**
-     * Construct a new instance.
-     *
-     * @param clientListener the client listener
-     * @param requestClass the request class
-     * @param replyClass the reply class
-     */
-    public LocalServiceConfiguration(final ClientListener<I, O> clientListener, final Class<I> requestClass, final Class<O> replyClass) {
-        this.clientListener = clientListener;
-        this.requestClass = requestClass;
-        this.replyClass = replyClass;
-    }
-
-    /**
-     * Create a new instance.
-     *
-     * @param clientListener the client listener
-     * @param requestClass the request class
-     * @param replyClass the reply class
-     * @param <I> the request type
-     * @param <O> the reply type
-     * @return a new configuration instance
-     */
-    public static <I, O> LocalServiceConfiguration<I, O> create(final ClientListener<I, O> clientListener, final Class<I> requestClass, final Class<O> replyClass) {
-        return new LocalServiceConfiguration<I,O>(clientListener, requestClass, replyClass);
-    }
-
-    /**
-     * Get the request listener for this service.
-     *
-     * @return the request listener
-     */
-    public ClientListener<I, O> getClientListener() {
-        return clientListener;
-    }
-
-    /**
-     * Get the request class.
-     *
-     * @return the request class
-     */
-    public Class<I> getRequestClass() {
-        return requestClass;
-    }
-
-    /**
-     * Get the reply class.
-     *
-     * @return the reply class
-     */
-    public Class<O> getReplyClass() {
-        return replyClass;
-    }
-
-    /**
-     * Get the service type.
-     *
-     * @return the service type
-     */
-    public String getServiceType() {
-        return serviceType;
-    }
-
-    /**
-     * Set the service type.
-     *
-     * @param serviceType the service type
-     */
-    public void setServiceType(final String serviceType) {
-        this.serviceType = serviceType;
-    }
-
-    /**
-     * Get the group name.
-     *
-     * @return the group name
-     */
-    public String getGroupName() {
-        return groupName;
-    }
-
-    /**
-     * Set the group name.
-     *
-     * @param groupName the group name
-     */
-    public void setGroupName(final String groupName) {
-        this.groupName = groupName;
-    }
-
-    /**
-     * Get the option map for the service.
-     *
-     * @return the option map
-     */
-    public OptionMap getOptionMap() {
-        return optionMap;
-    }
-
-    /**
-     * Set the option map for the service.
-     *
-     * @param optionMap the option map
-     */
-    public void setOptionMap(final OptionMap optionMap) {
-        if (optionMap == null) {
-            throw new NullPointerException("optionMap is null");
-        }
-        this.optionMap = optionMap;
-    }
-}

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Options.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Options.java	2009-10-24 22:49:32 UTC (rev 5571)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Options.java	2009-10-28 01:44:11 UTC (rev 5572)
@@ -44,38 +44,32 @@
     public static final Option<Boolean> LOAD_PROVIDERS = Option.simple(Options.class, "LOAD_PROVIDERS", Boolean.class);
 
     /**
-     * Request that the marshalling layer require the use of one of the listed marshalling protocols, in order of decreasing preference.  If
-     * not specified, use a default value.  The marshaller {@code "default"} can be specified explicitly for this default value.
+     * Request that the marshalling layer require the use of one of the listed marshalling protocols, in order of decreasing preference.
      */
     public static final Option<Sequence<String>> MARSHALLING_PROTOCOLS = Option.sequence(Options.class, "MARSHALLING_PROTOCOLS", String.class);
 
     /**
-     * Request that the marshalling layer require the presense of one of the listed user-defined class tables, in order of decreasing preference.  If
-     * not specified, no user class table should be used.  The string {@code "none"} indicates no class table.
+     * Request that the marshalling layer require the presense of one of the listed user-defined class tables, in order of decreasing preference.
      */
     public static final Option<Sequence<String>> MARSHALLING_CLASS_TABLES = Option.sequence(Options.class, "MARSHALLING_CLASS_TABLES", String.class);
 
     /**
-     * Request that the marshalling layer require the presense of one of the listed user-defined object tables, in order of decreasing preference.  If
-     * not specified, no user object table should be used.  The string {@code "none"} indicates no object table.
+     * Request that the marshalling layer require the presense of one of the listed user-defined object tables, in order of decreasing preference.
      */
     public static final Option<Sequence<String>> MARSHALLING_OBJECT_TABLES = Option.sequence(Options.class, "MARSHALLING_OBJECT_TABLES", String.class);
 
     /**
-     * Request that the marshalling layer require the presense of one of the listed class resolvers, in order of decreasing preference.  If
-     * not specified, classes are resolved on the remote side using a default strategy.  The string {@code "default"} indicates the default class resolver.
+     * Request that the marshalling layer require the presense of one of the listed class resolvers, in order of decreasing preference.
      */
     public static final Option<Sequence<String>> MARSHALLING_CLASS_RESOLVERS = Option.sequence(Options.class, "MARSHALLING_CLASS_RESOLVERS", String.class);
 
     /**
-     * Request that the marshalling layer require the presense of one of the listed object resolvers, in order of decreasing preference.  If
-     * not specified, no object substitution will take place.  The string {@code "none"} indicates no object resolver.
+     * Request that the marshalling layer require the presense of one of the listed object resolvers, in order of decreasing preference.
      */
     public static final Option<Sequence<String>> MARSHALLING_OBJECT_RESOLVERS = Option.sequence(Options.class, "MARSHALLING_OBJECT_RESOLVERS", String.class);
 
     /**
-     * Request that the marshalling layer require the presense of one of the listed user-defined externalizer factories, in order of decreasing preference.  If
-     * not specified, no user externalizer factory should be used.  The string {@code "none"} indicates no externalizer factory.
+     * Request that the marshalling layer require the presense of one of the listed user-defined externalizer factories, in order of decreasing preference.
      */
     public static final Option<Sequence<String>> MARSHALLING_EXTERNALIZER_FACTORIES = Option.sequence(Options.class, "MARSHALLING_EXTERNALIZER_FACTORIES", String.class);
 
@@ -85,7 +79,7 @@
     public static final Option<Integer> METRIC = Option.simple(Options.class, "METRIC", Integer.class);
 
     /**
-     * Specify that the registered service should or should not be visible remotely.  If not specified, defaults to {@code true}.
+     * Specify that the registered service should or should not be visible remotely.
      */
     public static final Option<Boolean> REMOTELY_VISIBLE = Option.simple(Options.class, "REMOTELY_VISIBLE", Boolean.class);
 
@@ -103,4 +97,10 @@
      * Specify the expected instance count for any configured marshaller or unmarshaller.
      */
     public static final Option<Integer> INSTANCE_COUNT = Option.simple(Options.class, "INSTANCE_COUNT", Integer.class);
+
+    /**
+     * Specify whether the service may be accessed from connections which are unencrypted, or whether encryption is
+     * required.
+     */
+    public static final Option<Boolean> REQUIRE_SECURE = Option.simple(Options.class, "REQUIRE_SECURE", Boolean.class);
 }

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Remoting.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Remoting.java	2009-10-24 22:49:32 UTC (rev 5571)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Remoting.java	2009-10-28 01:44:11 UTC (rev 5572)
@@ -30,9 +30,10 @@
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
 import java.util.ServiceLoader;
+import java.util.Map;
+import java.util.HashMap;
 import org.jboss.remoting3.spi.RequestHandler;
 import org.jboss.remoting3.spi.RemotingServiceDescriptor;
-import org.jboss.remoting3.spi.MarshallingProtocol;
 import org.jboss.remoting3.spi.ConnectionProviderFactory;
 import org.jboss.xnio.CloseableExecutor;
 import org.jboss.xnio.IoUtils;
@@ -43,6 +44,8 @@
 import org.jboss.marshalling.ClassResolver;
 import org.jboss.marshalling.ObjectResolver;
 import org.jboss.marshalling.ClassExternalizerFactory;
+import org.jboss.marshalling.ProviderDescriptor;
+import org.jboss.marshalling.MarshallerFactory;
 
 /**
  * The standalone interface into Remoting.  This class contains static methods that are useful to standalone programs
@@ -106,15 +109,13 @@
             }
         });
         if (optionMap.get(Options.LOAD_PROVIDERS, true)) {
-            for (RemotingServiceDescriptor descriptor : ServiceLoader.load(RemotingServiceDescriptor.class)) {
+            for (RemotingServiceDescriptor<?> descriptor : ServiceLoader.load(RemotingServiceDescriptor.class)) {
                 final String name = descriptor.getName();
-                final Class serviceType = descriptor.getType();
+                final Class<?> serviceType = descriptor.getType();
                 final Object service = descriptor.getService();
                 try {
                     if (serviceType == ConnectionProviderFactory.class) {
                         endpoint.addConnectionProvider(name, (ConnectionProviderFactory<?>) service);
-                    } else if (serviceType == MarshallingProtocol.class) {
-                        endpoint.addMarshallingProtocol(name, (MarshallingProtocol) service);
                     } else if (serviceType == ClassTable.class) {
                         endpoint.addUserClassTable(name, (ClassTable) service);
                     } else if (serviceType == ObjectTable.class) {
@@ -127,9 +128,25 @@
                         endpoint.addUserExternalizerFactory(name, (ClassExternalizerFactory) service);
                     }
                 } catch (DuplicateRegistrationException e) {
-                    log.debug("Duplicate registration for '" + name + "' of type " + serviceType);
+                    log.debug("Duplicate registration for '" + name + "' of " + serviceType);
                 }
             }
+            final Map<String, ProviderDescriptor> found = new HashMap<String, ProviderDescriptor>();
+            for (ProviderDescriptor descriptor : ServiceLoader.load(ProviderDescriptor.class)) {
+                final String name = descriptor.getName();
+                // find the best one
+                if (! found.containsKey(name) || found.get(name).getSupportedVersions()[0] < descriptor.getSupportedVersions()[0]) {
+                    found.put(name, descriptor);
+                }
+            }
+            for (String name : found.keySet()) {
+                final MarshallerFactory marshallerFactory = found.get(name).getMarshallerFactory();
+                try {
+                    endpoint.addMarshallingProtocol(name, marshallerFactory);
+                } catch (DuplicateRegistrationException e) {
+                    log.debug("Duplicate registration for '" + name + "' of " + MarshallerFactory.class);
+                }
+            }
         }
         return endpoint;
     }

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/ConnectionContext.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/ConnectionContext.java	2009-10-24 22:49:32 UTC (rev 5571)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/ConnectionContext.java	2009-10-28 01:44:11 UTC (rev 5572)
@@ -26,12 +26,16 @@
 
 /**
  * The context for connections to service incoming requests to open a client service.
+ *
+ * @remoting.consume
  */
 public interface ConnectionContext {
 
     /**
      * Open a service.
      *
+     * @remoting.nonblocking
+     *
      * @param serviceType the service type
      * @param groupName the service group name
      * @param optionMap the open options
@@ -40,6 +44,13 @@
     void openService(String serviceType, String groupName, OptionMap optionMap, ServiceResult serviceResult);
 
     /**
+     * Indicate that the remote side has terminated the connection, so the local side should be closed as well.
+     *
+     * @remoting.nonblocking
+     */
+    void remoteClosed();
+
+    /**
      * The result acceptor for a service open request.
      */
     interface ServiceResult {

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/ConnectionHandler.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/ConnectionHandler.java	2009-10-24 22:49:32 UTC (rev 5571)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/ConnectionHandler.java	2009-10-28 01:44:11 UTC (rev 5572)
@@ -24,6 +24,7 @@
 
 import java.io.Closeable;
 import org.jboss.xnio.Cancellable;
+import org.jboss.xnio.Result;
 
 /**
  * A connection to a foreign endpoint.  This interface is implemented by the protocol implementation.

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/ConnectionProvider.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/ConnectionProvider.java	2009-10-24 22:49:32 UTC (rev 5571)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/ConnectionProvider.java	2009-10-28 01:44:11 UTC (rev 5572)
@@ -23,6 +23,7 @@
 package org.jboss.remoting3.spi;
 
 import java.net.URI;
+import org.jboss.xnio.Result;
 import org.jboss.xnio.Cancellable;
 import org.jboss.xnio.OptionMap;
 

Deleted: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/MarshallingProtocol.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/MarshallingProtocol.java	2009-10-24 22:49:32 UTC (rev 5571)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/MarshallingProtocol.java	2009-10-28 01:44:11 UTC (rev 5572)
@@ -1,107 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2009, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.jboss.remoting3.spi;
-
-import org.jboss.marshalling.Marshaller;
-import org.jboss.marshalling.Unmarshaller;
-import org.jboss.marshalling.ClassTable;
-import org.jboss.marshalling.ObjectTable;
-import org.jboss.marshalling.ClassExternalizerFactory;
-import org.jboss.marshalling.ClassResolver;
-import org.jboss.marshalling.ObjectResolver;
-import org.jboss.xnio.Pool;
-import org.jboss.xnio.OptionMap;
-
-/**
- * A registered marshalling protocol.
- *
- * @remoting.implement
- */
-public interface MarshallingProtocol {
-
-    /**
-     * Get a configured unmarshaller pool.
-     *
-     * @param configuration the configuration to use
-     * @return the pool
-     */
-    Pool<Unmarshaller> getUnmarshallerPool(Configuration configuration);
-
-    /**
-     * Get a configured marshaller pool.
-     *
-     * @param configuration the configuration to use
-     * @return the pool
-     */
-    Pool<Marshaller> getMarshallerPool(Configuration configuration);
-
-    /**
-     * The configuration for a marshalling protocol.
-     *
-     * @remoting.consume
-     */
-    interface Configuration {
-
-        /**
-         * Get a user class table, if any.
-         *
-         * @return the user class table or {@code null} if none is configured
-         */
-        ClassTable getUserClassTable();
-
-        /**
-         * Get a user object table, if any.
-         *
-         * @return the user object table or {@code null} if none is configured
-         */
-        ObjectTable getUserObjectTable();
-
-        /**
-         * Get a user externalizer factory, if any.
-         *
-         * @return the user externalizer factory
-         */
-        ClassExternalizerFactory getUserExternalizerFactory();
-
-        /**
-         * Get a user class resolver, if any.
-         *
-         * @return the user class resolver
-         */
-        ClassResolver getUserClassResolver();
-
-        /**
-         * Get a user object resolver, if any.
-         *
-         * @return the user object resolver
-         */
-        ObjectResolver getUserObjectResolver();
-
-        /**
-         * Get the options to use for this marshaller configuration.
-         *
-         * @return the options
-         */
-        OptionMap getOptionMap();
-    }
-}

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/RemotingServiceDescriptor.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/RemotingServiceDescriptor.java	2009-10-24 22:49:32 UTC (rev 5571)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/RemotingServiceDescriptor.java	2009-10-28 01:44:11 UTC (rev 5572)
@@ -36,7 +36,6 @@
     /**
      * Get the type of service provided by this descriptor.  Only the following types are supported:
      * <ul>
-     * <li><code>{@link MarshallingProtocol}.class</code> - named marshalling protocol</li>
      * <li><code>{@link ConnectionProviderFactory}.class</code> - named connection provider URI scheme</li>
      * <li><code>{@link org.jboss.marshalling.ClassTable ClassTable}.class</code> - named marshalling class table</li>
      * <li><code>{@link org.jboss.marshalling.ObjectTable ObjectTable}.class</code> - named marshalling object table</li>

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/RequestHandlerConnector.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/RequestHandlerConnector.java	2009-10-24 22:49:32 UTC (rev 5571)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/RequestHandlerConnector.java	2009-10-28 01:44:11 UTC (rev 5572)
@@ -37,5 +37,5 @@
      * @return the cancellation handle
      * @throws SecurityException if this is a forwarding connector, thrown if the connector was not forwarded or if this method is called more than one time
      */
-    Cancellable createRequestHandler(Result<RequestHandler> result) throws SecurityException;
+    Cancellable createRequestHandler(org.jboss.xnio.Result<RequestHandler> result) throws SecurityException;
 }

Deleted: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/Result.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/Result.java	2009-10-24 22:49:32 UTC (rev 5571)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/Result.java	2009-10-28 01:44:11 UTC (rev 5572)
@@ -1,53 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2009, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.jboss.remoting3.spi;
-
-import java.io.IOException;
-
-/**
- * A handler for accepting the result of an operation.  Used by protocol implementations to tell Remoting
- * the result of an operation.
- *
- * @param <T> the type of the result
- */
-public interface Result<T> {
-
-    /**
-     * Indicate a successful result, and hand in the result value.
-     *
-     * @param result the result value
-     */
-    void setResult(T result);
-
-    /**
-     * Indicate a failure, and hand in the exception.
-     *
-     * @param exception the exception
-     */
-    void setException(IOException exception);
-
-    /**
-     * Indicate a cancellation of the operation.
-     */
-    void setCancelled();
-}

Modified: remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/simple/LocalBasicExample2Main.java
===================================================================
--- remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/simple/LocalBasicExample2Main.java	2009-10-24 22:49:32 UTC (rev 5571)
+++ remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/simple/LocalBasicExample2Main.java	2009-10-28 01:44:11 UTC (rev 5572)
@@ -27,7 +27,6 @@
 import org.jboss.remoting3.Endpoint;
 import org.jboss.remoting3.Remoting;
 import org.jboss.remoting3.Connection;
-import org.jboss.remoting3.LocalServiceConfiguration;
 import org.jboss.remoting3.Registration;
 import org.jboss.xnio.IoUtils;
 import org.jboss.xnio.OptionMap;
@@ -43,10 +42,9 @@
     public static void main(String[] args) throws Exception {
         final Endpoint endpoint = Remoting.createEndpoint("simple");
         try {
-            final LocalServiceConfiguration<String, String> config = LocalServiceConfiguration.create(new StringRot13ClientListener(), String.class, String.class);
-            config.setGroupName("main");
-            config.setServiceType("simple.rot13");
-            final Registration handle = endpoint.registerService(config);
+            final Registration handle = endpoint.serviceBuilder().setServiceType("simple.rot13").setGroupName("main")
+                    .setRequestType(String.class).setReplyType(String.class).setClientListener(new StringRot13ClientListener())
+                    .register();
             try {
                 final Connection connection = endpoint.connect(new URI("local:///"), OptionMap.EMPTY).get();
                 try {

Copied: remoting3/trunk/taglet/src/main/java/org/jboss/remoting3/taglet/RemotingNonBlockingTaglet.java (from rev 5492, remoting3/trunk/taglet/src/main/java/org/jboss/remoting3/taglet/RemotingInternalTaglet.java)
===================================================================
--- remoting3/trunk/taglet/src/main/java/org/jboss/remoting3/taglet/RemotingNonBlockingTaglet.java	                        (rev 0)
+++ remoting3/trunk/taglet/src/main/java/org/jboss/remoting3/taglet/RemotingNonBlockingTaglet.java	2009-10-28 01:44:11 UTC (rev 5572)
@@ -0,0 +1,40 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.remoting3.taglet;
+
+import com.sun.javadoc.Tag;
+
+public final class RemotingNonBlockingTaglet extends RemotingTypeTaglet {
+
+    public String getName() {
+        return "remoting.nonblocking";
+    }
+
+    public String toString(final Tag tag) {
+        return "<p><b>Non-blocking method</b> - this method is expected to operate on a non-blocking basis.  That is, " +
+                "the method is expected to return in a relatively short amount of time, and the result of the method is " +
+                "not expected to be available at the time this method returns.  Instead, the " +
+                "method implementation should take whatever steps are necessary to initiate the operation asynchronously " +
+                "and then return.  If a result is available immediately, it is allowed to report the result immediately.\n";
+    }
+}
\ No newline at end of file

Modified: remoting3/trunk/taglet/src/main/java/org/jboss/remoting3/taglet/RemotingTypeTaglet.java
===================================================================
--- remoting3/trunk/taglet/src/main/java/org/jboss/remoting3/taglet/RemotingTypeTaglet.java	2009-10-24 22:49:32 UTC (rev 5571)
+++ remoting3/trunk/taglet/src/main/java/org/jboss/remoting3/taglet/RemotingTypeTaglet.java	2009-10-28 01:44:11 UTC (rev 5572)
@@ -86,5 +86,6 @@
         add(tagletMap, new RemotingConsumeTaglet());
         add(tagletMap, new RemotingImplementTaglet());
         add(tagletMap, new RemotingInternalTaglet());
+        add(tagletMap, new RemotingNonBlockingTaglet());
     }
 }



More information about the jboss-remoting-commits mailing list