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. import java.text.ParseException;
  18. import java.text.SimpleDateFormat;
  19. import java.util.Locale;
  20. import org.apache.commons.beanutils.ConversionException;
  21. import org.apache.commons.betwixt.expression.Context;
  22. /**
  23. * <p>Default string <-> object conversion strategy.</p>
  24. * <p>
  25. * This delegates to ConvertUtils except when the type
  26. * is assignable from <code>java.util.Date</code>
  27. * but not from <code>java.sql.Date</code>.
  28. * In this case, the format used is (in SimpleDateFormat terms)
  29. * <code>EEE MMM dd HH:mm:ss zzz yyyy</code>.
  30. * This is the same as the output of the toString method on java.util.Date.
  31. * </p>
  32. * <p>
  33. * This should preserve the existing symantic behaviour whilst allowing round tripping of dates
  34. * (given the default settings).
  35. * </p>
  36. * @author Robert Burrell Donkin
  37. * @since 0.5
  38. */
  39. public class DefaultObjectStringConverter extends ConvertUtilsObjectStringConverter {
  40. /** Formats Dates to Strings and Strings to Dates */
  41. private static final SimpleDateFormat formatter
  42. = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.UK);
  43. /**
  44. * Converts an object to a string representation using ConvertUtils.
  45. * If the object is a java.util.Date and the type is java.util.Date
  46. * but not java.sql.Date
  47. * then SimpleDateFormat formatting to
  48. * <code>EEE MMM dd HH:mm:ss zzz yyyy</code>
  49. * will be used.
  50. * (This is the same as java.util.Date toString would return.)
  51. *
  52. * @param object the object to be converted, possibly null
  53. * @param type the property class of the object, not null
  54. * @param flavour a string allow symantic differences in formatting
  55. * to be communicated (ignored)
  56. * @param context convert against this context not null
  57. * @return a String representation, not null
  58. */
  59. public String objectToString(Object object, Class type, String flavour, Context context) {
  60. if ( object != null ) {
  61. if ( object instanceof java.util.Date && isUtilDate( type ) ) {
  62. return formatter.format( (java.util.Date) object );
  63. } else {
  64. // use ConvertUtils implementation
  65. return super.objectToString( object, type, flavour, context );
  66. }
  67. }
  68. return "";
  69. }
  70. /**
  71. * Converts an object to a string representation using ConvertUtils.
  72. *
  73. * @param value the String to be converted, not null
  74. * @param type the property class to be returned (if possible), not null
  75. * @param flavour a string allow symantic differences
  76. * in formatting to be communicated (ignored)
  77. * @param context not null
  78. * @return an Object converted from the String, not null
  79. */
  80. public Object stringToObject(String value, Class type, String flavour, Context context) {
  81. if ( isUtilDate( type ) ) {
  82. try {
  83. return formatter.parse( value );
  84. } catch ( ParseException ex ) {
  85. handleException( ex );
  86. // this supports any subclasses that do not which to throw exceptions
  87. // probably will result in a problem when the method will be invoked
  88. // but never mind
  89. return value;
  90. }
  91. } else {
  92. // use ConvertUtils implementation
  93. return super.stringToObject( value, type, flavour, context );
  94. }
  95. }
  96. /**
  97. * Allow subclasses to use a different exception handling strategy.
  98. * This class throws a <code>org.apache.commons.beanutils.ConversionException</code>
  99. * when conversion fails.
  100. * @param e the Exception to be handled
  101. * @throws org.apache.commons.beanutils.ConversionException when conversion fails
  102. */
  103. protected void handleException(Exception e) {
  104. throw new ConversionException( "String to object conversion failed: " + e.getMessage(), e );
  105. }
  106. /**
  107. * Is the given type a java.util.Date but not a java.sql.Date?
  108. * @param type test this class type
  109. * @return true is this is a until date but not a sql one
  110. */
  111. private boolean isUtilDate(Class type) {
  112. return ( java.util.Date.class.isAssignableFrom(type)
  113. && !java.sql.Date.class.isAssignableFrom(type)
  114. && !java.sql.Time.class.isAssignableFrom(type)
  115. && !java.sql.Timestamp.class.isAssignableFrom(type) );
  116. }
  117. }