View Javadoc
1   /**
2    * Redistribution and use of this software and associated documentation ("Software"), with or
3    * without modification, are permitted provided that the following conditions are met:
4    *
5    * 1. Redistributions of source code must retain copyright statements and notices. Redistributions
6    * must also contain a copy of this document.
7    *
8    * 2. Redistributions in binary form must reproduce the above copyright notice, this list of
9    * conditions and the following disclaimer in the documentation and/or other materials provided with
10   * the distribution.
11   *
12   * 3. The name "Exolab" must not be used to endorse or promote products derived from this Software
13   * without prior written permission of Intalio, Inc. For written permission, please contact
14   * info@exolab.org.
15   *
16   * 4. Products derived from this Software may not be called "Exolab" nor may "Exolab" appear in
17   * their names without prior written permission of Intalio, Inc. Exolab is a registered trademark of
18   * Intalio, Inc.
19   *
20   * 5. Due credit should be given to the Exolab Project (http://www.exolab.org/).
21   *
22   * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED OR
23   * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
24   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTALIO, INC. OR ITS
25   * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28   * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
29   * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30   *
31   * Copyright 1999-2002 (C) Intalio, Inc. All Rights Reserved.
32   *
33   * $Id$
34   */
35  
36  package org.exolab.castor.xml.schema.util;
37  
38  
39  import org.exolab.castor.types.Date;
40  import org.exolab.castor.types.Time;
41  
42  import java.text.DateFormat;
43  import java.text.ParseException;
44  import java.text.SimpleDateFormat;
45  
46  /**
47   * A class used for "guessing" the proper datatype of an XML attribute or an XML element with
48   * simpleContent.
49   *
50   * @author <a href="mailto:kvisco@intalio.com">Keith Visco</a>
51   * @version $Revision$ $Date: 2005-03-07 01:33:49 -0700 (Mon, 07 Mar 2005) $
52   **/
53  public class DatatypeHandler {
54  
55    /**
56     * The name of the XML Schema boolean type
57     **/
58    public static final String BOOLEAN_TYPE = "boolean";
59  
60    /**
61     * The name of the XML Schema date type
62     **/
63    public static final String DATE_TYPE = "date";
64  
65    /**
66     * The name of the XML Schema dateTime type
67     **/
68    public static final String DATETIME_TYPE = "dateTime";
69  
70    /**
71     * The name of the XML Schema double type
72     **/
73    public static final String DOUBLE_TYPE = "double";
74  
75    /**
76     * The name of the XML Schema float type
77     **/
78    public static final String FLOAT_TYPE = "float";
79  
80    /**
81     * The name of the XML Schema integer type
82     **/
83    public static final String INTEGER_TYPE = "integer";
84  
85    /**
86     * The name of the XML Schema long type
87     **/
88    public static final String LONG_TYPE = "long";
89  
90    /**
91     * The name of the XML Schema string type
92     **/
93    public static final String STRING_TYPE = "string";
94  
95    /**
96     * The name of the XML Schema time type
97     **/
98    public static final String TIME_TYPE = "time";
99  
100 
101 
102   private static final String TRUE = "true";
103   private static final String FALSE = "false";
104 
105   private static final String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS";
106   private static final String DATE_FORMAT_2 = "yyyy-MM-dd'T'HH:mm:ss";
107 
108 
109   /**
110    * Creates a new DatatypeHandler
111    *
112    **/
113   private DatatypeHandler() {
114     super();
115   } // -- DatatypeHandler
116 
117   /**
118    * Guesses the datatype for the given value. When the type cannot be determined, it simply
119    * defaults to DatatypeHandler.STRING_TYPE. <BR />
120    * <B>Note:</B> This may be a slow process.
121    *
122    * @param value the value to determine the type for
123    * @return the type that the value may be
124    **/
125   public static String guessType(String value) {
126     if (value == null)
127       return null;
128 
129     // -- If string is empty...not much we
130     // -- can do...
131     if (value.length() == 0)
132       return STRING_TYPE;
133 
134     // -- check for integer, must be done before check for long
135     try {
136       Integer.parseInt(value);
137       return INTEGER_TYPE;
138     } catch (NumberFormatException nfe) {
139     }
140 
141     // -- check for long
142     try {
143       Long.parseLong(value);
144       return LONG_TYPE;
145     } catch (NumberFormatException nfe) {
146     }
147 
148     // -- check for float, must be done before check for double
149     try {
150       Float.valueOf(value);
151       return FLOAT_TYPE;
152     } catch (NumberFormatException nfe) {
153     }
154 
155     // -- check for double
156     try {
157       Double.valueOf(value);
158       return DOUBLE_TYPE;
159     } catch (NumberFormatException nfe) {
160     }
161 
162     // -- check for boolean
163     if (value.equals(TRUE) || value.equals(FALSE)) {
164       return BOOLEAN_TYPE;
165     }
166 
167     // -- check for date
168     try {
169       Date.parseDate(value);
170       return DATE_TYPE;
171     } catch (ParseException px) {
172     }
173 
174     // -- check for time
175     try {
176       Time.parseTime(value);
177       return TIME_TYPE;
178     } catch (ParseException px) {
179     } catch (IllegalArgumentException ex) {
180     }
181 
182     // -- check for dateTime
183     DateFormat df = null;
184     if (value.indexOf('.') < 0)
185       df = new SimpleDateFormat(DATE_FORMAT);
186     else
187       df = new SimpleDateFormat(DATE_FORMAT_2);
188 
189     try {
190       df.parse(value);
191       return DATETIME_TYPE;
192     } catch (java.text.ParseException ex) {
193     }
194 
195 
196     // -- when all else fails :-)
197     return STRING_TYPE;
198   } // -- guessType
199 
200   /**
201    * Guesses which datatype should be used.
202    *
203    */
204   protected static String whichType(String type1, String type2) {
205 
206     // -- if both types are the same, return the type
207     if (type1.equals(type2))
208       return type1;
209     // -- if any type is a string, return string
210     if (type1.equals(STRING_TYPE) || (type2.equals(STRING_TYPE)))
211       return STRING_TYPE;
212     // -- neither type is a string
213     if (INTEGER_TYPE.equals(type1)) {
214       if (LONG_TYPE.equals(type2))
215         return LONG_TYPE;
216       else if (FLOAT_TYPE.equals(type2))
217         return FLOAT_TYPE;
218       else if (DOUBLE_TYPE.equals(type2))
219         return DOUBLE_TYPE;
220     } else if (LONG_TYPE.equals(type1)) {
221       if (INTEGER_TYPE.equals(type2))
222         return LONG_TYPE;
223       else if (FLOAT_TYPE.equals(type2))
224         return DOUBLE_TYPE;
225       else if (DOUBLE_TYPE.equals(type2))
226         return DOUBLE_TYPE;
227     } else if (FLOAT_TYPE.equals(type1)) {
228       if (INTEGER_TYPE.equals(type2))
229         return FLOAT_TYPE;
230       else if (LONG_TYPE.equals(type2))
231         return DOUBLE_TYPE;
232       else if (DOUBLE_TYPE.equals(type2))
233         return DOUBLE_TYPE;
234     } else if (DOUBLE_TYPE.equals(type1)) {
235       if (INTEGER_TYPE.equals(type2))
236         return DOUBLE_TYPE;
237       else if (LONG_TYPE.equals(type2))
238         return DOUBLE_TYPE;
239       else if (FLOAT_TYPE.equals(type2))
240         return DOUBLE_TYPE;
241     }
242     // -- when in doubt...return string
243     return STRING_TYPE;
244   } // -- whichType
245 
246 
247 } // -- DatatypeHandler