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, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  package net.jini.core.constraint;
20  
21  import java.io.IOException;
22  import java.io.InvalidObjectException;
23  import java.io.ObjectInputStream;
24  import java.io.Serializable;
25  import org.apache.river.api.io.AtomicSerial;
26  import org.apache.river.api.io.AtomicSerial.GetArg;
27  
28  /**
29   * Represents a constraint on the maximum amount of time to wait for a
30   * network connection to be established. The precise meaning of this will
31   * vary across communication mechanisms, but in the typical case of
32   * {@link java.net.Socket}-based communication, the intention is that this
33   * constraint controls the timeout parameter of the
34   * {@link java.net.Socket#connect(java.net.SocketAddress,int) connect} method.
35   * <p>
36   * The duration is translated into an absolute end time at the point of a
37   * remote call by adding the caller's current time.
38   *
39   * @author Sun Microsystems, Inc.
40   * @since 2.0
41   */
42  @AtomicSerial
43  public final class ConnectionRelativeTime
44  			implements RelativeTimeConstraint, Serializable
45  {
46      private static final long serialVersionUID = 6854732178792183150L;
47  
48      /**
49       * The maximum connection duration in milliseconds.
50       *
51       * @serial
52       */
53      private final long time;
54  
55      /**
56       * Creates a constraint with the specified duration.
57       *
58       * @param time the maximum connection duration in milliseconds
59       * @throws IllegalArgumentException if the argument is less than zero
60       */
61      public ConnectionRelativeTime(long time) {
62  	this(check(time), true);
63      }
64      
65      /**
66       * AtomicSerial constructor
67       * 
68       * @param arg atomic deserialization parameter 
69       * @throws IOException if there are I/O errors while reading from GetArg's
70       *         underlying <code>InputStream</code>
71       * @throws InvalidObjectException if object invariants aren't satisfied.
72       */
73      public ConnectionRelativeTime(GetArg arg) throws IOException{
74  	this(validate(arg.get("time", -1)), true);
75      }
76      
77      private ConnectionRelativeTime(long time, boolean check){
78  	this.time = time;
79      }
80      
81      private static long validate(long time) throws InvalidObjectException{
82  	if (time < 0) {
83  	    throw new InvalidObjectException("invalid duration");
84  	}
85  	return time;
86      }
87      
88      private static long check(long time){
89  	if (time < 0) {
90  	    throw new IllegalArgumentException("invalid duration");
91  	}
92  	return time;
93      }
94  
95      /**
96       * Returns the maximum connection duration in milliseconds.
97       *
98       * @return the maximum connection duration in milliseconds
99       */
100     public long getTime() {
101 	return time;
102     }
103 
104     /**
105      * Returns a {@link ConnectionAbsoluteTime} instance with time obtained
106      * by adding the specified base time argument to the duration value
107      * from this instance. If the addition results in overflow, a time value
108      * of <code>Long.MAX_VALUE</code> is used.
109      */
110     public InvocationConstraint makeAbsolute(long baseTime) {
111 	return new ConnectionAbsoluteTime(add(time, baseTime));
112     }
113 
114     private static long add(long dur, long time) {
115 	long ntime = time + dur;
116 	if (ntime < 0 && time > 0) {
117 	    ntime = Long.MAX_VALUE;
118 	}
119 	return ntime;
120     }
121 
122     /**
123      * Returns a hash code value for this object.
124      */
125     public int hashCode() {
126 	return (int)(ConnectionRelativeTime.class.hashCode() + time);
127     }
128 
129     /**
130      * Two instances of this class are equal if both have the same duration.
131      */
132     public boolean equals(Object obj) {
133 	if (!(obj instanceof ConnectionRelativeTime)) {
134 	    return false;
135 	}
136 	ConnectionRelativeTime cc = (ConnectionRelativeTime) obj;
137 	return time == cc.time;
138     }
139 
140     /**
141      * Returns a string representation of this object.
142      */
143     public String toString() {
144 	return "ConnectionRelativeTime[" + time + "]";
145     }
146 
147     /**
148      * Verifies that <code>time</code> is greater than or equal to zero.
149      *
150      * @throws InvalidObjectException if <code>time</code> is less than zero
151      * @param s ObjectInputStream
152      * @throws ClassNotFoundException if class not found.
153      * @throws IOException if a problem occurs during de-serialization.
154      */
155     private void readObject(ObjectInputStream s)
156 	throws IOException, ClassNotFoundException
157     {
158 	s.defaultReadObject();
159 	if (time < 0) {
160 	    throw new InvalidObjectException("invalid duration");
161 	}
162     }
163 }