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.BufferedReader;
041    import java.io.File;
042    import java.io.FileInputStream;
043    import java.io.InputStream;
044    import java.io.InputStreamReader;
045    import java.math.BigDecimal;
046    import java.math.BigInteger;
047    import java.util.GregorianCalendar;
048    import java.util.Iterator;
049    import java.util.Properties;
050    import gnu.classpath.ServiceFactory;
051    
052    /**
053     * Factory class to create new datatype objects mapping XML to and from Java
054     * objects.
055     *
056     * @author Chris Burdess
057     * @since 1.5
058     */
059    public abstract class DatatypeFactory
060    {
061    
062      /**
063       * JAXP 1.3 default property name.
064       */
065      public static final String DATATYPEFACTORY_PROPERTY = "javax.xml.datatype.DatatypeFactory";
066    
067      /**
068       * JAXP 1.3 default implementation class name.
069       */
070      public static final String DATATYPEFACTORY_IMPLEMENTATION_CLASS = "gnu.xml.datatype.JAXPDatatypeFactory";
071    
072      protected DatatypeFactory()
073      {
074      }
075    
076      /**
077       * Returns a new factory instance.
078       */
079      public static DatatypeFactory newInstance()
080        throws DatatypeConfigurationException
081      {
082        try
083          {
084            // 1. system property
085            String className = System.getProperty(DATATYPEFACTORY_PROPERTY);
086            if (className != null)
087              return (DatatypeFactory) Class.forName(className).newInstance();
088            // 2. jaxp.properties property
089            File javaHome = new File(System.getProperty("java.home"));
090            File javaHomeLib = new File(javaHome, "lib");
091            File jaxpProperties = new File(javaHomeLib, "jaxp.properties");
092            if (jaxpProperties.exists())
093              {
094                FileInputStream in = new FileInputStream(jaxpProperties);
095                Properties p = new Properties();
096                p.load(in);
097                in.close();
098                className = p.getProperty(DATATYPEFACTORY_PROPERTY);
099                if (className != null)
100                  return (DatatypeFactory) Class.forName(className).newInstance();
101              }
102            // 3. services
103            Iterator i = ServiceFactory.lookupProviders(DatatypeFactory.class);
104            if (i.hasNext())
105              return (DatatypeFactory) i.next();
106            // 4. fallback
107            Class t = Class.forName(DATATYPEFACTORY_IMPLEMENTATION_CLASS);
108            return (DatatypeFactory) t.newInstance();
109          }
110        catch (Exception e)
111          {
112            throw new DatatypeConfigurationException(e);
113          }
114      }
115    
116      /**
117       * Returns a new duration from its string representation.
118       * @param lexicalRepresentation the lexical representation of the
119       * duration, as specified in XML Schema 1.0 section 3.2.6.1.
120       */
121      public abstract Duration newDuration(String lexicalRepresentation);
122    
123      /**
124       * Returns a new duration.
125       * @param durationInMilliSeconds the duration in milliseconds
126       */
127      public abstract Duration newDuration(long durationInMilliSeconds);
128    
129      /**
130       * Returns a new duration by specifying the individual components.
131       * @param isPositive whether the duration is positive
132       * @param years the number of years
133       * @param months the number of months
134       * @param days the number of days
135       * @param hours the number of hours
136       * @param minutes th number of minutes
137       * @param seconds the number of seconds
138       */
139      public abstract Duration newDuration(boolean isPositive,
140                                           BigInteger years,
141                                           BigInteger months,
142                                           BigInteger days,
143                                           BigInteger hours,
144                                           BigInteger minutes,
145                                           BigDecimal seconds);
146    
147      /**
148       * Returns a new duration by specifying the individual components.
149       * @param isPositive whether the duration is positive
150       * @param years the number of years
151       * @param months the number of months
152       * @param days the number of days
153       * @param hours the number of hours
154       * @param minutes th number of minutes
155       * @param seconds the number of seconds
156       */
157      public Duration newDuration(boolean isPositive,
158                                  int years,
159                                  int months,
160                                  int days,
161                                  int hours,
162                                  int minutes,
163                                  int seconds)
164      {
165        return newDuration(isPositive,
166                           BigInteger.valueOf((long) years),
167                           BigInteger.valueOf((long) months),
168                           BigInteger.valueOf((long) days),
169                           BigInteger.valueOf((long) hours),
170                           BigInteger.valueOf((long) minutes),
171                           BigDecimal.valueOf((long) seconds));
172      }
173    
174      /**
175       * Returns a new dayTimeDuration from its string representation.
176       * @param lexicalRepresentation the lexical representation of the
177       * duration, as specified in XML Schema 1.0 section 3.2.6.1.
178       */
179      public Duration newDurationDayTime(String lexicalRepresentation)
180      {
181        return newDuration(lexicalRepresentation);
182      }
183    
184      /**
185       * Returns a new dayTimeDuration.
186       * @param durationInMilliseconds the duration in milliseconds
187       */
188      public Duration newDurationDayTime(long durationInMilliseconds)
189      {
190        // TODO xmlSchemaType
191        return newDuration(durationInMilliseconds);
192      }
193    
194      /**
195       * Returns a new dayTimeDuration by specifying the individual components.
196       * @param isPositive whether the duration is positive
197       * @param days the number of days
198       * @param hours the number of hours
199       * @param minutes th number of minutes
200       * @param seconds the number of seconds
201       */
202      public Duration newDurationDayTime(boolean isPositive,
203                                         BigInteger days,
204                                         BigInteger hours,
205                                         BigInteger minutes,
206                                         BigInteger seconds)
207      {
208        return newDuration(isPositive,
209                           null,
210                           null,
211                           days,
212                           hours,
213                           minutes,
214                           new BigDecimal(seconds));
215      }
216    
217      /**
218       * Returns a new dayTimeDuration by specifying the individual components.
219       * @param isPositive whether the duration is positive
220       * @param days the number of days
221       * @param hours the number of hours
222       * @param minutes th number of minutes
223       * @param seconds the number of seconds
224       */
225      public Duration newDurationDayTime(boolean isPositive,
226                                         int days,
227                                         int hours,
228                                         int minutes,
229                                         int seconds)
230      {
231        return newDuration(isPositive,
232                           null,
233                           null,
234                           BigInteger.valueOf((long) days),
235                           BigInteger.valueOf((long) hours),
236                           BigInteger.valueOf((long) minutes),
237                           BigDecimal.valueOf((long) seconds));
238      }
239    
240      /**
241       * Returns a new yearMonthDuration from its string representation.
242       * @param lexicalRepresentation the lexical representation of the
243       * duration, as specified in XML Schema 1.0 section 3.2.6.1.
244       */
245      public Duration newDurationYearMonth(String lexicalRepresentation)
246      {
247        return newDuration(lexicalRepresentation);
248      }
249    
250      /**
251       * Returns a new yearMonthDuration.
252       * @param durationInMilliseconds the duration in milliseconds
253       */
254      public Duration newDurationYearMonth(long durationInMilliseconds)
255      {
256        // TODO xmlSchemaType
257        return newDuration(durationInMilliseconds);
258      }
259    
260      /**
261       * Returns a new yearMonthDuration by specifying the individual components.
262       * @param isPositive whether the duration is positive
263       * @param years the number of years
264       * @param months the number of months
265       */
266      public Duration newDurationYearMonth(boolean isPositive,
267                                           BigInteger years,
268                                           BigInteger months)
269      {
270        return newDuration(isPositive,
271                           years,
272                           months,
273                           null,
274                           null,
275                           null,
276                           null);
277      }
278    
279      /**
280       * Returns a new yearMonthDuration by specifying the individual components.
281       * @param isPositive whether the duration is positive
282       * @param years the number of years
283       * @param months the number of months
284       */
285      public Duration newDurationYearMonth(boolean isPositive,
286                                           int years,
287                                           int months)
288      {
289        return newDuration(isPositive,
290                           BigInteger.valueOf((long) years),
291                           BigInteger.valueOf((long) months),
292                           null,
293                           null,
294                           null,
295                           null);
296      }
297    
298      /**
299       * Returns a new XMLGregorianCalendar with no fields initialized.
300       */
301      public abstract XMLGregorianCalendar newXMLGregorianCalendar();
302    
303      /**
304       * Returns a new XMLGregorianCalendar from a string representation.
305       * @param lexicalRepresentation the lexical representation as specified in
306       * XML Schema 1.0 Part 2, section 3.2.[7-14].1.
307       */
308      public abstract XMLGregorianCalendar newXMLGregorianCalendar(String lexicalRepresentation);
309      
310      /**
311       * Returns a new XMLGregorianCalendar based on the specified Gregorian
312       * calendar.
313       */
314      public abstract XMLGregorianCalendar newXMLGregorianCalendar(GregorianCalendar cal);
315    
316      /**
317       * Returns a new XMLGregorianCalendar with the specified components.
318       */
319      public abstract XMLGregorianCalendar newXMLGregorianCalendar(BigInteger year,
320                                                                   int month,
321                                                                   int day,
322                                                                   int hour,
323                                                                   int minute,
324                                                                   int second,
325                                                                   BigDecimal fractionalSecond,
326                                                                   int timezone);
327    
328      /**
329       * Returns a new XMLGregorianCalendar with the specified components.
330       */
331      public XMLGregorianCalendar newXMLGregorianCalendar(int year,
332                                                          int month,
333                                                          int day,
334                                                          int hour,
335                                                          int minute,
336                                                          int second,
337                                                          int millisecond,
338                                                          int timezone)
339      {
340        return newXMLGregorianCalendar(BigInteger.valueOf((long) year),
341                                       month,
342                                       day,
343                                       hour,
344                                       minute,
345                                       second,
346                                       new BigDecimal(((double) millisecond) / 1000.0),
347                                       timezone);
348      }
349    
350      /**
351       * Returns a new XMLGregorianCalendar with the specified components.
352       */
353      public XMLGregorianCalendar newXMLGregorianCalendarDate(int year,
354                                                              int month,
355                                                              int day,
356                                                              int timezone)
357      {
358        return newXMLGregorianCalendar(BigInteger.valueOf((long) year),
359                                       month,
360                                       day,
361                                       DatatypeConstants.FIELD_UNDEFINED,
362                                       DatatypeConstants.FIELD_UNDEFINED,
363                                       DatatypeConstants.FIELD_UNDEFINED,
364                                       null,
365                                       timezone);
366      }
367    
368      /**
369       * Returns a new XMLGregorianCalendar with the specified components.
370       */
371      public XMLGregorianCalendar newXMLGregorianCalendarTime(int hours,
372                                                              int minutes,
373                                                              int seconds,
374                                                              int timezone)
375      {
376        return newXMLGregorianCalendar(null,
377                                       DatatypeConstants.FIELD_UNDEFINED,
378                                       DatatypeConstants.FIELD_UNDEFINED,
379                                       hours,
380                                       minutes,
381                                       seconds,
382                                       null,
383                                       timezone);
384      }
385    
386      /**
387       * Returns a new XMLGregorianCalendar with the specified components.
388       */
389      public XMLGregorianCalendar newXMLGregorianCalendarTime(int hours,
390                                                              int minutes,
391                                                              int seconds,
392                                                              BigDecimal fractionalSecond,
393                                                              int timezone)
394      {
395        return newXMLGregorianCalendar(null,
396                                       DatatypeConstants.FIELD_UNDEFINED,
397                                       DatatypeConstants.FIELD_UNDEFINED,
398                                       hours,
399                                       minutes,
400                                       seconds,
401                                       fractionalSecond,
402                                       timezone);
403      }
404    
405      /**
406       * Returns a new XMLGregorianCalendar with the specified components.
407       */
408      public XMLGregorianCalendar newXMLGregorianCalendarTime(int hours,
409                                                              int minutes,
410                                                              int seconds,
411                                                              int milliseconds,
412                                                              int timezone)
413      {
414        return newXMLGregorianCalendar(null,
415                                       DatatypeConstants.FIELD_UNDEFINED,
416                                       DatatypeConstants.FIELD_UNDEFINED,
417                                       hours,
418                                       minutes,
419                                       seconds,
420                                       new BigDecimal(((double) milliseconds) / 1000.0),
421                                       timezone);
422      }
423        
424    }