Author: david.lloyd(a)jboss.com
Date: 2009-10-22 12:52:02 -0400 (Thu, 22 Oct 2009)
New Revision: 5562
Added:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/ConnectionProviderDescriptor.java
Modified:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Endpoint.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Options.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/RemoteExecutionException.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Remoting.java
Log:
Remoting API cleanup; start of service provider automation for connection providers.
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-17
00:14:13 UTC (rev 5561)
+++
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Endpoint.java 2009-10-22
16:52:02 UTC (rev 5562)
@@ -36,7 +36,7 @@
* @param requestListener the request listener
* @param requestClass the class of requests sent to this request listener
* @param replyClass the class of replies received back from this request listener
- * @return a handle for the client
+ * @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;
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-17
00:14:13 UTC (rev 5561)
+++
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Options.java 2009-10-22
16:52:02 UTC (rev 5562)
@@ -34,6 +34,16 @@
}
/**
+ * Configure the maximum number of threads for a simple endpoint.
+ */
+ public static final Option<Integer> MAX_THREADS = Option.simple(Options.class,
"MAX_THREADS", Integer.class);
+
+ /**
+ * Specify whether connection providers should automatically be detected and loaded.
+ */
+ 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.
*/
Modified:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/RemoteExecutionException.java
===================================================================
---
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/RemoteExecutionException.java 2009-10-17
00:14:13 UTC (rev 5561)
+++
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/RemoteExecutionException.java 2009-10-22
16:52:02 UTC (rev 5562)
@@ -76,15 +76,51 @@
}
/**
- * Rethrow the cause, if it is a runtime exception. This is a convenience method to
extract a runtime exception
- * from a remote execution exception.
+ * Convenience method to rethrow the cause of a {@code RemoteExecutionException} as a
specific type, in order
+ * to simplify application exception handling.
+ * <p/>
+ * A typical usage might look like this:
+ * <pre>
+ * try {
+ * client.invoke(request);
+ * } catch (RemoteExecutionException ree) {
+ * ree.rethrow(IOException.class);
+ * ree.rethrow(RuntimeException.class);
+ * throw ree.unexpected();
+ * }
+ * </pre>
+ * <p/>
+ * Note that if the nested exception is an {@link InterruptedException}, the type
that will actually be thrown
+ * will be {@link RemoteInterruptedException}.
*
- * @throws RuntimeException the cause
+ * @param type the class of the exception
+ * @param <T> the exception type
+ * @throws T the exception, if it matches the given type
*/
- public final void throwRuntime() throws RuntimeException {
+ public <T extends Throwable> void rethrow(Class<T> type) throws T {
final Throwable cause = getCause();
- if (cause instanceof RuntimeException) {
- throw ((RuntimeException)cause);
+ if (cause == null) {
+ return;
}
+ if (type.isAssignableFrom(cause.getClass()) || type ==
RemoteInterruptedException.class) {
+ if (cause instanceof InterruptedException) {
+ final RemoteInterruptedException rie = new
RemoteInterruptedException(cause.getMessage(), cause.getCause());
+ rie.setStackTrace(cause.getStackTrace());
+ throw rie;
+ }
+ throw type.cast(cause);
+ }
+ return;
}
+
+ /**
+ * Convenience method to get an unexpected exception type wrapped within a runtime
exception.
+ */
+ public IllegalStateException unexpected() {
+ Throwable cause = getCause();
+ if (cause instanceof InterruptedException) {
+ cause = new RemoteInterruptedException(cause.getMessage(),
cause.getCause());
+ }
+ throw new IllegalStateException("Unexpected remote exception occurred",
cause);
+ }
}
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-17
00:14:13 UTC (rev 5561)
+++
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Remoting.java 2009-10-22
16:52:02 UTC (rev 5562)
@@ -29,9 +29,12 @@
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
+import java.util.ServiceLoader;
import org.jboss.remoting3.spi.RequestHandler;
+import org.jboss.remoting3.spi.ConnectionProviderDescriptor;
import org.jboss.xnio.CloseableExecutor;
import org.jboss.xnio.IoUtils;
+import org.jboss.xnio.OptionMap;
import org.jboss.xnio.log.Logger;
/**
@@ -46,6 +49,8 @@
/**
* Create an endpoint. The endpoint will create its own thread pool with a maximum
of 10 threads.
+ * <p>
+ * You must have the {@link org.jboss.remoting3.EndpointPermission createEndpoint
EndpointPermission} to invoke this method.
*
* @param name the name of the endpoint
* @return the endpoint
@@ -56,7 +61,7 @@
/**
* Create an endpoint. The endpoint will create its own thread pool with a maximum
of {@code maxThreads} threads.
- *
+ * <p>
* You must have the {@link org.jboss.remoting3.EndpointPermission createEndpoint
EndpointPermission} to invoke this method.
*
* @param name the name of the endpoint
@@ -64,13 +69,41 @@
* @return the endpoint
*/
public static Endpoint createEndpoint(final String name, final int maxThreads) throws
IOException {
- final CloseableExecutor executor = createExecutor(maxThreads);
+ return createEndpoint(name, OptionMap.builder().set(Options.MAX_THREADS,
maxThreads).getMap());
+ }
+
+ /**
+ * Create an endpoint configured with the given option map. The following options
are supported:
+ * <ul>
+ * <li>{@link Options#MAX_THREADS} - specify the maximum number of threads for
the created thread pool (default 10)</li>
+ * <li>{@link Options#LOAD_PROVIDERS} - specify whether providers should be
auto-loaded (default {@code true})</li>
+ * </ul>
+ *
+ * @param name the endpoint name
+ * @param optionMap the endpoint options
+ * @return the endpoint
+ * @throws IOException if an error occurs
+ */
+ public static Endpoint createEndpoint(final String name, final OptionMap optionMap)
throws IOException {
+ if (name == null) {
+ throw new NullPointerException("name is null");
+ }
+ if (optionMap == null) {
+ throw new NullPointerException("optionMap is null");
+ }
+ final CloseableExecutor executor =
createExecutor(optionMap.get(Options.MAX_THREADS, 10));
final Endpoint endpoint = createEndpoint(executor, name);
endpoint.addCloseHandler(new CloseHandler<Endpoint>() {
public void handleClose(final Endpoint closed) {
IoUtils.safeClose(executor);
}
});
+ if (optionMap.get(Options.LOAD_PROVIDERS, true)) {
+ for (ConnectionProviderDescriptor descriptor :
ServiceLoader.load(ConnectionProviderDescriptor.class)) {
+ endpoint.addConnectionProvider(descriptor.getUriScheme(),
descriptor.getConnectionProviderFactory());
+ }
+ // todo - marshallers and components thereof
+ }
return endpoint;
}
@@ -124,58 +157,18 @@
* @throws IOException if an error occurs
*/
public static <I, O> Client<I, O> createLocalClient(final Endpoint
endpoint, final RequestListener<I, O> requestListener, final Class<I>
requestClass, final Class<O> replyClass) throws IOException {
+ boolean ok = false;
final RequestHandler requestHandler =
endpoint.createLocalRequestHandler(requestListener, requestClass, replyClass);
try {
- return endpoint.createClient(requestHandler, requestClass, replyClass);
+ final Client<I, O> client = endpoint.createClient(requestHandler,
requestClass, replyClass);
+ ok = true;
+ return client;
} finally {
- IoUtils.safeClose(requestHandler);
- }
- }
-
- /**
- * Convenience method to rethrow the cause of a {@code RemoteExecutionException} as a
specific type, in order
- * to simplify application exception handling.
- * <p/>
- * A typical usage might look like this:
- * <pre>
- * try {
- * client.invoke(request);
- * } catch (RemoteExecutionException ree) {
- * Remoting.rethrowAs(IOException.class, ree);
- * Remoting.rethrowAs(RuntimeException.class, ree);
- * Remoting.rethrowUnexpected(ree);
- * }
- * </pre>
- * <p/>
- * Note that if the nested exception is an {@link InterruptedException}, the type
that will actually be thrown
- * will be {@link RemoteInterruptedException}.
- *
- * @param type the class of the exception
- * @param original the remote execution exception
- * @param <T> the exception type
- * @throws T the exception, if it matches the given type
- */
- public static <T extends Throwable> void rethrowAs(Class<T> type,
RemoteExecutionException original) throws T {
- final Throwable cause = original.getCause();
- if (cause == null) {
- return;
- }
- if (type.isAssignableFrom(cause.getClass())) {
- if (cause instanceof InterruptedException) {
- throw new RemoteInterruptedException(cause.getMessage(),
cause.getCause());
+ if (! ok) {
+ IoUtils.safeClose(requestHandler);
}
- throw type.cast(cause);
}
- return;
}
- public static void rethrowUnexpected(RemoteExecutionException original) throws
IllegalStateException {
- Throwable cause = original.getCause();
- if (cause instanceof InterruptedException) {
- cause = new RemoteInterruptedException(cause.getMessage(),
cause.getCause());
- }
- throw new IllegalStateException("Unexpected remote exception occurred",
cause);
- }
-
private Remoting() { /* empty */ }
}
Added:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/ConnectionProviderDescriptor.java
===================================================================
---
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/ConnectionProviderDescriptor.java
(rev 0)
+++
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/ConnectionProviderDescriptor.java 2009-10-22
16:52:02 UTC (rev 5562)
@@ -0,0 +1,45 @@
+/*
+ * 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;
+
+/**
+ * A descriptor for automatically-discovered connection provider types. Since instances
of this interface are
+ * constructed automatically, implementing classes should have a no-arg constructor.
+ */
+public interface ConnectionProviderDescriptor {
+
+ /**
+ * Get the URI scheme for this provider. A provider factory may be registered more
than one time with different
+ * URI schemes.
+ *
+ * @return the URI scheme
+ */
+ String getUriScheme();
+
+ /**
+ * Get the connection provider factory to associate with the given URI scheme.
+ *
+ * @return the connection provider factory
+ */
+ ConnectionProviderFactory<?> getConnectionProviderFactory();
+}