Issue Details (XML | Word | Printable)

Key: APF-176
Type: Bug Bug
Status: Open Open
Priority: Minor Minor
Assignee: Matt Raible
Reporter: Matt Raible
Votes: 1
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
AppFuse

Move Timestamp conversion logic into DateConverter

Created: 23/Sep/05 11:06 AM   Updated: 23/Jan/07 01:03 PM
Component/s: Web - Struts
Affects Version/s: 1.8.2
Fix Version/s: None


 Description  « Hide
TimestampConverter is not used - seemingly b/c a Timestamp is a Date - therefore DateConverter is used

Sort Order: Ascending order - Click to sort in descending order
Matt Raible added a comment - 23/Sep/05 11:16 AM
For some reason, Struts in Tomcat can't determine the different between a Date and a Timestamp:

    protected Object convertToString(Class type, Object value) {

        if (value instanceof Date) {
            DateFormat df = new SimpleDateFormat(DateUtil.getDatePattern());
            // this works in unit tests, but when running in Tomcat, a java.util.Date
            // comes through as a java.sql.Timestamp - wierd eh?
            if (value instanceof Timestamp) {
                df = new SimpleDateFormat(TS_FORMAT);
            }
    
            try {
                return df.format(value);
            } catch (Exception e) {
                e.printStackTrace();
                throw new ConversionException("Error converting Date to String");
            }
        } else {
            return value.toString();
        }
    }

Matt Raible added a comment - 23/Sep/05 02:13 PM
Fixed in CVS - but now all dates render with a Timestamp format. Need to find a fix.

Matt Raible added a comment - 06/Apr/06 05:51 AM
Delaying fix b/c no one has reported issues with it.

Samuel Huang added a comment - 11/Apr/06 09:30 PM

Hi,

I found a workaround for this problem. Not sure if it
qualify for a fix but here it is.

If a domain object Event.java has the following properties

private Date dateStart;
private Date dateEnd;
private Timestamp timeSubmitted;
.....
// Usual getter and setter methods for above fields


Then create metadata/web/xDoclet-EventForm.xml and add

protected java.sql.Timestamp timeSubmitted;

protected String timeSubmittedDisplay;

public String getTimeSubmittedDisplay() {
return timeSubmittedDisplay;
}

public void setTimeSubmittedDisplay(String timeSubmittedDisplay){
this.timeSubmittedDisplay = timeSubmittedDisplay;
}

public java.sql.Timestamp getTimeSubmitted() {
if (getTimeSubmittedDisplay() != null) {
this.timeSubmitted = (java.sql.Timestamp)org.appfuse.util.TimestampConverter.convertToTimestamp(getTimeSubmittedDisplay());
}
return this.timeSubmitted;
}

public void setTimeSubmitted(java.sql.Timestamp timeSubmitted) {
this.timeSubmitted = timeSubmitted;

if (timeSubmitted != null) {
setTimeSubmittedDisplay(org.appfuse.util.TimestampConverter.convertToString(timeSubmitted));
}
}

Now the modified TimestampConverter from appfuse

public class TimestampConverter extends DateConverter {

    public static final String TS_FORMAT = DateUtil.getDatePattern() + " HH:mm:ss.S";

    protected Object convertToDate(Class type, Object value) {
        DateFormat df = new SimpleDateFormat(TS_FORMAT);
        if (value instanceof String) {
            try {
                if (StringUtils.isEmpty(value.toString())) {
                    return null;
                }

                return df.parse((String) value);
            } catch (Exception pe) {
                throw new ConversionException("Error converting String to Timestamp");
            }
        }

        throw new ConversionException("Could not convert "
                + value.getClass().getName() + " to " + type.getName());
    }

   
    protected Object convertToString(Class type, Object value) {
        DateFormat df = new SimpleDateFormat(TS_FORMAT);
        if (value instanceof Date) {
            try {
                return df.format(value);
            } catch (Exception e) {
                throw new ConversionException("Error converting Timestamp to String");
            }
        }

        return value.toString();
    }
    
    
    public static String convertToString(Object value) {
        DateFormat df = new SimpleDateFormat(TS_FORMAT);
        if (value instanceof Timestamp) {
            try {
                return df.format(value);
            } catch (Exception e) {
                throw new ConversionException("Error converting Timestamp to String");
            }
        }

        return value.toString();
    }
    
    public static Timestamp convertToTimestamp(Object value) {
        DateFormat df = new SimpleDateFormat(TS_FORMAT);
        if (value instanceof String) {
            try {
                if (StringUtils.isEmpty(value.toString())) {
                    return null;
                }

                return new Timestamp( df.parse((String) value).getTime() );
            } catch (Exception pe) {
                throw new ConversionException("Error converting String to Timestamp");
            }
        }

        throw new ConversionException("Could not convert String to Timestamp");
    }

}

That's it. If I didn't forget anything. Basically logic for converting Timestamp is moved to ActionForm.

One thing to watch out for is if particular date format is required e.g. dd/mm/yyyy
then edit(..) of EventAction may need to set Date explicitly like


public ActionForward edit(ActionMapping mapping, ActionForm form,
                              HttpServletRequest request,
                              HttpServletResponse response)
    throws Exception {
        if (log.isDebugEnabled()) {
            log.debug("Entering 'edit' method");
        }

        EventForm eventForm = (EventForm) form;

        // if an id is passed in, look up the user - otherwise
        // don't do anything - user is doing an add
        if (eventForm.getEventId() != null) {
            EventManager mgr = (EventManager) getBean("eventManager");
            Event event = mgr.getEvent(eventForm.getEventId());
            eventForm = (EventForm) convert(event);
            
            DateFormat df = new SimpleDateFormat(DateUtil.getDatePattern());
            
            Date startDate, endDate;
            try {
             startDate = event.getDateStart();
             if ( startDate!=null)
             eventForm.setDateStart( df.format(startDate) );
            } catch (Exception e) {
                log.error("Error getting dateStart field of Event in 'dd/MM/yyyy' format: " + e );
            }
            
            try {
             endDate = event.getDateEnd();
             if ( endDate!=null)
             eventForm.setDateEnd( df.format(endDate) );
            } catch (Exception e) {
             log.error("Error getting dateEnd field of Event in 'dd/MM/yyyy' format: " + e );
            }
            
            updateFormBean(mapping, request, eventForm);
        }

        return mapping.findForward("edit");
    }

Hope this is useful

Sam,