001: /**
002: * Copyright 2003-2007 Luck Consulting Pty Ltd
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */package net.sf.ehcache.distribution;
016:
017: import java.io.IOException;
018: import java.io.Serializable;
019: import java.net.Socket;
020: import java.rmi.server.RMIClientSocketFactory;
021: import java.rmi.server.RMISocketFactory;
022:
023: /**
024: * Default socket timeouts are unlikely to be suitable for cache replication. Sockets should
025: * fail fast.
026: * <p/>
027: * This class decorates the RMIClientSocketFactory so as to enable customisations to be placed
028: * on newly created sockets.
029: *
030: * @author <a href="mailto:gluck@thoughtworks.com">Greg Luck</a>
031: * @version $Id: ConfigurableRMIClientSocketFactory.java 519 2007-07-27 07:11:45Z gregluck $
032: * @see "http://java.sun.com/j2se/1.5.0/docs/guide/rmi/socketfactory/#1"
033: * @noinspection SerializableHasSerializationMethods,SerializableHasSerializationMethods
034: */
035: public final class ConfigurableRMIClientSocketFactory implements
036: Serializable, RMIClientSocketFactory {
037:
038: private static final int ONE_SECOND = 1000;
039:
040: private static final long serialVersionUID = 4920508630517373246L;
041:
042: private final int socketTimeoutMillis;
043:
044: /**
045: * Construct a new socket factory with the given timeout.
046: *
047: * @param socketTimeoutMillis
048: * @see Socket#setSoTimeout
049: */
050: public ConfigurableRMIClientSocketFactory(
051: Integer socketTimeoutMillis) {
052: if (socketTimeoutMillis == null) {
053: this .socketTimeoutMillis = ONE_SECOND;
054: } else {
055: this .socketTimeoutMillis = socketTimeoutMillis.intValue();
056: }
057: }
058:
059: /**
060: * Create a client socket connected to the specified host and port.
061: * <p/>
062: * If necessary this implementation can be changed to specify the outbound address to use
063: * e.g. <code>Socket socket = new Socket(host, port, localInterface , 0);</code>
064: *
065: * @param host the host name
066: * @param port the port number
067: * @return a socket connected to the specified host and port.
068: * @throws java.io.IOException if an I/O error occurs during socket creation
069: * @since 1.2
070: */
071: public Socket createSocket(String host, int port)
072: throws IOException {
073: Socket socket = RMISocketFactory.getDefaultSocketFactory()
074: .createSocket(host, port);
075:
076: socket.setSoTimeout(socketTimeoutMillis);
077:
078: return socket;
079: }
080:
081: /**
082: * Implements the Object hashCode method.
083: *
084: * @return a hash based on socket options
085: */
086: public int hashCode() {
087: return socketTimeoutMillis;
088: }
089:
090: /**
091: * The standard hashCode method which is necessary for SocketFactory classes.
092: * Omitting this method causes RMI to quickly error out
093: * with "too many open files" errors.
094: *
095: * @param object the comparison object
096: * @return equal if the classes are the same and the socket options are the name.
097: */
098: public boolean equals(Object object) {
099: if (object == null) {
100: return false;
101: } else {
102: return (getClass() == object.getClass() && socketTimeoutMillis == ((ConfigurableRMIClientSocketFactory) object).socketTimeoutMillis);
103: }
104: }
105:
106: }
|