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