/*
* 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;
import java.lang.ref.SoftReference;
import java.text.FieldPosition;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
/**
* Represents a constraint on delegation, such that if delegation is permitted,
* it be permitted only for a range of absolute times. 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 absolute
* times, all specified in milliseconds from midnight, January 1, 1970 UTC.
* The four times have the following semantics:
* <ul>
* <li><code>minStart</code> - delegation must not be permitted any earlier
* than this time
* <li><code>maxStart</code> - delegation must be permitted from this time
* onwards
* <li><code>minStop</code> - delegation must be permitted up until at least
* this time
* <li><code>maxStop</code> - delegation must not be permitted after this time
* </ul>
* To accommodate clock skew between systems, it may be desirable to specify
* 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 DelegationRelativeTime
* @since 2.0
*/
public final class DelegationAbsoluteTime
implements InvocationConstraint, Serializable
{
private static final long serialVersionUID = -2807470616717350051L;
/**
* The minimum start time in milliseconds from midnight, January 1, 1970
* UTC.
*
* @serial
*/
private final long minStart;
/**
* The maximum start time in milliseconds from midnight, January 1, 1970
* UTC.
*
* @serial
*/
private final long maxStart;
/**
* The minimum stop time in milliseconds from midnight, January 1, 1970
* UTC.
*
* @serial
*/
private final long minStop;
/**
* The maximum stop time in milliseconds from midnight, January 1, 1970
* UTC.
*
* @serial
*/
private final long maxStop;
/**
* SoftReference containing a SimpleDateFormat instance, or null.
*/
private static SoftReference formatterRef;
/**
* Creates a constraint with the specified absolute times.
*
* @param minStart the minimum start time in milliseconds from midnight,
* January 1, 1970 UTC
* @param maxStart the maximum start time in milliseconds from midnight,
* January 1, 1970 UTC
* @param minStop the minimum stop time in milliseconds from midnight,
* January 1, 1970 UTC
* @param maxStop the maximum stop time in milliseconds from midnight,
* January 1, 1970 UTC
* @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>
*/
public DelegationAbsoluteTime(long minStart,
long maxStart,
long minStop,
long maxStop)
{
if (minStart > maxStart || maxStart > minStop || minStop > maxStop) {
throw new IllegalArgumentException("illegal times");
}
this.minStart = minStart;
this.maxStart = maxStart;
this.minStop = minStop;
this.maxStop = maxStop;
}
/**
* Creates a constraint with the specified dates. The arguments passed to
* the constructor are neither modified nor retained; subsequent changes
* to those arguments have no effect on the instance created.
*
* @param minStart the minimum start date
* @param maxStart the maximum start date
* @param minStop the minimum stop date
* @param maxStop the maximum stop date
* @throws NullPointerException if any argument is <code>null</code>
* @throws IllegalArgumentException if <code>minStart</code> is later
* than <code>maxStart</code>, or <code>maxStart</code> is later than
* <code>minStop</code>, or <code>minStop</code> is later than
* <code>maxStop</code>
*/
public DelegationAbsoluteTime(Date minStart,
Date maxStart,
Date minStop,
Date maxStop)
{
this(minStart.getTime(), maxStart.getTime(),
minStop.getTime(), maxStop.getTime());
}
/**
* Returns the minimum start time in milliseconds from midnight, January 1,
* 1970 UTC.
*
* @return the minimum start time in milliseconds from midnight, January 1,
* 1970 UTC
*/
public long getMinStart() {
return minStart;
}
/**
* Returns the maximum start time in milliseconds from midnight, January 1,
* 1970 UTC.
*
* @return the maximum start time in milliseconds from midnight, January 1,
* 1970 UTC
*/
public long getMaxStart() {
return maxStart;
}
/**
* Returns the minimum stop time in milliseconds from midnight, January 1,
* 1970 UTC.
*
* @return the minimum stop time in milliseconds from midnight, January 1,
* 1970 UTC
*/
public long getMinStop() {
return minStop;
}
/**
* Returns the maximum stop time in milliseconds from midnight, January 1,
* 1970 UTC.
*
* @return the maximum stop time in milliseconds from midnight, January 1,
* 1970 UTC
*/
public long getMaxStop() {
return maxStop;
}
/**
* Returns a hash code value for this object.
*/
public int hashCode() {
return (int)(DelegationAbsoluteTime.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 DelegationAbsoluteTime)) {
return false;
}
DelegationAbsoluteTime dc = (DelegationAbsoluteTime) obj;
return (minStart == dc.minStart && maxStart == dc.maxStart &&
minStop == dc.minStop && maxStop == dc.maxStop);
}
/**
* Returns a string representation of this object.
*/
public String toString() {
SimpleDateFormat formatter = getFormatter();
FieldPosition pos = new FieldPosition(0);
StringBuffer buf = new StringBuffer(95);
buf.append("DelegationAbsoluteTime[start: ");
format(minStart, maxStart, formatter, buf, pos);
buf.append(", stop: ");
format(minStop, maxStop, formatter, buf, pos);
buf.append(']');
return buf.toString();
}
/**
* Format a min,max time pair.
*/
private static void format(long min,
long max,
SimpleDateFormat formatter,
StringBuffer buf,
FieldPosition pos)
{
if (min == max) {
formatter.format(new Date(min), buf, pos);
} else {
buf.append('[');
formatter.format(new Date(min), buf, pos);
buf.append(", ");
formatter.format(new Date(max), buf, pos);
buf.append(']');
}
}
/**
* Returns a formatter for "yyyy.MM.dd HH:mm:ss.SSSS zzz".
*/
private static synchronized SimpleDateFormat getFormatter() {
SimpleDateFormat formatter = null;
if (formatterRef != null) {
formatter = (SimpleDateFormat) formatterRef.get();
}
if (formatter == null) {
formatter = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss.SSSS zzz",
Locale.US);
formatterRef = new SoftReference(formatter);
}
return formatter;
}
/**
* 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>, and <code>minStop</code> is less than or equal to
* <code>maxStop</code>.
*
* @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>
*/
private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException
{
s.defaultReadObject();
if (minStart > maxStart || maxStart > minStop || minStop > maxStop) {
throw new InvalidObjectException("invalid times");
}
}
}