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 }