001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: *
019: */
020: package org.apache.mina.transport.socket.nio;
021:
022: import java.net.InetSocketAddress;
023: import java.net.SocketAddress;
024: import java.nio.channels.SelectionKey;
025: import java.nio.channels.Selector;
026: import java.nio.channels.SocketChannel;
027: import java.util.Collection;
028: import java.util.Iterator;
029: import java.util.concurrent.Executor;
030:
031: import org.apache.mina.common.AbstractPollingIoConnector;
032: import org.apache.mina.common.IoConnector;
033: import org.apache.mina.common.IoProcessor;
034: import org.apache.mina.common.TransportMetadata;
035: import org.apache.mina.transport.socket.DefaultSocketSessionConfig;
036: import org.apache.mina.transport.socket.SocketConnector;
037: import org.apache.mina.transport.socket.SocketSessionConfig;
038:
039: /**
040: * {@link IoConnector} for socket transport (TCP/IP).
041: *
042: * @author The Apache MINA Project (dev@mina.apache.org)
043: * @version $Rev: 389042 $, $Date: 2006-03-27 07:49:41Z $
044: */
045: public final class NioSocketConnector extends
046: AbstractPollingIoConnector<NioSession, SocketChannel> implements
047: SocketConnector {
048:
049: private volatile Selector selector;
050:
051: public NioSocketConnector() {
052: super (new DefaultSocketSessionConfig(), NioProcessor.class);
053: }
054:
055: public NioSocketConnector(int processorCount) {
056: super (new DefaultSocketSessionConfig(), NioProcessor.class,
057: processorCount);
058: }
059:
060: public NioSocketConnector(IoProcessor<NioSession> processor) {
061: super (new DefaultSocketSessionConfig(), processor);
062: }
063:
064: public NioSocketConnector(Executor executor,
065: IoProcessor<NioSession> processor) {
066: super (new DefaultSocketSessionConfig(), executor, processor);
067: }
068:
069: @Override
070: protected void init() throws Exception {
071: this .selector = Selector.open();
072: }
073:
074: @Override
075: protected void destroy() throws Exception {
076: if (selector != null) {
077: selector.close();
078: }
079: }
080:
081: public TransportMetadata getTransportMetadata() {
082: return NioSocketSession.METADATA;
083: }
084:
085: @Override
086: public SocketSessionConfig getSessionConfig() {
087: return (SocketSessionConfig) super .getSessionConfig();
088: }
089:
090: @Override
091: public InetSocketAddress getDefaultRemoteAddress() {
092: return (InetSocketAddress) super .getDefaultRemoteAddress();
093: }
094:
095: public void setDefaultRemoteAddress(
096: InetSocketAddress defaultRemoteAddress) {
097: super .setDefaultRemoteAddress(defaultRemoteAddress);
098: }
099:
100: @Override
101: protected Iterator<SocketChannel> allHandles() {
102: return new SocketChannelIterator(selector.keys());
103: }
104:
105: @Override
106: protected boolean connect(SocketChannel handle,
107: SocketAddress remoteAddress) throws Exception {
108: return handle.connect(remoteAddress);
109: }
110:
111: @Override
112: protected ConnectionRequest connectionRequest(SocketChannel handle) {
113: SelectionKey key = handle.keyFor(selector);
114: if (key == null) {
115: return null;
116: }
117:
118: return (ConnectionRequest) key.attachment();
119: }
120:
121: @Override
122: protected void close(SocketChannel handle) throws Exception {
123: SelectionKey key = handle.keyFor(selector);
124: if (key != null) {
125: key.cancel();
126: }
127: handle.close();
128: }
129:
130: @Override
131: protected boolean finishConnect(SocketChannel handle)
132: throws Exception {
133: SelectionKey key = handle.keyFor(selector);
134: if (handle.finishConnect()) {
135: if (key != null) {
136: key.cancel();
137: }
138: return true;
139: }
140:
141: return false;
142: }
143:
144: @Override
145: protected SocketChannel newHandle(SocketAddress localAddress)
146: throws Exception {
147: SocketChannel ch = SocketChannel.open();
148: ch.socket().setReuseAddress(true);
149: if (localAddress != null) {
150: ch.socket().bind(localAddress);
151: }
152: ch.configureBlocking(false);
153: return ch;
154: }
155:
156: @Override
157: protected NioSession newSession(IoProcessor<NioSession> processor,
158: SocketChannel handle) {
159: return new NioSocketSession(this , processor, handle);
160: }
161:
162: @Override
163: protected void register(SocketChannel handle,
164: ConnectionRequest request) throws Exception {
165: handle.register(selector, SelectionKey.OP_CONNECT, request);
166: }
167:
168: @Override
169: protected boolean select(int timeout) throws Exception {
170: return selector.select(timeout) > 0;
171: }
172:
173: @Override
174: protected Iterator<SocketChannel> selectedHandles() {
175: return new SocketChannelIterator(selector.selectedKeys());
176: }
177:
178: @Override
179: protected void wakeup() {
180: selector.wakeup();
181: }
182:
183: private static class SocketChannelIterator implements
184: Iterator<SocketChannel> {
185:
186: private final Iterator<SelectionKey> i;
187:
188: private SocketChannelIterator(
189: Collection<SelectionKey> selectedKeys) {
190: this .i = selectedKeys.iterator();
191: }
192:
193: public boolean hasNext() {
194: return i.hasNext();
195: }
196:
197: public SocketChannel next() {
198: SelectionKey key = i.next();
199: return (SocketChannel) key.channel();
200: }
201:
202: public void remove() {
203: i.remove();
204: }
205: }
206: }
|