📄 daytimedurationattribute.java
字号:
/*
* @(#)DayTimeDurationAttribute.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 com.sun.xacml.ParsingException;
import java.math.BigInteger;
import java.net.URI;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import java.util.regex.Matcher;
import org.w3c.dom.Node;
/**
* Representation of an xf:dayTimeDuration value. This class supports parsing
* xd:dayTimeDuration 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 Steve Hanna
*/
public class DayTimeDurationAttribute extends AttributeValue
{
/**
* Official name of this type
*/
public static final String identifier =
"http://www.w3.org/TR/2002/WD-xquery-operators-20020816#" +
"dayTimeDuration";
/**
* 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.
*/
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);
}
};
/**
* Regular expression for dayTimeDuration (a la java.util.regex)
*/
private static final String patternString =
"(\\-)?P((\\d+)?D)?(T((\\d+)?H)?((\\d+)?M)?((\\d+)?(.(\\d+)?)?S)?)?";
/**
* The index of the capturing group for the negative sign.
*/
private static final int GROUP_SIGN = 1;
/**
* The index of the capturing group for the number of days.
*/
private static final int GROUP_DAYS = 3;
/**
* The index of the capturing group for the number of hours.
*/
private static final int GROUP_HOURS = 6;
/**
* The index of the capturing group for the number of minutes.
*/
private static final int GROUP_MINUTES = 8;
/**
* The index of the capturing group for the number of seconds.
*/
private static final int GROUP_SECONDS = 10;
/**
* The index of the capturing group for the number of nanoseconds.
*/
private static final int GROUP_NANOSECONDS = 12;
/**
* Static BigInteger values. We only use these if one of
* the components is bigger than Integer.MAX_LONG and we
* want to detect overflow, so we don't initialize these
* until they're needed.
*/
private static BigInteger big24;
private static BigInteger big60;
private static BigInteger big1000;
private static BigInteger bigMaxLong;
/**
* A shared Pattern object, only initialized if needed
*/
private static Pattern pattern;
/**
* Negative flag. true if duration is negative, false otherwise
*/
private boolean negative;
/**
* Number of days
*/
private long days;
/**
* Number of hours
*/
private long hours;
/**
* Number of minutes
*/
private long minutes;
/**
* Number of seconds
*/
private long seconds;
/**
* Number of nanoseconds
*/
private int nanoseconds;
/**
* Total number of round seconds (in milliseconds)
*/
private long totalMillis;
/**
* Cached encoded value (null if not cached yet).
*/
private String encodedValue = null;
/**
* Creates a new <code>DayTimeDurationAttribute</code> that represents
* the duration supplied.
*
* @param negative true if the duration is negative, false otherwise
* @param days the number of days in the duration
* @param hours the number of hours in the duration
* @param minutes the number of minutes in the duration
* @param seconds the number of seconds in the duration
* @param nanoseconds the number of nanoseconds in the duration
* @throws IllegalArgumentException if the total number of milliseconds
* exceeds Long.MAX_LONG
*/
public DayTimeDurationAttribute(boolean negative, long days, long hours,
long minutes, long seconds,
int nanoseconds)
throws IllegalArgumentException {
super(identifierURI);
// Shouldn't happen, but just in case...
if (earlyException != null)
throw earlyException;
this.negative = negative;
this.days = days;
this.hours = hours;
this.minutes = minutes;
this.seconds = seconds;
this.nanoseconds = nanoseconds;
// Convert all the components except nanoseconds to milliseconds
// If any of the components is big (too big to be an int),
// use the BigInteger class to do the math so we can detect
// overflow.
if ((days > Integer.MAX_VALUE) || (hours > Integer.MAX_VALUE) ||
(minutes > Integer.MAX_VALUE) || (seconds > Integer.MAX_VALUE)) {
if (big24 == null) {
big24 = BigInteger.valueOf(24);
big60 = BigInteger.valueOf(60);
big1000 = BigInteger.valueOf(1000);
bigMaxLong = BigInteger.valueOf(Long.MAX_VALUE);
}
BigInteger bigDays = BigInteger.valueOf(days);
BigInteger bigHours = BigInteger.valueOf(hours);
BigInteger bigMinutes = BigInteger.valueOf(minutes);
BigInteger bigSeconds = BigInteger.valueOf(seconds);
BigInteger bigTotal = bigDays.multiply(big24).add(bigHours)
.multiply(big60).add(bigMinutes).multiply(big60)
.add(bigSeconds).multiply(big1000);
// If the result is bigger than Long.MAX_VALUE, we have an
// overflow. Indicate an error (should be a processing error,
// since it can be argued that we should handle gigantic
// values for this).
if (bigTotal.compareTo(bigMaxLong) == 1)
throw new IllegalArgumentException("total number of " +
"milliseconds " +
"exceeds Long.MAX_VALUE");
// If no overflow, convert to a long.
totalMillis = bigTotal.longValue();
} else {
// The numbers are small, so do it the fast way.
totalMillis = ((((((days * 24) + hours) * 60) + minutes) * 60) +
seconds) * 1000;
}
}
/**
* Returns a new <code>DayTimeDurationAttribute</code> that represents
* the xf:dayTimeDuration at a particular DOM node.
*
* @param root the <code>Node</code> that contains the desired value
* @return a new <code>DayTimeDurationAttribute</code> representing the
* appropriate value (null if there is a parsing error)
*/
public static DayTimeDurationAttribute getInstance(Node root)
throws ParsingException, NumberFormatException
{
return getInstance(root.getFirstChild().getNodeValue());
}
/**
* Returns the long value for the capturing group groupNumber.
* This method takes a Matcher that has been used to match a
* Pattern against a String, fetches the value for the specified
* capturing group, converts that value to an long, and returns
* the value. If that group did not match, 0 is returned.
* If the matched value is not a valid long, NumberFormatException
* is thrown.
*
* @param matcher the Matcher from which to fetch the group
* @param groupNumber the group number to fetch
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -