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