View Javadoc

1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License.
18   *
19   */
20  package org.apache.mina.common;
21  
22  import java.net.SocketAddress;
23  
24  /**
25   * A base implementation of {@link IoConnector}.
26   *
27   * @author The Apache MINA Project (dev@mina.apache.org)
28   * @version $Rev: 607163 $, $Date: 2007-12-27 20:20:07 -0700 (Thu, 27 Dec 2007) $
29   */
30  public abstract class AbstractIoConnector 
31          extends AbstractIoService implements IoConnector {
32      
33      private int connectTimeout = 60; // 1 minute
34      private SocketAddress defaultRemoteAddress;
35  
36      protected AbstractIoConnector(IoSessionConfig sessionConfig) {
37          super(sessionConfig);
38      }
39  
40      public final int getConnectTimeout() {
41          return connectTimeout;
42      }
43  
44      public final long getConnectTimeoutMillis() {
45          return connectTimeout * 1000L;
46      }
47  
48      public final void setConnectTimeout(int connectTimeout) {
49          if (connectTimeout <= 0) {
50              throw new IllegalArgumentException("connectTimeout: "
51                      + connectTimeout);
52          }
53          this.connectTimeout = connectTimeout;
54      }
55  
56      public SocketAddress getDefaultRemoteAddress() {
57          return defaultRemoteAddress;
58      }
59  
60      public final void setDefaultRemoteAddress(SocketAddress defaultRemoteAddress) {
61          if (defaultRemoteAddress == null) {
62              throw new NullPointerException("defaultRemoteAddress");
63          }
64          
65          if (!getTransportMetadata().getAddressType().isAssignableFrom(
66                  defaultRemoteAddress.getClass())) {
67              throw new IllegalArgumentException("defaultRemoteAddress type: "
68                      + defaultRemoteAddress.getClass() + " (expected: "
69                      + getTransportMetadata().getAddressType() + ")");
70          }
71          this.defaultRemoteAddress = defaultRemoteAddress;
72      }
73      
74      public final ConnectFuture connect() {
75          SocketAddress defaultRemoteAddress = getDefaultRemoteAddress();
76          if (defaultRemoteAddress == null) {
77              throw new IllegalStateException("defaultRemoteAddress is not set.");
78          }
79          
80          return connect(defaultRemoteAddress, null, null);
81      }
82      
83      public ConnectFuture connect(IoSessionInitializer<? extends ConnectFuture> sessionInitializer) {
84          SocketAddress defaultRemoteAddress = getDefaultRemoteAddress();
85          if (defaultRemoteAddress == null) {
86              throw new IllegalStateException("defaultRemoteAddress is not set.");
87          }
88          
89          return connect(defaultRemoteAddress, null, sessionInitializer);
90      }
91  
92      public final ConnectFuture connect(SocketAddress remoteAddress) {
93          return connect(remoteAddress, null, null);
94      }
95      
96      public ConnectFuture connect(SocketAddress remoteAddress,
97              IoSessionInitializer<? extends ConnectFuture> sessionInitializer) {
98          return connect(remoteAddress, null, sessionInitializer);
99      }
100     
101     public ConnectFuture connect(SocketAddress remoteAddress,
102             SocketAddress localAddress) {
103         return connect(remoteAddress, localAddress, null);
104     }
105 
106     public final ConnectFuture connect(SocketAddress remoteAddress,
107             SocketAddress localAddress, IoSessionInitializer<? extends ConnectFuture> sessionInitializer) {
108         if (isDisposing()) {
109             throw new IllegalStateException("Already disposed.");
110         }
111 
112         if (remoteAddress == null) {
113             throw new NullPointerException("remoteAddress");
114         }
115 
116         if (!getTransportMetadata().getAddressType().isAssignableFrom(
117                 remoteAddress.getClass())) {
118             throw new IllegalArgumentException("remoteAddress type: "
119                     + remoteAddress.getClass() + " (expected: "
120                     + getTransportMetadata().getAddressType() + ")");
121         }
122 
123         if (localAddress != null
124                 && !getTransportMetadata().getAddressType().isAssignableFrom(
125                         localAddress.getClass())) {
126             throw new IllegalArgumentException("localAddress type: "
127                     + localAddress.getClass() + " (expected: "
128                     + getTransportMetadata().getAddressType() + ")");
129         }
130 
131         if (getHandler() == null) {
132             if (getSessionConfig().isUseReadOperation()) {
133                 setHandler(new IoHandler() {
134                     public void exceptionCaught(IoSession session,
135                             Throwable cause) throws Exception {
136                     }
137 
138                     public void messageReceived(IoSession session,
139                             Object message) throws Exception {
140                     }
141 
142                     public void messageSent(IoSession session, Object message)
143                             throws Exception {
144                     }
145 
146                     public void sessionClosed(IoSession session)
147                             throws Exception {
148                     }
149 
150                     public void sessionCreated(IoSession session)
151                             throws Exception {
152                     }
153 
154                     public void sessionIdle(IoSession session, IdleStatus status)
155                             throws Exception {
156                     }
157 
158                     public void sessionOpened(IoSession session)
159                             throws Exception {
160                     }
161                 });
162             } else {
163                 throw new IllegalStateException("handler is not set.");
164             }
165         }
166 
167         return connect0(remoteAddress, localAddress, sessionInitializer);
168     }
169 
170     /**
171      * Implement this method to perform the actual connect operation.
172      *
173      * @param localAddress <tt>null</tt> if no local address is specified
174      */
175     protected abstract ConnectFuture connect0(SocketAddress remoteAddress,
176             SocketAddress localAddress, IoSessionInitializer<? extends ConnectFuture> sessionInitializer);
177 
178     /**
179      * Adds required internal attributes and {@link IoFutureListener}s
180      * related with event notifications to the specified {@code session}
181      * and {@code future}.  Do not call this method directly;
182      * {@link #finishSessionInitialization(IoSession, IoFuture, IoSessionInitializer)}
183      * will call this method instead.
184      */
185     @Override
186     protected final void finishSessionInitialization0(
187             final IoSession session, IoFuture future) {
188         // In case that ConnectFuture.cancel() is invoked before
189         // setSession() is invoked, add a listener that closes the
190         // connection immediately on cancellation.
191         future.addListener(new IoFutureListener<ConnectFuture>() {
192             public void operationComplete(ConnectFuture future) {
193                 if (future.isCanceled()) {
194                     session.close();
195                 }
196             }
197         });
198     }
199     
200     @Override
201     public String toString() {
202         TransportMetadata m = getTransportMetadata();
203         return '(' + m.getProviderName() + ' ' + m.getName() + " connector: " + 
204                "managedSessionCount: " + getManagedSessionCount() + ')'; 
205     }
206 }