001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.commons.betwixt.strategy; 018 019 import java.text.ParseException; 020 import java.text.SimpleDateFormat; 021 import java.util.Locale; 022 023 import org.apache.commons.beanutils.ConversionException; 024 import org.apache.commons.betwixt.expression.Context; 025 026 /** 027 * <p>Default string <-> object conversion strategy.</p> 028 * <p> 029 * This delegates to ConvertUtils except when the type 030 * is assignable from <code>java.util.Date</code> 031 * but not from <code>java.sql.Date</code>. 032 * In this case, the format used is (in SimpleDateFormat terms) 033 * <code>EEE MMM dd HH:mm:ss zzz yyyy</code>. 034 * This is the same as the output of the toString method on java.util.Date. 035 * </p> 036 * <p> 037 * This should preserve the existing symantic behaviour whilst allowing round tripping of dates 038 * (given the default settings). 039 * </p> 040 * @author Robert Burrell Donkin 041 * @since 0.5 042 */ 043 public class DefaultObjectStringConverter extends ConvertUtilsObjectStringConverter { 044 045 /** Formats Dates to Strings and Strings to Dates */ 046 private final SimpleDateFormat formatter 047 = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.UK); 048 049 /** 050 * Converts an object to a string representation using ConvertUtils. 051 * If the object is a java.util.Date and the type is java.util.Date 052 * but not java.sql.Date 053 * then SimpleDateFormat formatting to 054 * <code>EEE MMM dd HH:mm:ss zzz yyyy</code> 055 * will be used. 056 * (This is the same as java.util.Date toString would return.) 057 * 058 * @param object the object to be converted, possibly null 059 * @param type the property class of the object, not null 060 * @param flavour a string allow symantic differences in formatting 061 * to be communicated (ignored) 062 * @param context convert against this context not null 063 * @return a String representation, not null 064 */ 065 public String objectToString(Object object, Class type, String flavour, Context context) { 066 if ( object != null ) { 067 if ( object instanceof Class) { 068 return ((Class) object).getName(); 069 } 070 071 if ( object instanceof java.util.Date && isUtilDate( type ) ) { 072 073 return formatter.format( (java.util.Date) object ); 074 075 } else { 076 // use ConvertUtils implementation 077 return super.objectToString( object, type, flavour, context ); 078 } 079 } 080 return ""; 081 } 082 083 /** 084 * Converts an object to a string representation using ConvertUtils. 085 * 086 * @param value the String to be converted, not null 087 * @param type the property class to be returned (if possible), not null 088 * @param flavour a string allow symantic differences 089 * in formatting to be communicated (ignored) 090 * @param context not null 091 * @return an Object converted from the String, not null 092 */ 093 public Object stringToObject(String value, Class type, String flavour, Context context) { 094 if ( isUtilDate( type ) ) { 095 try { 096 097 return formatter.parse( value ); 098 099 } 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 }