001    /* DatatypeFactory.java --
002       Copyright (C) 2004, 2005, 2006  Free Software Foundation, Inc.
003    
004    This file is part of GNU Classpath.
005    
006    GNU Classpath is free software; you can redistribute it and/or modify
007    it under the terms of the GNU General Public License as published by
008    the Free Software Foundation; either version 2, or (at your option)
009    any later version.
010    
011    GNU Classpath is distributed in the hope that it will be useful, but
012    WITHOUT ANY WARRANTY; without even the implied warranty of
013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014    General Public License for more details.
015    
016    You should have received a copy of the GNU General Public License
017    along with GNU Classpath; see the file COPYING.  If not, write to the
018    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
019    02110-1301 USA.
020    
021    Linking this library statically or dynamically with other modules is
022    making a combined work based on this library.  Thus, the terms and
023    conditions of the GNU General Public License cover the whole
024    combination.
025    
026    As a special exception, the copyright holders of this library give you
027    permission to link this library with independent modules to produce an
028    executable, regardless of the license terms of these independent
029    modules, and to copy and distribute the resulting executable under
030    terms of your choice, provided that you also meet, for each linked
031    independent module, the terms and conditions of the license of that
032    module.  An independent module is a module which is not derived from
033    or based on this library.  If you modify this library, you may extend
034    this exception to your version of the library, but you are not
035    obligated to do so.  If you do not wish to do so, delete this
036    exception statement from your version. */
037    
038    package javax.xml.datatype;
039    
040    import java.io.File;
041    import java.io.FileInputStream;
042    import java.math.BigDecimal;
043    import java.math.BigInteger;
044    import java.util.GregorianCalendar;
045    import java.util.Iterator;
046    import java.util.Properties;
047    import java.util.ServiceLoader;
048    
049    /**
050     * Factory class to create new datatype objects mapping XML to and from Java
051     * objects.
052     *
053     * @author Chris Burdess
054     * @since 1.5
055     */
056    public abstract class DatatypeFactory
057    {
058    
059      /**
060       * JAXP 1.3 default property name.
061       */
062      public static final String DATATYPEFACTORY_PROPERTY = "javax.xml.datatype.DatatypeFactory";
063    
064      /**
065       * JAXP 1.3 default implementation class name.
066       */
067      public static final String DATATYPEFACTORY_IMPLEMENTATION_CLASS = "gnu.xml.datatype.JAXPDatatypeFactory";
068    
069      protected DatatypeFactory()
070      {
071      }
072    
073      /**
074       * Returns a new factory instance.
075       */
076      public static DatatypeFactory newInstance()
077        throws DatatypeConfigurationException
078      {
079        try
080          {
081            // 1. system property
082            String className = System.getProperty(DATATYPEFACTORY_PROPERTY);
083            if (className != null)
084              return (DatatypeFactory) Class.forName(className).newInstance();
085            // 2. jaxp.properties property
086            File javaHome = new File(System.getProperty("java.home"));
087            File javaHomeLib = new File(javaHome, "lib");
088            File jaxpProperties = new File(javaHomeLib, "jaxp.properties");
089            if (jaxpProperties.exists())
090              {
091                FileInputStream in = new FileInputStream(jaxpProperties);
092                Properties p = new Properties();
093                p.load(in);
094                in.close();
095                className = p.getProperty(DATATYPEFACTORY_PROPERTY);
096                if (className != null)
097                  return (DatatypeFactory) Class.forName(className).newInstance();
098              }
099            // 3. services
100            Iterator<DatatypeFactory> i = ServiceLoader.load(DatatypeFactory.class).iterator();
101            if (i.hasNext())
102              return i.next();
103            // 4. fallback
104            Class<?> t = Class.forName(DATATYPEFACTORY_IMPLEMENTATION_CLASS);
105            return (DatatypeFactory) t.newInstance();
106          }
107        catch (Exception e)
108          {
109            throw new DatatypeConfigurationException(e);
110          }
111      }
112    
113      /**
114       * Returns a new duration from its string representation.
115       * @param lexicalRepresentation the lexical representation of the
116       * duration, as specified in XML Schema 1.0 section 3.2.6.1.
117       */
118      public abstract Duration newDuration(String lexicalRepresentation);
119    
120      /**
121       * Returns a new duration.
122       * @param durationInMilliSeconds the duration in milliseconds
123       */
124      public abstract Duration newDuration(long durationInMilliSeconds);
125    
126      /**
127       * Returns a new duration by specifying the individual components.
128       * @param isPositive whether the duration is positive
129       * @param years the number of years
130       * @param months the number of months
131       * @param days the number of days
132       * @param hours the number of hours
133       * @param minutes th number of minutes
134       * @param seconds the number of seconds
135       */
136      public abstract Duration newDuration(boolean isPositive,
137                                           BigInteger years,
138                                           BigInteger months,
139                                           BigInteger days,
140                                           BigInteger hours,
141                                           BigInteger minutes,
142                                           BigDecimal seconds);
143    
144      /**
145       * Returns a new duration by specifying the individual components.
146       * @param isPositive whether the duration is positive
147       * @param years the number of years
148       * @param months the number of months
149       * @param days the number of days
150       * @param hours the number of hours
151       * @param minutes th number of minutes
152       * @param seconds the number of seconds
153       */
154      public Duration newDuration(boolean isPositive,
155                                  int years,
156                                  int months,
157                                  int days,
158                                  int hours,
159                                  int minutes,
160                                  int seconds)
161      {
162        return newDuration(isPositive,
163                           BigInteger.valueOf((long) years),
164                           BigInteger.valueOf((long) months),
165                           BigInteger.valueOf((long) days),
166                           BigInteger.valueOf((long) hours),
167                           BigInteger.valueOf((long) minutes),
168                           BigDecimal.valueOf((long) seconds));
169      }
170    
171      /**
172       * Returns a new dayTimeDuration from its string representation.
173       * @param lexicalRepresentation the lexical representation of the
174       * duration, as specified in XML Schema 1.0 section 3.2.6.1.
175       */
176      public Duration newDurationDayTime(String lexicalRepresentation)
177      {
178        return newDuration(lexicalRepresentation);
179      }
180    
181      /**
182       * Returns a new dayTimeDuration.
183       * @param durationInMilliseconds the duration in milliseconds
184       */
185      public Duration newDurationDayTime(long durationInMilliseconds)
186      {
187        // TODO xmlSchemaType
188        return newDuration(durationInMilliseconds);
189      }
190    
191      /**
192       * Returns a new dayTimeDuration by specifying the individual components.
193       * @param isPositive whether the duration is positive
194       * @param days the number of days
195       * @param hours the number of hours
196       * @param minutes th number of minutes
197       * @param seconds the number of seconds
198       */
199      public Duration newDurationDayTime(boolean isPositive,
200                                         BigInteger days,
201                                         BigInteger hours,
202                                         BigInteger minutes,
203                                         BigInteger seconds)
204      {
205        return newDuration(isPositive,
206                           null,
207                           null,
208                           days,
209                           hours,
210                           minutes,
211                           new BigDecimal(seconds));
212      }
213    
214      /**
215       * Returns a new dayTimeDuration by specifying the individual components.
216       * @param isPositive whether the duration is positive
217       * @param days the number of days
218       * @param hours the number of hours
219       * @param minutes th number of minutes
220       * @param seconds the number of seconds
221       */
222      public Duration newDurationDayTime(boolean isPositive,
223                                         int days,
224                                         int hours,
225                                         int minutes,
226                                         int seconds)
227      {
228        return newDuration(isPositive,
229                           null,
230                           null,
231                           BigInteger.valueOf((long) days),
232                           BigInteger.valueOf((long) hours),
233                           BigInteger.valueOf((long) minutes),
234                           BigDecimal.valueOf((long) seconds));
235      }
236    
237      /**
238       * Returns a new yearMonthDuration from its string representation.
239       * @param lexicalRepresentation the lexical representation of the
240       * duration, as specified in XML Schema 1.0 section 3.2.6.1.
241       */
242      public Duration newDurationYearMonth(String lexicalRepresentation)
243      {
244        return newDuration(lexicalRepresentation);
245      }
246    
247      /**
248       * Returns a new yearMonthDuration.
249       * @param durationInMilliseconds the duration in milliseconds
250       */
251      public Duration newDurationYearMonth(long durationInMilliseconds)
252      {
253        // TODO xmlSchemaType
254        return newDuration(durationInMilliseconds);
255      }
256    
257      /**
258       * Returns a new yearMonthDuration by specifying the individual components.
259       * @param isPositive whether the duration is positive
260       * @param years the number of years
261       * @param months the number of months
262       */
263      public Duration newDurationYearMonth(boolean isPositive,
264                                           BigInteger years,
265                                           BigInteger months)
266      {
267        return newDuration(isPositive,
268                           years,
269                           months,
270                           null,
271                           null,
272                           null,
273                           null);
274      }
275    
276      /**
277       * Returns a new yearMonthDuration by specifying the individual components.
278       * @param isPositive whether the duration is positive
279       * @param years the number of years
280       * @param months the number of months
281       */
282      public Duration newDurationYearMonth(boolean isPositive,
283                                           int years,
284                                           int months)
285      {
286        return newDuration(isPositive,
287                           BigInteger.valueOf((long) years),
288                           BigInteger.valueOf((long) months),
289                           null,
290                           null,
291                           null,
292                           null);
293      }
294    
295      /**
296       * Returns a new XMLGregorianCalendar with no fields initialized.
297       */
298      public abstract XMLGregorianCalendar newXMLGregorianCalendar();
299    
300      /**
301       * Returns a new XMLGregorianCalendar from a string representation.
302       * @param lexicalRepresentation the lexical representation as specified in
303       * XML Schema 1.0 Part 2, section 3.2.[7-14].1.
304       */
305      public abstract XMLGregorianCalendar newXMLGregorianCalendar(String lexicalRepresentation);
306    
307      /**
308       * Returns a new XMLGregorianCalendar based on the specified Gregorian
309       * calendar.
310       */
311      public abstract XMLGregorianCalendar newXMLGregorianCalendar(GregorianCalendar cal);
312    
313      /**
314       * Returns a new XMLGregorianCalendar with the specified components.
315       */
316      public abstract XMLGregorianCalendar newXMLGregorianCalendar(BigInteger year,
317                                                                   int month,
318                                                                   int day,
319                                                                   int hour,
320                                                                   int minute,
321                                                                   int second,
322                                                                   BigDecimal fractionalSecond,
323                                                                   int timezone);
324    
325      /**
326       * Returns a new XMLGregorianCalendar with the specified components.
327       */
328      public XMLGregorianCalendar newXMLGregorianCalendar(int year,
329                                                          int month,
330                                                          int day,
331                                                          int hour,
332                                                          int minute,
333                                                          int second,
334                                                          int millisecond,
335                                                          int timezone)
336      {
337        return newXMLGregorianCalendar(BigInteger.valueOf((long) year),
338                                       month,
339                                       day,
340                                       hour,
341                                       minute,
342                                       second,
343                                       new BigDecimal(((double) millisecond) / 1000.0),
344                                       timezone);
345      }
346    
347      /**
348       * Returns a new XMLGregorianCalendar with the specified components.
349       */
350      public XMLGregorianCalendar newXMLGregorianCalendarDate(int year,
351                                                              int month,
352                                                              int day,
353                                                              int timezone)
354      {
355        return newXMLGregorianCalendar(BigInteger.valueOf((long) year),
356                                       month,
357                                       day,
358                                       DatatypeConstants.FIELD_UNDEFINED,
359                                       DatatypeConstants.FIELD_UNDEFINED,
360                                       DatatypeConstants.FIELD_UNDEFINED,
361                                       null,
362                                       timezone);
363      }
364    
365      /**
366       * Returns a new XMLGregorianCalendar with the specified components.
367       */
368      public XMLGregorianCalendar newXMLGregorianCalendarTime(int hours,
369                                                              int minutes,
370                                                              int seconds,
371                                                              int timezone)
372      {
373        return newXMLGregorianCalendar(null,
374                                       DatatypeConstants.FIELD_UNDEFINED,
375                                       DatatypeConstants.FIELD_UNDEFINED,
376                                       hours,
377                                       minutes,
378                                       seconds,
379                                       null,
380                                       timezone);
381      }
382    
383      /**
384       * Returns a new XMLGregorianCalendar with the specified components.
385       */
386      public XMLGregorianCalendar newXMLGregorianCalendarTime(int hours,
387                                                              int minutes,
388                                                              int seconds,
389                                                              BigDecimal fractionalSecond,
390                                                              int timezone)
391      {
392        return newXMLGregorianCalendar(null,
393                                       DatatypeConstants.FIELD_UNDEFINED,
394                                       DatatypeConstants.FIELD_UNDEFINED,
395                                       hours,
396                                       minutes,
397                                       seconds,
398                                       fractionalSecond,
399                                       timezone);
400      }
401    
402      /**
403       * Returns a new XMLGregorianCalendar with the specified components.
404       */
405      public XMLGregorianCalendar newXMLGregorianCalendarTime(int hours,
406                                                              int minutes,
407                                                              int seconds,
408                                                              int milliseconds,
409                                                              int timezone)
410      {
411        return newXMLGregorianCalendar(null,
412                                       DatatypeConstants.FIELD_UNDEFINED,
413                                       DatatypeConstants.FIELD_UNDEFINED,
414                                       hours,
415                                       minutes,
416                                       seconds,
417                                       new BigDecimal(((double) milliseconds) / 1000.0),
418                                       timezone);
419      }
420    
421    }