1 /* 2 * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package javax.xml.datatype; 27 28 import java.math.BigDecimal; 29 import java.math.BigInteger; 30 import java.util.GregorianCalendar; 31 import java.util.regex.Matcher; 32 import java.util.regex.Pattern; 33 34 /** 35 * <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> 36 * 37 * <p>A new instance of the <code>DatatypeFactory</code> is created through the {@link #newInstance()} method 38 * that uses the following implementation resolution mechanisms to determine an implementation:</p> 39 * <ol> 40 * <li> 41 * If the system property specified by {@link #DATATYPEFACTORY_PROPERTY}, "<code>javax.xml.datatype.DatatypeFactory</code>", 42 * exists, a class with the name of the property value is instantiated. 43 * Any Exception thrown during the instantiation process is wrapped as a {@link DatatypeConfigurationException}. 44 * </li> 45 * <li> 46 * If the file ${JAVA_HOME}/lib/jaxp.properties exists, it is loaded in a {@link java.util.Properties} <code>Object</code>. 47 * The <code>Properties</code> <code>Object </code> is then queried for the property as documented in the prior step 48 * and processed as documented in the prior step. 49 * </li> 50 * <li> 51 * Uses the service-provider loading facilities, defined by the {@link java.util.ServiceLoader} class, to attempt 52 * to locate and load an implementation of the service using the {@linkplain 53 * java.util.ServiceLoader#load(java.lang.Class) default loading mechanism}: 54 * the service-provider loading facility will use the {@linkplain 55 * java.lang.Thread#getContextClassLoader() current thread's context class loader} 56 * to attempt to load the service. If the context class 57 * loader is null, the {@linkplain 58 * ClassLoader#getSystemClassLoader() system class loader} will be used. 59 * <br> 60 * In case of {@link java.util.ServiceConfigurationError service 61 * configuration error} a {@link javax.xml.datatype.DatatypeConfigurationException} 62 * will be thrown. 63 * </li> 64 * <li> 65 * The final mechanism is to attempt to instantiate the <code>Class</code> specified by 66 * {@link #DATATYPEFACTORY_IMPLEMENTATION_CLASS}. 67 * Any Exception thrown during the instantiation process is wrapped as a {@link DatatypeConfigurationException}. 68 * </li> 69 * </ol> 70 * 71 * @author <a href="mailto:Joseph.Fialli@Sun.COM">Joseph Fialli</a> 72 * @author <a href="mailto:Jeff.Suttor@Sun.com">Jeff Suttor</a> 73 * @author <a href="mailto:Neeraj.Bajaj@sun.com">Neeraj Bajaj</a> 74 * 75 * @version $Revision: 1.13 $, $Date: 2010/03/11 23:10:53 $ 76 * @since 1.5 77 */ 78 public abstract class DatatypeFactory { 79 80 /** 81 * <p>Default property name as defined in JSR 206: Java(TM) API for XML Processing (JAXP) 1.3.</p> 82 * 83 * <p>Default value is <code>javax.xml.datatype.DatatypeFactory</code>.</p> 84 */ 85 public static final String DATATYPEFACTORY_PROPERTY = 86 // We use a String constant here, rather than calling 87 // DatatypeFactory.class.getName() - in order to make javadoc 88 // generate a See Also: Constant Field Value link. 89 "javax.xml.datatype.DatatypeFactory"; 90 91 /** 92 * <p>Default implementation class name as defined in 93 * <em>JSR 206: Java(TM) API for XML Processing (JAXP) 1.3</em>.</p> 94 * 95 * <p>Implementers should specify the name of an appropriate class 96 * to be instantiated if no other implementation resolution mechanism 97 * succeeds.</p> 98 * 99 * <p>Users should not refer to this field; it is intended only to 100 * document a factory implementation detail. 101 * </p> 102 */ 103 public static final String DATATYPEFACTORY_IMPLEMENTATION_CLASS = 104 // We use new String() here to prevent javadoc from generating 105 // a See Also: Constant Field Value link. 106 new String("com.sun.org.apache.xerces.internal.jaxp.datatype.DatatypeFactoryImpl"); 107 108 /** 109 * http://www.w3.org/TR/xpath-datamodel/#xdtschema defines two regexps 110 * to constrain the value space of dayTimeDuration ([^YM]*[DT].*) 111 * and yearMonthDuration ([^DT]*). Note that these expressions rely on 112 * the fact that the value must be an xs:Duration, they simply exclude 113 * some Durations. 114 */ 115 private static final Pattern XDTSCHEMA_YMD = 116 Pattern.compile("[^DT]*"); 117 118 private static final Pattern XDTSCHEMA_DTD = 119 Pattern.compile("[^YM]*[DT].*"); 120 121 /** 122 * <p>Protected constructor to prevent instaniation outside of package.</p> 123 * 124 * <p>Use {@link #newInstance()} to create a <code>DatatypeFactory</code>.</p> 125 */ 126 protected DatatypeFactory() { 127 } 128 129 /** 130 * <p>Obtain a new instance of a <code>DatatypeFactory</code>.</p> 131 * 132 * <p>The implementation resolution mechanisms are <a href="#DatatypeFactory.newInstance">defined</a> in this 133 * <code>Class</code>'s documentation.</p> 134 * 135 * @return New instance of a <code>DatatypeFactory</code> 136 * 137 * @throws DatatypeConfigurationException If the implementation is not 138 * available or cannot be instantiated. 139 * 140 * @see #newInstance(String factoryClassName, ClassLoader classLoader) 141 */ 142 public static DatatypeFactory newInstance() 143 throws DatatypeConfigurationException { 144 145 return FactoryFinder.find( 146 /* The default property name according to the JAXP spec */ 147 DatatypeFactory.class, 148 /* The fallback implementation class name */ 149 DATATYPEFACTORY_IMPLEMENTATION_CLASS); 150 } 151 152 /** 153 * <p>Obtain a new instance of a <code>DatatypeFactory</code> from class name. 154 * This function is useful when there are multiple providers in the classpath. 155 * It gives more control to the application as it can specify which provider 156 * should be loaded.</p> 157 * 158 * <p>Once an application has obtained a reference to a <code>DatatypeFactory</code> 159 * it can use the factory to configure and obtain datatype instances.</P> 160 * 161 * 162 * <h2>Tip for Trouble-shooting</h2> 163 * <p>Setting the <code>jaxp.debug</code> system property will cause 164 * this method to print a lot of debug messages 165 * to <code>System.err</code> about what it is doing and where it is looking at.</p> 166 * 167 * <p> If you have problems try:</p> 168 * <pre> 169 * java -Djaxp.debug=1 YourProgram .... 170 * </pre> 171 * 172 * @param factoryClassName fully qualified factory class name that provides implementation of <code>javax.xml.datatype.DatatypeFactory</code>. 173 * 174 * @param classLoader <code>ClassLoader</code> used to load the factory class. If <code>null</code> 175 * current <code>Thread</code>'s context classLoader is used to load the factory class. 176 * 177 * @return New instance of a <code>DatatypeFactory</code> 178 * 179 * @throws DatatypeConfigurationException if <code>factoryClassName</code> is <code>null</code>, or 180 * the factory class cannot be loaded, instantiated. 181 * 182 * @see #newInstance() 183 * 184 * @since 1.6 185 */ 186 public static DatatypeFactory newInstance(String factoryClassName, ClassLoader classLoader) 187 throws DatatypeConfigurationException { 188 return FactoryFinder.newInstance(DatatypeFactory.class, 189 factoryClassName, classLoader, false); 190 } 191 192 /** 193 * <p>Obtain a new instance of a <code>Duration</code> 194 * specifying the <code>Duration</code> as its string representation, "PnYnMnDTnHnMnS", 195 * as defined in XML Schema 1.0 section 3.2.6.1.</p> 196 * 197 * <p>XML Schema Part 2: Datatypes, 3.2.6 duration, defines <code>duration</code> as:</p> 198 * <blockquote> 199 * duration represents a duration of time. 200 * The value space of duration is a six-dimensional space where the coordinates designate the 201 * Gregorian year, month, day, hour, minute, and second components defined in Section 5.5.3.2 of [ISO 8601], respectively. 202 * These components are ordered in their significance by their order of appearance i.e. as 203 * year, month, day, hour, minute, and second. 204 * </blockquote> 205 * <p>All six values are set and available from the created {@link Duration}</p> 206 * 207 * <p>The XML Schema specification states that values can be of an arbitrary size. 208 * Implementations may chose not to or be incapable of supporting arbitrarily large and/or small values. 209 * An {@link UnsupportedOperationException} will be thrown with a message indicating implementation limits 210 * if implementation capacities are exceeded.</p> 211 * 212 * @param lexicalRepresentation <code>String</code> representation of a <code>Duration</code>. 213 * 214 * @return New <code>Duration</code> created from parsing the <code>lexicalRepresentation</code>. 215 * 216 * @throws IllegalArgumentException If <code>lexicalRepresentation</code> is not a valid representation of a <code>Duration</code>. 217 * @throws UnsupportedOperationException If implementation cannot support requested values. 218 * @throws NullPointerException if <code>lexicalRepresentation</code> is <code>null</code>. 219 */ 220 public abstract Duration newDuration(final String lexicalRepresentation); 221 222 /** 223 * <p>Obtain a new instance of a <code>Duration</code> 224 * specifying the <code>Duration</code> as milliseconds.</p> 225 * 226 * <p>XML Schema Part 2: Datatypes, 3.2.6 duration, defines <code>duration</code> as:</p> 227 * <blockquote> 228 * duration represents a duration of time. 229 * The value space of duration is a six-dimensional space where the coordinates designate the 230 * Gregorian year, month, day, hour, minute, and second components defined in Section 5.5.3.2 of [ISO 8601], respectively. 231 * These components are ordered in their significance by their order of appearance i.e. as 232 * year, month, day, hour, minute, and second. 233 * </blockquote> 234 * <p>All six values are set by computing their values from the specified milliseconds 235 * and are available using the <code>get</code> methods of the created {@link Duration}. 236 * The values conform to and are defined by:</p> 237 * <ul> 238 * <li>ISO 8601:2000(E) Section 5.5.3.2 Alternative format</li> 239 * <li><a href="http://www.w3.org/TR/xmlschema-2/#isoformats"> 240 * W3C XML Schema 1.0 Part 2, Appendix D, ISO 8601 Date and Time Formats</a> 241 * </li> 242 * <li>{@link XMLGregorianCalendar} Date/Time Datatype Field Mapping Between XML Schema 1.0 and Java Representation</li> 243 * </ul> 244 * 245 * <p>The default start instance is defined by {@link GregorianCalendar}'s use of the start of the epoch: i.e., 246 * {@link java.util.Calendar#YEAR} = 1970, 247 * {@link java.util.Calendar#MONTH} = {@link java.util.Calendar#JANUARY}, 248 * {@link java.util.Calendar#DATE} = 1, etc. 249 * This is important as there are variations in the Gregorian Calendar, 250 * e.g. leap years have different days in the month = {@link java.util.Calendar#FEBRUARY} 251 * so the result of {@link Duration#getMonths()} and {@link Duration#getDays()} can be influenced.</p> 252 * 253 * @param durationInMilliSeconds Duration in milliseconds to create. 254 * 255 * @return New <code>Duration</code> representing <code>durationInMilliSeconds</code>. 256 */ 257 public abstract Duration newDuration(final long durationInMilliSeconds); 258 259 /** 260 * <p>Obtain a new instance of a <code>Duration</code> 261 * specifying the <code>Duration</code> as isPositive, years, months, days, hours, minutes, seconds.</p> 262 * 263 * <p>The XML Schema specification states that values can be of an arbitrary size. 264 * Implementations may chose not to or be incapable of supporting arbitrarily large and/or small values. 265 * An {@link UnsupportedOperationException} will be thrown with a message indicating implementation limits 266 * if implementation capacities are exceeded.</p> 267 * 268 * <p>A <code>null</code> value indicates that field is not set.</p> 269 * 270 * @param isPositive Set to <code>false</code> to create a negative duration. When the length 271 * of the duration is zero, this parameter will be ignored. 272 * @param years of this <code>Duration</code> 273 * @param months of this <code>Duration</code> 274 * @param days of this <code>Duration</code> 275 * @param hours of this <code>Duration</code> 276 * @param minutes of this <code>Duration</code> 277 * @param seconds of this <code>Duration</code> 278 * 279 * @return New <code>Duration</code> created from the specified values. 280 * 281 * @throws IllegalArgumentException If the values are not a valid representation of a 282 * <code>Duration</code>: if all the fields (years, months, ...) are null or 283 * if any of the fields is negative. 284 * @throws UnsupportedOperationException If implementation cannot support requested values. 285 */ 286 public abstract Duration newDuration( 287 final boolean isPositive, 288 final BigInteger years, 289 final BigInteger months, 290 final BigInteger days, 291 final BigInteger hours, 292 final BigInteger minutes, 293 final BigDecimal seconds); 294 295 /** 296 * <p>Obtain a new instance of a <code>Duration</code> 297 * specifying the <code>Duration</code> as isPositive, years, months, days, hours, minutes, seconds.</p> 298 * 299 * <p>A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.</p> 300 * 301 * @param isPositive Set to <code>false</code> to create a negative duration. When the length 302 * of the duration is zero, this parameter will be ignored. 303 * @param years of this <code>Duration</code> 304 * @param months of this <code>Duration</code> 305 * @param days of this <code>Duration</code> 306 * @param hours of this <code>Duration</code> 307 * @param minutes of this <code>Duration</code> 308 * @param seconds of this <code>Duration</code> 309 * 310 * @return New <code>Duration</code> created from the specified values. 311 * 312 * @throws IllegalArgumentException If the values are not a valid representation of a 313 * <code>Duration</code>: if any of the fields is negative. 314 * 315 * @see #newDuration( 316 * boolean isPositive, 317 * BigInteger years, 318 * BigInteger months, 319 * BigInteger days, 320 * BigInteger hours, 321 * BigInteger minutes, 322 * BigDecimal seconds) 323 */ 324 public Duration newDuration( 325 final boolean isPositive, 326 final int years, 327 final int months, 328 final int days, 329 final int hours, 330 final int minutes, 331 final int seconds) { 332 333 // years may not be set 334 BigInteger realYears = (years != DatatypeConstants.FIELD_UNDEFINED) ? BigInteger.valueOf((long) years) : null; 335 336 // months may not be set 337 BigInteger realMonths = (months != DatatypeConstants.FIELD_UNDEFINED) ? BigInteger.valueOf((long) months) : null; 338 339 // days may not be set 340 BigInteger realDays = (days != DatatypeConstants.FIELD_UNDEFINED) ? BigInteger.valueOf((long) days) : null; 341 342 // hours may not be set 343 BigInteger realHours = (hours != DatatypeConstants.FIELD_UNDEFINED) ? BigInteger.valueOf((long) hours) : null; 344 345 // minutes may not be set 346 BigInteger realMinutes = (minutes != DatatypeConstants.FIELD_UNDEFINED) ? BigInteger.valueOf((long) minutes) : null; 347 348 // seconds may not be set 349 BigDecimal realSeconds = (seconds != DatatypeConstants.FIELD_UNDEFINED) ? BigDecimal.valueOf((long) seconds) : null; 350 351 return newDuration( 352 isPositive, 353 realYears, 354 realMonths, 355 realDays, 356 realHours, 357 realMinutes, 358 realSeconds 359 ); 360 } 361 362 /** 363 * <p>Create a <code>Duration</code> of type <code>xdt:dayTimeDuration</code> by parsing its <code>String</code> representation, 364 * "<em>PnDTnHnMnS</em>", <a href="http://www.w3.org/TR/xpath-datamodel#dayTimeDuration"> 365 * XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration</a>.</p> 366 * 367 * <p>The datatype <code>xdt:dayTimeDuration</code> is a subtype of <code>xs:duration</code> 368 * whose lexical representation contains only day, hour, minute, and second components. 369 * This datatype resides in the namespace <code>http://www.w3.org/2003/11/xpath-datatypes</code>.</p> 370 * 371 * <p>All four values are set and available from the created {@link Duration}</p> 372 * 373 * <p>The XML Schema specification states that values can be of an arbitrary size. 374 * Implementations may chose not to or be incapable of supporting arbitrarily large and/or small values. 375 * An {@link UnsupportedOperationException} will be thrown with a message indicating implementation limits 376 * if implementation capacities are exceeded.</p> 377 * 378 * @param lexicalRepresentation Lexical representation of a duration. 379 * 380 * @return New <code>Duration</code> created using the specified <code>lexicalRepresentation</code>. 381 * 382 * @throws IllegalArgumentException If <code>lexicalRepresentation</code> is not a valid representation of a <code>Duration</code> expressed only in terms of days and time. 383 * @throws UnsupportedOperationException If implementation cannot support requested values. 384 * @throws NullPointerException If <code>lexicalRepresentation</code> is <code>null</code>. 385 */ 386 public Duration newDurationDayTime(final String lexicalRepresentation) { 387 // lexicalRepresentation must be non-null 388 if (lexicalRepresentation == null) { 389 throw new NullPointerException( 390 "Trying to create an xdt:dayTimeDuration with an invalid" 391 + " lexical representation of \"null\""); 392 } 393 394 // test lexicalRepresentation against spec regex 395 Matcher matcher = XDTSCHEMA_DTD.matcher(lexicalRepresentation); 396 if (!matcher.matches()) { 397 throw new IllegalArgumentException( 398 "Trying to create an xdt:dayTimeDuration with an invalid" 399 + " lexical representation of \"" + lexicalRepresentation 400 + "\", data model requires years and months only."); 401 } 402 403 return newDuration(lexicalRepresentation); 404 } 405 406 /** 407 * <p>Create a <code>Duration</code> of type <code>xdt:dayTimeDuration</code> using the specified milliseconds as defined in 408 * <a href="http://www.w3.org/TR/xpath-datamodel#dayTimeDuration"> 409 * XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration</a>.</p> 410 * 411 * <p>The datatype <code>xdt:dayTimeDuration</code> is a subtype of <code>xs:duration</code> 412 * whose lexical representation contains only day, hour, minute, and second components. 413 * This datatype resides in the namespace <code>http://www.w3.org/2003/11/xpath-datatypes</code>.</p> 414 * 415 * <p>All four values are set by computing their values from the specified milliseconds 416 * and are available using the <code>get</code> methods of the created {@link Duration}. 417 * The values conform to and are defined by:</p> 418 * <ul> 419 * <li>ISO 8601:2000(E) Section 5.5.3.2 Alternative format</li> 420 * <li><a href="http://www.w3.org/TR/xmlschema-2/#isoformats"> 421 * W3C XML Schema 1.0 Part 2, Appendix D, ISO 8601 Date and Time Formats</a> 422 * </li> 423 * <li>{@link XMLGregorianCalendar} Date/Time Datatype Field Mapping Between XML Schema 1.0 and Java Representation</li> 424 * </ul> 425 * 426 * <p>The default start instance is defined by {@link GregorianCalendar}'s use of the start of the epoch: i.e., 427 * {@link java.util.Calendar#YEAR} = 1970, 428 * {@link java.util.Calendar#MONTH} = {@link java.util.Calendar#JANUARY}, 429 * {@link java.util.Calendar#DATE} = 1, etc. 430 * This is important as there are variations in the Gregorian Calendar, 431 * e.g. leap years have different days in the month = {@link java.util.Calendar#FEBRUARY} 432 * so the result of {@link Duration#getDays()} can be influenced.</p> 433 * 434 * <p>Any remaining milliseconds after determining the day, hour, minute and second are discarded.</p> 435 * 436 * @param durationInMilliseconds Milliseconds of <code>Duration</code> to create. 437 * 438 * @return New <code>Duration</code> created with the specified <code>durationInMilliseconds</code>. 439 * 440 * @see <a href="http://www.w3.org/TR/xpath-datamodel#dayTimeDuration"> 441 * XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration</a> 442 */ 443 public Duration newDurationDayTime(final long durationInMilliseconds) { 444 445 return newDuration(durationInMilliseconds); 446 } 447 448 /** 449 * <p>Create a <code>Duration</code> of type <code>xdt:dayTimeDuration</code> using the specified 450 * <code>day</code>, <code>hour</code>, <code>minute</code> and <code>second</code> as defined in 451 * <a href="http://www.w3.org/TR/xpath-datamodel#dayTimeDuration"> 452 * XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration</a>.</p> 453 * 454 * <p>The datatype <code>xdt:dayTimeDuration</code> is a subtype of <code>xs:duration</code> 455 * whose lexical representation contains only day, hour, minute, and second components. 456 * This datatype resides in the namespace <code>http://www.w3.org/2003/11/xpath-datatypes</code>.</p> 457 * 458 * <p>The XML Schema specification states that values can be of an arbitrary size. 459 * Implementations may chose not to or be incapable of supporting arbitrarily large and/or small values. 460 * An {@link UnsupportedOperationException} will be thrown with a message indicating implementation limits 461 * if implementation capacities are exceeded.</p> 462 * 463 * <p>A <code>null</code> value indicates that field is not set.</p> 464 * 465 * @param isPositive Set to <code>false</code> to create a negative duration. When the length 466 * of the duration is zero, this parameter will be ignored. 467 * @param day Day of <code>Duration</code>. 468 * @param hour Hour of <code>Duration</code>. 469 * @param minute Minute of <code>Duration</code>. 470 * @param second Second of <code>Duration</code>. 471 * 472 * @return New <code>Duration</code> created with the specified <code>day</code>, <code>hour</code>, <code>minute</code> 473 * and <code>second</code>. 474 * 475 * @throws IllegalArgumentException If the values are not a valid representation of a 476 * <code>Duration</code>: if all the fields (day, hour, ...) are null or 477 * if any of the fields is negative. 478 * @throws UnsupportedOperationException If implementation cannot support requested values. 479 */ 480 public Duration newDurationDayTime( 481 final boolean isPositive, 482 final BigInteger day, 483 final BigInteger hour, 484 final BigInteger minute, 485 final BigInteger second) { 486 487 return newDuration( 488 isPositive, 489 null, // years 490 null, // months 491 day, 492 hour, 493 minute, 494 (second != null)? new BigDecimal(second):null 495 ); 496 } 497 498 /** 499 * <p>Create a <code>Duration</code> of type <code>xdt:dayTimeDuration</code> using the specified 500 * <code>day</code>, <code>hour</code>, <code>minute</code> and <code>second</code> as defined in 501 * <a href="http://www.w3.org/TR/xpath-datamodel#dayTimeDuration"> 502 * XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration</a>.</p> 503 * 504 * <p>The datatype <code>xdt:dayTimeDuration</code> is a subtype of <code>xs:duration</code> 505 * whose lexical representation contains only day, hour, minute, and second components. 506 * This datatype resides in the namespace <code>http://www.w3.org/2003/11/xpath-datatypes</code>.</p> 507 * 508 * <p>A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.</p> 509 * 510 * @param isPositive Set to <code>false</code> to create a negative duration. When the length 511 * of the duration is zero, this parameter will be ignored. 512 * @param day Day of <code>Duration</code>. 513 * @param hour Hour of <code>Duration</code>. 514 * @param minute Minute of <code>Duration</code>. 515 * @param second Second of <code>Duration</code>. 516 * 517 * @return New <code>Duration</code> created with the specified <code>day</code>, <code>hour</code>, <code>minute</code> 518 * and <code>second</code>. 519 * 520 * @throws IllegalArgumentException If the values are not a valid representation of a 521 * <code>Duration</code>: if any of the fields (day, hour, ...) is negative. 522 */ 523 public Duration newDurationDayTime( 524 final boolean isPositive, 525 final int day, 526 final int hour, 527 final int minute, 528 final int second) { 529 530 return newDurationDayTime( 531 isPositive, 532 BigInteger.valueOf((long) day), 533 BigInteger.valueOf((long) hour), 534 BigInteger.valueOf((long) minute), 535 BigInteger.valueOf((long) second) 536 ); 537 } 538 539 /** 540 * <p>Create a <code>Duration</code> of type <code>xdt:yearMonthDuration</code> by parsing its <code>String</code> representation, 541 * "<em>PnYnM</em>", <a href="http://www.w3.org/TR/xpath-datamodel#yearMonthDuration"> 542 * XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration</a>.</p> 543 * 544 * <p>The datatype <code>xdt:yearMonthDuration</code> is a subtype of <code>xs:duration</code> 545 * whose lexical representation contains only year and month components. 546 * This datatype resides in the namespace {@link javax.xml.XMLConstants#W3C_XPATH_DATATYPE_NS_URI}.</p> 547 * 548 * <p>Both values are set and available from the created {@link Duration}</p> 549 * 550 * <p>The XML Schema specification states that values can be of an arbitrary size. 551 * Implementations may chose not to or be incapable of supporting arbitrarily large and/or small values. 552 * An {@link UnsupportedOperationException} will be thrown with a message indicating implementation limits 553 * if implementation capacities are exceeded.</p> 554 * 555 * @param lexicalRepresentation Lexical representation of a duration. 556 * 557 * @return New <code>Duration</code> created using the specified <code>lexicalRepresentation</code>. 558 * 559 * @throws IllegalArgumentException If <code>lexicalRepresentation</code> is not a valid representation of a <code>Duration</code> expressed only in terms of years and months. 560 * @throws UnsupportedOperationException If implementation cannot support requested values. 561 * @throws NullPointerException If <code>lexicalRepresentation</code> is <code>null</code>. 562 */ 563 public Duration newDurationYearMonth( 564 final String lexicalRepresentation) { 565 566 // lexicalRepresentation must be non-null 567 if (lexicalRepresentation == null) { 568 throw new NullPointerException( 569 "Trying to create an xdt:yearMonthDuration with an invalid" 570 + " lexical representation of \"null\""); 571 } 572 573 // test lexicalRepresentation against spec regex 574 Matcher matcher = XDTSCHEMA_YMD.matcher(lexicalRepresentation); 575 if (!matcher.matches()) { 576 throw new IllegalArgumentException( 577 "Trying to create an xdt:yearMonthDuration with an invalid" 578 + " lexical representation of \"" + lexicalRepresentation 579 + "\", data model requires days and times only."); 580 } 581 582 return newDuration(lexicalRepresentation); 583 } 584 585 /** 586 * <p>Create a <code>Duration</code> of type <code>xdt:yearMonthDuration</code> using the specified milliseconds as defined in 587 * <a href="http://www.w3.org/TR/xpath-datamodel#yearMonthDuration"> 588 * XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration</a>.</p> 589 * 590 * <p>The datatype <code>xdt:yearMonthDuration</code> is a subtype of <code>xs:duration</code> 591 * whose lexical representation contains only year and month components. 592 * This datatype resides in the namespace {@link javax.xml.XMLConstants#W3C_XPATH_DATATYPE_NS_URI}.</p> 593 * 594 * <p>Both values are set by computing their values from the specified milliseconds 595 * and are available using the <code>get</code> methods of the created {@link Duration}. 596 * The values conform to and are defined by:</p> 597 * <ul> 598 * <li>ISO 8601:2000(E) Section 5.5.3.2 Alternative format</li> 599 * <li><a href="http://www.w3.org/TR/xmlschema-2/#isoformats"> 600 * W3C XML Schema 1.0 Part 2, Appendix D, ISO 8601 Date and Time Formats</a> 601 * </li> 602 * <li>{@link XMLGregorianCalendar} Date/Time Datatype Field Mapping Between XML Schema 1.0 and Java Representation</li> 603 * </ul> 604 * 605 * <p>The default start instance is defined by {@link GregorianCalendar}'s use of the start of the epoch: i.e., 606 * {@link java.util.Calendar#YEAR} = 1970, 607 * {@link java.util.Calendar#MONTH} = {@link java.util.Calendar#JANUARY}, 608 * {@link java.util.Calendar#DATE} = 1, etc. 609 * This is important as there are variations in the Gregorian Calendar, 610 * e.g. leap years have different days in the month = {@link java.util.Calendar#FEBRUARY} 611 * so the result of {@link Duration#getMonths()} can be influenced.</p> 612 * 613 * <p>Any remaining milliseconds after determining the year and month are discarded.</p> 614 * 615 * @param durationInMilliseconds Milliseconds of <code>Duration</code> to create. 616 * 617 * @return New <code>Duration</code> created using the specified <code>durationInMilliseconds</code>. 618 */ 619 public Duration newDurationYearMonth( 620 final long durationInMilliseconds) { 621 622 // create a Duration that only has sign, year & month 623 // Duration is immutable, so need to create a new Duration 624 // implementations may override this method in a more efficient way 625 Duration fullDuration = newDuration(durationInMilliseconds); 626 boolean isPositive = (fullDuration.getSign() == -1) ? false : true; 627 BigInteger years = 628 (BigInteger) fullDuration.getField(DatatypeConstants.YEARS); 629 if (years == null) { years = BigInteger.ZERO; } 630 BigInteger months = 631 (BigInteger) fullDuration.getField(DatatypeConstants.MONTHS); 632 if (months == null) { months = BigInteger.ZERO; } 633 634 return newDurationYearMonth(isPositive, years, months); 635 } 636 637 /** 638 * <p>Create a <code>Duration</code> of type <code>xdt:yearMonthDuration</code> using the specified 639 * <code>year</code> and <code>month</code> as defined in 640 * <a href="http://www.w3.org/TR/xpath-datamodel#yearMonthDuration"> 641 * XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration</a>.</p> 642 * 643 * <p>The XML Schema specification states that values can be of an arbitrary size. 644 * Implementations may chose not to or be incapable of supporting arbitrarily large and/or small values. 645 * An {@link UnsupportedOperationException} will be thrown with a message indicating implementation limits 646 * if implementation capacities are exceeded.</p> 647 * 648 * <p>A <code>null</code> value indicates that field is not set.</p> 649 * 650 * @param isPositive Set to <code>false</code> to create a negative duration. When the length 651 * of the duration is zero, this parameter will be ignored. 652 * @param year Year of <code>Duration</code>. 653 * @param month Month of <code>Duration</code>. 654 * 655 * @return New <code>Duration</code> created using the specified <code>year</code> and <code>month</code>. 656 * 657 * @throws IllegalArgumentException If the values are not a valid representation of a 658 * <code>Duration</code>: if all of the fields (year, month) are null or 659 * if any of the fields is negative. 660 * @throws UnsupportedOperationException If implementation cannot support requested values. 661 */ 662 public Duration newDurationYearMonth( 663 final boolean isPositive, 664 final BigInteger year, 665 final BigInteger month) { 666 667 return newDuration( 668 isPositive, 669 year, 670 month, 671 null, // days 672 null, // hours 673 null, // minutes 674 null // seconds 675 ); 676 } 677 678 /** 679 * <p>Create a <code>Duration</code> of type <code>xdt:yearMonthDuration</code> using the specified 680 * <code>year</code> and <code>month</code> as defined in 681 * <a href="http://www.w3.org/TR/xpath-datamodel#yearMonthDuration"> 682 * XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration</a>.</p> 683 * 684 * <p>A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.</p> 685 * 686 * @param isPositive Set to <code>false</code> to create a negative duration. When the length 687 * of the duration is zero, this parameter will be ignored. 688 * @param year Year of <code>Duration</code>. 689 * @param month Month of <code>Duration</code>. 690 * 691 * @return New <code>Duration</code> created using the specified <code>year</code> and <code>month</code>. 692 * 693 * @throws IllegalArgumentException If the values are not a valid representation of a 694 * <code>Duration</code>: if any of the fields (year, month) is negative. 695 */ 696 public Duration newDurationYearMonth( 697 final boolean isPositive, 698 final int year, 699 final int month) { 700 701 return newDurationYearMonth( 702 isPositive, 703 BigInteger.valueOf((long) year), 704 BigInteger.valueOf((long) month)); 705 } 706 707 /** 708 * <p>Create a new instance of an <code>XMLGregorianCalendar</code>.</p> 709 * 710 * <p>All date/time datatype fields set to {@link DatatypeConstants#FIELD_UNDEFINED} or null.</p> 711 * 712 * @return New <code>XMLGregorianCalendar</code> with all date/time datatype fields set to 713 * {@link DatatypeConstants#FIELD_UNDEFINED} or null. 714 */ 715 public abstract XMLGregorianCalendar newXMLGregorianCalendar(); 716 717 /** 718 * <p>Create a new XMLGregorianCalendar by parsing the String as a lexical representation.</p> 719 * 720 * <p>Parsing the lexical string representation is defined in 721 * <a href="http://www.w3.org/TR/xmlschema-2/#dateTime-order">XML Schema 1.0 Part 2, Section 3.2.[7-14].1, 722 * <em>Lexical Representation</em>.</a></p> 723 * 724 * <p>The string representation may not have any leading and trailing whitespaces.</p> 725 * 726 * <p>The parsing is done field by field so that 727 * the following holds for any lexically correct String x:</p> 728 * <pre> 729 * newXMLGregorianCalendar(x).toXMLFormat().equals(x) 730 * </pre> 731 * <p>Except for the noted lexical/canonical representation mismatches 732 * listed in <a href="http://www.w3.org/2001/05/xmlschema-errata#e2-45"> 733 * XML Schema 1.0 errata, Section 3.2.7.2</a>.</p> 734 * 735 * @param lexicalRepresentation Lexical representation of one the eight XML Schema date/time datatypes. 736 * 737 * @return <code>XMLGregorianCalendar</code> created from the <code>lexicalRepresentation</code>. 738 * 739 * @throws IllegalArgumentException If the <code>lexicalRepresentation</code> is not a valid <code>XMLGregorianCalendar</code>. 740 * @throws NullPointerException If <code>lexicalRepresentation</code> is <code>null</code>. 741 */ 742 public abstract XMLGregorianCalendar newXMLGregorianCalendar(final String lexicalRepresentation); 743 744 /** 745 * <p>Create an <code>XMLGregorianCalendar</code> from a {@link GregorianCalendar}.</p> 746 * 747 * <table border="2" rules="all" cellpadding="2"> 748 * <thead> 749 * <tr> 750 * <th align="center" colspan="2"> 751 * Field by Field Conversion from 752 * {@link GregorianCalendar} to an {@link XMLGregorianCalendar} 753 * </th> 754 * </tr> 755 * <tr> 756 * <th><code>java.util.GregorianCalendar</code> field</th> 757 * <th><code>javax.xml.datatype.XMLGregorianCalendar</code> field</th> 758 * </tr> 759 * </thead> 760 * <tbody> 761 * <tr> 762 * <td><code>ERA == GregorianCalendar.BC ? -YEAR : YEAR</code></td> 763 * <td>{@link XMLGregorianCalendar#setYear(int year)}</td> 764 * </tr> 765 * <tr> 766 * <td><code>MONTH + 1</code></td> 767 * <td>{@link XMLGregorianCalendar#setMonth(int month)}</td> 768 * </tr> 769 * <tr> 770 * <td><code>DAY_OF_MONTH</code></td> 771 * <td>{@link XMLGregorianCalendar#setDay(int day)}</td> 772 * </tr> 773 * <tr> 774 * <td><code>HOUR_OF_DAY, MINUTE, SECOND, MILLISECOND</code></td> 775 * <td>{@link XMLGregorianCalendar#setTime(int hour, int minute, int second, BigDecimal fractional)}</td> 776 * </tr> 777 * <tr> 778 * <td> 779 * <code>(ZONE_OFFSET + DST_OFFSET) / (60*1000)</code><br/> 780 * <em>(in minutes)</em> 781 * </td> 782 * <td>{@link XMLGregorianCalendar#setTimezone(int offset)}<sup><em>*</em></sup> 783 * </td> 784 * </tr> 785 * </tbody> 786 * </table> 787 * <p><em>*</em>conversion loss of information. It is not possible to represent 788 * a <code>java.util.GregorianCalendar</code> daylight savings timezone id in the 789 * XML Schema 1.0 date/time datatype representation.</p> 790 * 791 * <p>To compute the return value's <code>TimeZone</code> field, 792 * <ul> 793 * <li>when <code>this.getTimezone() != FIELD_UNDEFINED</code>, 794 * create a <code>java.util.TimeZone</code> with a custom timezone id 795 * using the <code>this.getTimezone()</code>.</li> 796 * <li>else use the <code>GregorianCalendar</code> default timezone value 797 * for the host is defined as specified by 798 * <code>java.util.TimeZone.getDefault()</code>.</li></p> 799 * 800 * @param cal <code>java.util.GregorianCalendar</code> used to create <code>XMLGregorianCalendar</code> 801 * 802 * @return <code>XMLGregorianCalendar</code> created from <code>java.util.GregorianCalendar</code> 803 * 804 * @throws NullPointerException If <code>cal</code> is <code>null</code>. 805 */ 806 public abstract XMLGregorianCalendar newXMLGregorianCalendar(final GregorianCalendar cal); 807 808 /** 809 * <p>Constructor allowing for complete value spaces allowed by 810 * W3C XML Schema 1.0 recommendation for xsd:dateTime and related 811 * builtin datatypes. Note that <code>year</code> parameter supports 812 * arbitrarily large numbers and fractionalSecond has infinite 813 * precision.</p> 814 * 815 * <p>A <code>null</code> value indicates that field is not set.</p> 816 * 817 * @param year of <code>XMLGregorianCalendar</code> to be created. 818 * @param month of <code>XMLGregorianCalendar</code> to be created. 819 * @param day of <code>XMLGregorianCalendar</code> to be created. 820 * @param hour of <code>XMLGregorianCalendar</code> to be created. 821 * @param minute of <code>XMLGregorianCalendar</code> to be created. 822 * @param second of <code>XMLGregorianCalendar</code> to be created. 823 * @param fractionalSecond of <code>XMLGregorianCalendar</code> to be created. 824 * @param timezone of <code>XMLGregorianCalendar</code> to be created. 825 * 826 * @return <code>XMLGregorianCalendar</code> created from specified values. 827 * 828 * @throws IllegalArgumentException If any individual parameter's value is outside the maximum value constraint for the field 829 * as determined by the Date/Time Data Mapping table in {@link XMLGregorianCalendar} 830 * or if the composite values constitute an invalid <code>XMLGregorianCalendar</code> instance 831 * as determined by {@link XMLGregorianCalendar#isValid()}. 832 */ 833 public abstract XMLGregorianCalendar newXMLGregorianCalendar( 834 final BigInteger year, 835 final int month, 836 final int day, 837 final int hour, 838 final int minute, 839 final int second, 840 final BigDecimal fractionalSecond, 841 final int timezone); 842 843 /** 844 * <p>Constructor of value spaces that a 845 * <code>java.util.GregorianCalendar</code> instance would need to convert to an 846 * <code>XMLGregorianCalendar</code> instance.</p> 847 * 848 * <p><code>XMLGregorianCalendar eon</code> and 849 * <code>fractionalSecond</code> are set to <code>null</code></p> 850 * 851 * <p>A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.</p> 852 * 853 * @param year of <code>XMLGregorianCalendar</code> to be created. 854 * @param month of <code>XMLGregorianCalendar</code> to be created. 855 * @param day of <code>XMLGregorianCalendar</code> to be created. 856 * @param hour of <code>XMLGregorianCalendar</code> to be created. 857 * @param minute of <code>XMLGregorianCalendar</code> to be created. 858 * @param second of <code>XMLGregorianCalendar</code> to be created. 859 * @param millisecond of <code>XMLGregorianCalendar</code> to be created. 860 * @param timezone of <code>XMLGregorianCalendar</code> to be created. 861 * 862 * @return <code>XMLGregorianCalendar</code> created from specified values. 863 * 864 * @throws IllegalArgumentException If any individual parameter's value is outside the maximum value constraint for the field 865 * as determined by the Date/Time Data Mapping table in {@link XMLGregorianCalendar} 866 * or if the composite values constitute an invalid <code>XMLGregorianCalendar</code> instance 867 * as determined by {@link XMLGregorianCalendar#isValid()}. 868 */ 869 public XMLGregorianCalendar newXMLGregorianCalendar( 870 final int year, 871 final int month, 872 final int day, 873 final int hour, 874 final int minute, 875 final int second, 876 final int millisecond, 877 final int timezone) { 878 879 // year may be undefined 880 BigInteger realYear = (year != DatatypeConstants.FIELD_UNDEFINED) ? BigInteger.valueOf((long) year) : null; 881 882 // millisecond may be undefined 883 // millisecond must be >= 0 millisecond <= 1000 884 BigDecimal realMillisecond = null; // undefined value 885 if (millisecond != DatatypeConstants.FIELD_UNDEFINED) { 886 if (millisecond < 0 || millisecond > 1000) { 887 throw new IllegalArgumentException( 888 "javax.xml.datatype.DatatypeFactory#newXMLGregorianCalendar(" 889 + "int year, int month, int day, int hour, int minute, int second, int millisecond, int timezone)" 890 + "with invalid millisecond: " + millisecond 891 ); 892 } 893 894 realMillisecond = BigDecimal.valueOf((long) millisecond).movePointLeft(3); 895 } 896 897 return newXMLGregorianCalendar( 898 realYear, 899 month, 900 day, 901 hour, 902 minute, 903 second, 904 realMillisecond, 905 timezone 906 ); 907 } 908 909 /** 910 * <p>Create a Java representation of XML Schema builtin datatype <code>date</code> or <code>g*</code>.</p> 911 * 912 * <p>For example, an instance of <code>gYear</code> can be created invoking this factory 913 * with <code>month</code> and <code>day</code> parameters set to 914 * {@link DatatypeConstants#FIELD_UNDEFINED}.</p> 915 * 916 * <p>A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.</p> 917 * 918 * @param year of <code>XMLGregorianCalendar</code> to be created. 919 * @param month of <code>XMLGregorianCalendar</code> to be created. 920 * @param day of <code>XMLGregorianCalendar</code> to be created. 921 * @param timezone offset in minutes. {@link DatatypeConstants#FIELD_UNDEFINED} indicates optional field is not set. 922 * 923 * @return <code>XMLGregorianCalendar</code> created from parameter values. 924 * 925 * @see DatatypeConstants#FIELD_UNDEFINED 926 * 927 * @throws IllegalArgumentException If any individual parameter's value is outside the maximum value constraint for the field 928 * as determined by the Date/Time Data Mapping table in {@link XMLGregorianCalendar} 929 * or if the composite values constitute an invalid <code>XMLGregorianCalendar</code> instance 930 * as determined by {@link XMLGregorianCalendar#isValid()}. 931 */ 932 public XMLGregorianCalendar newXMLGregorianCalendarDate( 933 final int year, 934 final int month, 935 final int day, 936 final int timezone) { 937 938 return newXMLGregorianCalendar( 939 year, 940 month, 941 day, 942 DatatypeConstants.FIELD_UNDEFINED, // hour 943 DatatypeConstants.FIELD_UNDEFINED, // minute 944 DatatypeConstants.FIELD_UNDEFINED, // second 945 DatatypeConstants.FIELD_UNDEFINED, // millisecond 946 timezone); 947 } 948 949 /** 950 * <p>Create a Java instance of XML Schema builtin datatype <code>time</code>.</p> 951 * 952 * <p>A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.</p> 953 * 954 * @param hours number of hours 955 * @param minutes number of minutes 956 * @param seconds number of seconds 957 * @param timezone offset in minutes. {@link DatatypeConstants#FIELD_UNDEFINED} indicates optional field is not set. 958 * 959 * @return <code>XMLGregorianCalendar</code> created from parameter values. 960 * 961 * @throws IllegalArgumentException If any individual parameter's value is outside the maximum value constraint for the field 962 * as determined by the Date/Time Data Mapping table in {@link XMLGregorianCalendar} 963 * or if the composite values constitute an invalid <code>XMLGregorianCalendar</code> instance 964 * as determined by {@link XMLGregorianCalendar#isValid()}. 965 * 966 * @see DatatypeConstants#FIELD_UNDEFINED 967 */ 968 public XMLGregorianCalendar newXMLGregorianCalendarTime( 969 final int hours, 970 final int minutes, 971 final int seconds, 972 final int timezone) { 973 974 return newXMLGregorianCalendar( 975 DatatypeConstants.FIELD_UNDEFINED, // Year 976 DatatypeConstants.FIELD_UNDEFINED, // Month 977 DatatypeConstants.FIELD_UNDEFINED, // Day 978 hours, 979 minutes, 980 seconds, 981 DatatypeConstants.FIELD_UNDEFINED, //Millisecond 982 timezone); 983 } 984 985 /** 986 * <p>Create a Java instance of XML Schema builtin datatype time.</p> 987 * 988 * <p>A <code>null</code> value indicates that field is not set.</p> 989 * <p>A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.</p> 990 * 991 * @param hours number of hours 992 * @param minutes number of minutes 993 * @param seconds number of seconds 994 * @param fractionalSecond value of <code>null</code> indicates that this optional field is not set. 995 * @param timezone offset in minutes. {@link DatatypeConstants#FIELD_UNDEFINED} indicates optional field is not set. 996 * 997 * @return <code>XMLGregorianCalendar</code> created from parameter values. 998 * 999 * @see DatatypeConstants#FIELD_UNDEFINED 1000 * 1001 * @throws IllegalArgumentException If any individual parameter's value is outside the maximum value constraint for the field 1002 * as determined by the Date/Time Data Mapping table in {@link XMLGregorianCalendar} 1003 * or if the composite values constitute an invalid <code>XMLGregorianCalendar</code> instance 1004 * as determined by {@link XMLGregorianCalendar#isValid()}. 1005 */ 1006 public XMLGregorianCalendar newXMLGregorianCalendarTime( 1007 final int hours, 1008 final int minutes, 1009 final int seconds, 1010 final BigDecimal fractionalSecond, 1011 final int timezone) { 1012 1013 return newXMLGregorianCalendar( 1014 null, // year 1015 DatatypeConstants.FIELD_UNDEFINED, // month 1016 DatatypeConstants.FIELD_UNDEFINED, // day 1017 hours, 1018 minutes, 1019 seconds, 1020 fractionalSecond, 1021 timezone); 1022 } 1023 1024 /** 1025 * <p>Create a Java instance of XML Schema builtin datatype time.</p> 1026 * 1027 * <p>A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.</p> 1028 * 1029 * @param hours number of hours 1030 * @param minutes number of minutes 1031 * @param seconds number of seconds 1032 * @param milliseconds number of milliseconds 1033 * @param timezone offset in minutes. {@link DatatypeConstants#FIELD_UNDEFINED} indicates optional field is not set. 1034 * 1035 * @return <code>XMLGregorianCalendar</code> created from parameter values. 1036 * 1037 * @see DatatypeConstants#FIELD_UNDEFINED 1038 * 1039 * @throws IllegalArgumentException If any individual parameter's value is outside the maximum value constraint for the field 1040 * as determined by the Date/Time Data Mapping table in {@link XMLGregorianCalendar} 1041 * or if the composite values constitute an invalid <code>XMLGregorianCalendar</code> instance 1042 * as determined by {@link XMLGregorianCalendar#isValid()}. 1043 */ 1044 public XMLGregorianCalendar newXMLGregorianCalendarTime( 1045 final int hours, 1046 final int minutes, 1047 final int seconds, 1048 final int milliseconds, 1049 final int timezone) { 1050 1051 // millisecond may be undefined 1052 // millisecond must be >= 0 millisecond <= 1000 1053 BigDecimal realMilliseconds = null; // undefined value 1054 if (milliseconds != DatatypeConstants.FIELD_UNDEFINED) { 1055 if (milliseconds < 0 || milliseconds > 1000) { 1056 throw new IllegalArgumentException( 1057 "javax.xml.datatype.DatatypeFactory#newXMLGregorianCalendarTime(" 1058 + "int hours, int minutes, int seconds, int milliseconds, int timezone)" 1059 + "with invalid milliseconds: " + milliseconds 1060 ); 1061 } 1062 1063 realMilliseconds = BigDecimal.valueOf((long) milliseconds).movePointLeft(3); 1064 } 1065 1066 return newXMLGregorianCalendarTime( 1067 hours, 1068 minutes, 1069 seconds, 1070 realMilliseconds, 1071 timezone 1072 ); 1073 } 1074 }