📄 dateattribute.java
字号:
/*
* @(#)DateAttribute.java
*
* Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistribution of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
* ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN")
* AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
* AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
* OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed or intended for use in
* the design, construction, operation or maintenance of any nuclear facility.
*/
package com.sun.xacml.attr;
import java.net.URI;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
import org.w3c.dom.Node;
/**
* Representation of an xs:date value. This class supports parsing
* xs:date values. All objects of this class are immutable and
* thread-safe. The <code>Date</code> objects returned are not, but
* these objects are cloned before being returned.
*
* @since 1.0
* @author Marco Barreno
* @author Seth Proctor
* @author Steve Hanna
*/
public class DateAttribute extends AttributeValue
{
/**
* Official name of this type
*/
public static final String identifier =
"http://www.w3.org/2001/XMLSchema#date";
/**
* URI version of name for this type
* <p>
* This field is initialized by a static initializer so that
* we can catch any exceptions thrown by URI(String) and
* transform them into a RuntimeException, since this should
* never happen but should be reported properly if it ever does.
* <p>
* This object is used for synchronization whenever we need
* protection across this whole class.
*/
private static URI identifierURI;
/**
* RuntimeException that wraps an Exception thrown during the
* creation of identifierURI, null if none.
*/
private static RuntimeException earlyException;
/**
* Static initializer that initializes the identifierURI
* class field so that we can catch any exceptions thrown
* by URI(String) and transform them into a RuntimeException.
* Such exceptions should never happen but should be reported
* properly if they ever do.
*/
static {
try {
identifierURI = new URI(identifier);
} catch (Exception e) {
earlyException = new IllegalArgumentException();
earlyException.initCause(e);
}
};
/**
* Parser for dates with no time zones
* <p>
* This field is only initialized if needed (by initParsers()).
* <p>
* NOTE: This object should only be accessed from code that
* has synchronized on it, since SimpleDateFormat objects are not
* thread-safe. If this is causing performance problems, we could
* easily make this a method variable in methods that use it
* instead of a class field. But that would mean we'd need to
* spend a lot more time creating these objects.
*/
private static DateFormat simpleParser;
/**
* Parser for dates with RFC 822 time zones (like +0300)
* <p>
* This field is only initialized if needed (by initParsers()).
* <p>
* NOTE: This object should only be accessed from code that
* has a lock on it, since SimpleDateFormat objects are not
* thread-safe.
*/
private static DateFormat zoneParser;
/**
* Calendar for GMT
* <p>
* NOTE: This object should only be accessed from code that
* has a lock on it, since Calendar objects are not generally
* thread-safe.
*/
private static Calendar gmtCalendar;
/**
* Number of nanoseconds per millisecond
* (shared by other classes in this package)
*/
static final int NANOS_PER_MILLI = 1000000;
/**
* Number of milliseconds per second
* (shared by other classes in this package)
*/
static final int MILLIS_PER_SECOND = 1000;
/**
* Number of seconds in a minute
* (shared by other classes in this package)
*/
static final int SECONDS_PER_MINUTE = 60;
/**
* Number of minutes in an hour
* (shared by other classes in this package)
*/
static final int MINUTES_PER_HOUR = 60;
/**
* Number of hours in a day
* (shared by other classes in this package)
*/
static final int HOURS_PER_DAY = 24;
/**
* Number of nanoseconds per second
* (shared by other classes in this package)
*/
static final int NANOS_PER_SECOND = NANOS_PER_MILLI * MILLIS_PER_SECOND;
/**
* Number of milliseconds in a minute
* (shared by other classes in this package)
*/
static final int MILLIS_PER_MINUTE =
MILLIS_PER_SECOND * SECONDS_PER_MINUTE;
/**
* Number of milliseconds in an hour
* (shared by other classes in this package)
*/
static final int MILLIS_PER_HOUR =
MILLIS_PER_MINUTE * MINUTES_PER_HOUR;
/**
* Number of milliseconds in a day
* (shared by other classes in this package)
*/
static final long MILLIS_PER_DAY = MILLIS_PER_HOUR * HOURS_PER_DAY;
/**
* Time zone value that indicates that the time zone was not
* specified.
*/
public static final int TZ_UNSPECIFIED = -1000000;
/**
* The instant (in GMT) at which the specified date began (midnight)
* in the specified time zone. If no time zone was specified,
* the local time zone is used.
*/
private Date value;
/**
* The time zone specified for this object (or TZ_UNSPECIFIED if
* unspecified). The offset to GMT, in minutes.
*/
private int timeZone;
/**
* The time zone actually used for this object (if it was
* originally unspecified, the default time zone used).
* The offset to GMT, in minutes.
*/
private int defaultedTimeZone;
/**
* Cached encoded value (null if not cached yet).
*/
private String encodedValue = null;
/**
* Creates a new <code>TimeAttribute</code> that represents
* the current date in the default time zone.
*/
public DateAttribute() {
this(new Date());
}
/**
* Creates a new <code>TimeAttribute</code> that represents
* the given date with default timezone values.
*
* @param date a <code>Date</code> object representing the
* instant at which the specified date began (midnight)
* in the specified time zone (the actual time value
* will be forced to midnight)
*/
public DateAttribute(Date date) {
super(identifierURI);
// Get the current time and GMT offset
int currOffset = DateTimeAttribute.getDefaultTZOffset(date);
long millis = date.getTime();
// Now find out the last time it was midnight local time
// (actually the last time it was midnight with the current
// GMT offset, but that's good enough).
// Skip back by time zone offset.
millis += currOffset * MILLIS_PER_MINUTE;
// Reset to last GMT midnight
millis -= millis % MILLIS_PER_DAY;
// Skip forward by time zone offset.
millis -= currOffset * MILLIS_PER_MINUTE;
date.setTime(millis);
init(date, currOffset, currOffset);
}
/**
* Creates a new <code>DateAttribute</code> that represents
* the date supplied.
*
* @param date a <code>Date</code> object representing the
* instant at which the specified date began (midnight)
* in the specified time zone
* @param timeZone the time zone specified for this object
* (or TZ_UNSPECIFIED if unspecified). The
* offset to GMT, in minutes.
* @param defaultedTimeZone the time zone actually used for this
* object (if it was originally unspecified,
* the default time zone used).
* The offset to GMT, in minutes.
*/
public DateAttribute(Date date, int timeZone, int defaultedTimeZone) {
super(identifierURI);
init(date, timeZone, defaultedTimeZone);
}
/**
* Initialization code shared by constructors.
*
* @param date a <code>Date</code> object representing the
* instant at which the specified date began (midnight)
* in the specified time zone.
* @param timeZone the time zone specified for this object
* (or TZ_UNSPECIFIED if unspecified). The
* offset to GMT, in minutes.
* @param defaultedTimeZone the time zone actually used for this
* object (if it was originally unspecified,
* the default time zone used).
* The offset to GMT, in minutes.
*/
private void init(Date date, int timeZone, int defaultedTimeZone) {
// Shouldn't happen, but just in case...
if (earlyException != null)
throw earlyException;
this.value = (Date) date.clone();
this.timeZone = timeZone;
this.defaultedTimeZone = defaultedTimeZone;
}
/**
* Returns a new <code>DateAttribute</code> that represents
* the xs:date at a particular DOM node.
*
* @param root the <code>Node</code> that contains the desired value
* @return a new <code>DateAttribute</code> representing the
* appropriate value (null if there is a parsing error)
*/
public static DateAttribute getInstance(Node root)
throws ParseException
{
return getInstance(root.getFirstChild().getNodeValue());
}
/**
* Returns a new <code>DateAttribute</code> that represents
* the xs:date value indicated by the string provided.
*
* @param value a string representing the desired value
* @return a new <code>DateAttribute</code> representing the
* desired value (null if there is a parsing error)
*/
public static DateAttribute getInstance(String value)
throws ParseException
{
Date dateValue = null;
int timeZone;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -