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.common;
021:
022: import java.net.SocketAddress;
023:
024: /**
025: * A base implementation of {@link IoConnector}.
026: *
027: * @author The Apache MINA Project (dev@mina.apache.org)
028: * @version $Rev: 607163 $, $Date: 2007-12-27 20:20:07 -0700 (Thu, 27 Dec 2007) $
029: */
030: public abstract class AbstractIoConnector extends AbstractIoService
031: implements IoConnector {
032:
033: private int connectTimeout = 60; // 1 minute
034: private SocketAddress defaultRemoteAddress;
035:
036: protected AbstractIoConnector(IoSessionConfig sessionConfig) {
037: super (sessionConfig);
038: }
039:
040: public final int getConnectTimeout() {
041: return connectTimeout;
042: }
043:
044: public final long getConnectTimeoutMillis() {
045: return connectTimeout * 1000L;
046: }
047:
048: public final void setConnectTimeout(int connectTimeout) {
049: if (connectTimeout <= 0) {
050: throw new IllegalArgumentException("connectTimeout: "
051: + connectTimeout);
052: }
053: this .connectTimeout = connectTimeout;
054: }
055:
056: public SocketAddress getDefaultRemoteAddress() {
057: return defaultRemoteAddress;
058: }
059:
060: public final void setDefaultRemoteAddress(
061: SocketAddress defaultRemoteAddress) {
062: if (defaultRemoteAddress == null) {
063: throw new NullPointerException("defaultRemoteAddress");
064: }
065:
066: if (!getTransportMetadata().getAddressType().isAssignableFrom(
067: defaultRemoteAddress.getClass())) {
068: throw new IllegalArgumentException(
069: "defaultRemoteAddress type: "
070: + defaultRemoteAddress.getClass()
071: + " (expected: "
072: + getTransportMetadata().getAddressType()
073: + ")");
074: }
075: this .defaultRemoteAddress = defaultRemoteAddress;
076: }
077:
078: public final ConnectFuture connect() {
079: SocketAddress defaultRemoteAddress = getDefaultRemoteAddress();
080: if (defaultRemoteAddress == null) {
081: throw new IllegalStateException(
082: "defaultRemoteAddress is not set.");
083: }
084:
085: return connect(defaultRemoteAddress, null, null);
086: }
087:
088: public ConnectFuture connect(
089: IoSessionInitializer<? extends ConnectFuture> sessionInitializer) {
090: SocketAddress defaultRemoteAddress = getDefaultRemoteAddress();
091: if (defaultRemoteAddress == null) {
092: throw new IllegalStateException(
093: "defaultRemoteAddress is not set.");
094: }
095:
096: return connect(defaultRemoteAddress, null, sessionInitializer);
097: }
098:
099: public final ConnectFuture connect(SocketAddress remoteAddress) {
100: return connect(remoteAddress, null, null);
101: }
102:
103: public ConnectFuture connect(
104: SocketAddress remoteAddress,
105: IoSessionInitializer<? extends ConnectFuture> sessionInitializer) {
106: return connect(remoteAddress, null, sessionInitializer);
107: }
108:
109: public ConnectFuture connect(SocketAddress remoteAddress,
110: SocketAddress localAddress) {
111: return connect(remoteAddress, localAddress, null);
112: }
113:
114: public final ConnectFuture connect(
115: SocketAddress remoteAddress,
116: SocketAddress localAddress,
117: IoSessionInitializer<? extends ConnectFuture> sessionInitializer) {
118: if (isDisposing()) {
119: throw new IllegalStateException("Already disposed.");
120: }
121:
122: if (remoteAddress == null) {
123: throw new NullPointerException("remoteAddress");
124: }
125:
126: if (!getTransportMetadata().getAddressType().isAssignableFrom(
127: remoteAddress.getClass())) {
128: throw new IllegalArgumentException("remoteAddress type: "
129: + remoteAddress.getClass() + " (expected: "
130: + getTransportMetadata().getAddressType() + ")");
131: }
132:
133: if (localAddress != null
134: && !getTransportMetadata().getAddressType()
135: .isAssignableFrom(localAddress.getClass())) {
136: throw new IllegalArgumentException("localAddress type: "
137: + localAddress.getClass() + " (expected: "
138: + getTransportMetadata().getAddressType() + ")");
139: }
140:
141: if (getHandler() == null) {
142: if (getSessionConfig().isUseReadOperation()) {
143: setHandler(new IoHandler() {
144: public void exceptionCaught(IoSession session,
145: Throwable cause) throws Exception {
146: }
147:
148: public void messageReceived(IoSession session,
149: Object message) throws Exception {
150: }
151:
152: public void messageSent(IoSession session,
153: Object message) throws Exception {
154: }
155:
156: public void sessionClosed(IoSession session)
157: throws Exception {
158: }
159:
160: public void sessionCreated(IoSession session)
161: throws Exception {
162: }
163:
164: public void sessionIdle(IoSession session,
165: IdleStatus status) throws Exception {
166: }
167:
168: public void sessionOpened(IoSession session)
169: throws Exception {
170: }
171: });
172: } else {
173: throw new IllegalStateException("handler is not set.");
174: }
175: }
176:
177: return connect0(remoteAddress, localAddress, sessionInitializer);
178: }
179:
180: /**
181: * Implement this method to perform the actual connect operation.
182: *
183: * @param localAddress <tt>null</tt> if no local address is specified
184: */
185: protected abstract ConnectFuture connect0(
186: SocketAddress remoteAddress,
187: SocketAddress localAddress,
188: IoSessionInitializer<? extends ConnectFuture> sessionInitializer);
189:
190: /**
191: * Adds required internal attributes and {@link IoFutureListener}s
192: * related with event notifications to the specified {@code session}
193: * and {@code future}. Do not call this method directly;
194: * {@link #finishSessionInitialization(IoSession, IoFuture, IoSessionInitializer)}
195: * will call this method instead.
196: */
197: @Override
198: protected final void finishSessionInitialization0(
199: final IoSession session, IoFuture future) {
200: // In case that ConnectFuture.cancel() is invoked before
201: // setSession() is invoked, add a listener that closes the
202: // connection immediately on cancellation.
203: future.addListener(new IoFutureListener<ConnectFuture>() {
204: public void operationComplete(ConnectFuture future) {
205: if (future.isCanceled()) {
206: session.close();
207: }
208: }
209: });
210: }
211:
212: @Override
213: public String toString() {
214: TransportMetadata m = getTransportMetadata();
215: return '(' + m.getProviderName() + ' ' + m.getName()
216: + " connector: " + "managedSessionCount: "
217: + getManagedSessionCount() + ')';
218: }
219: }
|