JBoss Remoting SVN: r5501 - in remoting3-multiplex/trunk: src and 6 other directories.
by jboss-remoting-commits@lists.jboss.org
Author: david.lloyd(a)jboss.com
Date: 2009-09-16 13:44:19 -0400 (Wed, 16 Sep 2009)
New Revision: 5501
Added:
remoting3-multiplex/trunk/src/
remoting3-multiplex/trunk/src/main/
remoting3-multiplex/trunk/src/main/java/
remoting3-multiplex/trunk/src/main/java/org/
remoting3-multiplex/trunk/src/main/java/org/jboss/
remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/
remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/
remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/AtomicArrayReferenceArray.java
remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/ConfigParam.java
remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/ConnectionConfiguration.java
remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/EstablishedConnection.java
remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/InitialReadHandlerImpl.java
remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/Loggers.java
remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/MessageType.java
remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/MultiplexConnectionHandler.java
remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/MultiplexConnectionProvider.java
remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/MultiplexOptions.java
remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/MultiplexRemoteRequestContext.java
remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/MultiplexRequestHandler.java
remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/MultiplexRequestHandlerConnector.java
remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/PermitManager.java
remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/ReadHandlerImpl.java
remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/ReceivingByteInput.java
remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/RemoteClient.java
remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/SendingByteOutput.java
remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/package-info.java
Log:
Initial import of new impl
Added: remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/AtomicArrayReferenceArray.java
===================================================================
--- remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/AtomicArrayReferenceArray.java (rev 0)
+++ remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/AtomicArrayReferenceArray.java 2009-09-16 17:44:19 UTC (rev 5501)
@@ -0,0 +1,170 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file 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.multiplex;
+
+import java.lang.reflect.Array;
+import java.util.concurrent.atomic.AtomicReferenceArray;
+
+final class AtomicArrayReferenceArray<V> extends AtomicReferenceArray<V[]> {
+
+ private final V[] emptyArray;
+ private final Class<V> componentType;
+
+ private static final long serialVersionUID = -4748109403436000080L;
+
+ private AtomicArrayReferenceArray(Class<V> componentType, int length) {
+ super(length);
+ this.componentType = componentType;
+ emptyArray = newInstance(componentType, 0);
+ }
+
+ public static <V> AtomicArrayReferenceArray<V> create(AtomicReferenceArray<V[]> array, Class<V> componentType) {
+ return new AtomicArrayReferenceArray<V>(array, componentType);
+ }
+
+ @SuppressWarnings({ "unchecked" })
+ private static <V> V[] copyOf(final Class<V> componentType, V[] old, int newLen) {
+ final V[] target = newInstance(componentType, newLen);
+ System.arraycopy(old, 0, target, 0, Math.min(old.length, newLen));
+ return target;
+ }
+
+ public void add(int idx, V value) {
+ for (;;) {
+ final V[] oldVal = get(idx);
+ final int oldLen = oldVal.length;
+ final V[] newVal = copyOf(componentType, oldVal, oldLen + 1);
+ newVal[oldLen] = value;
+ if (compareAndSet(idx, oldVal, newVal)) {
+ return;
+ }
+ }
+ }
+
+ public boolean addIfAbsent(int idx, V value, boolean identity) {
+ for (;;) {
+ final V[] oldVal = get(idx);
+ final int oldLen = oldVal.length;
+ if (identity || value == null) {
+ for (int i = 0; i < oldLen; i++) {
+ if (oldVal[i] == value) {
+ return false;
+ }
+ }
+ } else {
+ for (int i = 0; i < oldLen; i++) {
+ if (value.equals(oldVal[i])) {
+ return false;
+ }
+ }
+ }
+ final V[] newVal = copyOf(componentType, oldVal, oldLen + 1);
+ newVal[oldLen] = value;
+ if (compareAndSet(idx, oldVal, newVal)) {
+ return true;
+ }
+ }
+ }
+
+ public boolean remove(int idx, V value, boolean identity) {
+ for (;;) {
+ final V[] oldVal = get(idx);
+ final int oldLen = oldVal.length;
+ if (oldLen == 0) {
+ return false;
+ } else {
+ int index = -1;
+ if (identity || value == null) {
+ for (int i = 0; i < oldLen; i++) {
+ if (oldVal[i] == value) {
+ index = i;
+ break;
+ }
+ }
+ } else {
+ for (int i = 0; i < oldLen; i++) {
+ if (value.equals(oldVal[i])) {
+ index = i;
+ break;
+ }
+ }
+ }
+ if (index == -1) {
+ return false;
+ }
+ final V[] newVal = newInstance(componentType, oldLen - 1);
+ System.arraycopy(oldVal, 0, newVal, 0, index);
+ System.arraycopy(oldVal, index + 1, newVal, index, oldLen - index - 1);
+ if (compareAndSet(idx, oldVal, newVal)) {
+ return true;
+ }
+ }
+ }
+ }
+
+ public int removeAll(int idx, V value, boolean identity) {
+ for (;;) {
+ final V[] oldVal = get(idx);
+ final int oldLen = oldVal.length;
+ if (oldLen == 0) {
+ return 0;
+ } else {
+ final boolean[] removeSlots = new boolean[oldLen];
+ int removeCount = 0;
+ if (identity || value == null) {
+ for (int i = 0; i < oldLen; i++) {
+ if (oldVal[i] == value) {
+ removeSlots[i] = true;
+ removeCount++;
+ }
+ }
+ } else {
+ for (int i = 0; i < oldLen; i++) {
+ if (value.equals(oldVal[i])) {
+ removeSlots[i] = true;
+ removeCount++;
+ }
+ }
+ }
+ if (removeCount == 0) {
+ return 0;
+ }
+ final int newLen = oldLen - removeCount;
+ final V[] newVal;
+ if (newLen == 0) {
+ newVal = emptyArray;
+ } else {
+ newVal = newInstance(componentType, newLen);
+ for (int i = 0, j = 0; i < oldLen; i ++) {
+ if (! removeSlots[i]) {
+ newVal[j++] = oldVal[i];
+ }
+ }
+ }
+ if (compareAndSet(idx, oldVal, newVal)) {
+ return removeCount;
+ }
+ }
+ }
+ }
+}
Added: remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/ConfigParam.java
===================================================================
--- remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/ConfigParam.java (rev 0)
+++ remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/ConfigParam.java 2009-09-16 17:44:19 UTC (rev 5501)
@@ -0,0 +1,17 @@
+package org.jboss.remoting3.multiplex;
+
+/**
+ * Protocol message configuration parameters used in protocol negotiation phase. Do not delete, insert, or change the order of these
+ * enum constants. New constants must be added to the end.
+ */
+enum ConfigParam {
+ MAX_SUPPORTED_VERSION,
+ MAX_RECEIVE_SIZE,
+ MAX_TRANSMIT_SIZE,
+ MAX_RECEIVE_WINDOW_SIZE,
+ MAX_TRANSMIT_WINDOW_SIZE,
+ MAX_OUTBOUND_REQUESTS,
+ MAX_INBOUND_REQUESTS,
+ MAX_OUTBOUND_CLIENTS,
+ MAX_INBOUND_CLIENTS,
+}
Added: remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/ConnectionConfiguration.java
===================================================================
--- remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/ConnectionConfiguration.java (rev 0)
+++ remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/ConnectionConfiguration.java 2009-09-16 17:44:19 UTC (rev 5501)
@@ -0,0 +1,160 @@
+/*
+ * 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.multiplex;
+
+/**
+ * A configuration object for the multiplex protocol.
+ */
+public final class ConnectionConfiguration implements Cloneable {
+
+ private int linkMetric = 100;
+ private int maximumReceiveSize = 0x200;
+ private int maximumTransmitSize = 0x200;
+ private int receiveWindowSize = 5;
+ private int transmitWindowSize = 5;
+ private int maximumOutboundClients = 0x10;
+ private int maximumInboundClients = 0x10;
+ private int maximumOutboundRequests = 0x10;
+ private int maximumInboundRequests = 0x10;
+ private int maximumOutboundStreams = 0x20;
+ private int maximumInboundStreams = 0x20;
+
+ /**
+ * Construct a new instance.
+ */
+ public ConnectionConfiguration() {
+ }
+
+ /**
+ * Get the link metric to assign to this multiplex connection.
+ *
+ * @return the link metric
+ */
+ public int getLinkMetric() {
+ return linkMetric;
+ }
+
+ /**
+ * Set the link metric to assign to this multiplex connection.
+ *
+ * @param linkMetric the link metric
+ */
+ public void setLinkMetric(final int linkMetric) {
+ this.linkMetric = linkMetric;
+ }
+
+
+ public int getMaximumReceiveSize() {
+ return maximumReceiveSize;
+ }
+
+ public void setMaximumReceiveSize(final int maximumReceiveSize) {
+ this.maximumReceiveSize = maximumReceiveSize;
+ }
+
+ public int getMaximumTransmitSize() {
+ return maximumTransmitSize;
+ }
+
+ public void setMaximumTransmitSize(final int maximumTransmitSize) {
+ this.maximumTransmitSize = maximumTransmitSize;
+ }
+
+ public int getReceiveWindowSize() {
+ return receiveWindowSize;
+ }
+
+ public void setReceiveWindowSize(final int receiveWindowSize) {
+ this.receiveWindowSize = receiveWindowSize;
+ }
+
+ public int getTransmitWindowSize() {
+ return transmitWindowSize;
+ }
+
+ public void setTransmitWindowSize(final int transmitWindowSize) {
+ this.transmitWindowSize = transmitWindowSize;
+ }
+
+ public int getMaximumOutboundClients() {
+ return maximumOutboundClients;
+ }
+
+ public void setMaximumOutboundClients(final int maximumOutboundClients) {
+ this.maximumOutboundClients = maximumOutboundClients;
+ }
+
+ public int getMaximumInboundClients() {
+ return maximumInboundClients;
+ }
+
+ public void setMaximumInboundClients(final int maximumInboundClients) {
+ this.maximumInboundClients = maximumInboundClients;
+ }
+
+ public int getMaximumOutboundRequests() {
+ return maximumOutboundRequests;
+ }
+
+ public void setMaximumOutboundRequests(final int maximumOutboundRequests) {
+ this.maximumOutboundRequests = maximumOutboundRequests;
+ }
+
+ public int getMaximumInboundRequests() {
+ return maximumInboundRequests;
+ }
+
+ public void setMaximumInboundRequests(final int maximumInboundRequests) {
+ this.maximumInboundRequests = maximumInboundRequests;
+ }
+
+ public int getMaximumOutboundStreams() {
+ return maximumOutboundStreams;
+ }
+
+ public void setMaximumOutboundStreams(final int maximumOutboundStreams) {
+ this.maximumOutboundStreams = maximumOutboundStreams;
+ }
+
+ public int getMaximumInboundStreams() {
+ return maximumInboundStreams;
+ }
+
+ public void setMaximumInboundStreams(final int maximumInboundStreams) {
+ this.maximumInboundStreams = maximumInboundStreams;
+ }
+
+ /**
+ * Clone this configuration.
+ *
+ * @return the cloned configuration
+ */
+ public ConnectionConfiguration clone() {
+ try {
+ final ConnectionConfiguration clone = (ConnectionConfiguration) super.clone();
+ return clone;
+ } catch (CloneNotSupportedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
\ No newline at end of file
Added: remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/EstablishedConnection.java
===================================================================
--- remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/EstablishedConnection.java (rev 0)
+++ remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/EstablishedConnection.java 2009-09-16 17:44:19 UTC (rev 5501)
@@ -0,0 +1,237 @@
+/*
+ * 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.multiplex;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicReferenceArray;
+import java.util.Iterator;
+import org.jboss.marshalling.Marshaller;
+import org.jboss.marshalling.Unmarshaller;
+import org.jboss.remoting3.IndeterminateOutcomeException;
+import org.jboss.remoting3.spi.AbstractHandleableCloseable;
+import org.jboss.remoting3.spi.Cancellable;
+import org.jboss.remoting3.spi.ConnectionHandler;
+import org.jboss.remoting3.spi.RemoteRequestContext;
+import org.jboss.remoting3.spi.ReplyHandler;
+import org.jboss.remoting3.spi.RequestHandler;
+import org.jboss.remoting3.spi.RequestHandlerConnector;
+import org.jboss.remoting3.spi.Result;
+import org.jboss.remoting3.spi.SpiUtils;
+import org.jboss.xnio.BufferAllocator;
+import org.jboss.xnio.Buffers;
+import org.jboss.xnio.Pool;
+import org.jboss.xnio.IoFuture;
+import org.jboss.xnio.IoUtils;
+import org.jboss.xnio.channels.AllocatedMessageChannel;
+import org.jboss.xnio.log.Logger;
+
+/**
+ *
+ */
+final class EstablishedConnection extends AbstractHandleableCloseable implements ConnectionHandler {
+ private static final Logger log = Loggers.MAIN_LOGGER;
+
+ //--== Connection configuration items ==--
+ private final Pool<Marshaller> marshallerPool;
+ private final Pool<Unmarshaller> unmarshallerPool;
+ private final int linkMetric;
+ private final Executor executor;
+ // buffer allocator for outbound message assembly
+ private final BufferAllocator<ByteBuffer> allocator;
+
+ // running on remote node
+ private final AtomicReferenceArray<ReplyHandler> remoteRequests;
+ // sequence for outbound remote requests
+ private final PermitManager requestPermits;
+
+ // running on local node (key comes from remote side)
+ private final AtomicReferenceArray<RemoteRequestContext> localRequests;
+
+ // clients whose requests get forwarded to the remote side
+ private final AtomicReferenceArray<RemoteClient> remoteClients;
+ // sequence for clients whose requests get forwarded to the remote side
+ // LOW BIT == 0
+ private final PermitManager remoteClientPermits;
+
+ // clients whose requests are handled on this side (key comes from remote side)
+ private final AtomicReferenceArray<RequestHandler> requestedClients;
+ // LOW BIT == 1;
+ private final PermitManager forwardedClientPermits;
+
+ // the data channel
+ private final AllocatedMessageChannel channel;
+ // the local connection handler
+ private final ConnectionHandler localConnectionHandler;
+
+ private final int sendWindowSize;
+
+ private static final ThreadLocal<EstablishedConnection> currentConnection = new ThreadLocal<EstablishedConnection>();
+
+ public EstablishedConnection(final AllocatedMessageChannel channel, final ConnectionConfiguration configuration, final ConnectionHandler localConnectionHandler) {
+ super(configuration.getExecutor());
+ this.channel = channel;
+ linkMetric = configuration.getLinkMetric();
+ executor = configuration.getExecutor();
+ if (executor == null) {
+ throw new NullPointerException("executor is null");
+ }
+ allocator = Buffers.createHeapByteBufferAllocator(configuration.getMaximumTransmitSize());
+ marshallerPool = configuration.getMarshallerPool();
+ unmarshallerPool = configuration.getUnmarshallerPool();
+ final int maximumInboundRequests = configuration.getMaximumInboundRequests();
+ remoteRequests = new AtomicReferenceArray<ReplyHandler>(maximumInboundRequests);
+ requestPermits = new PermitManager(maximumInboundRequests);
+ final int maximumOutboundRequests = configuration.getMaximumOutboundRequests();
+ localRequests = new AtomicReferenceArray<RemoteRequestContext>(maximumOutboundRequests);
+ final int maximumOutboundClients = configuration.getMaximumOutboundClients();
+ remoteClients = new AtomicReferenceArray<RemoteClient>(maximumOutboundClients);
+ remoteClientPermits = new PermitManager(maximumOutboundClients);
+ final int maximumInboundClients = configuration.getMaximumInboundClients();
+ requestedClients = new AtomicReferenceArray<RequestHandler>(maximumInboundClients);
+ forwardedClientPermits = new PermitManager(maximumInboundClients);
+ sendWindowSize = configuration.getTransmitWindowSize();
+ this.localConnectionHandler = localConnectionHandler;
+ }
+
+ static EstablishedConnection getCurrent() {
+ return currentConnection.get();
+ }
+
+ void setCurrent() {
+ if (currentConnection.get() != null) {
+ throw new IllegalStateException("Reentrant setCurrent()");
+ }
+ currentConnection.set(this);
+ }
+
+ void clearCurrent() {
+ if (currentConnection.get() != this) {
+ throw new IllegalStateException("clearCurrent() from wrong context");
+ }
+ currentConnection.set(null);
+ }
+
+ // sequence methods
+
+ protected Executor getExecutor() {
+ return executor;
+ }
+
+ int getLinkMetric() {
+ return linkMetric;
+ }
+
+ BufferAllocator<ByteBuffer> getAllocator() {
+ return allocator;
+ }
+
+ AllocatedMessageChannel getChannel() {
+ return channel;
+ }
+
+ Pool<Marshaller> getMarshallerPool() {
+ return marshallerPool;
+ }
+
+ Pool<Unmarshaller> getUnmarshallerPool() {
+ return unmarshallerPool;
+ }
+
+ ConnectionHandler getLocalConnectionHandler() {
+ return localConnectionHandler;
+ }
+
+ private static final IoFuture.Notifier<RequestHandler, Result<RequestHandler>> RHS_RESULT_NOTIFIER =
+ new IoFuture.HandlingNotifier<RequestHandler, Result<RequestHandler>>() {
+ public void handleCancelled(final Result<RequestHandler> attachment) {
+ log.trace("Failed to open remote service (cancelled)");
+ attachment.setCancelled();
+ }
+
+ public void handleFailed(final IOException exception, final Result<RequestHandler> attachment) {
+ log.trace("Failed to open remote service: %s", exception);
+ attachment.setException(exception);
+ }
+
+ public void handleDone(final RequestHandler result, final Result<RequestHandler> attachment) {
+ log.trace("Opened %s", result);
+ attachment.setResult(result);
+ }
+ };
+
+ protected void closeAction() {
+ // just to make sure...
+ IoUtils.safeClose(channel);
+ final IndeterminateOutcomeException ioe = new IndeterminateOutcomeException("The connection was closed");
+ // Things running remotely
+ for (int i = 0; i < remoteRequests.length(); i ++) {
+ SpiUtils.safeHandleException(remoteRequests.getAndSet(i, null), ioe);
+ }
+ for (RemoteClient x : clearing(remoteClients)) {
+ IoUtils.safeClose(x.getRequestHandler());
+ }
+ // Things running locally
+ for (RemoteRequestContext localRequest : clearing(localRequests)) {
+ localRequest.cancel();
+ }
+ }
+
+ public String toString() {
+ return "multiplex connection <" + Integer.toHexString(hashCode()) + "> via " + channel;
+ }
+
+ public Cancellable open(final String serviceName, final String groupName, final Result<RequestHandler> result) {
+ return null;
+ }
+
+ public RequestHandlerConnector createConnector(final RequestHandler localHandler) {
+ return null;
+ }
+
+ int getSendWindowSize() {
+ return sendWindowSize;
+ }
+
+ private static <T> Iterable<T> clearing(final AtomicReferenceArray<T> array) {
+ return new Iterable<T>() {
+
+ public Iterator<T> iterator() {
+ return new Iterator<T>() {
+ private int idx;
+ public boolean hasNext() {
+ return idx < array.length();
+ }
+
+ public T next() {
+ return array.getAndSet(idx++, null);
+ }
+
+ public void remove() {
+ }
+ };
+ }
+ };
+ }
+}
\ No newline at end of file
Added: remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/InitialReadHandlerImpl.java
===================================================================
--- remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/InitialReadHandlerImpl.java (rev 0)
+++ remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/InitialReadHandlerImpl.java 2009-09-16 17:44:19 UTC (rev 5501)
@@ -0,0 +1,125 @@
+/*
+ * 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.multiplex;
+
+import org.jboss.xnio.IoReadHandler;
+import org.jboss.xnio.IoUtils;
+import org.jboss.xnio.channels.AllocatedMessageChannel;
+import org.jboss.remoting3.spi.Result;
+import org.jboss.remoting3.spi.ConnectionHandlerFactory;
+import org.jboss.remoting3.ProtocolException;
+import java.nio.ByteBuffer;
+import java.nio.BufferUnderflowException;
+import java.io.IOException;
+
+/**
+ * Read handler for initial (negotiation) phase of connection.
+ */
+final class InitialReadHandlerImpl implements IoReadHandler<AllocatedMessageChannel> {
+
+ private final Result<ConnectionHandlerFactory> result;
+
+ private static final int GREETING = 0x484a524d;
+ private static final int MAX_VERSION = 0;
+
+ private final ConnectionConfiguration connectionConfiguration;
+
+ InitialReadHandlerImpl(final Result<ConnectionHandlerFactory> result, final ConnectionConfiguration connectionConfiguration) {
+ this.result = result;
+ this.connectionConfiguration = connectionConfiguration;
+ }
+
+ public void handleReadable(final AllocatedMessageChannel channel) {
+ try {
+ final ByteBuffer buffer = channel.receive();
+ if (buffer.getInt() != GREETING) {
+ throw new IOException("Incorrect greeting");
+ }
+ final ConfigParam[] paramIds = ConfigParam.values();
+ final ConnectionConfiguration conf = connectionConfiguration;
+ final int count = buffer.getShort() & 0xffff;
+ for (int i = 0; i < count; i ++) {
+ final int id = buffer.get() & 0xff;
+ if (id > paramIds.length) {
+ continue;
+ }
+ final ConfigParam configParam = paramIds[id];
+ switch (configParam) {
+ case MAX_SUPPORTED_VERSION: {
+ // since we're version 0, the remote side must support us, and we support nothing else, so...
+ break;
+ }
+ case MAX_RECEIVE_SIZE: {
+ conf.setMaximumTransmitSize(Math.min(validate(ConfigParam.MAX_RECEIVE_SIZE, buffer.getInt(), 0x100, 0x100000), conf.getMaximumTransmitSize()));
+ break;
+ }
+ case MAX_TRANSMIT_SIZE: {
+ conf.setMaximumReceiveSize(Math.min(validate(ConfigParam.MAX_TRANSMIT_SIZE, buffer.getInt(), 0x100, 0x100000), conf.getMaximumReceiveSize()));
+ break;
+ }
+ case MAX_RECEIVE_WINDOW_SIZE: {
+ conf.setTransmitWindowSize(Math.min(validate(ConfigParam.MAX_RECEIVE_WINDOW_SIZE, buffer.getInt(), 0x2, 0x400), conf.getTransmitWindowSize()));
+ break;
+ }
+ case MAX_TRANSMIT_WINDOW_SIZE: {
+ conf.setReceiveWindowSize(Math.min(validate(ConfigParam.MAX_TRANSMIT_WINDOW_SIZE, buffer.getInt(), 0x2, 0x400), conf.getReceiveWindowSize()));
+ break;
+ }
+ case MAX_OUTBOUND_REQUESTS: {
+ conf.setMaximumInboundRequests(Math.min(validate(ConfigParam.MAX_OUTBOUND_REQUESTS, buffer.getInt(), 0, 0x100000), conf.getMaximumInboundRequests()));
+ break;
+ }
+ case MAX_INBOUND_REQUESTS: {
+ conf.setMaximumOutboundRequests(Math.min(validate(ConfigParam.MAX_INBOUND_REQUESTS, buffer.getInt(), 0, 0x100000), conf.getMaximumOutboundRequests()));
+ break;
+ }
+ case MAX_OUTBOUND_CLIENTS: {
+ conf.setMaximumInboundClients(Math.min(validate(ConfigParam.MAX_OUTBOUND_CLIENTS, buffer.getInt(), 0, 0x100000), conf.getMaximumInboundClients()));
+ break;
+ }
+ case MAX_INBOUND_CLIENTS: {
+ conf.setMaximumOutboundClients(Math.min(validate(ConfigParam.MAX_INBOUND_CLIENTS, buffer.getInt(), 0, 0x100000), conf.getMaximumOutboundClients()));
+ break;
+ }
+ default: {
+ // should not be possible
+ throw new IllegalStateException();
+ }
+ }
+ }
+ } catch (IOException e) {
+ IoUtils.safeClose(channel);
+ result.setException(e);
+ } catch (BufferUnderflowException e) {
+ IoUtils.safeClose(channel);
+ result.setException(new ProtocolException("Truncated greeting packet"));
+ }
+ }
+
+ private static int validate(Object field, int val, int min, int max) throws ProtocolException {
+ if (val >= min && val <= max) {
+ return val;
+ }
+ throw new ProtocolException("Value of " + field + " is out of range (expected " + min + " <= n <= " + max + ", got " + val + ")");
+ }
+}
Added: remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/Loggers.java
===================================================================
--- remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/Loggers.java (rev 0)
+++ remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/Loggers.java 2009-09-16 17:44:19 UTC (rev 5501)
@@ -0,0 +1,37 @@
+/*
+ * 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.multiplex;
+
+import org.jboss.xnio.log.Logger;
+
+final class Loggers {
+
+ private Loggers() {
+ }
+
+ private static final String MAIN_LOGGER_NAME = "org.jboss.remoting.multiplex";
+ private static final String REQUEST_HANDLER_LOGGER_NAME = MAIN_LOGGER_NAME + ".request-handler";
+
+ static final Logger REQUEST_HANDLER_LOGGER = Logger.getLogger(REQUEST_HANDLER_LOGGER_NAME);
+ static final Logger MAIN_LOGGER = Logger.getLogger(MAIN_LOGGER_NAME);
+}
Added: remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/MessageType.java
===================================================================
--- remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/MessageType.java (rev 0)
+++ remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/MessageType.java 2009-09-16 17:44:19 UTC (rev 5501)
@@ -0,0 +1,73 @@
+/*
+ * 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.multiplex;
+
+final class MessageType {
+ private MessageType() {}
+
+ public static final int FIRST = 0x80;
+ public static final int LAST = 0x40;
+
+ // Stream message data types
+
+ public static final int DATA = 0x00;
+ public static final int CANCEL = 0x01;
+ public static final int FINAL = 0x02;
+
+ /**
+ * Request - multi-packet
+ */
+ public static final int REQUEST = 0x00;
+ public static final int REPLY = 0x01;
+ public static final int REQUEST_RECEIVE_FAILED = 0x02;
+ public static final int REQUEST_FAILED = 0x03;
+
+ /**
+ * Request receiver aborts transmission.
+ */
+ public static final int REMOTE_REQUEST_ABORT = 0x10;
+ public static final int REMOTE_REPLY_ABORT = 0x11;
+ public static final int REMOTE_REQUEST_RECEIVE_FAILED_ABORT = 0x12;
+ public static final int REMOTE_REQUEST_FAILED_ABORT = 0x13;
+
+ /**
+ * Request transmitter aborts transmission.
+ */
+ public static final int REQUEST_ABORT = 0x20;
+ public static final int REPLY_ABORT = 0x21;
+ public static final int REQUEST_RECEIVE_FAILED_ABORT = 0x22;
+ public static final int REQUEST_FAILED_ABORT = 0x23;
+
+ public static final int REQUEST_CANCEL = 0x30;
+ public static final int REQUEST_CANCEL_ACK = 0x31;
+ public static final int CLIENT_OPEN = 0x32;
+ public static final int CLIENT_OPEN_CANCEL = 0x33;
+ public static final int CLIENT_OPEN_ACK = 0x34;
+ public static final int CLIENT_OPEN_CANCEL_ACK = 0x35;
+ public static final int CLIENT_NOT_FOUND = 0x36;
+ public static final int CLIENT_REMOTE_CLOSE = 0x37;
+ public static final int CLIENT_CLOSE = 0x38;
+
+
+
+}
Added: remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/MultiplexConnectionHandler.java
===================================================================
--- remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/MultiplexConnectionHandler.java (rev 0)
+++ remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/MultiplexConnectionHandler.java 2009-09-16 17:44:19 UTC (rev 5501)
@@ -0,0 +1,105 @@
+/*
+ * 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.multiplex;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+import java.util.concurrent.atomic.AtomicBoolean;
+import org.jboss.remoting3.spi.Cancellable;
+import org.jboss.remoting3.spi.ConnectionHandler;
+import org.jboss.remoting3.spi.RequestHandler;
+import org.jboss.remoting3.spi.RequestHandlerConnector;
+import org.jboss.remoting3.spi.Result;
+import org.jboss.xnio.BufferAllocator;
+import org.jboss.xnio.channels.AllocatedMessageChannel;
+import org.jboss.xnio.channels.Channels;
+import org.jboss.xnio.log.Logger;
+
+final class MultiplexConnectionHandler implements ConnectionHandler {
+ private static final Logger log = Logger.getLogger("org.jboss.remoting.multiplex");
+
+ private final EstablishedConnection establishedConnection;
+ private final Charset charset = Charset.forName("utf-8");
+
+ MultiplexConnectionHandler(final EstablishedConnection establishedConnection) {
+ this.establishedConnection = establishedConnection;
+ }
+
+ public Cancellable open(final String serviceName, final String groupName, final Result<RequestHandler> result) {
+ final EstablishedConnection establishedConnection = this.establishedConnection;
+ final int id = establishedConnection.nextRemoteClient();
+ final BufferAllocator<ByteBuffer> allocator = establishedConnection.getAllocator();
+ final ByteBuffer buffer = allocator.allocate();
+ final AllocatedMessageChannel channel = establishedConnection.getChannel();
+ final RemoteClient remoteClient = new RemoteClient(result, new MultiplexRequestHandler(id, establishedConnection));
+ establishedConnection.addOutstandingClient(id, remoteClient);
+ buffer.put((byte) MessageType.CLIENT_OPEN);
+ buffer.putInt(id);
+ final byte[] serviceNameBytes = serviceName.getBytes(charset);
+ buffer.putShort((short) serviceNameBytes.length);
+ buffer.put(serviceNameBytes);
+ final byte[] groupNameBytes = groupName.getBytes(charset);
+ buffer.putShort((short) groupNameBytes.length);
+ buffer.put(groupNameBytes);
+ buffer.flip();
+ try {
+ Channels.sendBlocking(channel, buffer);
+ } catch (IOException e) {
+ result.setException(e);
+ establishedConnection.removeRemoteClient(id);
+ }
+ return new Cancellable() {
+ private final AtomicBoolean cancelled = new AtomicBoolean();
+
+ public void cancel() {
+ if (cancelled.getAndSet(true)) {
+ // cancel already sent
+ return;
+ }
+ if (remoteClient.getRequestHandler() != null) {
+ // already done; don't waste the bandwidth
+ return;
+ }
+ final ByteBuffer buffer = allocator.allocate();
+ buffer.put((byte) MessageType.CLIENT_OPEN_CANCEL);
+ buffer.putInt(id);
+ buffer.flip();
+ try {
+ Channels.sendBlocking(channel, buffer);
+ } catch (IOException e) {
+ log.trace("Sending a request to cancel a client open failed");
+ }
+ }
+ };
+ }
+
+ public RequestHandlerConnector createConnector(final RequestHandler localHandler) {
+ final int id = establishedConnection.addLocalClient(localHandler);
+ return null;
+ }
+
+ public void close() throws IOException {
+ establishedConnection.close();
+ }
+}
Added: remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/MultiplexConnectionProvider.java
===================================================================
--- remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/MultiplexConnectionProvider.java (rev 0)
+++ remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/MultiplexConnectionProvider.java 2009-09-16 17:44:19 UTC (rev 5501)
@@ -0,0 +1,70 @@
+/*
+ * 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.multiplex;
+
+import org.jboss.remoting3.spi.ConnectionProvider;
+import org.jboss.remoting3.spi.Cancellable;
+import org.jboss.remoting3.spi.ConnectionHandlerFactory;
+import org.jboss.remoting3.spi.Result;
+import org.jboss.remoting3.spi.SpiUtils;
+import org.jboss.remoting3.OptionMap;
+import org.jboss.xnio.TcpConnector;
+import org.jboss.xnio.FutureConnection;
+import org.jboss.xnio.IoFuture;
+import org.jboss.xnio.channels.TcpChannel;
+import java.net.URI;
+import java.net.InetSocketAddress;
+import java.io.IOException;
+
+public final class MultiplexConnectionProvider implements ConnectionProvider {
+
+ private final TcpConnector tcpConnector;
+
+ public MultiplexConnectionProvider(final TcpConnector tcpConnector) {
+ this.tcpConnector = tcpConnector;
+ }
+
+ public Cancellable connect(final URI uri, final OptionMap connectOptions, final Result<ConnectionHandlerFactory> result) throws IllegalArgumentException {
+ final String host = uri.getHost();
+ final int port = uri.getPort();
+ if (port == -1) {
+ throw new IllegalArgumentException("A valid port number must be explicitly specified");
+ }
+ // TODO - change this to use async DNS via XNIO DNS
+ final FutureConnection<InetSocketAddress,TcpChannel> connection = tcpConnector.connectTo(new InetSocketAddress(host, port), null);
+ connection.addNotifier(new IoFuture.HandlingNotifier<TcpChannel, Result<ConnectionHandlerFactory>>() {
+ public void handleFailed(final IOException exception, final Result<ConnectionHandlerFactory> attachment) {
+ attachment.setException(exception);
+ }
+
+ public void handleDone(final TcpChannel result, final Result<ConnectionHandlerFactory> attachment) {
+ attachment.setResult(null);
+ }
+
+ public void handleCancelled(final Result<ConnectionHandlerFactory> attachment) {
+ attachment.setCancelled();
+ }
+ }, result);
+ return SpiUtils.cancellable(connection);
+ }
+}
Added: remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/MultiplexOptions.java
===================================================================
--- remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/MultiplexOptions.java (rev 0)
+++ remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/MultiplexOptions.java 2009-09-16 17:44:19 UTC (rev 5501)
@@ -0,0 +1,108 @@
+/*
+ * 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.multiplex;
+
+import org.jboss.remoting3.Option;
+
+/**
+ * Options which may be used to configure a multiplex connection.
+ */
+public final class MultiplexOptions {
+
+ private MultiplexOptions() {
+ }
+
+ /**
+ * The maximum message receive size to specify to the remote side. This is the size of the largest protocol message
+ * that can be sent from the remote side to the local side. The remote side may elect to send messages of a smaller
+ * size, but it may not send larger messages (such messages will cause the connection to close with a protocol error).
+ * This setting does <b>not</b> affect the maximum request or reply size. This value should be set to at least {@code 256}
+ * if specified.
+ */
+ public static final Option<Integer> MAX_RECEIVE_SIZE = Option.simple(MultiplexOptions.class, "MAX_RECEIVE_SIZE", Integer.class);
+
+ /**
+ * The maximum message size that this side will send to a peer. If the peer specifies a smaller maximum receive size,
+ * that size will be used; otherwise this value will be. This value should be set to at least {@code 256} if specified.
+ *
+ * @see #MAX_RECEIVE_SIZE
+ */
+ public static final Option<Integer> MAX_TRANSMIT_SIZE = Option.simple(MultiplexOptions.class, "MAX_TRANSMIT_SIZE", Integer.class);
+
+ /**
+ * The maximum send window size that will be used by this end of the connection. The peer may specify a smaller size,
+ * in which case that value will be used. Increasing this size may decrease latency at the cost of increased memory demands.
+ * The minimum allowed value for this option is {@code 2}.
+ */
+ public static final Option<Integer> MAX_SEND_WINDOW_SIZE = Option.simple(MultiplexOptions.class, "MAX_SEND_WINDOW_SIZE", Integer.class);
+
+ /**
+ * The maximum receive window size that this end of the connection can support. The peer will not send unacknowledged messages
+ * beyond this window size. The minimum allowed value for this option is {@code 2}.
+ */
+ public static final Option<Integer> MAX_RECEIVE_WINDOW_SIZE = Option.simple(MultiplexOptions.class, "MAX_RECEIVE_WINDOW_SIZE", Integer.class);
+
+ /**
+ * The maximum number of concurrent inbound requests that this end of the connection will be configured to support. Using a larger number
+ * increases concurrency at the cost of additional memory demands.
+ */
+ public static final Option<Integer> MAX_INBOUND_REQUESTS = Option.simple(MultiplexOptions.class, "MAX_INBOUND_REQUESTS", Integer.class);
+
+ /**
+ * The maximum number of concurrent outbound requests that this end of the connection will be configured to support. Using a larger number
+ * increases concurrency at the cost of additional memory demands.
+ */
+ public static final Option<Integer> MAX_OUTBOUND_REQUESTS = Option.simple(MultiplexOptions.class, "MAX_OUTBOUND_REQUESTS", Integer.class);
+
+ /**
+ * The maximum number of concurrently active inbound clients that this end of the connection will be configured to accept. Using a larger number
+ * increases concurrency at the cost of additional memory demands.
+ */
+ public static final Option<Integer> MAX_INBOUND_CLIENTS = Option.simple(MultiplexOptions.class, "MAX_INBOUND_CLIENTS", Integer.class);
+
+ /**
+ * The maximum number of concurrently active outbound clients that this end of the connection will be configured to support. Using a larger number
+ * increases concurrency at the cost of additional memory demands.
+ */
+ public static final Option<Integer> MAX_OUTBOUND_CLIENTS = Option.simple(MultiplexOptions.class, "MAX_OUTBOUND_CLIENTS", Integer.class);
+
+ /**
+ * The maximum number of inbound streams. This is the number of streams that the remote side is allowed to initiate, regardless of
+ * the actual direction of flow of the stream itself.
+ */
+ public static final Option<Integer> MAX_INBOUND_STREAMS = Option.simple(MultiplexOptions.class, "MAX_INBOUND_STREAMS", Integer.class);
+
+ /**
+ * The maximum number of outbound streams. This is the number of streams that the local side is allowed to initiate, regardless of
+ * the actual direction of flow of the stream itself.
+ */
+ public static final Option<Integer> MAX_OUTBOUND_STREAMS = Option.simple(MultiplexOptions.class, "MAX_OUTBOUND_STREAMS", Integer.class);
+
+ /**
+ * The number of milliseconds to wait before sending accumulated ACK messages. Higher values increase bandwidth at the cost of latency.
+ * Setting this value to 0 will immediately send ACK messages.
+ */
+ public static final Option<Integer> ACK_CORK_MILLISECONDS = Option.simple(MultiplexOptions.class, "ACK_CORK_MILLISECONDS", Integer.class);
+
+ // todo - authentication/security mechanisms
+}
Added: remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/MultiplexRemoteRequestContext.java
===================================================================
--- remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/MultiplexRemoteRequestContext.java (rev 0)
+++ remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/MultiplexRemoteRequestContext.java 2009-09-16 17:44:19 UTC (rev 5501)
@@ -0,0 +1,61 @@
+/*
+ * 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.multiplex;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.concurrent.atomic.AtomicBoolean;
+import org.jboss.remoting3.spi.RemoteRequestContext;
+import org.jboss.xnio.channels.AllocatedMessageChannel;
+import org.jboss.xnio.channels.Channels;
+import org.jboss.xnio.log.Logger;
+
+final class MultiplexRemoteRequestContext implements RemoteRequestContext {
+ private static final Logger log = Loggers.MAIN_LOGGER;
+
+ private final int id;
+ private final EstablishedConnection connection;
+ private final AtomicBoolean cancelled = new AtomicBoolean();
+
+ public MultiplexRemoteRequestContext(final int id, final EstablishedConnection connection) {
+ this.id = id;
+ this.connection = connection;
+ }
+
+ public void cancel() {
+ if (cancelled.getAndSet(true)) {
+ return;
+ }
+ final AllocatedMessageChannel messageChannel = connection.getChannel();
+ ByteBuffer buf = ByteBuffer.allocate(5);
+ buf.put((byte) MessageType.REQUEST_CANCEL);
+ buf.putInt(id);
+ buf.flip();
+ try {
+ Channels.sendBlocking(messageChannel, buf);
+ log.trace("Sent cancel request for ID %d", Integer.valueOf(id));
+ } catch (IOException e) {
+ log.trace("Failed to send a request cancel message: %s", e);
+ }
+ }
+}
Added: remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/MultiplexRequestHandler.java
===================================================================
--- remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/MultiplexRequestHandler.java (rev 0)
+++ remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/MultiplexRequestHandler.java 2009-09-16 17:44:19 UTC (rev 5501)
@@ -0,0 +1,110 @@
+/*
+ * 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.multiplex;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import org.jboss.marshalling.ByteOutput;
+import org.jboss.marshalling.Marshaller;
+import org.jboss.remoting3.spi.AbstractHandleableCloseable;
+import org.jboss.remoting3.spi.RemoteRequestContext;
+import org.jboss.remoting3.spi.ReplyHandler;
+import org.jboss.remoting3.spi.RequestHandler;
+import org.jboss.remoting3.spi.SpiUtils;
+import org.jboss.xnio.BufferAllocator;
+import org.jboss.xnio.IoUtils;
+import org.jboss.xnio.channels.Channels;
+import org.jboss.xnio.log.Logger;
+import org.jboss.xnio.Pool;
+
+/**
+ * Handler for outbound requests.
+ */
+final class MultiplexRequestHandler extends AbstractHandleableCloseable<RequestHandler> implements RequestHandler {
+ private static final Logger log = Loggers.REQUEST_HANDLER_LOGGER;
+
+ private final int identifier;
+ private final BufferAllocator<ByteBuffer> allocator;
+ private final Pool<Marshaller> marshallerPool;
+ private final EstablishedConnection connection;
+
+ MultiplexRequestHandler(final int identifier, final EstablishedConnection connection) {
+ super(connection.getExecutor());
+ this.connection = connection;
+ this.identifier = identifier;
+ allocator = connection.getAllocator();
+ }
+
+ @Override
+ protected void closeAction() throws IOException {
+ connection.removeRemoteClient(identifier);
+ ByteBuffer buffer = allocator.allocate();
+ buffer.put((byte) MessageType.CLIENT_CLOSE);
+ buffer.putInt(identifier);
+ buffer.flip();
+ Channels.sendBlocking(connection.getChannel(), buffer);
+ }
+
+ public RemoteRequestContext receiveRequest(final Object request, final ReplyHandler handler) {
+ log.trace("Sending outbound request (request id = %d) (type is %s)", request == null ? "null" : request.getClass());
+ final EstablishedConnection connection = this.connection;
+ connection.setCurrent();
+ try {
+ final Marshaller marshaller = marshallerPool.allocate();
+ final ByteOutput output = new SendingByteOutput(null, allocator, connection.getSendWindowSize());
+ boolean ok = false;
+ try {
+ marshaller.start(output);
+ marshaller.write(MessageType.REQUEST);
+ marshaller.writeInt(identifier);
+ final int id = connection.nextRequest();
+ connection.addRemoteRequest(id, handler);
+ marshaller.writeInt(id);
+ marshaller.writeObject(request);
+ ok = true;
+ marshaller.finish();
+ marshallerPool.free(marshaller);
+ output.close();
+ return new MultiplexRemoteRequestContext(id, connection);
+ } finally {
+ IoUtils.safeClose(output);
+ if (! ok) try {
+ marshaller.finish();
+ marshallerPool.free(marshaller);
+ } catch (final Exception e) {
+ log.trace("Failed to free a marshaller back into the pool: %s", e);
+ }
+ }
+ } catch (final IOException t) {
+ log.trace(t, "receiveRequest failed with an exception");
+ SpiUtils.safeHandleException(handler, t);
+ return SpiUtils.getBlankRemoteRequestContext();
+ } finally {
+ connection.clearCurrent();
+ }
+ }
+
+ public String toString() {
+ return "forwarding request handler <" + Integer.toHexString(hashCode()) + "> (id = " + identifier + ") for " + connection;
+ }
+}
\ No newline at end of file
Added: remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/MultiplexRequestHandlerConnector.java
===================================================================
--- remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/MultiplexRequestHandlerConnector.java (rev 0)
+++ remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/MultiplexRequestHandlerConnector.java 2009-09-16 17:44:19 UTC (rev 5501)
@@ -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.multiplex;
+
+import org.jboss.remoting3.spi.RequestHandlerConnector;
+import org.jboss.remoting3.spi.Cancellable;
+import org.jboss.remoting3.spi.RequestHandler;
+import org.jboss.remoting3.spi.Result;
+
+final class MultiplexRequestHandlerConnector implements RequestHandlerConnector {
+ private final EstablishedConnection connection;
+
+ MultiplexRequestHandlerConnector(final EstablishedConnection connection) {
+ this.connection = connection;
+ }
+
+ public Cancellable createRequestHandler(final Result<RequestHandler> result) throws SecurityException {
+ throw new SecurityException("Not forwarded");
+ }
+}
Added: remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/PermitManager.java
===================================================================
--- remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/PermitManager.java (rev 0)
+++ remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/PermitManager.java 2009-09-16 17:44:19 UTC (rev 5501)
@@ -0,0 +1,123 @@
+/*
+ * 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.multiplex;
+
+import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
+
+public final class PermitManager {
+
+ private final Object lock = new Object();
+ private final int maxPermits;
+ private final int[] permitIds;
+ private int topOfStack;
+
+ public PermitManager(final int maxPermits) {
+ synchronized (lock) {
+ this.maxPermits = maxPermits;
+ permitIds = new int[maxPermits];
+ for (int i = 0; i < maxPermits; i ++) {
+ permitIds[i] = i;
+ }
+ }
+ }
+
+ public Permit acquireInterruptibly() throws InterruptedException {
+ final int maxPermits = this.maxPermits;
+ synchronized (lock) {
+ int topOfStack;
+ while ((topOfStack = this.topOfStack) == maxPermits) {
+ lock.wait();
+ }
+ final int[] permitIds = this.permitIds;
+ int id = permitIds[topOfStack];
+ this.topOfStack = topOfStack + 1;
+ return new Permit(id);
+ }
+ }
+
+ public Permit acquire() {
+ final int maxPermits = this.maxPermits;
+ synchronized (lock) {
+ boolean intr = Thread.interrupted();
+ try {
+ int topOfStack;
+ while ((topOfStack = this.topOfStack) == maxPermits) try {
+ lock.wait();
+ } catch (InterruptedException e) {
+ intr = true;
+ }
+ final int[] permitIds = this.permitIds;
+ int id = permitIds[topOfStack];
+ this.topOfStack = topOfStack + 1;
+ return new Permit(id);
+ } finally {
+ if (intr) Thread.currentThread().interrupt();
+ }
+ }
+ }
+
+ private static final AtomicIntegerFieldUpdater<Permit> permitUpdater =
+ AtomicIntegerFieldUpdater.newUpdater(Permit.class, "id");
+
+ public final class Permit {
+ private volatile int id;
+
+ private Permit(final int id) {
+ this.id = id;
+ }
+
+ public int getId() {
+ final int id = this.id;
+ if (id == -1) {
+ throw new IllegalStateException("Permit already released");
+ }
+ return id;
+ }
+
+ public boolean released() {
+ return id == -1;
+ }
+
+ public void release() {
+ doRelease();
+ }
+
+ private boolean doRelease() {
+ final int id;
+ if ((id = permitUpdater.getAndSet(this, -1)) != -1) {
+ synchronized (lock) {
+ permitIds[--topOfStack] = id;
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ protected void finalize() {
+ if (doRelease()) {
+ // todo log leak
+ }
+ }
+ }
+}
Added: remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/ReadHandlerImpl.java
===================================================================
--- remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/ReadHandlerImpl.java (rev 0)
+++ remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/ReadHandlerImpl.java 2009-09-16 17:44:19 UTC (rev 5501)
@@ -0,0 +1,69 @@
+/*
+ * 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.multiplex;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import org.jboss.marshalling.MarshallerFactory;
+import org.jboss.marshalling.MarshallingConfiguration;
+import org.jboss.marshalling.Marshaller;
+import org.jboss.marshalling.Unmarshaller;
+import org.jboss.remoting3.spi.ConnectionHandler;
+import org.jboss.xnio.IoReadHandler;
+import org.jboss.xnio.IoUtils;
+import org.jboss.xnio.Buffers;
+import org.jboss.xnio.Pool;
+import org.jboss.xnio.channels.ReadableAllocatedMessageChannel;
+import org.jboss.xnio.log.Logger;
+
+final class ReadHandlerImpl implements IoReadHandler<ReadableAllocatedMessageChannel> {
+ private static final Logger log = Logger.getLogger("org.jboss.remoting.multiplex");
+
+ private final int maxReceiveSize;
+ private final int maxSendSize;
+ private final int receiveWindowSize;
+ private final int sendWindowSize;
+ private final Pool<Marshaller> marshallerPool;
+ private final Pool<Unmarshaller> unmarshallerPool;
+ private final ConnectionHandler connectionHandler;
+
+ public void handleReadable(final ReadableAllocatedMessageChannel channel) {
+ final ByteBuffer buffer;
+ try {
+ buffer = channel.receive();
+ } catch (IOException e) {
+ log.error("I/O error in protocol channel; closing channel (%s)", e);
+ IoUtils.safeClose(connectionHandler);
+ IoUtils.safeClose(channel);
+ return;
+ }
+ if (log.isTrace()) {
+ log.trace("Received raw message:\n%s", Buffers.createDumper(buffer, 8, 1));
+ }
+ final int idByte = buffer.get() & 0xff;
+ final boolean isMulti = (idByte & 0x80) != 0;
+ final boolean isFirst = isMulti && (idByte & 0x40) != 0;
+ final boolean isLast = isMulti && (idByte & 0x20) != 0;
+
+ }
+}
Added: remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/ReceivingByteInput.java
===================================================================
--- remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/ReceivingByteInput.java (rev 0)
+++ remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/ReceivingByteInput.java 2009-09-16 17:44:19 UTC (rev 5501)
@@ -0,0 +1,193 @@
+/*
+ * 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.multiplex;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InterruptedIOException;
+import java.nio.ByteBuffer;
+import java.util.Queue;
+import java.util.ArrayDeque;
+import org.jboss.marshalling.ByteInput;
+import org.jboss.xnio.Buffers;
+import org.jboss.remoting3.ProtocolException;
+
+final class ReceivingByteInput extends InputStream implements ByteInput {
+ private final Queue<ByteBuffer> window;
+ private final Runnable ackTask;
+ private final Runnable closeTask;
+
+ private IOException failure;
+ private boolean done;
+
+ ReceivingByteInput(final Runnable ackTask, final int windowSize, final Runnable closeTask) {
+ this.ackTask = ackTask;
+ this.closeTask = closeTask;
+ window = new ArrayDeque<ByteBuffer>(windowSize);
+ }
+
+ public int read() throws IOException {
+ final Queue<ByteBuffer> window = this.window;
+ synchronized (this) {
+ while (window.isEmpty()) {
+ if (done) {
+ return -1;
+ }
+ checkFailure();
+ try {
+ wait();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new InterruptedIOException("Interrupted on read()");
+ }
+ }
+ final ByteBuffer buf = window.peek();
+ try {
+ return buf.get() & 0xff;
+ } finally {
+ if (buf.remaining() == 0) {
+ window.poll();
+ ackTask.run();
+ }
+ }
+ }
+ }
+
+ public int read(final byte[] bytes, int offs, int len) throws IOException {
+ if (len == 0) {
+ return 0;
+ }
+ synchronized (this) {
+ while (window.isEmpty()) {
+ if (done) {
+ return -1;
+ }
+ checkFailure();
+ try {
+ wait();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new InterruptedIOException("Interrupted on read()");
+ }
+ }
+ final Queue<ByteBuffer> window = this.window;
+ int total = 0;
+ while (len > 0) {
+ final ByteBuffer buffer = window.peek();
+ if (buffer == null) {
+ break;
+ }
+ final int bytecnt = Math.min(buffer.remaining(), len);
+ buffer.get(bytes, offs, bytecnt);
+ total += bytecnt;
+ len -= bytecnt;
+ if (buffer.remaining() == 0) {
+ window.poll();
+ ackTask.run();
+ }
+ }
+ return total;
+ }
+ }
+
+ public int available() throws IOException {
+ synchronized (this) {
+ int total = 0;
+ for (ByteBuffer buffer : window) {
+ total += buffer.remaining();
+ if (total < 0) {
+ return Integer.MAX_VALUE;
+ }
+ }
+ return total;
+ }
+ }
+
+ public long skip(long qty) throws IOException {
+ final Queue<ByteBuffer> window = this.window;
+ synchronized (this) {
+ while (window.isEmpty()) {
+ if (done) {
+ return 0L;
+ }
+ checkFailure();
+ try {
+ wait();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new InterruptedIOException("Interrupted on read()");
+ }
+ }
+ long skipped = 0L;
+ while (qty > 0L) {
+ final ByteBuffer buffer = window.peek();
+ if (buffer == null) {
+ break;
+ }
+ final int bytecnt = Math.min(buffer.remaining(), (int) Math.max((long)Integer.MAX_VALUE, qty));
+ Buffers.skip(buffer, bytecnt);
+ skipped += bytecnt;
+ qty -= bytecnt;
+ if (buffer.remaining() == 0) {
+ window.poll();
+ ackTask.run();
+ }
+ }
+ return skipped;
+ }
+ }
+
+ private void checkFailure() throws IOException {
+ final IOException failure = this.failure;
+ if (failure != null) {
+ failure.setStackTrace(new Throwable().getStackTrace());
+ try {
+ throw failure;
+ } finally {
+ done = true;
+ this.failure = null;
+ }
+ }
+ }
+
+ void push(ByteBuffer buffer) throws IOException {
+ synchronized (this) {
+ checkFailure();
+ try {
+ window.add(buffer);
+ } catch (IllegalStateException e) {
+ throw new ProtocolException("Stream window overrun");
+ }
+ }
+ }
+
+ public void close() throws IOException {
+ synchronized (this) {
+ if (! done) {
+ window.clear();
+ done = true;
+ closeTask.run();
+ }
+ }
+ }
+}
Added: remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/RemoteClient.java
===================================================================
--- remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/RemoteClient.java (rev 0)
+++ remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/RemoteClient.java 2009-09-16 17:44:19 UTC (rev 5501)
@@ -0,0 +1,49 @@
+/*
+ * 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.multiplex;
+
+import org.jboss.remoting3.spi.Result;
+import org.jboss.remoting3.spi.RequestHandler;
+import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
+
+final class RemoteClient {
+
+ @SuppressWarnings({ "UnusedDeclaration" })
+ private volatile Result<RequestHandler> result;
+ private final RequestHandler requestHandler;
+ private static final AtomicReferenceFieldUpdater<RemoteClient, Result> updater = AtomicReferenceFieldUpdater.newUpdater(RemoteClient.class, Result.class, "result");
+
+ RemoteClient(final Result<RequestHandler> result, final RequestHandler requestHandler) {
+ this.result = result;
+ this.requestHandler = requestHandler;
+ }
+
+ @SuppressWarnings({ "unchecked" })
+ Result<RequestHandler> takeResult() {
+ return updater.getAndSet(this, null);
+ }
+
+ public RequestHandler getRequestHandler() {
+ return result == null ? requestHandler : null;
+ }
+}
Added: remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/SendingByteOutput.java
===================================================================
--- remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/SendingByteOutput.java (rev 0)
+++ remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/SendingByteOutput.java 2009-09-16 17:44:19 UTC (rev 5501)
@@ -0,0 +1,165 @@
+/*
+ * 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.multiplex;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.nio.channels.ClosedByInterruptException;
+import org.jboss.marshalling.ByteOutput;
+import org.jboss.xnio.BufferAllocator;
+import org.jboss.xnio.channels.WritableMessageChannel;
+
+final class SendingByteOutput extends OutputStream implements ByteOutput {
+ private ByteBuffer buffer;
+ private final BufferAllocator<ByteBuffer> allocator;
+ private final WritableMessageChannel channel;
+ private int windowSize;
+ private boolean closed;
+ private IOException remoteException;
+
+ public SendingByteOutput(final WritableMessageChannel channel, final BufferAllocator<ByteBuffer> allocator, final int windowSize) {
+ this.channel = channel;
+ this.allocator = allocator;
+ this.windowSize = windowSize;
+ }
+
+ private static IOException closed() {
+ return new IOException("Stream is closed");
+ }
+
+ private void checkClosed() throws IOException {
+ if (closed) {
+ throw closed();
+ }
+ if (remoteException != null) {
+ closed = true;
+ throw remoteException;
+ }
+ }
+
+ public void write(final int b) throws IOException {
+ synchronized (this) {
+ checkClosed();
+ final ByteBuffer buffer = this.buffer;
+ if (buffer == null) {
+ this.buffer = allocator.allocate();
+ } else if (! buffer.hasRemaining()) {
+ send();
+ this.buffer = allocator.allocate();
+ }
+ buffer.put((byte) b);
+ }
+ }
+
+ public void write(final byte[] b, int off, int len) throws IOException {
+ synchronized (this) {
+ checkClosed();
+ while (len > 0) {
+ ByteBuffer buffer = this.buffer;
+ if (buffer == null) {
+ buffer = this.buffer = allocator.allocate();
+ } else if (! buffer.hasRemaining()) {
+ send();
+ buffer = this.buffer = allocator.allocate();
+ }
+ final int cnt = Math.min(len, buffer.remaining());
+ buffer.put(b, off, cnt);
+ len -= cnt;
+ off += cnt;
+
+ }
+ }
+ }
+
+ // call with lock held
+ private void send() throws IOException {
+ while (windowSize == 0) {
+ try {
+ wait();
+ } catch (InterruptedException e) {
+ buffer = null;
+ closed = true;
+ Thread.currentThread().interrupt();
+ throw new ClosedByInterruptException();
+ }
+ checkClosed();
+ }
+ final ByteBuffer buffer = this.buffer;
+ this.buffer = null;
+ buffer.flip();
+ final WritableMessageChannel channel = this.channel;
+ try {
+ while (! (channel.send(buffer))) {
+ channel.awaitWritable();
+ checkClosed();
+ if (Thread.currentThread().isInterrupted()) {
+ closed = true;
+ throw new ClosedByInterruptException();
+ }
+ }
+ } finally {
+ allocator.free(buffer);
+ }
+ windowSize--;
+ }
+
+ void acknowledge() {
+ synchronized (this) {
+ windowSize++;
+ notify();
+ }
+ }
+
+ public void flush() throws IOException {
+ synchronized (this) {
+ final ByteBuffer buffer = this.buffer;
+ if (buffer != null && buffer.position() > 0) {
+ send();
+ }
+ }
+ }
+
+ public void close() throws IOException {
+ synchronized (this) {
+ if (closed) {
+ return;
+ }
+ final ByteBuffer buffer = this.buffer;
+ if (buffer != null && buffer.position() > 0) {
+ send();
+ }
+ closed = true;
+ }
+ }
+
+ void abort() {
+ synchronized (this) {
+ if (closed) {
+ return;
+ }
+ closed = true;
+ notifyAll();
+ }
+ }
+}
Added: remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/package-info.java
===================================================================
--- remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/package-info.java (rev 0)
+++ remoting3-multiplex/trunk/src/main/java/org/jboss/remoting3/multiplex/package-info.java 2009-09-16 17:44:19 UTC (rev 5501)
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+/**
+ * The Remoting 3 multiplex protocol implementation.
+ */
+package org.jboss.remoting3.multiplex;
\ No newline at end of file
15 years, 3 months
JBoss Remoting SVN: r5500 - remoting3-multiplex.
by jboss-remoting-commits@lists.jboss.org
Author: david.lloyd(a)jboss.com
Date: 2009-09-16 13:43:12 -0400 (Wed, 16 Sep 2009)
New Revision: 5500
Added:
remoting3-multiplex/trunk/
Log:
Prepare new impl
15 years, 3 months
JBoss Remoting SVN: r5499 - remoting3-multiplex.
by jboss-remoting-commits@lists.jboss.org
Author: david.lloyd(a)jboss.com
Date: 2009-09-16 13:42:58 -0400 (Wed, 16 Sep 2009)
New Revision: 5499
Removed:
remoting3-multiplex/trunk/
Log:
Wipe out old impl
15 years, 3 months
JBoss Remoting SVN: r5498 - remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3.
by jboss-remoting-commits@lists.jboss.org
Author: david.lloyd(a)jboss.com
Date: 2009-09-16 12:36:27 -0400 (Wed, 16 Sep 2009)
New Revision: 5498
Modified:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Option.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/OptionMap.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Options.java
Log:
Make options and option maps serializable
Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Option.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Option.java 2009-09-16 16:09:24 UTC (rev 5497)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Option.java 2009-09-16 16:36:27 UTC (rev 5498)
@@ -23,18 +23,27 @@
package org.jboss.remoting3;
import java.util.Collection;
+import java.io.Serializable;
+import java.io.ObjectStreamException;
+import java.io.InvalidObjectException;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
/**
- * A strongly-typed option to configure an aspect of a service. Options are immutable and use identity comparisons
- * and hash codes, and they are not serializable.
+ * A strongly-typed option to configure an aspect of a service or connection. Options are immutable and use identity comparisons
+ * and hash codes. Options should always be declared as {@code public static final} members in order to support serialization.
*
* @param <T> the option value type
*/
-public abstract class Option<T> {
+public abstract class Option<T> implements Serializable {
+ private static final long serialVersionUID = -1564427329140182760L;
+
+ private final Class<?> declClass;
private final String name;
- Option(final String name) {
+ Option(final Class<?> declClass, final String name) {
+ this.declClass = declClass;
if (name == null) {
throw new NullPointerException("name is null");
}
@@ -45,39 +54,40 @@
* Create an option with a simple type. The class object given <b>must</b> represent some immutable type, otherwise
* unexpected behavior may result.
*
- * @param name the name of this option
+ * @param declClass the declaring class of the option
+ * @param name the (field) name of this option
* @param type the class of the value associated with this option
- * @param <T> the type of the value associated with this option
* @return the option instance
*/
- public static <T> Option<T> simple(final String name, final Class<T> type) {
- return new SingleOption<T>(name, type);
+ public static <T> Option<T> simple(final Class<?> declClass, final String name, final Class<T> type) {
+ return new SingleOption<T>(declClass, name, type);
}
/**
* Create an option with a sequence type. The class object given <b>must</b> represent some immutable type, otherwise
* unexpected behavior may result.
*
- * @param name the name of this option
+ * @param declClass the declaring class of the option
+ * @param name the (field) name of this option
* @param elementType the class of the sequence element value associated with this option
- * @param <T> the type of the sequence element value associated with this option
* @return the option instance
*/
- public static <T> Option<Sequence<T>> sequence(final String name, final Class<T> elementType) {
- return new SequenceOption<T>(name, elementType);
+ public static <T> Option<Sequence<T>> sequence(final Class<?> declClass, final String name, final Class<T> elementType) {
+ return new SequenceOption<T>(declClass, name, elementType);
}
/**
* Create an option with a flag set type. The class object given <b>must</b> represent some immutable type, otherwise
* unexpected behavior may result.
*
- * @param name the name of this option
+ * @param declClass the declaring class of the option
+ * @param name the (field) name of this option
* @param elementType the class of the flag values associated with this option
* @param <T> the type of the flag values associated with this option
* @return the option instance
*/
- public static <T extends Enum<T>> Option<FlagSet<T>> flags(final String name, final Class<T> elementType) {
- return new FlagsOption<T>(name, elementType);
+ public static <T extends Enum<T>> Option<FlagSet<T>> flags(final Class<?> declClass, final String name, final Class<T> elementType) {
+ return new FlagsOption<T>(declClass, name, elementType);
}
/**
@@ -90,6 +100,15 @@
}
/**
+ * Get a human-readible string representation of this object.
+ *
+ * @return the string representation
+ */
+ public String toString() {
+ return super.toString() + " (" + declClass.getName() + "#" + name + ")";
+ }
+
+ /**
* Return the given object as the type of this option. If the cast could not be completed, an exception is thrown.
*
* @param o the object to cast
@@ -97,14 +116,40 @@
* @throws ClassCastException if the object is not of a compatible type
*/
public abstract T cast(Object o) throws ClassCastException;
+
+ /**
+ * Resolve this instance for serialization.
+ *
+ * @return the resolved object
+ * @throws ObjectStreamException if the object could not be resolved
+ */
+ protected final Object readResolve() throws ObjectStreamException {
+ try {
+ final Field field = declClass.getField(name);
+ final int modifiers = field.getModifiers();
+ if (! Modifier.isProtected(modifiers)) {
+ throw new InvalidObjectException("Invalid Option instance (the field is not public)");
+ }
+ if (! Modifier.isStatic(modifiers)) {
+ throw new InvalidObjectException("Invalid Option instance (the field is not static)");
+ }
+ return field.get(null);
+ } catch (NoSuchFieldException e) {
+ throw new InvalidObjectException("Invalid Option instance (no matching field)");
+ } catch (IllegalAccessException e) {
+ throw new InvalidObjectException("Invalid Option instance (Illegal access on field get)");
+ }
+ }
}
final class SingleOption<T> extends Option<T> {
- private final Class<T> type;
+ private static final long serialVersionUID = 2449094406108952764L;
- SingleOption(final String name, final Class<T> type) {
- super(name);
+ private transient final Class<T> type;
+
+ SingleOption(final Class<?> declClass, final String name, final Class<T> type) {
+ super(declClass, name);
this.type = type;
}
@@ -114,10 +159,13 @@
}
final class SequenceOption<T> extends Option<Sequence<T>> {
- private final Class<T> elementType;
- SequenceOption(final String name, final Class<T> elementType) {
- super(name);
+ private static final long serialVersionUID = -4328676629293125136L;
+
+ private transient final Class<T> elementType;
+
+ SequenceOption(final Class<?> declClass, final String name, final Class<T> elementType) {
+ super(declClass, name);
this.elementType = elementType;
}
@@ -136,10 +184,12 @@
final class FlagsOption<T extends Enum<T>> extends Option<FlagSet<T>> {
- private final Class<T> elementType;
+ private static final long serialVersionUID = -5487268452958691541L;
- FlagsOption(final String name, final Class<T> elementType) {
- super(name);
+ private transient final Class<T> elementType;
+
+ FlagsOption(final Class<?> declClass, final String name, final Class<T> elementType) {
+ super(declClass, name);
this.elementType = elementType;
}
Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/OptionMap.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/OptionMap.java 2009-09-16 16:09:24 UTC (rev 5497)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/OptionMap.java 2009-09-16 16:36:27 UTC (rev 5498)
@@ -28,12 +28,15 @@
import java.util.Map;
import java.util.Collections;
import java.util.IdentityHashMap;
+import java.io.Serializable;
/**
* An immutable map of options to option values. No {@code null} keys or values are permitted.
*/
-public final class OptionMap implements Iterable<Option<?>> {
+public final class OptionMap implements Iterable<Option<?>>, Serializable {
+ private static final long serialVersionUID = 3632842565346928132L;
+
private final Map<Option<?>, Object> value;
private OptionMap(final Map<Option<?>, Object> value) {
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-09-16 16:09:24 UTC (rev 5497)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Options.java 2009-09-16 16:36:27 UTC (rev 5498)
@@ -34,45 +34,45 @@
* 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.
*/
- public static final Option<Sequence<String>> MARSHALLING_PROTOCOLS = Option.sequence("jboss.remoting3.marshalling.protocols", String.class);
+ 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.
*/
- public static final Option<Sequence<String>> MARSHALLING_CLASS_TABLES = Option.sequence("jboss.remoting3.marshalling.classTables", String.class);
+ 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.
*/
- public static final Option<Sequence<String>> MARSHALLING_OBJECT_TABLES = Option.sequence("jboss.remoting3.marshalling.objectTables", String.class);
+ 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.
*/
- public static final Option<Sequence<String>> MARSHALLING_CLASS_RESOLVERS = Option.sequence("jboss.remoting3.marshalling.classResolvers", String.class);
+ 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.
*/
- public static final Option<Sequence<String>> MARSHALLING_OBJECT_RESOLVERS = Option.sequence("jboss.remoting3.marshalling.objectResolvers", String.class);
+ 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.
*/
- public static final Option<Sequence<String>> MARSHALLING_EXTERNALIZER_FACTORIES = Option.sequence("jboss.remoting3.marshalling.externalizerFactories", String.class);
+ public static final Option<Sequence<String>> MARSHALLING_EXTERNALIZER_FACTORIES = Option.sequence(Options.class, "MARSHALLING_EXTERNALIZER_FACTORIES", String.class);
/**
* Specify a metric which is a hint that describes the relative desirability of this service.
*/
- public static final Option<Integer> METRIC = Option.simple("jboss.remoting3.metric", Integer.class);
+ 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}.
*/
- public static final Option<Boolean> REMOTELY_VISIBLE = Option.simple("jboss.remoting3.remotelyVisible", Boolean.class);
+ public static final Option<Boolean> REMOTELY_VISIBLE = Option.simple(Options.class, "REMOTELY_VISIBLE", Boolean.class);
}
15 years, 3 months
JBoss Remoting SVN: r5497 - in remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3: spi and 1 other directory.
by jboss-remoting-commits@lists.jboss.org
Author: david.lloyd(a)jboss.com
Date: 2009-09-16 12:09:24 -0400 (Wed, 16 Sep 2009)
New Revision: 5497
Modified:
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/Option.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/OptionMap.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Sequence.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/ConnectionProvider.java
Log:
Support passing options in to the connect() method
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-09-16 15:39:14 UTC (rev 5496)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Endpoint.java 2009-09-16 16:09:24 UTC (rev 5497)
@@ -78,10 +78,11 @@
* This method does not block; use the return value to wait for a result if you wish to block.
*
* @param destination the destination
+ * @param connectOptions options to configure this connection
* @return the future connection
* @throws IOException if an error occurs while starting the connect attempt
*/
- IoFuture<? extends Connection> connect(URI destination) throws IOException;
+ IoFuture<? extends Connection> connect(URI destination, OptionMap connectOptions) throws IOException;
/**
* Register a connection provider for a URI scheme. The provider factory is called with the context which can
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-09-16 15:39:14 UTC (rev 5496)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/EndpointImpl.java 2009-09-16 16:09:24 UTC (rev 5497)
@@ -337,18 +337,22 @@
return registration;
}
- public IoFuture<? extends Connection> connect(final URI destination) throws IOException {
+ public IoFuture<? extends Connection> connect(final URI destination, final OptionMap connectOptions) throws IOException {
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(CONNECT_PERM);
}
- final ConnectionProvider connectionProvider = connectionProviders.get(destination.getScheme());
+ final String scheme = destination.getScheme();
+ final ConnectionProvider connectionProvider = connectionProviders.get(scheme);
+ 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);
}
};
- connectionProvider.connect(destination, futureResult.getResult());
+ connectionProvider.connect(destination, connectOptions, futureResult.getResult());
return futureResult;
}
Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Option.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Option.java 2009-09-16 15:39:14 UTC (rev 5496)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Option.java 2009-09-16 16:09:24 UTC (rev 5497)
@@ -22,6 +22,8 @@
package org.jboss.remoting3;
+import java.util.Collection;
+
/**
* A strongly-typed option to configure an aspect of a service. Options are immutable and use identity comparisons
* and hash codes, and they are not serializable.
@@ -120,7 +122,15 @@
}
public Sequence<T> cast(final Object o) {
- return ((Sequence<?>)o).cast(elementType);
+ if (o instanceof Sequence) {
+ return ((Sequence<?>)o).cast(elementType);
+ } else if (o instanceof Object[]){
+ return Sequence.of((Object[])o).cast(elementType);
+ } else if (o instanceof Collection) {
+ return Sequence.of((Collection<?>)o).cast(elementType);
+ } else {
+ throw new ClassCastException("Not a sequence");
+ }
}
}
Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/OptionMap.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/OptionMap.java 2009-09-16 15:39:14 UTC (rev 5496)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/OptionMap.java 2009-09-16 16:09:24 UTC (rev 5497)
@@ -41,13 +41,23 @@
}
/**
+ * Determine whether this option map contains the given option.
+ *
+ * @param option the option to check
+ * @return {@code true} if the option is present in the option map
+ */
+ public boolean contains(Option<?> option) {
+ return value.containsKey(option);
+ }
+
+ /**
* Get the value of an option from this option map.
*
* @param option the option to get
* @param <T> the type of the option
* @return the option value, or {@code null} if it is not present
*/
- <T> T get(Option<T> option) {
+ public <T> T get(Option<T> option) {
return option.cast(value.get(option));
}
@@ -129,6 +139,22 @@
}
/**
+ * Add int values to an Integer sequence key.
+ *
+ * @param key the key
+ * @param values the values
+ * @return this builder
+ */
+ public Builder addSequence(Option<Sequence<Integer>> key, int... values) {
+ Integer[] a = new Integer[values.length];
+ for (int i = 0; i < values.length; i++) {
+ a[i] = Integer.valueOf(values[i]);
+ }
+ list.add(new OVPair<Sequence<Integer>>(key, Sequence.of(a)));
+ return this;
+ }
+
+ /**
* Add a long value to a Long key.
*
* @param key the option
@@ -141,6 +167,22 @@
}
/**
+ * Add long values to an Long sequence key.
+ *
+ * @param key the key
+ * @param values the values
+ * @return this builder
+ */
+ public Builder addSequence(Option<Sequence<Long>> key, long... values) {
+ Long[] a = new Long[values.length];
+ for (int i = 0; i < values.length; i++) {
+ a[i] = Long.valueOf(values[i]);
+ }
+ list.add(new OVPair<Sequence<Long>>(key, Sequence.of(a)));
+ return this;
+ }
+
+ /**
* Add a boolean value to a Boolean key.
*
* @param key the option
@@ -152,7 +194,24 @@
return this;
}
+
/**
+ * Add boolean values to an Boolean sequence key.
+ *
+ * @param key the key
+ * @param values the values
+ * @return this builder
+ */
+ public Builder addSequence(Option<Sequence<Boolean>> key, boolean... values) {
+ Boolean[] a = new Boolean[values.length];
+ for (int i = 0; i < values.length; i++) {
+ a[i] = Boolean.valueOf(values[i]);
+ }
+ list.add(new OVPair<Sequence<Boolean>>(key, Sequence.of(a)));
+ return this;
+ }
+
+ /**
* Add a key-value pair, where the value is a sequence type.
*
* @param key the key
Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Sequence.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Sequence.java 2009-09-16 15:39:14 UTC (rev 5496)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Sequence.java 2009-09-16 16:09:24 UTC (rev 5497)
@@ -79,6 +79,9 @@
* @return a sequence
*/
public static <T> Sequence<T> of(Collection<T> members) {
+ if (members instanceof Sequence) {
+ return (Sequence<T>) members;
+ }
final Object[] objects = members.toArray();
if (objects.length == 0) {
return empty();
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-09-16 15:39:14 UTC (rev 5496)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/ConnectionProvider.java 2009-09-16 16:09:24 UTC (rev 5497)
@@ -23,6 +23,7 @@
package org.jboss.remoting3.spi;
import java.net.URI;
+import org.jboss.remoting3.OptionMap;
/**
* A connection provider. Used to establish connections with remote systems. There is typically one instance
@@ -37,9 +38,10 @@
* stored in the result variable possibly asynchronously.
*
* @param uri the URI to connect to
+ * @param connectOptions the options to use for this connection
* @param result the result which should receive the connection
* @return a handle which may be used to cancel the connect attempt
* @throws IllegalArgumentException if the URI is not valid
*/
- Cancellable connect(URI uri, Result<ConnectionHandlerFactory> result) throws IllegalArgumentException;
+ Cancellable connect(URI uri, OptionMap connectOptions, Result<ConnectionHandlerFactory> result) throws IllegalArgumentException;
}
15 years, 3 months
JBoss Remoting SVN: r5496 - remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3.
by jboss-remoting-commits@lists.jboss.org
Author: david.lloyd(a)jboss.com
Date: 2009-09-16 11:39:14 -0400 (Wed, 16 Sep 2009)
New Revision: 5496
Modified:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/OptionMap.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Options.java
Log:
Add more convenience options for option maps
Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/OptionMap.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/OptionMap.java 2009-09-16 15:38:45 UTC (rev 5495)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/OptionMap.java 2009-09-16 15:39:14 UTC (rev 5496)
@@ -117,6 +117,42 @@
}
/**
+ * Add an int value to an Integer key.
+ *
+ * @param key the option
+ * @param value the value
+ * @return this builder
+ */
+ public Builder add(Option<Integer> key, int value) {
+ list.add(new OVPair<Integer>(key, Integer.valueOf(value)));
+ return this;
+ }
+
+ /**
+ * Add a long value to a Long key.
+ *
+ * @param key the option
+ * @param value the value
+ * @return this builder
+ */
+ public Builder add(Option<Long> key, long value) {
+ list.add(new OVPair<Long>(key, Long.valueOf(value)));
+ return this;
+ }
+
+ /**
+ * Add a boolean value to a Boolean key.
+ *
+ * @param key the option
+ * @param value the value
+ * @return this builder
+ */
+ public Builder add(Option<Boolean> key, boolean value) {
+ list.add(new OVPair<Boolean>(key, Boolean.valueOf(value)));
+ return this;
+ }
+
+ /**
* Add a key-value pair, where the value is a sequence type.
*
* @param key the key
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-09-16 15:38:45 UTC (rev 5495)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Options.java 2009-09-16 15:39:14 UTC (rev 5496)
@@ -32,7 +32,7 @@
/**
* 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.
+ * not specified, use a default value. The marshaller {@code "default"} can be specified explicitly for this default value.
*/
public static final Option<Sequence<String>> MARSHALLING_PROTOCOLS = Option.sequence("jboss.remoting3.marshalling.protocols", String.class);
15 years, 3 months
JBoss Remoting SVN: r5495 - remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3.
by jboss-remoting-commits@lists.jboss.org
Author: david.lloyd(a)jboss.com
Date: 2009-09-16 11:38:45 -0400 (Wed, 16 Sep 2009)
New Revision: 5495
Added:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/ProtocolException.java
Log:
Add protocol exception type
Added: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/ProtocolException.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/ProtocolException.java (rev 0)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/ProtocolException.java 2009-09-16 15:38:45 UTC (rev 5495)
@@ -0,0 +1,69 @@
+/*
+ * 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;
+
+/**
+ * Indicates a wire protocol problem.
+ */
+public class ProtocolException extends RemotingException {
+
+ private static final long serialVersionUID = -5105448889133043476L;
+
+ /**
+ * Constructs a {@code ProtocolException} with no detail message. The cause is not initialized, and may subsequently be
+ * initialized by a call to {@link #initCause(Throwable) initCause}.
+ */
+ public ProtocolException() {
+ }
+
+ /**
+ * Constructs a {@code ProtocolException} with the specified detail message. The cause is not initialized, and may
+ * subsequently be initialized by a call to {@link #initCause(Throwable) initCause}.
+ *
+ * @param msg the detail message
+ */
+ public ProtocolException(final String msg) {
+ super(msg);
+ }
+
+ /**
+ * Constructs a {@code ProtocolException} with the specified cause. The detail message is set to:
+ * <pre>(cause == null ? null : cause.toString())</pre>
+ * (which typically contains the class and detail message of {@code cause}).
+ *
+ * @param cause the cause (which is saved for later retrieval by the {@link #getCause()} method)
+ */
+ public ProtocolException(final Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * Constructs a {@code ProtocolException} with the specified detail message and cause.
+ *
+ * @param msg the detail message
+ * @param cause the cause (which is saved for later retrieval by the {@link #getCause()} method)
+ */
+ public ProtocolException(final String msg, final Throwable cause) {
+ super(msg, cause);
+ }
+}
15 years, 3 months
JBoss Remoting SVN: r5494 - remoting2/branches/2.x/src/tests/org/jboss/test/remoting/marshall/config.
by jboss-remoting-commits@lists.jboss.org
Author: ron.sigal(a)jboss.com
Date: 2009-09-16 11:09:55 -0400 (Wed, 16 Sep 2009)
New Revision: 5494
Modified:
remoting2/branches/2.x/src/tests/org/jboss/test/remoting/marshall/config/ConfigTestMarshaller.java
Log:
JBREM-1102: Put a wrapper around the wrote counter.
Modified: remoting2/branches/2.x/src/tests/org/jboss/test/remoting/marshall/config/ConfigTestMarshaller.java
===================================================================
--- remoting2/branches/2.x/src/tests/org/jboss/test/remoting/marshall/config/ConfigTestMarshaller.java 2009-09-16 04:25:18 UTC (rev 5493)
+++ remoting2/branches/2.x/src/tests/org/jboss/test/remoting/marshall/config/ConfigTestMarshaller.java 2009-09-16 15:09:55 UTC (rev 5494)
@@ -40,13 +40,15 @@
protected static Logger log = Logger.getLogger(ConfigTestMarshaller.class);
private static final long serialVersionUID = 1L;
private static volatile int cloned;
- private static volatile int wrote;
+// private static volatile int wrote;
+ private static volatile IntHolder wrote = new IntHolder(0);
public void write(Object dataObject, OutputStream output, int version) throws IOException
{
log.info(this + "writing Wrapper");
super.write(new Wrapper(dataObject), output, version);
- wrote++;
+// wrote++;
+ wrote.increment();
log.info("wrote: " + wrote + ", cloned: " + cloned);
}
@@ -61,14 +63,45 @@
public static boolean ok(boolean b, int count)
{
log.info("wrote: " + wrote + ", cloned: " + cloned);
- return (b ? wrote > 0 : wrote == 0) && cloned == count;
+// return (b ? wrote > 0 : wrote == 0) && cloned == count;
+ int w = wrote.getI();
+ return (b ? w > 0 : w == 0);
}
public static void reset()
{
cloned = 0;
- wrote = 0;
+// wrote = 0;
+ wrote.setI(0);
log.info("reset(): wrote: " + wrote + ", cloned: " + cloned);
}
+
+ static class IntHolder
+ {
+ int i;
+
+ IntHolder(int i)
+ {
+ this.i = i;
+ }
+ public int getI()
+ {
+ return i;
+ }
+ public void setI(int i)
+ {
+ this.i = i;
+ log.info("setting i", new Exception("setting i"));
+ }
+ public void increment()
+ {
+ i++;
+ log.info("incrementing i", new Exception("incrementing i"));
+ }
+ public String toString()
+ {
+ return Integer.toString(i);
+ }
+ }
}
15 years, 3 months
JBoss Remoting SVN: r5493 - remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3.
by jboss-remoting-commits@lists.jboss.org
Author: david.lloyd(a)jboss.com
Date: 2009-09-16 00:25:18 -0400 (Wed, 16 Sep 2009)
New Revision: 5493
Modified:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Options.java
Log:
javadoc
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-09-16 04:13:30 UTC (rev 5492)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Options.java 2009-09-16 04:25:18 UTC (rev 5493)
@@ -22,24 +22,57 @@
package org.jboss.remoting3;
+/**
+ * Common options for service registration.
+ */
public final class Options {
private Options() {
}
+ /**
+ * 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.
+ */
public static final Option<Sequence<String>> MARSHALLING_PROTOCOLS = Option.sequence("jboss.remoting3.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.
+ */
public static final Option<Sequence<String>> MARSHALLING_CLASS_TABLES = Option.sequence("jboss.remoting3.marshalling.classTables", 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.
+ */
public static final Option<Sequence<String>> MARSHALLING_OBJECT_TABLES = Option.sequence("jboss.remoting3.marshalling.objectTables", 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.
+ */
public static final Option<Sequence<String>> MARSHALLING_CLASS_RESOLVERS = Option.sequence("jboss.remoting3.marshalling.classResolvers", 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.
+ */
public static final Option<Sequence<String>> MARSHALLING_OBJECT_RESOLVERS = Option.sequence("jboss.remoting3.marshalling.objectResolvers", 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.
+ */
public static final Option<Sequence<String>> MARSHALLING_EXTERNALIZER_FACTORIES = Option.sequence("jboss.remoting3.marshalling.externalizerFactories", String.class);
+ /**
+ * Specify a metric which is a hint that describes the relative desirability of this service.
+ */
public static final Option<Integer> METRIC = Option.simple("jboss.remoting3.metric", Integer.class);
- public static final Option<Boolean> EXTERNALLY_VISIBLE = Option.simple("jboss.remoting3.externallyVisible", Boolean.class);
+ /**
+ * Specify that the registered service should or should not be visible remotely. If not specified, defaults to {@code true}.
+ */
+ public static final Option<Boolean> REMOTELY_VISIBLE = Option.simple("jboss.remoting3.remotelyVisible", Boolean.class);
}
15 years, 3 months
JBoss Remoting SVN: r5492 - in remoting3/trunk: jboss-remoting and 5 other directories.
by jboss-remoting-commits@lists.jboss.org
Author: david.lloyd(a)jboss.com
Date: 2009-09-16 00:13:30 -0400 (Wed, 16 Sep 2009)
New Revision: 5492
Added:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/FlagSet.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Option.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/OptionMap.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Options.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Sequence.java
Removed:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/ServiceLocationListener.java
Modified:
remoting3/trunk/compat/src/main/java/org/jboss/remoting3/compat/UnwrappingRequestHandler.java
remoting3/trunk/compat/src/main/java/org/jboss/remoting3/compat/WrappingRequestHandler.java
remoting3/trunk/jboss-remoting/pom.xml
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/CloseHandler.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Connection.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/EndpointImpl.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/LocalServiceConfiguration.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/RequestCancelHandler.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/RequestListener.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/ServiceRegistration.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/ServiceRegistrationListener.java
remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/protocol/basic/BasicProtocol.java
remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/protocol/basic/BasicRequestHandler.java
remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/protocol/basic/BasicServerReplyTransmitter.java
remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/protocol/basic/BasicServerRequestConsumer.java
remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/simple/MultiplexClientExample.java
remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/simple/MultiplexServerExample.java
remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/simple/StreamingRot13RequestListener.java
remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/simple/StringRot13RequestListener.java
remoting3/trunk/samples/src/test/java/org/jboss/remoting3/samples/protocol/basic/BasicTestCase.java
remoting3/trunk/taglet/pom.xml
Log:
Make some changes to the service registration procedure; add javadocs
Modified: remoting3/trunk/compat/src/main/java/org/jboss/remoting3/compat/UnwrappingRequestHandler.java
===================================================================
--- remoting3/trunk/compat/src/main/java/org/jboss/remoting3/compat/UnwrappingRequestHandler.java 2009-09-16 03:01:55 UTC (rev 5491)
+++ remoting3/trunk/compat/src/main/java/org/jboss/remoting3/compat/UnwrappingRequestHandler.java 2009-09-16 04:13:30 UTC (rev 5492)
@@ -22,7 +22,6 @@
package org.jboss.remoting3.compat;
-import org.jboss.remoting3.spi.AbstractAutoCloseable;
import org.jboss.remoting3.spi.RequestHandler;
import org.jboss.remoting3.spi.RemoteRequestContext;
import org.jboss.remoting3.spi.ReplyHandler;
Modified: remoting3/trunk/compat/src/main/java/org/jboss/remoting3/compat/WrappingRequestHandler.java
===================================================================
--- remoting3/trunk/compat/src/main/java/org/jboss/remoting3/compat/WrappingRequestHandler.java 2009-09-16 03:01:55 UTC (rev 5491)
+++ remoting3/trunk/compat/src/main/java/org/jboss/remoting3/compat/WrappingRequestHandler.java 2009-09-16 04:13:30 UTC (rev 5492)
@@ -25,7 +25,6 @@
import org.jboss.remoting3.spi.RequestHandler;
import org.jboss.remoting3.spi.RemoteRequestContext;
import org.jboss.remoting3.spi.ReplyHandler;
-import org.jboss.remoting3.spi.AbstractAutoCloseable;
import java.util.concurrent.Executor;
/**
Modified: remoting3/trunk/jboss-remoting/pom.xml
===================================================================
--- remoting3/trunk/jboss-remoting/pom.xml 2009-09-16 03:01:55 UTC (rev 5491)
+++ remoting3/trunk/jboss-remoting/pom.xml 2009-09-16 04:13:30 UTC (rev 5492)
@@ -29,7 +29,7 @@
<groupId>org.jboss.remoting</groupId>
<artifactId>jboss-remoting</artifactId>
<packaging>jar</packaging>
- <version>1.1.0.CR1</version>
+ <version>3.1.0.CR1</version>
<dependencies>
<dependency>
<groupId>org.jboss.xnio</groupId>
Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/CloseHandler.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/CloseHandler.java 2009-09-16 03:01:55 UTC (rev 5491)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/CloseHandler.java 2009-09-16 04:13:30 UTC (rev 5492)
@@ -28,6 +28,7 @@
* @param <T> the type of resource
*
* @apiviz.exclude
+ * @remoting.implement
*/
public interface CloseHandler<T> {
Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Connection.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Connection.java 2009-09-16 03:01:55 UTC (rev 5491)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Connection.java 2009-09-16 04:13:30 UTC (rev 5492)
@@ -28,9 +28,7 @@
/**
* A connection to a remote peer.
* <p/>
- * This interface is part of the Remoting public API. It is intended to be consumed by Remoting applications; it is
- * not intended to be implemented by them. Methods may be added to this interface in future minor releases without
- * advance notice.
+ * @remoting.consume
*/
public interface Connection extends HandleableCloseable<Connection> {
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-09-16 03:01:55 UTC (rev 5491)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/EndpointImpl.java 2009-09-16 04:13:30 UTC (rev 5492)
@@ -172,8 +172,9 @@
}
final String serviceType = configuration.getServiceType();
final String groupName = configuration.getGroupName();
- final int metric = configuration.getMetric();
- if (metric < 0) {
+ 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");
}
ServiceURI.validateServiceType(serviceType);
@@ -247,7 +248,7 @@
final ServiceRegistrationListener.ServiceInfo serviceInfo = new ServiceRegistrationListener.ServiceInfo();
serviceInfo.setGroupName(groupName);
serviceInfo.setServiceType(serviceType);
- serviceInfo.setMetric(metric);
+ serviceInfo.setOptionMap(optionMap);
serviceInfo.setRegistrationHandle(newHandle);
serviceInfo.setRequestHandlerConnector(requestHandlerConnector);
executor.execute(new Runnable() {
@@ -324,7 +325,7 @@
for (ServiceRegistration service : services) {
final ServiceRegistrationListener.ServiceInfo serviceInfo = new ServiceRegistrationListener.ServiceInfo();
serviceInfo.setGroupName(service.getGroupName());
- serviceInfo.setMetric(service.getMetric());
+ serviceInfo.setOptionMap(service.getOptionMap());
serviceInfo.setRegistrationHandle(service.getHandle());
serviceInfo.setRequestHandlerConnector(service.getConnector());
serviceInfo.setServiceType(service.getServiceType());
Added: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/FlagSet.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/FlagSet.java (rev 0)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/FlagSet.java 2009-09-16 04:13:30 UTC (rev 5492)
@@ -0,0 +1,149 @@
+/*
+ * 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 java.util.AbstractSet;
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.Collections;
+import java.util.Collection;
+import java.io.Serializable;
+
+/**
+ * An immutable set of some enumeration type. Used to build immutable sets of flags for flag options.
+ *
+ * @param <E> the element type
+ */
+public final class FlagSet<E extends Enum<E>> extends AbstractSet<E> implements Serializable {
+
+ private final Class<E> type;
+ private final EnumSet<E> values;
+ private static final long serialVersionUID = 4155828678034140336L;
+
+ private FlagSet(final Class<E> type, final EnumSet<E> values) {
+ this.type = type;
+ this.values = values;
+ }
+
+ /**
+ * Create a flag set that is a copy of a given collection.
+ *
+ * @param elementType the element type
+ * @param original the original flag collection
+ * @param <E> the element type
+ * @return the flag set
+ */
+ public static <E extends Enum<E>> FlagSet<E> copyOf(Class<E> elementType, Collection<E> original) {
+ return new FlagSet<E>(elementType, EnumSet.copyOf(original));
+ }
+
+ /**
+ * Create an empty flag set of a given type.
+ *
+ * @param elementType the element type
+ * @param <E> the element type
+ * @return the flag set
+ */
+ public static <E extends Enum<E>> FlagSet<E> noneOf(Class<E> elementType) {
+ return new FlagSet<E>(elementType, EnumSet.noneOf(elementType));
+ }
+
+ /**
+ * Create a full flag set of a given type.
+ *
+ * @param elementType the element type
+ * @param <E> the element type
+ * @return the flag set
+ */
+ public static <E extends Enum<E>> FlagSet<E> allOf(Class<E> elementType) {
+ return new FlagSet<E>(elementType, EnumSet.allOf(elementType));
+ }
+
+ /**
+ * Create a flag set of the given elements.
+ *
+ * @param elements the elements
+ * @param <E> the element type
+ * @return the flag set
+ */
+ @SuppressWarnings({ "unchecked" })
+ public static <E extends Enum<E>> FlagSet<E> of(E... elements) {
+ if (elements.length == 0) {
+ throw new IllegalArgumentException("Empty elements array");
+ }
+ Class elementType = elements[0].getClass();
+ while (elementType.getSuperclass() != Enum.class) elementType = elementType.getSuperclass();
+ return new FlagSet<E>((Class<E>)elementType, EnumSet.<E>of(elements[0], elements));
+ }
+
+ /**
+ * Get the element type for this flag set.
+ *
+ * @return the element type
+ */
+ public Class<E> getElementType() {
+ return type;
+ }
+
+ /**
+ * Cast this flag set to a flag set of the given element type.
+ *
+ * @param type the element type
+ * @param <N> the element type
+ * @return this flag set
+ * @throws ClassCastException if the elements of this flag set are not of the given type
+ */
+ @SuppressWarnings({ "unchecked" })
+ public <N extends Enum<N>> FlagSet<N> cast(Class<N> type) throws ClassCastException {
+ this.type.asSubclass(type);
+ return (FlagSet<N>) this;
+ }
+
+ /**
+ * Determine if this flag set contains the given value.
+ *
+ * @param o the value
+ * @return {@code true} if the value is within this set
+ */
+ public boolean contains(final Object o) {
+ return values.contains(o);
+ }
+
+ /**
+ * Get an iterator over this flag set.
+ *
+ * @return an iterator
+ */
+ public Iterator<E> iterator() {
+ return Collections.unmodifiableSet(values).iterator();
+ }
+
+ /**
+ * Get the number of elements in this flag set.
+ *
+ * @return the number of elements
+ */
+ public int size() {
+ return values.size();
+ }
+}
Modified: 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-09-16 03:01:55 UTC (rev 5491)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/LocalServiceConfiguration.java 2009-09-16 04:13:30 UTC (rev 5492)
@@ -33,7 +33,7 @@
private final Class<O> replyClass;
private String serviceType;
private String groupName;
- private int metric;
+ private OptionMap optionMap = OptionMap.EMPTY;
/**
* Construct a new instance.
@@ -112,20 +112,23 @@
}
/**
- * Get the metric.
+ * Get the option map for the service.
*
- * @return the metric
+ * @return the option map
*/
- public int getMetric() {
- return metric;
+ public OptionMap getOptionMap() {
+ return optionMap;
}
/**
- * Set the metric.
+ * Set the option map for the service.
*
- * @param metric the metric
+ * @param optionMap the option map
*/
- public void setMetric(final int metric) {
- this.metric = metric;
+ public void setOptionMap(final OptionMap optionMap) {
+ if (optionMap == null) {
+ throw new NullPointerException("optionMap is null");
+ }
+ this.optionMap = optionMap;
}
}
Added: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Option.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Option.java (rev 0)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Option.java 2009-09-16 04:13:30 UTC (rev 5492)
@@ -0,0 +1,140 @@
+/*
+ * 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;
+
+/**
+ * A strongly-typed option to configure an aspect of a service. Options are immutable and use identity comparisons
+ * and hash codes, and they are not serializable.
+ *
+ * @param <T> the option value type
+ */
+public abstract class Option<T> {
+
+ private final String name;
+
+ Option(final String name) {
+ if (name == null) {
+ throw new NullPointerException("name is null");
+ }
+ this.name = name;
+ }
+
+ /**
+ * Create an option with a simple type. The class object given <b>must</b> represent some immutable type, otherwise
+ * unexpected behavior may result.
+ *
+ * @param name the name of this option
+ * @param type the class of the value associated with this option
+ * @param <T> the type of the value associated with this option
+ * @return the option instance
+ */
+ public static <T> Option<T> simple(final String name, final Class<T> type) {
+ return new SingleOption<T>(name, type);
+ }
+
+ /**
+ * Create an option with a sequence type. The class object given <b>must</b> represent some immutable type, otherwise
+ * unexpected behavior may result.
+ *
+ * @param name the name of this option
+ * @param elementType the class of the sequence element value associated with this option
+ * @param <T> the type of the sequence element value associated with this option
+ * @return the option instance
+ */
+ public static <T> Option<Sequence<T>> sequence(final String name, final Class<T> elementType) {
+ return new SequenceOption<T>(name, elementType);
+ }
+
+ /**
+ * Create an option with a flag set type. The class object given <b>must</b> represent some immutable type, otherwise
+ * unexpected behavior may result.
+ *
+ * @param name the name of this option
+ * @param elementType the class of the flag values associated with this option
+ * @param <T> the type of the flag values associated with this option
+ * @return the option instance
+ */
+ public static <T extends Enum<T>> Option<FlagSet<T>> flags(final String name, final Class<T> elementType) {
+ return new FlagsOption<T>(name, elementType);
+ }
+
+ /**
+ * Get the name of this option.
+ *
+ * @return the option name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Return the given object as the type of this option. If the cast could not be completed, an exception is thrown.
+ *
+ * @param o the object to cast
+ * @return the cast object
+ * @throws ClassCastException if the object is not of a compatible type
+ */
+ public abstract T cast(Object o) throws ClassCastException;
+}
+
+final class SingleOption<T> extends Option<T> {
+
+ private final Class<T> type;
+
+ SingleOption(final String name, final Class<T> type) {
+ super(name);
+ this.type = type;
+ }
+
+ public T cast(final Object o) {
+ return type.cast(o);
+ }
+}
+
+final class SequenceOption<T> extends Option<Sequence<T>> {
+ private final Class<T> elementType;
+
+ SequenceOption(final String name, final Class<T> elementType) {
+ super(name);
+ this.elementType = elementType;
+ }
+
+ public Sequence<T> cast(final Object o) {
+ return ((Sequence<?>)o).cast(elementType);
+ }
+}
+
+final class FlagsOption<T extends Enum<T>> extends Option<FlagSet<T>> {
+
+ private final Class<T> elementType;
+
+ FlagsOption(final String name, final Class<T> elementType) {
+ super(name);
+ this.elementType = elementType;
+ }
+
+ public FlagSet<T> cast(final Object o) throws ClassCastException {
+ final FlagSet<?> flagSet = (FlagSet<?>) o;
+ return flagSet.cast(elementType);
+ }
+}
\ No newline at end of file
Added: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/OptionMap.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/OptionMap.java (rev 0)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/OptionMap.java 2009-09-16 04:13:30 UTC (rev 5492)
@@ -0,0 +1,203 @@
+/*
+ * 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 java.util.Iterator;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.Collections;
+import java.util.IdentityHashMap;
+
+/**
+ * An immutable map of options to option values. No {@code null} keys or values are permitted.
+ */
+public final class OptionMap implements Iterable<Option<?>> {
+
+ private final Map<Option<?>, Object> value;
+
+ private OptionMap(final Map<Option<?>, Object> value) {
+ this.value = value;
+ }
+
+ /**
+ * Get the value of an option from this option map.
+ *
+ * @param option the option to get
+ * @param <T> the type of the option
+ * @return the option value, or {@code null} if it is not present
+ */
+ <T> T get(Option<T> option) {
+ return option.cast(value.get(option));
+ }
+
+ /**
+ * Iterate over the options in this map.
+ *
+ * @return an iterator over the options
+ */
+ public Iterator<Option<?>> iterator() {
+ return Collections.unmodifiableCollection(value.keySet()).iterator();
+ }
+
+ /**
+ * Get the number of options stored in this map.
+ *
+ * @return the number of options
+ */
+ public int size() {
+ return value.size();
+ }
+
+ /**
+ * The empty option map.
+ */
+ public static final OptionMap EMPTY = new OptionMap(Collections.<Option<?>, Object>emptyMap());
+
+ /**
+ * Create a new builder.
+ *
+ * @return a new builder
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * A builder for immutable option maps.
+ */
+ public static final class Builder {
+
+ private static class OVPair<T> {
+ Option<T> option;
+ T value;
+
+ private OVPair(final Option<T> option, final T value) {
+ this.option = option;
+ this.value = value;
+ }
+ }
+
+ private List<OVPair<?>> list = new ArrayList<OVPair<?>>();
+
+ /**
+ * Add a key-value pair.
+ *
+ * @param key the key
+ * @param value the value
+ * @param <T> the option type
+ * @return this builder
+ */
+ public <T> Builder add(Option<T> key, T value) {
+ if (value == null) {
+ throw new NullPointerException("value is null");
+ }
+ list.add(new OVPair<T>(key, value));
+ return this;
+ }
+
+ /**
+ * Add a key-value pair, where the value is a sequence type.
+ *
+ * @param key the key
+ * @param values the values
+ * @param <T> the option type
+ * @return this builder
+ */
+ public <T> Builder addSequence(Option<Sequence<T>> key, T... values) {
+ list.add(new OVPair<Sequence<T>>(key, Sequence.of(values)));
+ return this;
+ }
+
+ /**
+ * Add a key-value pair, where the value is a flag type.
+ *
+ * @param key the key
+ * @param values the values
+ * @param <T> the option type
+ * @return this builder
+ */
+ public <T extends Enum<T>> Builder addFlags(Option<FlagSet<T>> key, T... values) {
+ list.add(new OVPair<FlagSet<T>>(key, FlagSet.of(values)));
+ return this;
+ }
+
+ private <T> void copy(Map<?, ?> map, Option<T> option) {
+ add(option, option.cast(map.get(option)));
+ }
+
+ /**
+ * Add all the entries of a map. Any keys of the map which are not valid {@link Option}s, or whose
+ * values are not valid arguments for the given {@code Option}, will cause an exception to be thrown.
+ *
+ * @param map the map
+ * @return this builder
+ * @throws ClassCastException if any entries of the map are not valid option-value pairs
+ */
+ public Builder add(Map<?, ?> map) throws ClassCastException {
+ for (Object key : map.keySet()) {
+ final Option<?> option = Option.class.cast(key);
+ copy(map, option);
+ }
+ return this;
+ }
+
+ private <T> void copy(OptionMap optionMap, Option<T> option) {
+ add(option, optionMap.get(option));
+ }
+
+ /**
+ * Add all entries from an existing option map to the one being built.
+ *
+ * @param optionMap the original option map
+ * @return this builder
+ */
+ public Builder addAll(OptionMap optionMap) {
+ for (Option<?> option : optionMap) {
+ copy(optionMap, option);
+ }
+ return this;
+ }
+
+ /**
+ * Build a map that reflects the current state of this builder.
+ *
+ * @return the new immutable option map
+ */
+ public OptionMap getMap() {
+ final List<OVPair<?>> list = this.list;
+ if (list.size() == 0) {
+ return EMPTY;
+ } else if (list.size() == 1) {
+ final OVPair<?> pair = list.get(0);
+ return new OptionMap(Collections.<Option<?>, Object>singletonMap(pair.option, pair.value));
+ } else {
+ final Map<Option<?>, Object> map = new IdentityHashMap<Option<?>, Object>();
+ for (OVPair<?> ovPair : list) {
+ map.put(ovPair.option, ovPair.value);
+ }
+ return new OptionMap(map);
+ }
+ }
+ }
+}
Added: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Options.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Options.java (rev 0)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Options.java 2009-09-16 04:13:30 UTC (rev 5492)
@@ -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;
+
+public final class Options {
+
+ private Options() {
+ }
+
+ public static final Option<Sequence<String>> MARSHALLING_PROTOCOLS = Option.sequence("jboss.remoting3.marshalling.protocols", String.class);
+
+ public static final Option<Sequence<String>> MARSHALLING_CLASS_TABLES = Option.sequence("jboss.remoting3.marshalling.classTables", String.class);
+
+ public static final Option<Sequence<String>> MARSHALLING_OBJECT_TABLES = Option.sequence("jboss.remoting3.marshalling.objectTables", String.class);
+
+ public static final Option<Sequence<String>> MARSHALLING_CLASS_RESOLVERS = Option.sequence("jboss.remoting3.marshalling.classResolvers", String.class);
+
+ public static final Option<Sequence<String>> MARSHALLING_OBJECT_RESOLVERS = Option.sequence("jboss.remoting3.marshalling.objectResolvers", String.class);
+
+ public static final Option<Sequence<String>> MARSHALLING_EXTERNALIZER_FACTORIES = Option.sequence("jboss.remoting3.marshalling.externalizerFactories", String.class);
+
+ public static final Option<Integer> METRIC = Option.simple("jboss.remoting3.metric", Integer.class);
+
+ public static final Option<Boolean> EXTERNALLY_VISIBLE = Option.simple("jboss.remoting3.externallyVisible", Boolean.class);
+}
Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/RequestCancelHandler.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/RequestCancelHandler.java 2009-09-16 03:01:55 UTC (rev 5491)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/RequestCancelHandler.java 2009-09-16 04:13:30 UTC (rev 5492)
@@ -26,8 +26,10 @@
* A handler for request listeners to receive a notification when a request was cancelled.
*
* @param <O> the reply type
+ * @see org.jboss.remoting3.RequestContext#addCancelHandler(RequestCancelHandler)
*
* @apiviz.exclude
+ * @remoting.implement
*/
public interface RequestCancelHandler<O> {
Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/RequestListener.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/RequestListener.java 2009-09-16 03:01:55 UTC (rev 5491)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/RequestListener.java 2009-09-16 04:13:30 UTC (rev 5492)
@@ -28,6 +28,7 @@
* @param <I> the request type
* @param <O> the reply type
*
+ * @remoting.implement
* @apiviz.landmark
*/
public interface RequestListener<I, O> {
Added: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Sequence.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Sequence.java (rev 0)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Sequence.java 2009-09-16 04:13:30 UTC (rev 5492)
@@ -0,0 +1,163 @@
+/*
+ * 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 java.io.Serializable;
+import java.util.Iterator;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.AbstractList;
+import java.util.List;
+import java.util.RandomAccess;
+
+/**
+ * An immutable sequence of elements. Though this class implements {@link java.util.List}, it is in fact
+ * immutable.
+ *
+ * @param <T> the element type
+ */
+public final class Sequence<T> extends AbstractList<T> implements List<T>, RandomAccess, Serializable {
+
+ private static final long serialVersionUID = 3042164316147742903L;
+
+ private final Object[] values;
+
+ private static final Object[] empty = new Object[0];
+
+ private Sequence(final Object[] values) {
+ final Object[] realValues = values.clone();
+ this.values = realValues;
+ for (Object realValue : realValues) {
+ if (realValue == null) {
+ throw new NullPointerException("value member is null");
+ }
+ }
+ }
+
+ private static final Sequence EMPTY = new Sequence(empty);
+
+ /**
+ * Return a sequence of the given members.
+ *
+ * @param members the members
+ * @param <T> the element type
+ * @return a sequence
+ */
+ public static <T> Sequence<T> of(T... members) {
+ if (members.length == 0) {
+ return empty();
+ } else {
+ return new Sequence<T>(members);
+ }
+ }
+
+ /**
+ * Return a sequence of the given members.
+ *
+ * @param members the members
+ * @param <T> the element type
+ * @return a sequence
+ */
+ public static <T> Sequence<T> of(Collection<T> members) {
+ final Object[] objects = members.toArray();
+ if (objects.length == 0) {
+ return empty();
+ }
+ return new Sequence<T>(objects);
+ }
+
+ /**
+ * Cast a sequence to a different type <b>if</b> all the contained elements are of the subtype.
+ *
+ * @param newType the class to cast to
+ * @param <N> the new type
+ * @return the typecast sequence
+ * @throws ClassCastException if any elements could not be cast
+ */
+ @SuppressWarnings({ "unchecked" })
+ public <N> Sequence<N> cast(Class<N> newType) throws ClassCastException {
+ for (Object value : values) {
+ newType.cast(value);
+ }
+ return (Sequence<N>) this;
+ }
+
+ /**
+ * Return an empty sequence.
+ *
+ * @param <T> the element type
+ * @return the empty sequence
+ */
+ @SuppressWarnings({ "unchecked" })
+ public static <T> Sequence<T> empty() {
+ return (Sequence<T>) EMPTY;
+ }
+
+ /**
+ * Get an iterator over the elements of this sequence.
+ *
+ * @return an iterator over the elements of this sequence
+ */
+ @SuppressWarnings({ "unchecked" })
+ public Iterator<T> iterator() {
+ return Arrays.<T>asList((T[]) values).iterator();
+ }
+
+ /**
+ * Return the number of elements in this sequence.
+ *
+ * @return the number of elements
+ */
+ public int size() {
+ return values.length;
+ }
+
+ /**
+ * Determine whether this sequence is empty.
+ *
+ * @return {@code true} if the sequence has no elements
+ */
+ public boolean isEmpty() {
+ return values.length != 0;
+ }
+
+ /**
+ * Get a copy of the values array.
+ *
+ * @return a copy of the values array
+ */
+ public Object[] toArray() {
+ return values.clone();
+ }
+
+ /**
+ * Get the value at a certain index.
+ *
+ * @param index the index
+ * @return the value
+ */
+ @SuppressWarnings({ "unchecked" })
+ public T get(final int index) {
+ return (T) values[index];
+ }
+}
Deleted: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/ServiceLocationListener.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/ServiceLocationListener.java 2009-09-16 03:01:55 UTC (rev 5491)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/ServiceLocationListener.java 2009-09-16 04:13:30 UTC (rev 5492)
@@ -1,97 +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 java.net.URI;
-
-/**
- * A listener for watching service location events on an endpoint.
- *
- * @apiviz.landmark
- */
-public interface ServiceLocationListener {
- void serviceLocated(SimpleCloseable listenerHandler, ServiceInfo info);
-
- /**
- * Information about a located service.
- */
- final class ServiceInfo {
- private URI serviceUri;
- private URI locationUri;
- private int metric;
-
- /**
- * Get the URI of the located service.
- *
- * @return the URI
- */
- public URI getServiceUri() {
- return serviceUri;
- }
-
- /**
- * Set the URI of the located service.
- *
- * @param serviceUri the URI
- */
- public void setServiceUri(final URI serviceUri) {
- this.serviceUri = serviceUri;
- }
-
- /**
- * Get the URI of the location of the located service.
- *
- * @return the URI
- */
- public URI getLocationUri() {
- return locationUri;
- }
-
- /**
- * Set the URI of the location of the located service.
- *
- * @param locationUri the URI
- */
- public void setLocationUri(final URI locationUri) {
- this.locationUri = locationUri;
- }
-
- /**
- * Get the preference metric of this located service.
- *
- * @return the preference metric
- */
- public int getMetric() {
- return metric;
- }
-
- /**
- * Set the preference metric of this located service.
- *
- * @param metric the preference metric
- */
- public void setMetric(final int metric) {
- this.metric = metric;
- }
- }
-}
Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/ServiceRegistration.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/ServiceRegistration.java 2009-09-16 03:01:55 UTC (rev 5491)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/ServiceRegistration.java 2009-09-16 04:13:30 UTC (rev 5492)
@@ -32,22 +32,22 @@
private final String serviceType;
private final String groupName;
private final String endpointName;
- private final int metric;
+ private final OptionMap optionMap;
private final RequestHandlerConnector connector;
private volatile SimpleCloseable handle;
- ServiceRegistration(final String serviceType, final String groupName, final String endpointName, final int metric, final RequestHandlerConnector connector) {
+ ServiceRegistration(final String serviceType, final String groupName, final String endpointName, final OptionMap optionMap, final RequestHandlerConnector connector) {
remote = true;
this.serviceType = serviceType;
this.groupName = groupName;
this.endpointName = endpointName;
- this.metric = metric;
+ this.optionMap = optionMap;
this.connector = connector;
}
ServiceRegistration(final String serviceType, final String groupName, final String endpointName, final RequestHandlerConnector connector) {
remote = false;
- metric = 0;
+ optionMap = OptionMap.EMPTY;
this.serviceType = serviceType;
this.groupName = groupName;
this.endpointName = endpointName;
@@ -76,8 +76,8 @@
return endpointName;
}
- public int getMetric() {
- return metric;
+ public OptionMap getOptionMap() {
+ return optionMap;
}
public RequestHandlerConnector getConnector() {
Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/ServiceRegistrationListener.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/ServiceRegistrationListener.java 2009-09-16 03:01:55 UTC (rev 5491)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/ServiceRegistrationListener.java 2009-09-16 04:13:30 UTC (rev 5492)
@@ -28,6 +28,7 @@
* A listener for watching service registrations on an endpoint.
*
* @apiviz.landmark
+ * @remoting.implement
*/
public interface ServiceRegistrationListener {
@@ -47,9 +48,9 @@
final class ServiceInfo implements Cloneable {
private String serviceType;
private String groupName;
- private int metric;
private RequestHandlerConnector requestHandlerConnector;
private SimpleCloseable registrationHandle;
+ private OptionMap optionMap;
/**
* Construct a new instance.
@@ -94,21 +95,21 @@
}
/**
- * Get the metric.
+ * Get the option map.
*
- * @return the metric
+ * @return the option map
*/
- public int getMetric() {
- return metric;
+ public OptionMap getOptionMap() {
+ return optionMap;
}
/**
- * Set the metric.
+ * Set the option map.
*
- * @param metric the metric
+ * @param optionMap the option map
*/
- public void setMetric(final int metric) {
- this.metric = metric;
+ public void setOptionMap(final OptionMap optionMap) {
+ this.optionMap = optionMap;
}
/**
Modified: remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/protocol/basic/BasicProtocol.java
===================================================================
--- remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/protocol/basic/BasicProtocol.java 2009-09-16 03:01:55 UTC (rev 5491)
+++ remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/protocol/basic/BasicProtocol.java 2009-09-16 04:13:30 UTC (rev 5492)
@@ -24,7 +24,6 @@
import org.jboss.remoting3.spi.RequestHandler;
import org.jboss.remoting3.spi.ReplyHandler;
-import org.jboss.remoting3.spi.Handle;
import org.jboss.xnio.channels.StreamChannel;
import org.jboss.xnio.channels.ChannelOutputStream;
import org.jboss.xnio.channels.ChannelInputStream;
Modified: remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/protocol/basic/BasicRequestHandler.java
===================================================================
--- remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/protocol/basic/BasicRequestHandler.java 2009-09-16 03:01:55 UTC (rev 5491)
+++ remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/protocol/basic/BasicRequestHandler.java 2009-09-16 04:13:30 UTC (rev 5492)
@@ -26,7 +26,6 @@
import org.jboss.remoting3.spi.ReplyHandler;
import org.jboss.remoting3.spi.RemoteRequestContext;
import org.jboss.remoting3.spi.SpiUtils;
-import org.jboss.remoting3.spi.AbstractAutoCloseable;
import org.jboss.marshalling.Marshaller;
import org.jboss.xnio.channels.StreamChannel;
import org.jboss.xnio.IoUtils;
Modified: remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/protocol/basic/BasicServerReplyTransmitter.java
===================================================================
--- remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/protocol/basic/BasicServerReplyTransmitter.java 2009-09-16 03:01:55 UTC (rev 5491)
+++ remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/protocol/basic/BasicServerReplyTransmitter.java 2009-09-16 04:13:30 UTC (rev 5492)
@@ -28,7 +28,6 @@
import org.jboss.xnio.IoUtils;
import org.jboss.xnio.log.Logger;
import org.jboss.remoting3.spi.RequestHandler;
-import org.jboss.remoting3.spi.Handle;
/**
*
Modified: remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/protocol/basic/BasicServerRequestConsumer.java
===================================================================
--- remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/protocol/basic/BasicServerRequestConsumer.java 2009-09-16 03:01:55 UTC (rev 5491)
+++ remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/protocol/basic/BasicServerRequestConsumer.java 2009-09-16 04:13:30 UTC (rev 5492)
@@ -24,7 +24,6 @@
import org.jboss.marshalling.Unmarshaller;
import org.jboss.remoting3.spi.RequestHandler;
-import org.jboss.remoting3.spi.Handle;
import org.jboss.remoting3.spi.RemoteRequestContext;
import org.jboss.remoting3.spi.ReplyHandler;
import org.jboss.xnio.channels.StreamChannel;
Modified: remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/simple/MultiplexClientExample.java
===================================================================
--- remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/simple/MultiplexClientExample.java 2009-09-16 03:01:55 UTC (rev 5491)
+++ remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/simple/MultiplexClientExample.java 2009-09-16 04:13:30 UTC (rev 5492)
@@ -24,17 +24,13 @@
import org.jboss.remoting3.Endpoint;
import org.jboss.remoting3.Remoting;
-import org.jboss.remoting3.ClientSource;
import org.jboss.remoting3.Client;
import org.jboss.remoting3.multiplex.MultiplexProtocol;
import org.jboss.remoting3.multiplex.MultiplexConfiguration;
import org.jboss.remoting3.multiplex.MultiplexConnection;
-import org.jboss.remoting3.spi.RequestHandlerSource;
-import org.jboss.remoting3.spi.Handle;
import org.jboss.xnio.IoUtils;
import org.jboss.xnio.Buffers;
import org.jboss.xnio.Xnio;
-import org.jboss.xnio.CloseableTcpConnector;
import org.jboss.xnio.ConfigurableFactory;
import org.jboss.xnio.ChannelSource;
import org.jboss.xnio.IoFuture;
Modified: remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/simple/MultiplexServerExample.java
===================================================================
--- remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/simple/MultiplexServerExample.java 2009-09-16 03:01:55 UTC (rev 5491)
+++ remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/simple/MultiplexServerExample.java 2009-09-16 04:13:30 UTC (rev 5492)
@@ -27,8 +27,6 @@
import org.jboss.remoting3.LocalServiceConfiguration;
import org.jboss.remoting3.multiplex.MultiplexProtocol;
import org.jboss.remoting3.multiplex.MultiplexConfiguration;
-import org.jboss.remoting3.spi.RequestHandlerSource;
-import org.jboss.remoting3.spi.Handle;
import org.jboss.xnio.IoUtils;
import org.jboss.xnio.Buffers;
import org.jboss.xnio.IoHandlerFactory;
Modified: remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/simple/StreamingRot13RequestListener.java
===================================================================
--- remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/simple/StreamingRot13RequestListener.java 2009-09-16 03:01:55 UTC (rev 5491)
+++ remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/simple/StreamingRot13RequestListener.java 2009-09-16 04:13:30 UTC (rev 5492)
@@ -2,7 +2,6 @@
import java.io.IOException;
import java.io.Reader;
-import org.jboss.remoting3.AbstractRequestListener;
import org.jboss.remoting3.RemoteExecutionException;
import org.jboss.remoting3.RequestContext;
Modified: remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/simple/StringRot13RequestListener.java
===================================================================
--- remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/simple/StringRot13RequestListener.java 2009-09-16 03:01:55 UTC (rev 5491)
+++ remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/simple/StringRot13RequestListener.java 2009-09-16 04:13:30 UTC (rev 5492)
@@ -1,7 +1,6 @@
package org.jboss.remoting3.samples.simple;
import java.io.IOException;
-import org.jboss.remoting3.AbstractRequestListener;
import org.jboss.remoting3.RemoteExecutionException;
import org.jboss.remoting3.RequestContext;
import org.jboss.xnio.log.Logger;
Modified: remoting3/trunk/samples/src/test/java/org/jboss/remoting3/samples/protocol/basic/BasicTestCase.java
===================================================================
--- remoting3/trunk/samples/src/test/java/org/jboss/remoting3/samples/protocol/basic/BasicTestCase.java 2009-09-16 03:01:55 UTC (rev 5491)
+++ remoting3/trunk/samples/src/test/java/org/jboss/remoting3/samples/protocol/basic/BasicTestCase.java 2009-09-16 04:13:30 UTC (rev 5492)
@@ -32,12 +32,10 @@
import org.jboss.xnio.channels.StreamChannel;
import org.jboss.remoting3.Endpoint;
import org.jboss.remoting3.Remoting;
-import org.jboss.remoting3.AbstractRequestListener;
import org.jboss.remoting3.RequestContext;
import org.jboss.remoting3.RemoteExecutionException;
import org.jboss.remoting3.Client;
import org.jboss.remoting3.spi.RequestHandler;
-import org.jboss.remoting3.spi.Handle;
import org.jboss.marshalling.MarshallingConfiguration;
import org.jboss.marshalling.river.RiverMarshallerFactory;
import java.util.concurrent.ThreadPoolExecutor;
Modified: remoting3/trunk/taglet/pom.xml
===================================================================
--- remoting3/trunk/taglet/pom.xml 2009-09-16 03:01:55 UTC (rev 5491)
+++ remoting3/trunk/taglet/pom.xml 2009-09-16 04:13:30 UTC (rev 5492)
@@ -29,7 +29,7 @@
<groupId>org.jboss.remoting</groupId>
<artifactId>jboss-remoting-taglet</artifactId>
<packaging>jar</packaging>
- <version>1.1.0.CR1</version>
+ <version>3.1.0.CR1</version>
<dependencies>
<dependency>
15 years, 3 months