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