/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package net.jini.core.constraint; import java.io.IOException; import java.io.InvalidObjectException; import java.io.ObjectInputStream; import java.io.Serializable; /** * Represents a constraint on delegation, such that if delegation is permitted, * it be permitted only for a range of time measured relative to the start of * the remote call. The mechanisms and credentials used to support this are * not specified by this constraint. Each end of the range is itself specified * as a range, yielding four durations, all specified in milliseconds. If * <code>t</code> represents the current time at the start of a remote call, * then the four durations have the following semantics: * <ul> * <li><code>minStart</code> - delegation must not be permitted any earlier * than time <code>t + minStart</code> * <li><code>maxStart</code> - delegation must be permitted from time * <code>t + maxStart</code> onwards * <li><code>minStop</code> - delegation must be permitted up until at least * time <code>t + minStop</code> * <li><code>maxStop</code> - delegation must not be permitted after time * <code>t + maxStop</code> * </ul> * The durations are translated into absolute end times at the point of a * remote call by adding the caller's current time. To accommodate clock skew * between systems, it is permitted (and may be desirable) to specify negative * values for the minimum and maximum start durations, to include start times * that are earlier than the current time. * <p> * The use of an instance of this class does not directly imply a * {@link ClientAuthentication#YES} constraint or a {@link Delegation#YES} * constraint; those must be specified separately to ensure that the client * actually authenticates itself and that delegation is actually used. * Because this constraint is conditional on delegation, it does not conflict * with {@link ClientAuthentication#NO} or {@link Delegation#NO}. * * @author Sun Microsystems, Inc. * @see ClientAuthentication * @see Delegation * @see DelegationAbsoluteTime * @since 2.0 */ public final class DelegationRelativeTime implements RelativeTimeConstraint, Serializable { private static final long serialVersionUID = 7148935984332761810L; /** * The minimum start duration in milliseconds. * * @serial */ private final long minStart; /** * The maximum start duration in milliseconds. * * @serial */ private final long maxStart; /** * The minimum stop duration in milliseconds. * * @serial */ private final long minStop; /** * The maximum stop duration in milliseconds. * * @serial */ private final long maxStop; /** * Creates a constraint with the specified durations. * * @param minStart the minimum start duration in milliseconds * @param maxStart the maximum start duration in milliseconds * @param minStop the minimum stop duration in milliseconds * @param maxStop the maximum stop duration in milliseconds * @throws IllegalArgumentException if <code>minStart</code> is greater * than <code>maxStart</code>, or <code>maxStart</code> is greater than * <code>minStop</code>, or <code>minStop</code> is greater than * <code>maxStop</code>, or <code>minStop</code> is less than zero */ public DelegationRelativeTime(long minStart, long maxStart, long minStop, long maxStop) { if (minStart > maxStart || maxStart > minStop || minStop > maxStop || minStop < 0) { throw new IllegalArgumentException("invalid durations"); } this.minStart = minStart; this.maxStart = maxStart; this.minStop = minStop; this.maxStop = maxStop; } /** * Returns the minimum start duration in milliseconds. * * @return the minimum start duration in milliseconds */ public long getMinStart() { return minStart; } /** * Returns the maximum start duration in milliseconds. * * @return the maximum start duration in milliseconds */ public long getMaxStart() { return maxStart; } /** * Returns the minimum stop duration in milliseconds. * * @return the minimum stop duration in milliseconds */ public long getMinStop() { return minStop; } /** * Returns the maximum stop duration in milliseconds. * * @return the maximum stop duration in milliseconds */ public long getMaxStop() { return maxStop; } /** * Returns a {@link DelegationAbsoluteTime} instance with times obtained * by adding the specified base time argument to the duration values * from this instance. If an addition results in underflow or overflow, a * time value of <code>Long.MIN_VALUE</code> or * <code>Long.MAX_VALUE</code> is used, respectively. */ public InvocationConstraint makeAbsolute(long baseTime) { return new DelegationAbsoluteTime(add(minStart, baseTime), add(maxStart, baseTime), add(minStop, baseTime), add(maxStop, baseTime)); } private static long add(long dur, long time) { long ntime = time + dur; if (ntime >= 0 && time < 0 && dur < 0) { ntime = Long.MIN_VALUE; } else if (ntime < 0 && time > 0 && dur > 0) { ntime = Long.MAX_VALUE; } return ntime; } /** * Returns a hash code value for this object. */ public int hashCode() { return (int)(DelegationRelativeTime.class.hashCode() + minStart + maxStart + minStop + maxStop); } /** * Two instances of this class are equal if both have the same minimum * start, the same maximum start, the same minimum stop, and the same * maximum stop. */ public boolean equals(Object obj) { if (!(obj instanceof DelegationRelativeTime)) { return false; } DelegationRelativeTime dc = (DelegationRelativeTime) obj; return (minStart == dc.minStart && maxStart == dc.maxStart && minStop == dc.minStop && maxStop == dc.maxStop); } /** * Returns a string representation of this object. */ public String toString() { String s = "DelegationRelativeTime[start: "; if (minStart == maxStart) { s += minStart + ", stop: "; } else { s += "[" + minStart + ", " + maxStart + "], stop: "; } if (minStop == maxStop) { s += minStop + "]"; } else { s += "[" + minStop + ", " + maxStop + "]]"; } return s; } /** * Verifies that <code>minStart</code> is less than or equal to * <code>maxStart</code>, <code>maxStart</code> is less than or equal to * <code>minStop</code>, <code>minStop</code> is less than or equal to * <code>maxStop</code>, and <code>minStop</code> is greater than or equal * to zero. * * @throws InvalidObjectException if <code>minStart</code> is greater * than <code>maxStart</code>, or <code>maxStart</code> is greater than * <code>minStop</code>, or <code>minStop</code> is greater than * <code>maxStop</code>, or <code>minStop</code> is less than zero */ private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException { s.defaultReadObject(); if (minStart > maxStart || maxStart > minStop || minStop > maxStop || minStop < 0) { throw new InvalidObjectException("invalid durations"); } } }