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