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 }