View Javadoc

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