001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: *
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: */
018:
019: /**
020: * @author Mikhail A. Markov, Vasily Zakharov
021: * @version $Revision: 1.1.2.2 $
022: */package org.apache.harmony.rmi.transport;
023:
024: import java.io.IOException;
025: import java.io.Serializable;
026: import java.net.NoRouteToHostException;
027: import java.net.ServerSocket;
028: import java.net.Socket;
029: import java.net.SocketException;
030: import java.net.UnknownHostException;
031: import java.rmi.server.RMIClientSocketFactory;
032: import java.rmi.server.RMIServerSocketFactory;
033: import java.rmi.server.RMISocketFactory;
034: import java.security.AccessController;
035:
036: import org.apache.harmony.rmi.common.GetBooleanPropAction;
037: import org.apache.harmony.rmi.common.GetLongPropAction;
038: import org.apache.harmony.rmi.common.RMILog;
039: import org.apache.harmony.rmi.common.RMIProperties;
040: import org.apache.harmony.rmi.internal.nls.Messages;
041: import org.apache.harmony.rmi.transport.proxy.HttpProxyRMISocketFactory;
042: import org.apache.harmony.rmi.transport.proxy.Proxy;
043: import org.apache.harmony.rmi.transport.proxy.ProxyRMISocketFactory;
044: import org.apache.harmony.rmi.transport.tcp.DirectRMISocketFactory;
045:
046: /**
047: * Default {@link RMISocketFactory} which is used by RMI runtime to create
048: * client and server sockets. First it tries direct sockets and if
049: * the attempt fails it tries HTTP-through sockets.
050: *
051: * @author Mikhail A. Markov, Vasily Zakharov
052: * @version $Revision: 1.1.2.2 $
053: */
054: public class DefaultRMISocketFactory extends RMISocketFactory implements
055: Serializable, RMIProperties {
056:
057: /**
058: * serialVersionUID
059: */
060: private static final long serialVersionUID = 8559677966812417163L;
061:
062: // Should we disable direct socket connections or not.
063: private static final boolean disableDirectSocket = ((Boolean) AccessController
064: .doPrivileged(new GetBooleanPropAction(
065: DISABLE_DIRECT_SOCKET_PROP))).booleanValue();
066:
067: // Should we disable HTTP tunneling or not.
068: private static final boolean disableHttp = ((Boolean) AccessController
069: .doPrivileged(new GetBooleanPropAction(DISABLEHTTP_PROP)))
070: .booleanValue();
071:
072: // Should we try HTTP connections after every SocketException or not.
073: private static final boolean eagerHttpFallback = ((Boolean) AccessController
074: .doPrivileged(new GetBooleanPropAction(
075: EAGERHTTPFALLBACK_PROP))).booleanValue();
076:
077: // Direct sockets factory.
078: private static final DirectRMISocketFactory directRsf = new DirectRMISocketFactory();
079:
080: // Proxy sockets factory.
081: private static final ProxyRMISocketFactory proxyRsf = new HttpProxyRMISocketFactory();
082:
083: /*
084: * Max period of time (in ms) for trying direct connections before
085: * attempting HTTP. Default value is 15000 ms (15 sec.).
086: */
087: private static long connTimeout = ((Long) AccessController
088: .doPrivileged(new GetLongPropAction(CONNECTTIMEOUT_PROP,
089: 15000))).longValue();
090:
091: // Log for logging proxy connections activity.
092: private static final RMILog proxyTransportLog = RMILog
093: .getProxyTransportLog();
094:
095: /**
096: * {@inheritDoc}
097: */
098: public Socket createSocket(String host, int port)
099: throws IOException {
100: if (proxyTransportLog.isLoggable(RMILog.BRIEF)) {
101: // rmi.log.114=Creating socket to [{0}:{1}].
102: proxyTransportLog.log(RMILog.BRIEF, Messages.getString(
103: "rmi.log.114", host, port)); //$NON-NLS-1$
104: }
105: Socket s = null;
106: Proxy proxy = new Proxy();
107:
108: if (disableDirectSocket) {
109: // If direct connections are disabled, fallback to proxy connection.
110: if (proxyTransportLog.isLoggable(RMILog.VERBOSE)) {
111: // rmi.log.115=Direct socket connections disabled, trying proxy connection to [{0}:{1}].
112: proxyTransportLog.log(RMILog.VERBOSE, Messages
113: .getString("rmi.log.115", //$NON-NLS-1$
114: host, port));
115: }
116: } else {
117: if (disableHttp || !(proxy.isSet())) {
118: // If HTTP is not available, use simple direct connection.
119: s = directRsf.createSocket(host, port);
120:
121: if (s == null) {
122: // rmi.log.116=Unable to connect to [
123: String msg = Messages.getString("rmi.log.116") + host + ':' + port //$NON-NLS-1$
124: + ']';
125: if (proxyTransportLog.isLoggable(RMILog.BRIEF)) {
126: proxyTransportLog.log(RMILog.BRIEF, msg);
127: }
128: throw new NoRouteToHostException(msg);
129: }
130: } else { // Both direct and HTTP connections are available.
131: s = null;
132: IOException ex = null;
133:
134: try {
135: s = directRsf.createSocket(host, port,
136: (int) connTimeout);
137: } catch (IOException ioe) {
138: ex = ioe;
139: }
140:
141: if (s == null) {
142: // Direct socket attempt failed.
143: if (proxyTransportLog.isLoggable(RMILog.BRIEF)) {
144: // rmi.log.117=Direct socket connection to [{0}:{1}] failed.
145: proxyTransportLog.log(RMILog.BRIEF, Messages
146: .getString("rmi.log.117", host, port)); //$NON-NLS-1$
147: }
148:
149: if (ex != null) {
150: if ((eagerHttpFallback && !(ex instanceof SocketException))
151: || (!eagerHttpFallback
152: && !(ex instanceof UnknownHostException) && !(ex instanceof NoRouteToHostException))) {
153: throw ex;
154: } else {
155: if (proxyTransportLog
156: .isLoggable(RMILog.VERBOSE)) {
157: // rmi.log.118=Trying proxy connection to [{1}:{1}].
158: proxyTransportLog.log(RMILog.VERBOSE,
159: Messages.getString(
160: "rmi.log.118", //$NON-NLS-1$
161: host, port));
162: } // Falling through to HTTP connection attempt.
163: }
164: } else {
165: // rmi.95=Connection to [{0}:{1}] timed out
166: throw new NoRouteToHostException(Messages
167: .getString("rmi.95", //$NON-NLS-1$
168: host, port));
169: }
170: } else if (proxyTransportLog.isLoggable(RMILog.BRIEF)) {
171: // rmi.log.11A=Direct socket connection to [{0}:{1}] from port {2} succeeded.
172: proxyTransportLog
173: .log(
174: RMILog.BRIEF,
175: Messages
176: .getString(
177: "rmi.log.11A", new Object[] { host, port, s.getLocalPort() })); //$NON-NLS-1$
178: }
179: }
180: }
181:
182: // Either disableDirectSocket or fallback from direct connection attempt.
183: if (s == null) {
184: s = proxyRsf.createSocket(proxy, host, port);
185:
186: if (s == null) {
187: // rmi.log.11B=Proxy connection to [{0}:{1}] failed
188: String msg = Messages.getString(
189: "rmi.log.11B", host, port); //$NON-NLS-1$
190: if (proxyTransportLog.isLoggable(RMILog.BRIEF)) {
191: proxyTransportLog.log(RMILog.BRIEF, msg);
192: }
193:
194: throw new NoRouteToHostException(msg);
195: }
196:
197: if (proxyTransportLog.isLoggable(RMILog.BRIEF)) {
198: // rmi.log.11C=Proxy connection to [{0}:{1}] from port {2} succeeded.
199: proxyTransportLog.log(RMILog.BRIEF, Messages.getString(
200: "rmi.log.11C", //$NON-NLS-1$
201: new Object[] { host, port, s.getLocalPort() }));
202: }
203: }
204: return s;
205: }
206:
207: /**
208: * {@inheritDoc}
209: */
210: public ServerSocket createServerSocket(int port) throws IOException {
211: return ((!disableDirectSocket && disableHttp) ? (RMISocketFactory) directRsf
212: : proxyRsf).createServerSocket(port);
213: }
214:
215: /**
216: * Helper method: returns non-null RMIClientSocketFactory.
217: * Returns specified RMIClientSocketFactory if it is not null; otherwise
218: * returns result of getSocketFactory method call if it is not null;
219: * otherwise returns result of getDefaultSocketFactory method call.
220: *
221: * @param csf RMIClientSocketFactory to check
222: *
223: * @return non-null RMIClientSocketFactory
224: */
225: public static RMIClientSocketFactory getNonNullClientFactory(
226: RMIClientSocketFactory csf) {
227: RMIClientSocketFactory factory = (csf == null) ? getSocketFactory()
228: : csf;
229: return (factory == null) ? getDefaultSocketFactory() : factory;
230: }
231:
232: /**
233: * Helper method: returns non-null RMIServerSocketFactory.
234: * Returns specified RMIServerSocketFactory if it is not null; otherwise
235: * returns result of getSocketFactory method call if it is not null;
236: * otherwise returns result of getDefaultSocketFactory method call.
237: *
238: * @param ssf RMIServerSocketFactory to check
239: *
240: * @return non-null RMIServerSocketFactory
241: */
242: public static RMIServerSocketFactory getNonNullServerFactory(
243: RMIServerSocketFactory ssf) {
244: RMIServerSocketFactory factory = (ssf == null) ? getSocketFactory()
245: : ssf;
246: return (factory == null) ? getDefaultSocketFactory() : factory;
247: }
248: }
|