View Javadoc

1   /*
2    * Copyright 2001-2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */ 
16  package org.apache.commons.betwixt.strategy;
17  
18  import java.text.ParseException;
19  import java.text.SimpleDateFormat;
20  import java.util.Locale;
21  
22  import org.apache.commons.beanutils.ConversionException;
23  import org.apache.commons.betwixt.expression.Context;
24  
25  /*** 
26   * <p>Default string &lt;-&gt; object conversion strategy.</p>
27   * <p>
28   * This delegates to ConvertUtils except when the type 
29   * is assignable from <code>java.util.Date</code>
30   * but not from <code>java.sql.Date</code>.
31   * In this case, the format used is (in SimpleDateFormat terms) 
32   * <code>EEE MMM dd HH:mm:ss zzz yyyy</code>.
33   * This is the same as the output of the toString method on java.util.Date.
34   * </p>
35   * <p>
36   * This should preserve the existing symantic behaviour whilst allowing round tripping of dates
37   * (given the default settings).
38   * </p>
39   * @author Robert Burrell Donkin
40   * @since 0.5
41   */
42  public class DefaultObjectStringConverter extends ConvertUtilsObjectStringConverter {
43      
44      /*** Formats Dates to Strings and Strings to Dates */
45      private final SimpleDateFormat formatter 
46          = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.UK);
47      
48      /***
49        * Converts an object to a string representation using ConvertUtils.
50        * If the object is a java.util.Date and the type is java.util.Date 
51        * but not java.sql.Date
52        * then SimpleDateFormat formatting to 
53        * <code>EEE MMM dd HH:mm:ss zzz yyyy</code>
54        * will be used. 
55        * (This is the same as java.util.Date toString would return.)
56        *
57        * @param object the object to be converted, possibly null
58        * @param type the property class of the object, not null
59        * @param flavour a string allow symantic differences in formatting 
60        * to be communicated (ignored)
61        * @param context convert against this context not null
62        * @return a String representation, not null
63        */
64      public String objectToString(Object object, Class type, String flavour, Context context) {
65          if ( object != null ) {
66              if ( object instanceof Class) {
67                  return ((Class) object).getName();
68              }
69                  
70              if ( object instanceof java.util.Date && isUtilDate( type ) ) {
71                  
72                  return formatter.format( (java.util.Date) object );
73                  
74              } else {
75                  // use ConvertUtils implementation
76                  return super.objectToString( object, type, flavour, context );
77              }
78          }
79          return "";
80      }
81      
82      /***
83        * Converts an object to a string representation using ConvertUtils.
84        * 
85        * @param value the String to be converted, not null
86        * @param type the property class to be returned (if possible), not null
87        * @param flavour a string allow symantic differences 
88        * in formatting to be communicated (ignored)
89        * @param context not null
90        * @return an Object converted from the String, not null
91        */
92      public Object stringToObject(String value, Class type, String flavour, Context context) {
93              if ( isUtilDate( type ) ) {
94                  try {
95                      
96                      return formatter.parse( value );
97                      
98                  } catch ( ParseException ex ) { 
99                      handleException( ex );
100                     // this supports any subclasses that do not which to throw exceptions
101                     // probably will result in a problem when the method will be invoked
102                     // but never mind
103                     return value;
104                 }
105             } else {
106                 // use ConvertUtils implementation
107                 return super.stringToObject( value, type, flavour, context );
108             }
109     }
110     
111     /*** 
112       * Allow subclasses to use a different exception handling strategy.
113       * This class throws a <code>org.apache.commons.beanutils.ConversionException</code>
114       * when conversion fails.
115       * @param e the Exception to be handled
116       * @throws org.apache.commons.beanutils.ConversionException when conversion fails
117       */
118     protected void handleException(Exception e) {
119         throw new ConversionException( "String to object conversion failed: " + e.getMessage(), e );
120     }
121     
122     /***
123       * Is the given type a java.util.Date but not a java.sql.Date?
124       * @param type test this class type
125       * @return true is this is a until date but not a sql one
126       */
127     private boolean isUtilDate(Class type) {
128         return ( java.util.Date.class.isAssignableFrom(type) 
129              && !java.sql.Date.class.isAssignableFrom(type)
130              && !java.sql.Time.class.isAssignableFrom(type) 
131              && !java.sql.Timestamp.class.isAssignableFrom(type) );
132     }
133 }