diff --git a/transport/src/main/java/io/netty/bootstrap/AbstractBootstrap.java b/transport/src/main/java/io/netty/bootstrap/AbstractBootstrap.java index 8009c95a08..43b38fd4b4 100644 --- a/transport/src/main/java/io/netty/bootstrap/AbstractBootstrap.java +++ b/transport/src/main/java/io/netty/bootstrap/AbstractBootstrap.java @@ -35,6 +35,7 @@ import io.netty.util.internal.StringUtil; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.SocketAddress; +import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; @@ -314,7 +315,7 @@ public abstract class AbstractBootstrap, C ext } final ChannelFuture initAndRegister() { - final Channel channel = channelFactory().newChannel(); + final Channel channel = channelFactory.newChannel(); try { init(channel); } catch (Throwable t) { @@ -376,6 +377,41 @@ public abstract class AbstractBootstrap, C ext return (B) this; } + /** + * Returns the configured {@link EventLoopGroup} or {@code null} if non is configured yet. + * + * @deprecated Use {@link #config()} instead. + */ + @Deprecated + public final EventLoopGroup group() { + return group; + } + + /** + * Returns the {@link AbstractBootstrapConfig} object that can be used to obtain the current config + * of the bootstrap. + */ + public abstract AbstractBootstrapConfig config(); + + static Map copiedMap(Map map) { + final Map copied; + synchronized (map) { + if (map.isEmpty()) { + return Collections.emptyMap(); + } + copied = new LinkedHashMap(map); + } + return Collections.unmodifiableMap(copied); + } + + final Map, Object> options0() { + return options; + } + + final Map, Object> attrs0() { + return attrs; + } + final SocketAddress localAddress() { return localAddress; } @@ -389,66 +425,19 @@ public abstract class AbstractBootstrap, C ext return handler; } - /** - * Return the configured {@link EventLoopGroup} or {@code null} if non is configured yet. - */ - public EventLoopGroup group() { - return group; - } - final Map, Object> options() { - return options; + return copiedMap(options); } final Map, Object> attrs() { - return attrs; + return copiedMap(attrs); } @Override public String toString() { StringBuilder buf = new StringBuilder() .append(StringUtil.simpleClassName(this)) - .append('('); - if (group != null) { - buf.append("group: ") - .append(StringUtil.simpleClassName(group)) - .append(", "); - } - if (channelFactory != null) { - buf.append("channelFactory: ") - .append(channelFactory) - .append(", "); - } - if (localAddress != null) { - buf.append("localAddress: ") - .append(localAddress) - .append(", "); - } - synchronized (options) { - if (!options.isEmpty()) { - buf.append("options: ") - .append(options) - .append(", "); - } - } - synchronized (attrs) { - if (!attrs.isEmpty()) { - buf.append("attrs: ") - .append(attrs) - .append(", "); - } - } - if (handler != null) { - buf.append("handler: ") - .append(handler) - .append(", "); - } - if (buf.charAt(buf.length() - 1) == '(') { - buf.append(')'); - } else { - buf.setCharAt(buf.length() - 2, ')'); - buf.setLength(buf.length() - 1); - } + .append('(').append(config()).append(')'); return buf.toString(); } diff --git a/transport/src/main/java/io/netty/bootstrap/AbstractBootstrapConfig.java b/transport/src/main/java/io/netty/bootstrap/AbstractBootstrapConfig.java new file mode 100644 index 0000000000..976ec94640 --- /dev/null +++ b/transport/src/main/java/io/netty/bootstrap/AbstractBootstrapConfig.java @@ -0,0 +1,135 @@ +/* + * Copyright 2016 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.bootstrap; + +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelOption; +import io.netty.channel.EventLoopGroup; +import io.netty.util.AttributeKey; +import io.netty.util.internal.ObjectUtil; +import io.netty.util.internal.StringUtil; + +import java.net.SocketAddress; +import java.util.Map; + +/** + * Exposes the configuration of an {@link AbstractBootstrap}. + */ +public abstract class AbstractBootstrapConfig, C extends Channel> { + + protected final B bootstrap; + + protected AbstractBootstrapConfig(B bootstrap) { + this.bootstrap = ObjectUtil.checkNotNull(bootstrap, "bootstrap"); + } + + /** + * Returns the configured local address or {@code null} if non is configured yet. + */ + public final SocketAddress localAddress() { + return bootstrap.localAddress(); + } + + /** + * Returns the configured {@link ChannelFactory} or {@code null} if non is configured yet. + */ + @SuppressWarnings("deprecation") + public final ChannelFactory channelFactory() { + return bootstrap.channelFactory(); + } + + /** + * Returns the configured {@link ChannelHandler} or {@code null} if non is configured yet. + */ + public final ChannelHandler handler() { + return bootstrap.handler(); + } + + /** + * Returns a copy of the configured options. + */ + public final Map, Object> options() { + return bootstrap.options(); + } + + /** + * Returns a copy of the configured attributes. + */ + public final Map, Object> attrs() { + return bootstrap.attrs(); + } + + /** + * Returns the configured {@link EventLoopGroup} or {@code null} if non is configured yet. + */ + @SuppressWarnings("deprecation") + public final EventLoopGroup group() { + return bootstrap.group(); + } + + @Override + public String toString() { + StringBuilder buf = new StringBuilder() + .append(StringUtil.simpleClassName(this)) + .append('('); + EventLoopGroup group = group(); + if (group != null) { + buf.append("group: ") + .append(StringUtil.simpleClassName(group)) + .append(", "); + } + @SuppressWarnings("deprecation") + ChannelFactory factory = channelFactory(); + if (factory != null) { + buf.append("channelFactory: ") + .append(factory) + .append(", "); + } + SocketAddress localAddress = localAddress(); + if (localAddress != null) { + buf.append("localAddress: ") + .append(localAddress) + .append(", "); + } + + Map, Object> options = options(); + if (!options.isEmpty()) { + buf.append("options: ") + .append(options) + .append(", "); + } + Map, Object> attrs = attrs(); + if (!attrs.isEmpty()) { + buf.append("attrs: ") + .append(attrs) + .append(", "); + } + ChannelHandler handler = handler(); + if (handler != null) { + buf.append("handler: ") + .append(handler) + .append(", "); + } + if (buf.charAt(buf.length() - 1) == '(') { + buf.append(')'); + } else { + buf.setCharAt(buf.length() - 2, ')'); + buf.setLength(buf.length() - 1); + } + return buf.toString(); + } +} diff --git a/transport/src/main/java/io/netty/bootstrap/Bootstrap.java b/transport/src/main/java/io/netty/bootstrap/Bootstrap.java index 30edff0833..00abf9e2fb 100644 --- a/transport/src/main/java/io/netty/bootstrap/Bootstrap.java +++ b/transport/src/main/java/io/netty/bootstrap/Bootstrap.java @@ -53,6 +53,8 @@ public class Bootstrap extends AbstractBootstrap { private static final AddressResolverGroup DEFAULT_RESOLVER = DefaultAddressResolverGroup.INSTANCE; + private final BootstrapConfig config = new BootstrapConfig(this); + @SuppressWarnings("unchecked") private volatile AddressResolverGroup resolver = (AddressResolverGroup) DEFAULT_RESOLVER; @@ -113,7 +115,7 @@ public class Bootstrap extends AbstractBootstrap { throw new IllegalStateException("remoteAddress not set"); } - return doResolveAndConnect(remoteAddress, localAddress()); + return doResolveAndConnect(remoteAddress, config.localAddress()); } /** @@ -139,7 +141,7 @@ public class Bootstrap extends AbstractBootstrap { } validate(); - return doResolveAndConnect(remoteAddress, localAddress()); + return doResolveAndConnect(remoteAddress, config.localAddress()); } /** @@ -256,9 +258,9 @@ public class Bootstrap extends AbstractBootstrap { @SuppressWarnings("unchecked") void init(Channel channel) throws Exception { ChannelPipeline p = channel.pipeline(); - p.addLast(handler()); + p.addLast(config.handler()); - final Map, Object> options = options(); + final Map, Object> options = options0(); synchronized (options) { for (Entry, Object> e: options.entrySet()) { try { @@ -271,7 +273,7 @@ public class Bootstrap extends AbstractBootstrap { } } - final Map, Object> attrs = attrs(); + final Map, Object> attrs = attrs0(); synchronized (attrs) { for (Entry, Object> e: attrs.entrySet()) { channel.attr((AttributeKey) e.getKey()).set(e.getValue()); @@ -282,7 +284,7 @@ public class Bootstrap extends AbstractBootstrap { @Override public Bootstrap validate() { super.validate(); - if (handler() == null) { + if (config.handler() == null) { throw new IllegalStateException("handler not set"); } return this; @@ -306,17 +308,15 @@ public class Bootstrap extends AbstractBootstrap { } @Override - public String toString() { - if (remoteAddress == null) { - return super.toString(); - } + public final BootstrapConfig config() { + return config; + } - StringBuilder buf = new StringBuilder(super.toString()); - buf.setLength(buf.length() - 1); + final SocketAddress remoteAddress() { + return remoteAddress; + } - return buf.append(", remoteAddress: ") - .append(remoteAddress) - .append(')') - .toString(); + final AddressResolverGroup resolver() { + return resolver; } } diff --git a/transport/src/main/java/io/netty/bootstrap/BootstrapConfig.java b/transport/src/main/java/io/netty/bootstrap/BootstrapConfig.java new file mode 100644 index 0000000000..24d9fa45e1 --- /dev/null +++ b/transport/src/main/java/io/netty/bootstrap/BootstrapConfig.java @@ -0,0 +1,58 @@ +/* + * Copyright 2016 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.bootstrap; + +import io.netty.channel.Channel; +import io.netty.resolver.AddressResolverGroup; + +import java.net.SocketAddress; + +/** + * Exposes the configuration of a {@link Bootstrap}. + */ +public final class BootstrapConfig extends AbstractBootstrapConfig { + + BootstrapConfig(Bootstrap bootstrap) { + super(bootstrap); + } + + /** + * Returns the configured remote address or {@code null} if non is configured yet. + */ + public SocketAddress remoteAddress() { + return bootstrap.remoteAddress(); + } + + /** + * Returns the configured {@link AddressResolverGroup} or the default if non is configured yet. + */ + public AddressResolverGroup resolver() { + return bootstrap.resolver(); + } + + @Override + public String toString() { + StringBuilder buf = new StringBuilder(super.toString()); + buf.setLength(buf.length() - 1); + buf.append(", resolver: ").append(resolver()); + SocketAddress remoteAddress = remoteAddress(); + if (remoteAddress != null) { + buf.append(", remoteAddress: ") + .append(remoteAddress); + } + return buf.append(')').toString(); + } +} diff --git a/transport/src/main/java/io/netty/bootstrap/ServerBootstrap.java b/transport/src/main/java/io/netty/bootstrap/ServerBootstrap.java index 38929b1b71..822a1cd133 100644 --- a/transport/src/main/java/io/netty/bootstrap/ServerBootstrap.java +++ b/transport/src/main/java/io/netty/bootstrap/ServerBootstrap.java @@ -29,7 +29,6 @@ import io.netty.channel.EventLoopGroup; import io.netty.channel.ServerChannel; import io.netty.util.AttributeKey; import io.netty.util.internal.OneTimeTask; -import io.netty.util.internal.StringUtil; import io.netty.util.internal.logging.InternalLogger; import io.netty.util.internal.logging.InternalLoggerFactory; @@ -48,6 +47,7 @@ public class ServerBootstrap extends AbstractBootstrap, Object> childOptions = new LinkedHashMap, Object>(); private final Map, Object> childAttrs = new LinkedHashMap, Object>(); + private final ServerBootstrapConfig config = new ServerBootstrapConfig(this); private volatile EventLoopGroup childGroup; private volatile ChannelHandler childHandler; @@ -138,22 +138,14 @@ public class ServerBootstrap extends AbstractBootstrap, Object> options = options(); + final Map, Object> options = options0(); synchronized (options) { channel.config().setOptions(options); } - final Map, Object> attrs = attrs(); + final Map, Object> attrs = attrs0(); synchronized (attrs) { for (Entry, Object> e: attrs.entrySet()) { @SuppressWarnings("unchecked") @@ -179,7 +171,7 @@ public class ServerBootstrap extends AbstractBootstrap, Object> childOptions() { + return copiedMap(childOptions); + } + + final Map, Object> childAttrs() { + return copiedMap(childAttrs); + } + + @Override + public final ServerBootstrapConfig config() { + return config; } } diff --git a/transport/src/main/java/io/netty/bootstrap/ServerBootstrapConfig.java b/transport/src/main/java/io/netty/bootstrap/ServerBootstrapConfig.java new file mode 100644 index 0000000000..1401d59eb3 --- /dev/null +++ b/transport/src/main/java/io/netty/bootstrap/ServerBootstrapConfig.java @@ -0,0 +1,105 @@ +/* + * Copyright 2016 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.bootstrap; + +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelOption; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.ServerChannel; +import io.netty.util.AttributeKey; +import io.netty.util.internal.StringUtil; + +import java.util.Map; + +/** + * Exposes the configuration of a {@link ServerBootstrapConfig}. + */ +public final class ServerBootstrapConfig extends AbstractBootstrapConfig { + + ServerBootstrapConfig(ServerBootstrap bootstrap) { + super(bootstrap); + } + + /** + * Returns the configured {@link EventLoopGroup} which will be used for the child channels or {@code null} + * if non is configured yet. + */ + @SuppressWarnings("deprecation") + public EventLoopGroup childGroup() { + return bootstrap.childGroup(); + } + + /** + * Returns the configured {@link ChannelHandler} be used for the child channels or {@code null} + * if non is configured yet. + */ + public ChannelHandler childHandler() { + return bootstrap.childHandler(); + } + + /** + * Returns a copy of the configured options which will be used for the child channels. + */ + public Map, Object> childOptions() { + return bootstrap.childOptions(); + } + + /** + * Returns a copy of the configured attributes which will be used for the child channels. + */ + public Map, Object> childAttrs() { + return bootstrap.childAttrs(); + } + + @Override + public String toString() { + StringBuilder buf = new StringBuilder(super.toString()); + buf.setLength(buf.length() - 1); + buf.append(", "); + EventLoopGroup childGroup = childGroup(); + if (childGroup != null) { + buf.append("childGroup: "); + buf.append(StringUtil.simpleClassName(childGroup)); + buf.append(", "); + } + Map, Object> childOptions = childOptions(); + if (!childOptions.isEmpty()) { + buf.append("childOptions: "); + buf.append(childOptions); + buf.append(", "); + } + Map, Object> childAttrs = childAttrs(); + if (!childAttrs.isEmpty()) { + buf.append("childAttrs: "); + buf.append(childAttrs); + buf.append(", "); + } + ChannelHandler childHandler = childHandler(); + if (childHandler != null) { + buf.append("childHandler: "); + buf.append(childHandler); + buf.append(", "); + } + if (buf.charAt(buf.length() - 1) == '(') { + buf.append(')'); + } else { + buf.setCharAt(buf.length() - 2, ')'); + buf.setLength(buf.length() - 1); + } + + return buf.toString(); + } +}