Introduce UniqueName, UniqueKey, and Signal
- UniqueKey removes the duplication between ChannelOption and AttributeKey - UniqueName provides common name collision check for AttributeKey, ChannelOption, and Signal. - Replaced ReplayError with Signal
This commit is contained in:
parent
5344dc242c
commit
dbd973d825
@ -1,26 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2011 The Netty Project
|
|
||||||
*
|
|
||||||
* The Netty Project licenses this file to you under the Apache License,
|
|
||||||
* version 2.0 (the "License"); you may not use this file except in compliance
|
|
||||||
* with the License. You may obtain a copy of the License at:
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
|
||||||
package io.netty.handler.codec;
|
|
||||||
|
|
||||||
final class ReplayError extends Error {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 2666698631187527681L;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public synchronized Throwable fillInStackTrace() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
@ -25,6 +25,7 @@ import io.netty.channel.ChannelHandlerContext;
|
|||||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||||
import io.netty.channel.ChannelInboundHandlerContext;
|
import io.netty.channel.ChannelInboundHandlerContext;
|
||||||
import io.netty.channel.ChannelPipeline;
|
import io.netty.channel.ChannelPipeline;
|
||||||
|
import io.netty.util.Signal;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A specialized variation of {@link StreamToMessageDecoder} which enables implementation
|
* A specialized variation of {@link StreamToMessageDecoder} which enables implementation
|
||||||
@ -281,6 +282,8 @@ import io.netty.channel.ChannelPipeline;
|
|||||||
*/
|
*/
|
||||||
public abstract class ReplayingDecoder<O, S extends Enum<S>> extends ChannelInboundHandlerAdapter<Byte> {
|
public abstract class ReplayingDecoder<O, S extends Enum<S>> extends ChannelInboundHandlerAdapter<Byte> {
|
||||||
|
|
||||||
|
static final Signal REPLAY = new Signal(ReplayingDecoder.class.getName() + ".REPLAY");
|
||||||
|
|
||||||
private final ChannelBufferHolder<Byte> in = ChannelBufferHolders.byteBuffer();
|
private final ChannelBufferHolder<Byte> in = ChannelBufferHolders.byteBuffer();
|
||||||
private final ChannelBuffer cumulation = in.byteBuffer();
|
private final ChannelBuffer cumulation = in.byteBuffer();
|
||||||
private final ReplayingDecoderBuffer replayable = new ReplayingDecoderBuffer(cumulation);
|
private final ReplayingDecoderBuffer replayable = new ReplayingDecoderBuffer(cumulation);
|
||||||
@ -365,8 +368,9 @@ public abstract class ReplayingDecoder<O, S extends Enum<S>> extends ChannelInbo
|
|||||||
in.discardReadBytes();
|
in.discardReadBytes();
|
||||||
ctx.fireInboundBufferUpdated();
|
ctx.fireInboundBufferUpdated();
|
||||||
}
|
}
|
||||||
} catch (ReplayError replay) {
|
} catch (Signal replay) {
|
||||||
// Ignore
|
// Ignore
|
||||||
|
replay.expect(REPLAY);
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
ctx.fireExceptionCaught(t);
|
ctx.fireExceptionCaught(t);
|
||||||
}
|
}
|
||||||
@ -393,7 +397,8 @@ public abstract class ReplayingDecoder<O, S extends Enum<S>> extends ChannelInbo
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (ReplayError replay) {
|
} catch (Signal replay) {
|
||||||
|
replay.expect(REPLAY);
|
||||||
// Return to the checkpoint (or oldPosition) and retry.
|
// Return to the checkpoint (or oldPosition) and retry.
|
||||||
int checkpoint = this.checkpoint;
|
int checkpoint = this.checkpoint;
|
||||||
if (checkpoint >= 0) {
|
if (checkpoint >= 0) {
|
||||||
|
@ -15,6 +15,12 @@
|
|||||||
*/
|
*/
|
||||||
package io.netty.handler.codec;
|
package io.netty.handler.codec;
|
||||||
|
|
||||||
|
import io.netty.buffer.ChannelBuffer;
|
||||||
|
import io.netty.buffer.ChannelBufferFactory;
|
||||||
|
import io.netty.buffer.ChannelBufferIndexFinder;
|
||||||
|
import io.netty.buffer.ChannelBuffers;
|
||||||
|
import io.netty.util.Signal;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
@ -24,14 +30,9 @@ import java.nio.channels.GatheringByteChannel;
|
|||||||
import java.nio.channels.ScatteringByteChannel;
|
import java.nio.channels.ScatteringByteChannel;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
import io.netty.buffer.ChannelBuffer;
|
|
||||||
import io.netty.buffer.ChannelBufferFactory;
|
|
||||||
import io.netty.buffer.ChannelBufferIndexFinder;
|
|
||||||
import io.netty.buffer.ChannelBuffers;
|
|
||||||
|
|
||||||
class ReplayingDecoderBuffer implements ChannelBuffer {
|
class ReplayingDecoderBuffer implements ChannelBuffer {
|
||||||
|
|
||||||
private static final Error REPLAY = new ReplayError();
|
private static final Signal REPLAY = ReplayingDecoder.REPLAY;
|
||||||
|
|
||||||
private final ChannelBuffer buffer;
|
private final ChannelBuffer buffer;
|
||||||
private boolean terminated;
|
private boolean terminated;
|
||||||
|
@ -1,51 +1,13 @@
|
|||||||
package io.netty.util;
|
package io.netty.util;
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
|
||||||
public final class AttributeKey<T> implements Serializable, Comparable<AttributeKey<T>> {
|
public final class AttributeKey<T> extends UniqueKey<T> {
|
||||||
|
|
||||||
private static final long serialVersionUID = 2783354860083517323L;
|
|
||||||
|
|
||||||
private static final ConcurrentMap<String, Boolean> names = new ConcurrentHashMap<String, Boolean>();
|
private static final ConcurrentMap<String, Boolean> names = new ConcurrentHashMap<String, Boolean>();
|
||||||
|
|
||||||
private final String name;
|
|
||||||
private final Class<T> valueType;
|
|
||||||
private final String strVal;
|
|
||||||
|
|
||||||
public AttributeKey(String name, Class<T> valueType) {
|
public AttributeKey(String name, Class<T> valueType) {
|
||||||
if (name == null) {
|
super(names, name, valueType);
|
||||||
throw new NullPointerException("name");
|
|
||||||
}
|
|
||||||
if (valueType == null) {
|
|
||||||
throw new NullPointerException("valueType");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (names.putIfAbsent(name, Boolean.TRUE) != null) {
|
|
||||||
throw new IllegalArgumentException("key name already in use: " + name);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.name = name;
|
|
||||||
this.valueType = valueType;
|
|
||||||
strVal = name + '[' + valueType.getSimpleName() + ']';
|
|
||||||
}
|
|
||||||
|
|
||||||
public String name() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Class<T> valueType() {
|
|
||||||
return valueType;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compareTo(AttributeKey<T> o) {
|
|
||||||
return name().compareTo(o.name());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return strVal;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
47
common/src/main/java/io/netty/util/Signal.java
Normal file
47
common/src/main/java/io/netty/util/Signal.java
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
package io.netty.util;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
|
||||||
|
public final class Signal extends Error {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -221145131122459977L;
|
||||||
|
|
||||||
|
private static final ConcurrentMap<String, Boolean> map =
|
||||||
|
new ConcurrentHashMap<String, Boolean>();
|
||||||
|
|
||||||
|
private final SignalName uname;
|
||||||
|
|
||||||
|
public Signal(String name) {
|
||||||
|
super(name);
|
||||||
|
uname = new SignalName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void expect(Signal signal) {
|
||||||
|
if (this != signal) {
|
||||||
|
throw new IllegalStateException("unexpected signal: " + signal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Throwable initCause(Throwable cause) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Throwable fillInStackTrace() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return uname.name();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class SignalName extends UniqueName {
|
||||||
|
protected SignalName(String name) {
|
||||||
|
super(map, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
32
common/src/main/java/io/netty/util/UniqueKey.java
Normal file
32
common/src/main/java/io/netty/util/UniqueKey.java
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
package io.netty.util;
|
||||||
|
|
||||||
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
|
||||||
|
public class UniqueKey<T> extends UniqueName {
|
||||||
|
|
||||||
|
private final Class<T> valueType;
|
||||||
|
private final String strVal;
|
||||||
|
|
||||||
|
protected UniqueKey(ConcurrentMap<String, Boolean> map, String name, Class<T> valueType) {
|
||||||
|
super(map, name, valueType);
|
||||||
|
this.valueType = valueType;
|
||||||
|
strVal = name + '[' + valueType.getSimpleName() + ']';
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void validateArgs(Object... args) {
|
||||||
|
super.validateArgs(args);
|
||||||
|
if (args[0] == null) {
|
||||||
|
throw new NullPointerException("valueType");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public final Class<T> valueType() {
|
||||||
|
return valueType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return strVal;
|
||||||
|
}
|
||||||
|
}
|
74
common/src/main/java/io/netty/util/UniqueName.java
Normal file
74
common/src/main/java/io/netty/util/UniqueName.java
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
package io.netty.util;
|
||||||
|
|
||||||
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
public class UniqueName implements Comparable<UniqueName> {
|
||||||
|
|
||||||
|
private static final AtomicInteger nextId = new AtomicInteger();
|
||||||
|
|
||||||
|
private final int id;
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
protected UniqueName(ConcurrentMap<String, Boolean> map, String name, Object... args) {
|
||||||
|
if (map == null) {
|
||||||
|
throw new NullPointerException("map");
|
||||||
|
}
|
||||||
|
if (name == null) {
|
||||||
|
throw new NullPointerException("name");
|
||||||
|
}
|
||||||
|
if (args != null && args.length > 0) {
|
||||||
|
validateArgs(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (map.putIfAbsent(name, Boolean.TRUE) != null) {
|
||||||
|
throw new IllegalArgumentException(String.format("'%s' already in use", name));
|
||||||
|
}
|
||||||
|
|
||||||
|
id = nextId.incrementAndGet();
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void validateArgs(Object... args) {
|
||||||
|
// Subclasses will override.
|
||||||
|
}
|
||||||
|
|
||||||
|
public final String name() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final int hashCode() {
|
||||||
|
return super.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean equals(Object o) {
|
||||||
|
return super.equals(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(UniqueName o) {
|
||||||
|
if (this == o) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret = name.compareTo(o.name);
|
||||||
|
if (ret != 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id < o.id) {
|
||||||
|
return -1;
|
||||||
|
} else if (id > o.id) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return name();
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,7 @@
|
|||||||
package io.netty.channel;
|
package io.netty.channel;
|
||||||
|
|
||||||
|
import io.netty.util.UniqueKey;
|
||||||
|
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.NetworkInterface;
|
import java.net.NetworkInterface;
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
@ -7,7 +9,7 @@ import java.util.List;
|
|||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
|
||||||
public class ChannelOption<T> implements Comparable<ChannelOption<T>> {
|
public class ChannelOption<T> extends UniqueKey<T> {
|
||||||
|
|
||||||
private static final ConcurrentMap<String, Boolean> names = new ConcurrentHashMap<String, Boolean>();
|
private static final ConcurrentMap<String, Boolean> names = new ConcurrentHashMap<String, Boolean>();
|
||||||
|
|
||||||
@ -75,33 +77,8 @@ public class ChannelOption<T> implements Comparable<ChannelOption<T>> {
|
|||||||
public static final ChannelOption<SocketAddress> SCTP_SET_PEER_PRIMARY_ADDR =
|
public static final ChannelOption<SocketAddress> SCTP_SET_PEER_PRIMARY_ADDR =
|
||||||
new ChannelOption<SocketAddress>("SCTP_SET_PEER_PRIMARY_ADDR", SocketAddress.class);
|
new ChannelOption<SocketAddress>("SCTP_SET_PEER_PRIMARY_ADDR", SocketAddress.class);
|
||||||
|
|
||||||
private final String name;
|
|
||||||
private final Class<T> valueType;
|
|
||||||
private final String strVal;
|
|
||||||
|
|
||||||
public ChannelOption(String name, Class<T> valueType) {
|
public ChannelOption(String name, Class<T> valueType) {
|
||||||
if (name == null) {
|
super(names, name, valueType);
|
||||||
throw new NullPointerException("name");
|
|
||||||
}
|
|
||||||
if (valueType == null) {
|
|
||||||
throw new NullPointerException("valueType");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (names.putIfAbsent(name, Boolean.TRUE) != null) {
|
|
||||||
throw new IllegalArgumentException("option name already in use: " + name);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.name = name;
|
|
||||||
this.valueType = valueType;
|
|
||||||
strVal = name + '[' + valueType.getSimpleName() + ']';
|
|
||||||
}
|
|
||||||
|
|
||||||
public String name() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Class<T> valueType() {
|
|
||||||
return valueType;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void validate(T value) {
|
public void validate(T value) {
|
||||||
@ -109,14 +86,4 @@ public class ChannelOption<T> implements Comparable<ChannelOption<T>> {
|
|||||||
throw new NullPointerException("value");
|
throw new NullPointerException("value");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compareTo(ChannelOption<T> o) {
|
|
||||||
return name().compareTo(o.name());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return strVal;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user