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 }