0001 /*
0002 * Copyright 2004-2006 Sun Microsystems, Inc. All Rights Reserved.
0003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004 *
0005 * This code is free software; you can redistribute it and/or modify it
0006 * under the terms of the GNU General Public License version 2 only, as
0007 * published by the Free Software Foundation. Sun designates this
0008 * particular file as subject to the "Classpath" exception as provided
0009 * by Sun in the LICENSE file that accompanied this code.
0010 *
0011 * This code is distributed in the hope that it will be useful, but WITHOUT
0012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0014 * version 2 for more details (a copy is included in the LICENSE file that
0015 * accompanied this code).
0016 *
0017 * You should have received a copy of the GNU General Public License version
0018 * 2 along with this work; if not, write to the Free Software Foundation,
0019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020 *
0021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022 * CA 95054 USA or visit www.sun.com if you need additional information or
0023 * have any questions.
0024 */
0025
0026 package javax.xml.datatype;
0027
0028 import java.math.BigInteger;
0029 import java.math.BigDecimal;
0030 import java.util.GregorianCalendar;
0031 import java.util.regex.Matcher;
0032 import java.util.regex.Pattern;
0033
0034 /**
0035 * <p>Factory that creates new <code>javax.xml.datatype</code> <code>Object</code>s that map XML to/from Java <code>Object</code>s.</p>
0036 *
0037 * <p><a name="DatatypeFactory.newInstance"/>{@link #newInstance()} is used to create a new <code>DatatypeFactory</code>.
0038 * The following implementation resolution mechanisms are used in the following order:</p>
0039 * <ol>
0040 * <li>
0041 * If the system property specified by {@link #DATATYPEFACTORY_PROPERTY}, "<code>javax.xml.datatype.DatatypeFactory</code>",
0042 * exists, a class with the name of the property's value is instantiated.
0043 * Any Exception thrown during the instantiation process is wrapped as a {@link DatatypeConfigurationException}.
0044 * </li>
0045 * <li>
0046 * If the file ${JAVA_HOME}/lib/jaxp.properties exists, it is loaded in a {@link java.util.Properties} <code>Object</code>.
0047 * The <code>Properties</code> <code>Object </code> is then queried for the property as documented in the prior step
0048 * and processed as documented in the prior step.
0049 * </li>
0050 * <li>
0051 * The services resolution mechanism is used, e.g. <code>META-INF/services/java.xml.datatype.DatatypeFactory</code>.
0052 * Any Exception thrown during the instantiation process is wrapped as a {@link DatatypeConfigurationException}.
0053 * </li>
0054 * <li>
0055 * The final mechanism is to attempt to instantiate the <code>Class</code> specified by
0056 * {@link #DATATYPEFACTORY_IMPLEMENTATION_CLASS}.
0057 * Any Exception thrown during the instantiation process is wrapped as a {@link DatatypeConfigurationException}.
0058 * </li>
0059 * </ol>
0060 *
0061 * @author <a href="mailto:Joseph.Fialli@Sun.COM">Joseph Fialli</a>
0062 * @author <a href="mailto:Jeff.Suttor@Sun.com">Jeff Suttor</a>
0063 * @author <a href="mailto:Neeraj.Bajaj@sun.com">Neeraj Bajaj</a>
0064 *
0065 * @version $Revision: 1.10 $, $Date: 2006/05/19 01:08:42 $
0066 * @since 1.5
0067 */
0068 public abstract class DatatypeFactory {
0069
0070 /**
0071 * <p>Default property name as defined in JSR 206: Java(TM) API for XML Processing (JAXP) 1.3.</p>
0072 *
0073 * <p>Default value is <code>javax.xml.datatype.DatatypeFactory</code>.</p>
0074 */
0075 public static final String DATATYPEFACTORY_PROPERTY = "javax.xml.datatype.DatatypeFactory";
0076
0077 /**
0078 * <p>Default implementation class name as defined in
0079 * <em>JSR 206: Java(TM) API for XML Processing (JAXP) 1.3</em>.</p>
0080 *
0081 * <p>Implementers should specify the name of an appropriate class
0082 * to be instantiated if no other implementation resolution mechanism
0083 * succeeds.</p>
0084 *
0085 * <p>Users should not refer to this field; it is intended only to
0086 * document a factory implementation detail.
0087 * </p>
0088 */
0089 public static final String DATATYPEFACTORY_IMPLEMENTATION_CLASS = new String(
0090 "com.sun.org.apache.xerces.internal.jaxp.datatype.DatatypeFactoryImpl");
0091
0092 /**
0093 * http://www.w3.org/TR/xpath-datamodel/#xdtschema defines two regexps
0094 * to constrain the value space of dayTimeDuration ([^YM]*[DT].*)
0095 * and yearMonthDuration ([^DT]*). Note that these expressions rely on
0096 * the fact that the value must be an xs:Duration, they simply exclude
0097 * some Durations.
0098 */
0099 private static final Pattern XDTSCHEMA_YMD = Pattern
0100 .compile("[^DT]*");
0101
0102 private static final Pattern XDTSCHEMA_DTD = Pattern
0103 .compile("[^YM]*[DT].*");
0104
0105 /**
0106 * <p>Protected constructor to prevent instaniation outside of package.</p>
0107 *
0108 * <p>Use {@link #newInstance()} to create a <code>DatatypeFactory</code>.</p>
0109 */
0110 protected DatatypeFactory() {
0111 }
0112
0113 /**
0114 * <p>Obtain a new instance of a <code>DatatypeFactory</code>.</p>
0115 *
0116 * <p>The implementation resolution mechanisms are <a href="#DatatypeFactory.newInstance">defined</a> in this
0117 * <code>Class</code>'s documentation.</p>
0118 *
0119 * @return New instance of a <code>DatatypeFactory</code>
0120 *
0121 * @throws DatatypeConfigurationException If the implementation is not
0122 * available or cannot be instantiated.
0123 *
0124 * @see #newInstance(String factoryClassName, ClassLoader classLoader)
0125 */
0126 public static DatatypeFactory newInstance()
0127 throws DatatypeConfigurationException {
0128
0129 try {
0130 return (DatatypeFactory) FactoryFinder.find(
0131 /* The default property name according to the JAXP spec */
0132 DATATYPEFACTORY_PROPERTY,
0133 /* The fallback implementation class name */
0134 DATATYPEFACTORY_IMPLEMENTATION_CLASS);
0135 } catch (FactoryFinder.ConfigurationError e) {
0136 throw new DatatypeConfigurationException(e.getMessage(), e
0137 .getException());
0138 }
0139 }
0140
0141 /**
0142 * <p>Obtain a new instance of a <code>DatatypeFactory</code> from class name.
0143 * This function is useful when there are multiple providers in the classpath.
0144 * It gives more control to the application as it can specify which provider
0145 * should be loaded.</p>
0146 *
0147 * <p>Once an application has obtained a reference to a <code>DatatypeFactory</code>
0148 * it can use the factory to configure and obtain datatype instances.</P>
0149 *
0150 *
0151 * <h2>Tip for Trouble-shooting</h2>
0152 * <p>Setting the <code>jaxp.debug</code> system property will cause
0153 * this method to print a lot of debug messages
0154 * to <code>System.err</code> about what it is doing and where it is looking at.</p>
0155 *
0156 * <p> If you have problems try:</p>
0157 * <pre>
0158 * java -Djaxp.debug=1 YourProgram ....
0159 * </pre>
0160 *
0161 * @param factoryClassName fully qualified factory class name that provides implementation of <code>javax.xml.datatype.DatatypeFactory</code>.
0162 *
0163 * @param classLoader <code>ClassLoader</code> used to load the factory class. If <code>null</code>
0164 * current <code>Thread</code>'s context classLoader is used to load the factory class.
0165 *
0166 * @return New instance of a <code>DatatypeFactory</code>
0167 *
0168 * @throws DatatypeConfigurationException if <code>factoryClassName</code> is <code>null</code>, or
0169 * the factory class cannot be loaded, instantiated.
0170 *
0171 * @see #newInstance()
0172 *
0173 * @since 1.6
0174 */
0175 public static DatatypeFactory newInstance(String factoryClassName,
0176 ClassLoader classLoader)
0177 throws DatatypeConfigurationException {
0178 try {
0179 return (DatatypeFactory) FactoryFinder.newInstance(
0180 factoryClassName, classLoader, false);
0181 } catch (FactoryFinder.ConfigurationError e) {
0182 throw new DatatypeConfigurationException(e.getMessage(), e
0183 .getException());
0184 }
0185 }
0186
0187 /**
0188 * <p>Obtain a new instance of a <code>Duration</code>
0189 * specifying the <code>Duration</code> as its string representation, "PnYnMnDTnHnMnS",
0190 * as defined in XML Schema 1.0 section 3.2.6.1.</p>
0191 *
0192 * <p>XML Schema Part 2: Datatypes, 3.2.6 duration, defines <code>duration</code> as:</p>
0193 * <blockquote>
0194 * duration represents a duration of time.
0195 * The value space of duration is a six-dimensional space where the coordinates designate the
0196 * Gregorian year, month, day, hour, minute, and second components defined in Section 5.5.3.2 of [ISO 8601], respectively.
0197 * These components are ordered in their significance by their order of appearance i.e. as
0198 * year, month, day, hour, minute, and second.
0199 * </blockquote>
0200 * <p>All six values are set and availabe from the created {@link Duration}</p>
0201 *
0202 * <p>The XML Schema specification states that values can be of an arbitrary size.
0203 * Implementations may chose not to or be incapable of supporting arbitrarily large and/or small values.
0204 * An {@link UnsupportedOperationException} will be thrown with a message indicating implementation limits
0205 * if implementation capacities are exceeded.</p>
0206 *
0207 * @param lexicalRepresentation <code>String</code> representation of a <code>Duration</code>.
0208 *
0209 * @return New <code>Duration</code> created from parsing the <code>lexicalRepresentation</code>.
0210 *
0211 * @throws IllegalArgumentException If <code>lexicalRepresentation</code> is not a valid representation of a <code>Duration</code>.
0212 * @throws UnsupportedOperationException If implementation cannot support requested values.
0213 * @throws NullPointerException if <code>lexicalRepresentation</code> is <code>null</code>.
0214 */
0215 public abstract Duration newDuration(
0216 final String lexicalRepresentation);
0217
0218 /**
0219 * <p>Obtain a new instance of a <code>Duration</code>
0220 * specifying the <code>Duration</code> as milliseconds.</p>
0221 *
0222 * <p>XML Schema Part 2: Datatypes, 3.2.6 duration, defines <code>duration</code> as:</p>
0223 * <blockquote>
0224 * duration represents a duration of time.
0225 * The value space of duration is a six-dimensional space where the coordinates designate the
0226 * Gregorian year, month, day, hour, minute, and second components defined in Section 5.5.3.2 of [ISO 8601], respectively.
0227 * These components are ordered in their significance by their order of appearance i.e. as
0228 * year, month, day, hour, minute, and second.
0229 * </blockquote>
0230 * <p>All six values are set by computing their values from the specified milliseconds
0231 * and are availabe using the <code>get</code> methods of the created {@link Duration}.
0232 * The values conform to and are defined by:</p>
0233 * <ul>
0234 * <li>ISO 8601:2000(E) Section 5.5.3.2 Alternative format</li>
0235 * <li><a href="http://www.w3.org/TR/xmlschema-2/#isoformats">
0236 * W3C XML Schema 1.0 Part 2, Appendix D, ISO 8601 Date and Time Formats</a>
0237 * </li>
0238 * <li>{@link XMLGregorianCalendar} Date/Time Datatype Field Mapping Between XML Schema 1.0 and Java Representation</li>
0239 * </ul>
0240 *
0241 * <p>The default start instance is defined by {@link GregorianCalendar}'s use of the start of the epoch: i.e.,
0242 * {@link java.util.Calendar#YEAR} = 1970,
0243 * {@link java.util.Calendar#MONTH} = {@link java.util.Calendar#JANUARY},
0244 * {@link java.util.Calendar#DATE} = 1, etc.
0245 * This is important as there are variations in the Gregorian Calendar,
0246 * e.g. leap years have different days in the month = {@link java.util.Calendar#FEBRUARY}
0247 * so the result of {@link Duration#getMonths()} and {@link Duration#getDays()} can be influenced.</p>
0248 *
0249 * @param durationInMilliSeconds Duration in milliseconds to create.
0250 *
0251 * @return New <code>Duration</code> representing <code>durationInMilliSeconds</code>.
0252 */
0253 public abstract Duration newDuration(
0254 final long durationInMilliSeconds);
0255
0256 /**
0257 * <p>Obtain a new instance of a <code>Duration</code>
0258 * specifying the <code>Duration</code> as isPositive, years, months, days, hours, minutes, seconds.</p>
0259 *
0260 * <p>The XML Schema specification states that values can be of an arbitrary size.
0261 * Implementations may chose not to or be incapable of supporting arbitrarily large and/or small values.
0262 * An {@link UnsupportedOperationException} will be thrown with a message indicating implementation limits
0263 * if implementation capacities are exceeded.</p>
0264 *
0265 * <p>A <code>null</code> value indicates that field is not set.</p>
0266 *
0267 * @param isPositive Set to <code>false</code> to create a negative duration. When the length
0268 * of the duration is zero, this parameter will be ignored.
0269 * @param years of this <code>Duration</code>
0270 * @param months of this <code>Duration</code>
0271 * @param days of this <code>Duration</code>
0272 * @param hours of this <code>Duration</code>
0273 * @param minutes of this <code>Duration</code>
0274 * @param seconds of this <code>Duration</code>
0275 *
0276 * @return New <code>Duration</code> created from the specified values.
0277 *
0278 * @throws IllegalArgumentException If the values are not a valid representation of a
0279 * <code>Duration</code>: if all the fields (years, months, ...) are null or
0280 * if any of the fields is negative.
0281 * @throws UnsupportedOperationException If implementation cannot support requested values.
0282 */
0283 public abstract Duration newDuration(final boolean isPositive,
0284 final BigInteger years, final BigInteger months,
0285 final BigInteger days, final BigInteger hours,
0286 final BigInteger minutes, final BigDecimal seconds);
0287
0288 /**
0289 * <p>Obtain a new instance of a <code>Duration</code>
0290 * specifying the <code>Duration</code> as isPositive, years, months, days, hours, minutes, seconds.</p>
0291 *
0292 * <p>A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.</p>
0293 *
0294 * @param isPositive Set to <code>false</code> to create a negative duration. When the length
0295 * of the duration is zero, this parameter will be ignored.
0296 * @param years of this <code>Duration</code>
0297 * @param months of this <code>Duration</code>
0298 * @param days of this <code>Duration</code>
0299 * @param hours of this <code>Duration</code>
0300 * @param minutes of this <code>Duration</code>
0301 * @param seconds of this <code>Duration</code>
0302 *
0303 * @return New <code>Duration</code> created from the specified values.
0304 *
0305 * @throws IllegalArgumentException If the values are not a valid representation of a
0306 * <code>Duration</code>: if any of the fields is negative.
0307 *
0308 * @see #newDuration(
0309 * boolean isPositive,
0310 * BigInteger years,
0311 * BigInteger months,
0312 * BigInteger days,
0313 * BigInteger hours,
0314 * BigInteger minutes,
0315 * BigDecimal seconds)
0316 */
0317 public Duration newDuration(final boolean isPositive,
0318 final int years, final int months, final int days,
0319 final int hours, final int minutes, final int seconds) {
0320
0321 // years may not be set
0322 BigInteger realYears = (years != DatatypeConstants.FIELD_UNDEFINED) ? BigInteger
0323 .valueOf((long) years)
0324 : null;
0325
0326 // months may not be set
0327 BigInteger realMonths = (months != DatatypeConstants.FIELD_UNDEFINED) ? BigInteger
0328 .valueOf((long) months)
0329 : null;
0330
0331 // days may not be set
0332 BigInteger realDays = (days != DatatypeConstants.FIELD_UNDEFINED) ? BigInteger
0333 .valueOf((long) days)
0334 : null;
0335
0336 // hours may not be set
0337 BigInteger realHours = (hours != DatatypeConstants.FIELD_UNDEFINED) ? BigInteger
0338 .valueOf((long) hours)
0339 : null;
0340
0341 // minutes may not be set
0342 BigInteger realMinutes = (minutes != DatatypeConstants.FIELD_UNDEFINED) ? BigInteger
0343 .valueOf((long) minutes)
0344 : null;
0345
0346 // seconds may not be set
0347 BigDecimal realSeconds = (seconds != DatatypeConstants.FIELD_UNDEFINED) ? BigDecimal
0348 .valueOf((long) seconds)
0349 : null;
0350
0351 return newDuration(isPositive, realYears, realMonths, realDays,
0352 realHours, realMinutes, realSeconds);
0353 }
0354
0355 /**
0356 * <p>Create a <code>Duration</code> of type <code>xdt:dayTimeDuration</code> by parsing its <code>String</code> representation,
0357 * "<em>PnDTnHnMnS</em>", <a href="http://www.w3.org/TR/xpath-datamodel#dt-dayTimeDuration">
0358 * XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration</a>.</p>
0359 *
0360 * <p>The datatype <code>xdt:dayTimeDuration</code> is a subtype of <code>xs:duration</code>
0361 * whose lexical representation contains only day, hour, minute, and second components.
0362 * This datatype resides in the namespace <code>http://www.w3.org/2003/11/xpath-datatypes</code>.</p>
0363 *
0364 * <p>All four values are set and availabe from the created {@link Duration}</p>
0365 *
0366 * <p>The XML Schema specification states that values can be of an arbitrary size.
0367 * Implementations may chose not to or be incapable of supporting arbitrarily large and/or small values.
0368 * An {@link UnsupportedOperationException} will be thrown with a message indicating implementation limits
0369 * if implementation capacities are exceeded.</p>
0370 *
0371 * @param lexicalRepresentation Lexical representation of a duration.
0372 *
0373 * @return New <code>Duration</code> created using the specified <code>lexicalRepresentation</code>.
0374 *
0375 * @throws IllegalArgumentException If <code>lexicalRepresentation</code> is not a valid representation of a <code>Duration</code> expressed only in terms of days and time.
0376 * @throws UnsupportedOperationException If implementation cannot support requested values.
0377 * @throws NullPointerException If <code>lexicalRepresentation</code> is <code>null</code>.
0378 */
0379 public Duration newDurationDayTime(
0380 final String lexicalRepresentation) {
0381 // lexicalRepresentation must be non-null
0382 if (lexicalRepresentation == null) {
0383 throw new NullPointerException(
0384 "Trying to create an xdt:dayTimeDuration with an invalid"
0385 + " lexical representation of \"null\"");
0386 }
0387
0388 // test lexicalRepresentation against spec regex
0389 Matcher matcher = XDTSCHEMA_DTD.matcher(lexicalRepresentation);
0390 if (!matcher.matches()) {
0391 throw new IllegalArgumentException(
0392 "Trying to create an xdt:dayTimeDuration with an invalid"
0393 + " lexical representation of \""
0394 + lexicalRepresentation
0395 + "\", data model requires years and months only.");
0396 }
0397
0398 return newDuration(lexicalRepresentation);
0399 }
0400
0401 /**
0402 * <p>Create a <code>Duration</code> of type <code>xdt:dayTimeDuration</code> using the specified milliseconds as defined in
0403 * <a href="http://www.w3.org/TR/xpath-datamodel#dt-dayTimeDuration">
0404 * XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration</a>.</p>
0405 *
0406 * <p>The datatype <code>xdt:dayTimeDuration</code> is a subtype of <code>xs:duration</code>
0407 * whose lexical representation contains only day, hour, minute, and second components.
0408 * This datatype resides in the namespace <code>http://www.w3.org/2003/11/xpath-datatypes</code>.</p>
0409 *
0410 * <p>All four values are set by computing their values from the specified milliseconds
0411 * and are availabe using the <code>get</code> methods of the created {@link Duration}.
0412 * The values conform to and are defined by:</p>
0413 * <ul>
0414 * <li>ISO 8601:2000(E) Section 5.5.3.2 Alternative format</li>
0415 * <li><a href="http://www.w3.org/TR/xmlschema-2/#isoformats">
0416 * W3C XML Schema 1.0 Part 2, Appendix D, ISO 8601 Date and Time Formats</a>
0417 * </li>
0418 * <li>{@link XMLGregorianCalendar} Date/Time Datatype Field Mapping Between XML Schema 1.0 and Java Representation</li>
0419 * </ul>
0420 *
0421 * <p>The default start instance is defined by {@link GregorianCalendar}'s use of the start of the epoch: i.e.,
0422 * {@link java.util.Calendar#YEAR} = 1970,
0423 * {@link java.util.Calendar#MONTH} = {@link java.util.Calendar#JANUARY},
0424 * {@link java.util.Calendar#DATE} = 1, etc.
0425 * This is important as there are variations in the Gregorian Calendar,
0426 * e.g. leap years have different days in the month = {@link java.util.Calendar#FEBRUARY}
0427 * so the result of {@link Duration#getDays()} can be influenced.</p>
0428 *
0429 * <p>Any remaining milliseconds after determining the day, hour, minute and second are discarded.</p>
0430 *
0431 * @param durationInMilliseconds Milliseconds of <code>Duration</code> to create.
0432 *
0433 * @return New <code>Duration</code> created with the specified <code>durationInMilliseconds</code>.
0434 *
0435 * @see <a href="http://www.w3.org/TR/xpath-datamodel#dt-dayTimeDuration">
0436 * XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration</a>
0437 */
0438 public Duration newDurationDayTime(final long durationInMilliseconds) {
0439
0440 return newDuration(durationInMilliseconds);
0441 }
0442
0443 /**
0444 * <p>Create a <code>Duration</code> of type <code>xdt:dayTimeDuration</code> using the specified
0445 * <code>day</code>, <code>hour</code>, <code>minute</code> and <code>second</code> as defined in
0446 * <a href="http://www.w3.org/TR/xpath-datamodel#dt-dayTimeDuration">
0447 * XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration</a>.</p>
0448 *
0449 * <p>The datatype <code>xdt:dayTimeDuration</code> is a subtype of <code>xs:duration</code>
0450 * whose lexical representation contains only day, hour, minute, and second components.
0451 * This datatype resides in the namespace <code>http://www.w3.org/2003/11/xpath-datatypes</code>.</p>
0452 *
0453 * <p>The XML Schema specification states that values can be of an arbitrary size.
0454 * Implementations may chose not to or be incapable of supporting arbitrarily large and/or small values.
0455 * An {@link UnsupportedOperationException} will be thrown with a message indicating implementation limits
0456 * if implementation capacities are exceeded.</p>
0457 *
0458 * <p>A <code>null</code> value indicates that field is not set.</p>
0459 *
0460 * @param isPositive Set to <code>false</code> to create a negative duration. When the length
0461 * of the duration is zero, this parameter will be ignored.
0462 * @param day Day of <code>Duration</code>.
0463 * @param hour Hour of <code>Duration</code>.
0464 * @param minute Minute of <code>Duration</code>.
0465 * @param second Second of <code>Duration</code>.
0466 *
0467 * @return New <code>Duration</code> created with the specified <code>day</code>, <code>hour</code>, <code>minute</code>
0468 * and <code>second</code>.
0469 *
0470 * @throws IllegalArgumentException If the values are not a valid representation of a
0471 * <code>Duration</code>: if all the fields (day, hour, ...) are null or
0472 * if any of the fields is negative.
0473 * @throws UnsupportedOperationException If implementation cannot support requested values.
0474 */
0475 public Duration newDurationDayTime(final boolean isPositive,
0476 final BigInteger day, final BigInteger hour,
0477 final BigInteger minute, final BigInteger second) {
0478
0479 return newDuration(isPositive, null, // years
0480 null, // months
0481 day, hour, minute, (second != null) ? new BigDecimal(
0482 second) : null);
0483 }
0484
0485 /**
0486 * <p>Create a <code>Duration</code> of type <code>xdt:dayTimeDuration</code> using the specified
0487 * <code>day</code>, <code>hour</code>, <code>minute</code> and <code>second</code> as defined in
0488 * <a href="http://www.w3.org/TR/xpath-datamodel#dt-dayTimeDuration">
0489 * XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration</a>.</p>
0490 *
0491 * <p>The datatype <code>xdt:dayTimeDuration</code> is a subtype of <code>xs:duration</code>
0492 * whose lexical representation contains only day, hour, minute, and second components.
0493 * This datatype resides in the namespace <code>http://www.w3.org/2003/11/xpath-datatypes</code>.</p>
0494 *
0495 * <p>A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.</p>
0496 *
0497 * @param isPositive Set to <code>false</code> to create a negative duration. When the length
0498 * of the duration is zero, this parameter will be ignored.
0499 * @param day Day of <code>Duration</code>.
0500 * @param hour Hour of <code>Duration</code>.
0501 * @param minute Minute of <code>Duration</code>.
0502 * @param second Second of <code>Duration</code>.
0503 *
0504 * @return New <code>Duration</code> created with the specified <code>day</code>, <code>hour</code>, <code>minute</code>
0505 * and <code>second</code>.
0506 *
0507 * @throws IllegalArgumentException If the values are not a valid representation of a
0508 * <code>Duration</code>: if any of the fields (day, hour, ...) is negative.
0509 */
0510 public Duration newDurationDayTime(final boolean isPositive,
0511 final int day, final int hour, final int minute,
0512 final int second) {
0513
0514 return newDurationDayTime(isPositive, BigInteger
0515 .valueOf((long) day), BigInteger.valueOf((long) hour),
0516 BigInteger.valueOf((long) minute), BigInteger
0517 .valueOf((long) second));
0518 }
0519
0520 /**
0521 * <p>Create a <code>Duration</code> of type <code>xdt:yearMonthDuration</code> by parsing its <code>String</code> representation,
0522 * "<em>PnYnM</em>", <a href="http://www.w3.org/TR/xpath-datamodel#dt-yearMonthDuration">
0523 * XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration</a>.</p>
0524 *
0525 * <p>The datatype <code>xdt:yearMonthDuration</code> is a subtype of <code>xs:duration</code>
0526 * whose lexical representation contains only year and month components.
0527 * This datatype resides in the namespace {@link javax.xml.XMLConstants#W3C_XPATH_DATATYPE_NS_URI}.</p>
0528 *
0529 * <p>Both values are set and availabe from the created {@link Duration}</p>
0530 *
0531 * <p>The XML Schema specification states that values can be of an arbitrary size.
0532 * Implementations may chose not to or be incapable of supporting arbitrarily large and/or small values.
0533 * An {@link UnsupportedOperationException} will be thrown with a message indicating implementation limits
0534 * if implementation capacities are exceeded.</p>
0535 *
0536 * @param lexicalRepresentation Lexical representation of a duration.
0537 *
0538 * @return New <code>Duration</code> created using the specified <code>lexicalRepresentation</code>.
0539 *
0540 * @throws IllegalArgumentException If <code>lexicalRepresentation</code> is not a valid representation of a <code>Duration</code> expressed only in terms of years and months.
0541 * @throws UnsupportedOperationException If implementation cannot support requested values.
0542 * @throws NullPointerException If <code>lexicalRepresentation</code> is <code>null</code>.
0543 */
0544 public Duration newDurationYearMonth(
0545 final String lexicalRepresentation) {
0546
0547 // lexicalRepresentation must be non-null
0548 if (lexicalRepresentation == null) {
0549 throw new NullPointerException(
0550 "Trying to create an xdt:yearMonthDuration with an invalid"
0551 + " lexical representation of \"null\"");
0552 }
0553
0554 // test lexicalRepresentation against spec regex
0555 Matcher matcher = XDTSCHEMA_YMD.matcher(lexicalRepresentation);
0556 if (!matcher.matches()) {
0557 throw new IllegalArgumentException(
0558 "Trying to create an xdt:yearMonthDuration with an invalid"
0559 + " lexical representation of \""
0560 + lexicalRepresentation
0561 + "\", data model requires days and times only.");
0562 }
0563
0564 return newDuration(lexicalRepresentation);
0565 }
0566
0567 /**
0568 * <p>Create a <code>Duration</code> of type <code>xdt:yearMonthDuration</code> using the specified milliseconds as defined in
0569 * <a href="http://www.w3.org/TR/xpath-datamodel#dt-yearMonthDuration">
0570 * XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration</a>.</p>
0571 *
0572 * <p>The datatype <code>xdt:yearMonthDuration</code> is a subtype of <code>xs:duration</code>
0573 * whose lexical representation contains only year and month components.
0574 * This datatype resides in the namespace {@link javax.xml.XMLConstants#W3C_XPATH_DATATYPE_NS_URI}.</p>
0575 *
0576 * <p>Both values are set by computing their values from the specified milliseconds
0577 * and are availabe using the <code>get</code> methods of the created {@link Duration}.
0578 * The values conform to and are defined by:</p>
0579 * <ul>
0580 * <li>ISO 8601:2000(E) Section 5.5.3.2 Alternative format</li>
0581 * <li><a href="http://www.w3.org/TR/xmlschema-2/#isoformats">
0582 * W3C XML Schema 1.0 Part 2, Appendix D, ISO 8601 Date and Time Formats</a>
0583 * </li>
0584 * <li>{@link XMLGregorianCalendar} Date/Time Datatype Field Mapping Between XML Schema 1.0 and Java Representation</li>
0585 * </ul>
0586 *
0587 * <p>The default start instance is defined by {@link GregorianCalendar}'s use of the start of the epoch: i.e.,
0588 * {@link java.util.Calendar#YEAR} = 1970,
0589 * {@link java.util.Calendar#MONTH} = {@link java.util.Calendar#JANUARY},
0590 * {@link java.util.Calendar#DATE} = 1, etc.
0591 * This is important as there are variations in the Gregorian Calendar,
0592 * e.g. leap years have different days in the month = {@link java.util.Calendar#FEBRUARY}
0593 * so the result of {@link Duration#getMonths()} can be influenced.</p>
0594 *
0595 * <p>Any remaining milliseconds after determining the year and month are discarded.</p>
0596 *
0597 * @param durationInMilliseconds Milliseconds of <code>Duration</code> to create.
0598 *
0599 * @return New <code>Duration</code> created using the specified <code>durationInMilliseconds</code>.
0600 */
0601 public Duration newDurationYearMonth(
0602 final long durationInMilliseconds) {
0603
0604 // create a Duration that only has sign, year & month
0605 // Duration is immutable, so need to create a new Duration
0606 // implementations may override this method in a more efficient way
0607 Duration fullDuration = newDuration(durationInMilliseconds);
0608 boolean isPositive = (fullDuration.getSign() == -1) ? false
0609 : true;
0610 BigInteger years = (BigInteger) fullDuration
0611 .getField(DatatypeConstants.YEARS);
0612 if (years == null) {
0613 years = BigInteger.ZERO;
0614 }
0615 BigInteger months = (BigInteger) fullDuration
0616 .getField(DatatypeConstants.MONTHS);
0617 if (months == null) {
0618 months = BigInteger.ZERO;
0619 }
0620
0621 return newDurationYearMonth(isPositive, years, months);
0622 }
0623
0624 /**
0625 * <p>Create a <code>Duration</code> of type <code>xdt:yearMonthDuration</code> using the specified
0626 * <code>year</code> and <code>month</code> as defined in
0627 * <a href="http://www.w3.org/TR/xpath-datamodel#dt-yearMonthyDuration">
0628 * XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration</a>.</p>
0629 *
0630 * <p>The XML Schema specification states that values can be of an arbitrary size.
0631 * Implementations may chose not to or be incapable of supporting arbitrarily large and/or small values.
0632 * An {@link UnsupportedOperationException} will be thrown with a message indicating implementation limits
0633 * if implementation capacities are exceeded.</p>
0634 *
0635 * <p>A <code>null</code> value indicates that field is not set.</p>
0636 *
0637 * @param isPositive Set to <code>false</code> to create a negative duration. When the length
0638 * of the duration is zero, this parameter will be ignored.
0639 * @param year Year of <code>Duration</code>.
0640 * @param month Month of <code>Duration</code>.
0641 *
0642 * @return New <code>Duration</code> created using the specified <code>year</code> and <code>month</code>.
0643 *
0644 * @throws IllegalArgumentException If the values are not a valid representation of a
0645 * <code>Duration</code>: if all of the fields (year, month) are null or
0646 * if any of the fields is negative.
0647 * @throws UnsupportedOperationException If implementation cannot support requested values.
0648 */
0649 public Duration newDurationYearMonth(final boolean isPositive,
0650 final BigInteger year, final BigInteger month) {
0651
0652 return newDuration(isPositive, year, month, null, // days
0653 null, // hours
0654 null, // minutes
0655 null // seconds
0656 );
0657 }
0658
0659 /**
0660 * <p>Create a <code>Duration</code> of type <code>xdt:yearMonthDuration</code> using the specified
0661 * <code>year</code> and <code>month</code> as defined in
0662 * <a href="http://www.w3.org/TR/xpath-datamodel#dt-yearMonthyDuration">
0663 * XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration</a>.</p>
0664 *
0665 * <p>A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.</p>
0666 *
0667 * @param isPositive Set to <code>false</code> to create a negative duration. When the length
0668 * of the duration is zero, this parameter will be ignored.
0669 * @param year Year of <code>Duration</code>.
0670 * @param month Month of <code>Duration</code>.
0671 *
0672 * @return New <code>Duration</code> created using the specified <code>year</code> and <code>month</code>.
0673 *
0674 * @throws IllegalArgumentException If the values are not a valid representation of a
0675 * <code>Duration</code>: if any of the fields (year, month) is negative.
0676 */
0677 public Duration newDurationYearMonth(final boolean isPositive,
0678 final int year, final int month) {
0679
0680 return newDurationYearMonth(isPositive, BigInteger
0681 .valueOf((long) year), BigInteger.valueOf((long) month));
0682 }
0683
0684 /**
0685 * <p>Create a new instance of an <code>XMLGregorianCalendar</code>.</p>
0686 *
0687 * <p>All date/time datatype fields set to {@link DatatypeConstants#FIELD_UNDEFINED} or null.</p>
0688 *
0689 * @return New <code>XMLGregorianCalendar</code> with all date/time datatype fields set to
0690 * {@link DatatypeConstants#FIELD_UNDEFINED} or null.
0691 */
0692 public abstract XMLGregorianCalendar newXMLGregorianCalendar();
0693
0694 /**
0695 * <p>Create a new XMLGregorianCalendar by parsing the String as a lexical representation.</p>
0696 *
0697 * <p>Parsing the lexical string representation is defined in
0698 * <a href="http://www.w3.org/TR/xmlschema-2/#dateTime-order">XML Schema 1.0 Part 2, Section 3.2.[7-14].1,
0699 * <em>Lexical Representation</em>.</a></p>
0700 *
0701 * <p>The string representation may not have any leading and trailing whitespaces.</p>
0702 *
0703 * <p>The parsing is done field by field so that
0704 * the following holds for any lexically correct String x:</p>
0705 * <pre>
0706 * newXMLGregorianCalendar(x).toXMLFormat().equals(x)
0707 * </pre>
0708 * <p>Except for the noted lexical/canonical representation mismatches
0709 * listed in <a href="http://www.w3.org/2001/05/xmlschema-errata#e2-45">
0710 * XML Schema 1.0 errata, Section 3.2.7.2</a>.</p>
0711 *
0712 * @param lexicalRepresentation Lexical representation of one the eight XML Schema date/time datatypes.
0713 *
0714 * @return <code>XMLGregorianCalendar</code> created from the <code>lexicalRepresentation</code>.
0715 *
0716 * @throws IllegalArgumentException If the <code>lexicalRepresentation</code> is not a valid <code>XMLGregorianCalendar</code>.
0717 * @throws NullPointerException If <code>lexicalRepresentation</code> is <code>null</code>.
0718 */
0719 public abstract XMLGregorianCalendar newXMLGregorianCalendar(
0720 final String lexicalRepresentation);
0721
0722 /**
0723 * <p>Create an <code>XMLGregorianCalendar</code> from a {@link GregorianCalendar}.</p>
0724 *
0725 * <table border="2" rules="all" cellpadding="2">
0726 * <thead>
0727 * <tr>
0728 * <th align="center" colspan="2">
0729 * Field by Field Conversion from
0730 * {@link GregorianCalendar} to an {@link XMLGregorianCalendar}
0731 * </th>
0732 * </tr>
0733 * <tr>
0734 * <th><code>java.util.GregorianCalendar</code> field</th>
0735 * <th><code>javax.xml.datatype.XMLGregorianCalendar</code> field</th>
0736 * </tr>
0737 * </thead>
0738 * <tbody>
0739 * <tr>
0740 * <td><code>ERA == GregorianCalendar.BC ? -YEAR : YEAR</code></td>
0741 * <td>{@link XMLGregorianCalendar#setYear(int year)}</td>
0742 * </tr>
0743 * <tr>
0744 * <td><code>MONTH + 1</code></td>
0745 * <td>{@link XMLGregorianCalendar#setMonth(int month)}</td>
0746 * </tr>
0747 * <tr>
0748 * <td><code>DAY_OF_MONTH</code></td>
0749 * <td>{@link XMLGregorianCalendar#setDay(int day)}</td>
0750 * </tr>
0751 * <tr>
0752 * <td><code>HOUR_OF_DAY, MINUTE, SECOND, MILLISECOND</code></td>
0753 * <td>{@link XMLGregorianCalendar#setTime(int hour, int minute, int second, BigDecimal fractional)}</td>
0754 * </tr>
0755 * <tr>
0756 * <td>
0757 * <code>(ZONE_OFFSET + DST_OFFSET) / (60*1000)</code><br/>
0758 * <em>(in minutes)</em>
0759 * </td>
0760 * <td>{@link XMLGregorianCalendar#setTimezone(int offset)}<sup><em>*</em></sup>
0761 * </td>
0762 * </tr>
0763 * </tbody>
0764 * </table>
0765 * <p><em>*</em>conversion loss of information. It is not possible to represent
0766 * a <code>java.util.GregorianCalendar</code> daylight savings timezone id in the
0767 * XML Schema 1.0 date/time datatype representation.</p>
0768 *
0769 * <p>To compute the return value's <code>TimeZone</code> field,
0770 * <ul>
0771 * <li>when <code>this.getTimezone() != FIELD_UNDEFINED</code>,
0772 * create a <code>java.util.TimeZone</code> with a custom timezone id
0773 * using the <code>this.getTimezone()</code>.</li>
0774 * <li>else use the <code>GregorianCalendar</code> default timezone value
0775 * for the host is defined as specified by
0776 * <code>java.util.TimeZone.getDefault()</code>.</li></p>
0777 *
0778 * @param cal <code>java.util.GregorianCalendar</code> used to create <code>XMLGregorianCalendar</code>
0779 *
0780 * @return <code>XMLGregorianCalendar</code> created from <code>java.util.GregorianCalendar</code>
0781 *
0782 * @throws NullPointerException If <code>cal</code> is <code>null</code>.
0783 */
0784 public abstract XMLGregorianCalendar newXMLGregorianCalendar(
0785 final GregorianCalendar cal);
0786
0787 /**
0788 * <p>Constructor allowing for complete value spaces allowed by
0789 * W3C XML Schema 1.0 recommendation for xsd:dateTime and related
0790 * builtin datatypes. Note that <code>year</code> parameter supports
0791 * arbitrarily large numbers and fractionalSecond has infinite
0792 * precision.</p>
0793 *
0794 * <p>A <code>null</code> value indicates that field is not set.</p>
0795 *
0796 * @param year of <code>XMLGregorianCalendar</code> to be created.
0797 * @param month of <code>XMLGregorianCalendar</code> to be created.
0798 * @param day of <code>XMLGregorianCalendar</code> to be created.
0799 * @param hour of <code>XMLGregorianCalendar</code> to be created.
0800 * @param minute of <code>XMLGregorianCalendar</code> to be created.
0801 * @param second of <code>XMLGregorianCalendar</code> to be created.
0802 * @param fractionalSecond of <code>XMLGregorianCalendar</code> to be created.
0803 * @param timezone of <code>XMLGregorianCalendar</code> to be created.
0804 *
0805 * @return <code>XMLGregorianCalendar</code> created from specified values.
0806 *
0807 * @throws IllegalArgumentException If any individual parameter's value is outside the maximum value constraint for the field
0808 * as determined by the Date/Time Data Mapping table in {@link XMLGregorianCalendar}
0809 * or if the composite values constitute an invalid <code>XMLGregorianCalendar</code> instance
0810 * as determined by {@link XMLGregorianCalendar#isValid()}.
0811 */
0812 public abstract XMLGregorianCalendar newXMLGregorianCalendar(
0813 final BigInteger year, final int month, final int day,
0814 final int hour, final int minute, final int second,
0815 final BigDecimal fractionalSecond, final int timezone);
0816
0817 /**
0818 * <p>Constructor of value spaces that a
0819 * <code>java.util.GregorianCalendar</code> instance would need to convert to an
0820 * <code>XMLGregorianCalendar</code> instance.</p>
0821 *
0822 * <p><code>XMLGregorianCalendar eon</code> and
0823 * <code>fractionalSecond</code> are set to <code>null</code></p>
0824 *
0825 * <p>A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.</p>
0826 *
0827 * @param year of <code>XMLGregorianCalendar</code> to be created.
0828 * @param month of <code>XMLGregorianCalendar</code> to be created.
0829 * @param day of <code>XMLGregorianCalendar</code> to be created.
0830 * @param hour of <code>XMLGregorianCalendar</code> to be created.
0831 * @param minute of <code>XMLGregorianCalendar</code> to be created.
0832 * @param second of <code>XMLGregorianCalendar</code> to be created.
0833 * @param millisecond of <code>XMLGregorianCalendar</code> to be created.
0834 * @param timezone of <code>XMLGregorianCalendar</code> to be created.
0835 *
0836 * @return <code>XMLGregorianCalendar</code> created from specified values.
0837 *
0838 * @throws IllegalArgumentException If any individual parameter's value is outside the maximum value constraint for the field
0839 * as determined by the Date/Time Data Mapping table in {@link XMLGregorianCalendar}
0840 * or if the composite values constitute an invalid <code>XMLGregorianCalendar</code> instance
0841 * as determined by {@link XMLGregorianCalendar#isValid()}.
0842 */
0843 public XMLGregorianCalendar newXMLGregorianCalendar(final int year,
0844 final int month, final int day, final int hour,
0845 final int minute, final int second, final int millisecond,
0846 final int timezone) {
0847
0848 // year may be undefined
0849 BigInteger realYear = (year != DatatypeConstants.FIELD_UNDEFINED) ? BigInteger
0850 .valueOf((long) year)
0851 : null;
0852
0853 // millisecond may be undefined
0854 // millisecond must be >= 0 millisecond <= 1000
0855 BigDecimal realMillisecond = null; // undefined value
0856 if (millisecond != DatatypeConstants.FIELD_UNDEFINED) {
0857 if (millisecond < 0 || millisecond > 1000) {
0858 throw new IllegalArgumentException(
0859 "javax.xml.datatype.DatatypeFactory#newXMLGregorianCalendar("
0860 + "int year, int month, int day, int hour, int minute, int second, int millisecond, int timezone)"
0861 + "with invalid millisecond: "
0862 + millisecond);
0863 }
0864
0865 realMillisecond = BigDecimal.valueOf((long) millisecond)
0866 .movePointLeft(3);
0867 }
0868
0869 return newXMLGregorianCalendar(realYear, month, day, hour,
0870 minute, second, realMillisecond, timezone);
0871 }
0872
0873 /**
0874 * <p>Create a Java representation of XML Schema builtin datatype <code>date</code> or <code>g*</code>.</p>
0875 *
0876 * <p>For example, an instance of <code>gYear</code> can be created invoking this factory
0877 * with <code>month</code> and <code>day</code> parameters set to
0878 * {@link DatatypeConstants#FIELD_UNDEFINED}.</p>
0879 *
0880 * <p>A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.</p>
0881 *
0882 * @param year of <code>XMLGregorianCalendar</code> to be created.
0883 * @param month of <code>XMLGregorianCalendar</code> to be created.
0884 * @param day of <code>XMLGregorianCalendar</code> to be created.
0885 * @param timezone offset in minutes. {@link DatatypeConstants#FIELD_UNDEFINED} indicates optional field is not set.
0886 *
0887 * @return <code>XMLGregorianCalendar</code> created from parameter values.
0888 *
0889 * @see DatatypeConstants#FIELD_UNDEFINED
0890 *
0891 * @throws IllegalArgumentException If any individual parameter's value is outside the maximum value constraint for the field
0892 * as determined by the Date/Time Data Mapping table in {@link XMLGregorianCalendar}
0893 * or if the composite values constitute an invalid <code>XMLGregorianCalendar</code> instance
0894 * as determined by {@link XMLGregorianCalendar#isValid()}.
0895 */
0896 public XMLGregorianCalendar newXMLGregorianCalendarDate(
0897 final int year, final int month, final int day,
0898 final int timezone) {
0899
0900 return newXMLGregorianCalendar(year, month, day,
0901 DatatypeConstants.FIELD_UNDEFINED, // hour
0902 DatatypeConstants.FIELD_UNDEFINED, // minute
0903 DatatypeConstants.FIELD_UNDEFINED, // second
0904 DatatypeConstants.FIELD_UNDEFINED, // millisecond
0905 timezone);
0906 }
0907
0908 /**
0909 * <p>Create a Java instance of XML Schema builtin datatype <code>time</code>.</p>
0910 *
0911 * <p>A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.</p>
0912 *
0913 * @param hours number of hours
0914 * @param minutes number of minutes
0915 * @param seconds number of seconds
0916 * @param timezone offset in minutes. {@link DatatypeConstants#FIELD_UNDEFINED} indicates optional field is not set.
0917 *
0918 * @return <code>XMLGregorianCalendar</code> created from parameter values.
0919 *
0920 * @throws IllegalArgumentException If any individual parameter's value is outside the maximum value constraint for the field
0921 * as determined by the Date/Time Data Mapping table in {@link XMLGregorianCalendar}
0922 * or if the composite values constitute an invalid <code>XMLGregorianCalendar</code> instance
0923 * as determined by {@link XMLGregorianCalendar#isValid()}.
0924 *
0925 * @see DatatypeConstants#FIELD_UNDEFINED
0926 */
0927 public XMLGregorianCalendar newXMLGregorianCalendarTime(
0928 final int hours, final int minutes, final int seconds,
0929 final int timezone) {
0930
0931 return newXMLGregorianCalendar(
0932 DatatypeConstants.FIELD_UNDEFINED, // Year
0933 DatatypeConstants.FIELD_UNDEFINED, // Month
0934 DatatypeConstants.FIELD_UNDEFINED, // Day
0935 hours, minutes, seconds,
0936 DatatypeConstants.FIELD_UNDEFINED, //Millisecond
0937 timezone);
0938 }
0939
0940 /**
0941 * <p>Create a Java instance of XML Schema builtin datatype time.</p>
0942 *
0943 * <p>A <code>null</code> value indicates that field is not set.</p>
0944 * <p>A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.</p>
0945 *
0946 * @param hours number of hours
0947 * @param minutes number of minutes
0948 * @param seconds number of seconds
0949 * @param fractionalSecond value of <code>null</code> indicates that this optional field is not set.
0950 * @param timezone offset in minutes. {@link DatatypeConstants#FIELD_UNDEFINED} indicates optional field is not set.
0951 *
0952 * @return <code>XMLGregorianCalendar</code> created from parameter values.
0953 *
0954 * @see DatatypeConstants#FIELD_UNDEFINED
0955 *
0956 * @throws IllegalArgumentException If any individual parameter's value is outside the maximum value constraint for the field
0957 * as determined by the Date/Time Data Mapping table in {@link XMLGregorianCalendar}
0958 * or if the composite values constitute an invalid <code>XMLGregorianCalendar</code> instance
0959 * as determined by {@link XMLGregorianCalendar#isValid()}.
0960 */
0961 public XMLGregorianCalendar newXMLGregorianCalendarTime(
0962 final int hours, final int minutes, final int seconds,
0963 final BigDecimal fractionalSecond, final int timezone) {
0964
0965 return newXMLGregorianCalendar(null, // year
0966 DatatypeConstants.FIELD_UNDEFINED, // month
0967 DatatypeConstants.FIELD_UNDEFINED, // day
0968 hours, minutes, seconds, fractionalSecond, timezone);
0969 }
0970
0971 /**
0972 * <p>Create a Java instance of XML Schema builtin datatype time.</p>
0973 *
0974 * <p>A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.</p>
0975 *
0976 * @param hours number of hours
0977 * @param minutes number of minutes
0978 * @param seconds number of seconds
0979 * @param milliseconds number of milliseconds
0980 * @param timezone offset in minutes. {@link DatatypeConstants#FIELD_UNDEFINED} indicates optional field is not set.
0981 *
0982 * @return <code>XMLGregorianCalendar</code> created from parameter values.
0983 *
0984 * @see DatatypeConstants#FIELD_UNDEFINED
0985 *
0986 * @throws IllegalArgumentException If any individual parameter's value is outside the maximum value constraint for the field
0987 * as determined by the Date/Time Data Mapping table in {@link XMLGregorianCalendar}
0988 * or if the composite values constitute an invalid <code>XMLGregorianCalendar</code> instance
0989 * as determined by {@link XMLGregorianCalendar#isValid()}.
0990 */
0991 public XMLGregorianCalendar newXMLGregorianCalendarTime(
0992 final int hours, final int minutes, final int seconds,
0993 final int milliseconds, final int timezone) {
0994
0995 // millisecond may be undefined
0996 // millisecond must be >= 0 millisecond <= 1000
0997 BigDecimal realMilliseconds = null; // undefined value
0998 if (milliseconds != DatatypeConstants.FIELD_UNDEFINED) {
0999 if (milliseconds < 0 || milliseconds > 1000) {
1000 throw new IllegalArgumentException(
1001 "javax.xml.datatype.DatatypeFactory#newXMLGregorianCalendarTime("
1002 + "int hours, int minutes, int seconds, int milliseconds, int timezone)"
1003 + "with invalid milliseconds: "
1004 + milliseconds);
1005 }
1006
1007 realMilliseconds = BigDecimal.valueOf((long) milliseconds)
1008 .movePointLeft(3);
1009 }
1010
1011 return newXMLGregorianCalendarTime(hours, minutes, seconds,
1012 realMilliseconds, timezone);
1013 }
1014 }
|