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.james.transport.mailets;
21  
22  import javax.net.SocketFactory;
23  
24  import java.io.IOException;
25  import java.net.InetAddress;
26  import java.net.InetSocketAddress;
27  import java.net.Socket;
28  import java.net.UnknownHostException;
29  
30  /***
31   * It is used by RemoteDelivery in order to make possible to bind the client
32   * socket to a specific ip address.
33   *
34   * This is not a nice solution because the ip address must be shared by all 
35   * RemoteDelivery instances. It would be better to modify JavaMail 
36   * (current version 1.3) to support a corresonding property, e.g.
37   * mail.smtp.bindAdress.
38   * 
39   * This used to not extend javax.net.SocketFactory descendant, because 
40   * 1. it was not necessary because JavaMail 1.2 uses reflection when accessing
41   * this class;
42   * 2. it was not desirable because it would require java 1.4.
43   * 
44   * But since James 2.3.0a1:
45   * 1. we require Java 1.4 so the dependency on SocketFactory is
46   * not really an issue;
47   * 2. Javamail 1.4 cast the object returned by getDefault to SocketFactory and
48   * fails to create the socket if we don't extend SocketFactory.
49   * 
50   * Note: Javamail 1.4 should correctly support mail.smtp.localaddr so we could
51   * probably get rid of this class and simply add that property to the Session.
52   */
53  public class RemoteDeliverySocketFactory extends SocketFactory {
54      
55      /***
56       * @param addr the ip address or host name the delivery socket will bind to
57       */
58      static void setBindAdress(String addr) throws UnknownHostException {
59          if (addr == null) bindAddress = null;
60          else bindAddress = InetAddress.getByName(addr);
61      }
62      
63      /***
64       * the same as the similarly named javax.net.SocketFactory operation.
65       */
66      public static SocketFactory getDefault() {
67          return new RemoteDeliverySocketFactory();
68      }
69      
70      /***
71       * the same as the similarly named javax.net.SocketFactory operation.
72       * Just to be safe, it is not used by JavaMail 1.3.
73       * This is the only method used by JavaMail 1.4.
74       */
75      public Socket createSocket() throws IOException {
76          Socket s = new Socket();
77          s.bind(new InetSocketAddress(bindAddress, 0));
78          return s;
79      }
80      
81      /***
82       * the same as the similarly named javax.net.SocketFactory operation.
83       * This is the one which is used by JavaMail 1.3.
84       * This is not used by JavaMail 1.4.
85       */
86      public Socket createSocket(String host, int port)
87                              throws IOException, UnknownHostException {
88          return new Socket(host, port, bindAddress, 0);
89      }
90      
91      /***
92       * the same as the similarly named javax.net.SocketFactory operation.
93       * Just to be safe, it is not used by JavaMail 1.3.
94       * This is not used by JavaMail 1.4.
95       */
96      public Socket createSocket(String host,
97                                      int port,
98                                      InetAddress clientHost,
99                                      int clientPort)
100                                     throws IOException,
101                                     UnknownHostException {
102         return new Socket(host, port, 
103                 clientHost == null ? bindAddress : clientHost, clientPort);
104     }
105     
106     /***
107      * the same as the similarly named javax.net.SocketFactory operation.
108      * Just to be safe, it is not used by JavaMail 1.3.
109      * This is not used by JavaMail 1.4.
110      */
111     public Socket createSocket(InetAddress host, int port) throws IOException {
112         return new Socket(host, port, bindAddress, 0);
113     }
114     
115     /***
116      * the same as the similarly named javax.net.SocketFactory operation.
117      * Just to be safe, it is not used by JavaMail 1.3.
118      * This is not used by JavaMail 1.4.
119      */
120     public Socket createSocket(InetAddress address,
121                                     int port,
122                                     InetAddress clientAddress,
123                                     int clientPort)
124                              throws IOException {
125         return new Socket(address, port, 
126                 clientAddress == null ? bindAddress : clientAddress, 
127                 clientPort);
128     }
129     
130     /***
131      * it should be set by setBindAdress(). Null means the socket is bind to 
132      * the default address.
133      */
134     private static InetAddress bindAddress;
135 }