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