Author: david.lloyd(a)jboss.com
Date: 2009-10-23 18:24:45 -0400 (Fri, 23 Oct 2009)
New Revision: 5569
Added:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/BasicMarshallingProtocol.java
Modified:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/CopyOnWriteHashMap.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/EndpointImpl.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Options.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/MarshallingProtocol.java
Log:
Simplify service registration internals; add basic impl of MarshallingProtocol; add config
options to marshalling configuration
Added:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/BasicMarshallingProtocol.java
===================================================================
---
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/BasicMarshallingProtocol.java
(rev 0)
+++
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/BasicMarshallingProtocol.java 2009-10-23
22:24:45 UTC (rev 5569)
@@ -0,0 +1,122 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+
+package org.jboss.remoting3;
+
+import org.jboss.remoting3.spi.MarshallingProtocol;
+import org.jboss.marshalling.Unmarshaller;
+import org.jboss.marshalling.Marshaller;
+import org.jboss.marshalling.MarshallerFactory;
+import org.jboss.marshalling.MarshallingConfiguration;
+import org.jboss.marshalling.Marshalling;
+import org.jboss.marshalling.reflect.SunReflectiveCreator;
+import org.jboss.xnio.Pool;
+import org.jboss.xnio.OptionMap;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.io.IOException;
+
+/**
+ * A marshalling protocol which wraps a {@link org.jboss.marshalling.MarshallerFactory}.
+ */
+public final class BasicMarshallingProtocol implements MarshallingProtocol {
+
+ private final MarshallerFactory marshallerFactory;
+ private final int version;
+
+ private static final SunReflectiveCreator creator = AccessController.doPrivileged(new
PrivilegedAction<SunReflectiveCreator>() {
+ public SunReflectiveCreator run() {
+ return new SunReflectiveCreator();
+ }
+ });
+
+ /**
+ * Construct a new instance.
+ *
+ * @param marshallerFactory the marshaller factory to use
+ * @param version the wire protocol version to specify
+ */
+ public BasicMarshallingProtocol(final MarshallerFactory marshallerFactory, final int
version) {
+ // todo: security check?
+ this.marshallerFactory = marshallerFactory;
+ this.version = version;
+ }
+
+ /** {@inheritDoc} */
+ public Pool<Unmarshaller> getUnmarshallerPool(final Configuration
configuration) {
+ final MarshallingConfiguration config = buildConfig(configuration);
+ return new Pool<Unmarshaller>() {
+ public Unmarshaller allocate() {
+ try {
+ return marshallerFactory.createUnmarshaller(config);
+ } catch (IOException e) {
+ // todo log
+ return null;
+ }
+ }
+
+ public void free(final Unmarshaller resource) throws IllegalArgumentException
{
+ }
+
+ public void discard(final Unmarshaller resource) {
+ }
+ };
+ }
+
+ /** {@inheritDoc} */
+ public Pool<Marshaller> getMarshallerPool(final Configuration configuration) {
+ final MarshallingConfiguration config = buildConfig(configuration);
+ return new Pool<Marshaller>() {
+ public Marshaller allocate() {
+ try {
+ return marshallerFactory.createMarshaller(config);
+ } catch (IOException e) {
+ // todo log
+ return null;
+ }
+ }
+
+ public void free(final Marshaller resource) throws IllegalArgumentException
{
+ }
+
+ public void discard(final Marshaller resource) {
+ }
+ };
+ }
+
+ private MarshallingConfiguration buildConfig(final Configuration configuration) {
+ final MarshallingConfiguration config = new MarshallingConfiguration();
+ config.setCreator(creator);
+ config.setStreamHeader(Marshalling.nullStreamHeader());
+ config.setClassExternalizerFactory(configuration.getUserExternalizerFactory());
+ config.setClassTable(configuration.getUserClassTable());
+ config.setClassResolver(configuration.getUserClassResolver());
+ config.setObjectResolver(configuration.getUserObjectResolver());
+ config.setObjectTable(configuration.getUserObjectTable());
+ final OptionMap optionMap = configuration.getOptionMap();
+ config.setBufferSize(optionMap.get(Options.BUFFER_SIZE, 512));
+ config.setClassCount(optionMap.get(Options.CLASS_COUNT, 64));
+ config.setInstanceCount(optionMap.get(Options.INSTANCE_COUNT, 256));
+ config.setVersion(version);
+ return config;
+ }
+}
Modified:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/CopyOnWriteHashMap.java
===================================================================
---
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/CopyOnWriteHashMap.java 2009-10-23
21:19:18 UTC (rev 5568)
+++
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/CopyOnWriteHashMap.java 2009-10-23
22:24:45 UTC (rev 5569)
@@ -26,6 +26,7 @@
import java.util.Set;
import java.util.Collection;
import java.util.HashMap;
+import java.util.IdentityHashMap;
import static java.util.Collections.emptyMap;
import static java.util.Collections.singletonMap;
import static java.util.Collections.unmodifiableMap;
@@ -34,6 +35,7 @@
import java.util.concurrent.ConcurrentMap;
final class CopyOnWriteHashMap<K, V> implements ConcurrentMap<K, V> {
+ private final boolean identity;
private final Object writeLock;
private volatile Map<K, V> map = emptyMap();
@@ -42,6 +44,11 @@
}
CopyOnWriteHashMap(final Object writeLock) {
+ this(false, writeLock);
+ }
+
+ CopyOnWriteHashMap(final boolean identity, final Object writeLock) {
+ this.identity = identity;
this.writeLock = writeLock;
}
@@ -59,7 +66,7 @@
if (map.size() == 0) {
this.map = singletonMap(key, value);
} else {
- final HashMap<K, V> copy = new HashMap<K, V>(map);
+ final Map<K, V> copy = copy(map);
map.put(key, value);
this.map = copy;
}
@@ -78,7 +85,7 @@
if (map.size() == 1) {
this.map = emptyMap();
} else {
- final HashMap<K, V> copy = new HashMap<K, V>(map);
+ final Map<K, V> copy = copy(map);
map.remove(key);
this.map = copy;
}
@@ -100,7 +107,7 @@
if (map.size() == 1) {
this.map = singletonMap(key, newValue);
} else {
- final HashMap<K, V> copy = new HashMap<K, V>(map);
+ final Map<K, V> copy = copy(map);
map.put(key, newValue);
this.map = copy;
}
@@ -122,7 +129,7 @@
if (map.size() == 1) {
this.map = singletonMap(key, value);
} else {
- final HashMap<K, V> copy = new HashMap<K, V>(map);
+ final Map<K, V> copy = copy(map);
map.put(key, value);
this.map = copy;
}
@@ -164,7 +171,7 @@
if (map.size() == 0) {
this.map = singletonMap(key, value);
} else {
- final HashMap<K, V> copy = new HashMap<K, V>(map);
+ final Map<K, V> copy = copy(map);
map.put(key, value);
this.map = copy;
}
@@ -181,7 +188,7 @@
if (map.size() == 1) {
this.map = emptyMap();
} else {
- final HashMap<K, V> copy = new HashMap<K, V>(map);
+ final Map<K, V> copy = copy(map);
map.remove(key);
this.map = copy;
}
@@ -190,6 +197,10 @@
}
}
+ private Map<K, V> copy(final Map<K, V> map) {
+ return identity ? new IdentityHashMap<K,V>(map) : new HashMap<K,
V>(map);
+ }
+
public void putAll(final Map<? extends K, ? extends V> m) {
}
Modified:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/EndpointImpl.java
===================================================================
---
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/EndpointImpl.java 2009-10-23
21:19:18 UTC (rev 5568)
+++
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/EndpointImpl.java 2009-10-23
22:24:45 UTC (rev 5569)
@@ -83,6 +83,10 @@
return new CopyOnWriteHashMap<K, V>(lock);
}
+ static <K, V> ConcurrentMap<K, V> concurrentIdentityMap(Object lock) {
+ return new CopyOnWriteHashMap<K, V>(true, lock);
+ }
+
static <T> Set<T> concurrentSet(Object lock) {
return Collections.<T>newSetFromMap(EndpointImpl.<T,
Boolean>concurrentMap(lock));
}
@@ -113,7 +117,7 @@
*/
private final Object serviceRegistrationLock = new Object();
- private final Set<ListenerRegistration<ServiceRegistrationListener>>
serviceListenerRegistrations =
Collections.newSetFromMap(EndpointImpl.<ListenerRegistration<ServiceRegistrationListener>,
Boolean>concurrentMap(serviceRegistrationLock));
+ private final ConcurrentMap<Registration, ServiceRegistrationListener>
serviceListenerRegistrations = concurrentIdentityMap(serviceRegistrationLock);
private final ConcurrentMap<String, ConcurrentMap<String,
ServiceRegistration>> registeredLocalServices =
concurrentMap(serviceRegistrationLock);
private final ConcurrentMap<String, ConnectionProvider<?>>
connectionProviders = concurrentMap();
@@ -244,7 +248,7 @@
}
};
registration.setHandle(handle);
- final Iterator<ListenerRegistration<ServiceRegistrationListener>>
serviceListenerRegistrations;
+ final Iterator<Map.Entry<Registration,ServiceRegistrationListener>>
serviceListenerRegistrations;
final Object lock = serviceRegistrationLock;
synchronized (lock) {
// actually register the service, and while we have the lock, snag a copy of
the registration listener list
@@ -260,7 +264,7 @@
}
submap.put(canonGroupName, registration);
// snapshot
- serviceListenerRegistrations = this.serviceListenerRegistrations.iterator();
+ serviceListenerRegistrations =
this.serviceListenerRegistrations.entrySet().iterator();
}
// notify all service listener registrations that were registered at the time the
service was created
final ServiceRegistrationListener.ServiceInfo serviceInfo = new
ServiceRegistrationListener.ServiceInfo();
@@ -271,12 +275,11 @@
serviceInfo.setRequestHandlerConnector(requestHandlerConnector);
executor.execute(new Runnable() {
public void run() {
- final
Iterator<ListenerRegistration<ServiceRegistrationListener>> iter =
serviceListenerRegistrations;
+ final
Iterator<Map.Entry<Registration,ServiceRegistrationListener>> iter =
serviceListenerRegistrations;
while (iter.hasNext()) {
- final ListenerRegistration<ServiceRegistrationListener> slr =
iter.next();
- final ServiceRegistrationListener registrationListener =
slr.getResource();
+ final Map.Entry<Registration,ServiceRegistrationListener> slr =
iter.next();
try {
- registrationListener.serviceRegistered(slr,
serviceInfo.clone());
+ slr.getValue().serviceRegistered(slr.getKey(),
serviceInfo.clone());
} catch (Throwable t) {
logListenerError(t);
}
@@ -329,9 +332,13 @@
sm.checkPermission(ADD_SERVICE_LISTENER_PERM);
}
final List<ServiceRegistration> services;
- final ListenerRegistration<ServiceRegistrationListener> registration = new
ListenerRegistration<ServiceRegistrationListener>(listener);
+ final Registration registration = new Registration() {
+ public void close() {
+ serviceListenerRegistrations.remove(this);
+ }
+ };
synchronized (serviceRegistrationLock) {
- serviceListenerRegistrations.add(registration);
+ serviceListenerRegistrations.put(registration, listener);
if (flags == null || ! flags.contains(ListenerFlag.INCLUDE_OLD)) {
// need to make a copy of the whole list
services = new ArrayList<ServiceRegistration>();
@@ -575,24 +582,6 @@
}
}
- private final class ListenerRegistration<T> implements Registration {
- private final T resource;
-
- private ListenerRegistration(final T resource) {
- this.resource = resource;
- }
-
- public void close() {
- synchronized (serviceRegistrationLock) {
- serviceListenerRegistrations.remove(this);
- }
- }
-
- T getResource() {
- return resource;
- }
- }
-
private final ConnectionContext localConnectionContext = new
LocalConnectionContext();
private final ConnectionHandler loopbackConnectionHandler = new
LoopbackConnectionHandler();
private final Connection loopbackConnection = new LoopbackConnection();
@@ -604,7 +593,7 @@
}
}
- final class LocalConnectionProvider implements ConnectionProvider<Void> {
+ private final class LocalConnectionProvider implements ConnectionProvider<Void>
{
public Cancellable connect(final URI uri, final OptionMap connectOptions, final
Result<ConnectionHandlerFactory> result) throws IllegalArgumentException {
result.setResult(new ConnectionHandlerFactory() {
Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Options.java
===================================================================
---
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Options.java 2009-10-23
21:19:18 UTC (rev 5568)
+++
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Options.java 2009-10-23
22:24:45 UTC (rev 5569)
@@ -88,4 +88,19 @@
* 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(Options.class, "REMOTELY_VISIBLE", Boolean.class);
+
+ /**
+ * Specify the buffer size for any configured marshaller or unmarshaller.
+ */
+ public static final Option<Integer> BUFFER_SIZE = Option.simple(Options.class,
"BUFFER_SIZE", Integer.class);
+
+ /**
+ * Specify the expected class count for any configured marshaller or unmarshaller.
+ */
+ public static final Option<Integer> CLASS_COUNT = Option.simple(Options.class,
"CLASS_COUNT", Integer.class);
+
+ /**
+ * Specify the expected instance count for any configured marshaller or
unmarshaller.
+ */
+ public static final Option<Integer> INSTANCE_COUNT =
Option.simple(Options.class, "INSTANCE_COUNT", Integer.class);
}
Modified:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/MarshallingProtocol.java
===================================================================
---
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/MarshallingProtocol.java 2009-10-23
21:19:18 UTC (rev 5568)
+++
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/MarshallingProtocol.java 2009-10-23
22:24:45 UTC (rev 5569)
@@ -30,6 +30,7 @@
import org.jboss.marshalling.ClassResolver;
import org.jboss.marshalling.ObjectResolver;
import org.jboss.xnio.Pool;
+import org.jboss.xnio.OptionMap;
/**
* A registered marshalling protocol.
@@ -95,5 +96,12 @@
* @return the user object resolver
*/
ObjectResolver getUserObjectResolver();
+
+ /**
+ * Get the options to use for this marshaller configuration.
+ *
+ * @return the options
+ */
+ OptionMap getOptionMap();
}
}