package com.globant.katari.sample.time.view; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang.Validate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.propertyeditors.CustomDateEditor; import org.springframework.validation.BindException; import org.springframework.web.bind.ServletRequestDataBinder; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.SimpleFormController; import com.globant.katari.sample.time.application.SaveTimeEntryCommand; import com.globant.katari.sample.time.domain.Activity; import com.globant.katari.sample.time.domain.Project; import com.globant.katari.sample.time.domain.TimeRepository; /** Defines common functionality to edit and save time entries. * * Customize a binder with a date and defines the format date to be used. * Sets the reference data for projects and activities. * * @author nicolas.frontini */ public abstract class BaseTimeController extends SimpleFormController { /** The class logger. */ private static Logger log = LoggerFactory.getLogger(BaseTimeController.class); /** The simple date format. */ private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM/dd/yyyy"); /** The time entry repository. */ private TimeRepository timeRepository; /** Formats a Date into a date/time string. * * @param date the time value to be formatted into a time string. * * @return the formatted time string. */ public static String formatDate(final Date date) { return getDateFormat().format(date); } /** Returns the date format. * * @return the date format. */ public static DateFormat getDateFormat() { return simpleDateFormat; } /** Default initialization for the controller. * * The list of roles provide all the existing roles in the system. * * @param theTimeRepository The time entry repository. */ public BaseTimeController(final TimeRepository theTimeRepository) { Validate.notNull(theTimeRepository, "The time entry repository cannot be null"); timeRepository = theTimeRepository; } /** Receives the request to save a time entry. * * Generate a view for a specific view name, returning the ModelAndView * provided there. * * @param request The HTTP request we are processing. * * @param response The HTTP response we are creating. * * @param command Form object with request parameters bound onto it. * * @param errors Errors instance without errors. * * @exception Exception if the application logic throws an exception. * * @return the ModelAndView for the next view. */ protected final ModelAndView onSubmit(final HttpServletRequest request, final HttpServletResponse response, final Object command, final BindException errors) throws Exception { log.trace("Entering onSubmit"); SaveTimeEntryCommand saveTimeEntryCommand = (SaveTimeEntryCommand) command; saveTimeEntryCommand.execute(); ModelAndView successMav = new ModelAndView("redirect:myTime.do?date=" + formatDate(saveTimeEntryCommand.getDate())); log.trace("Leaving onSubmit"); return successMav; } /** Gets the time entry repository. * * @return The time entry repository. */ protected TimeRepository getTimeRepository() { return timeRepository; } /** Initialize the given binder instance with a custom date editor. * * @param request current HTTP request. * * @param binder the new binder instance. * * @exception Exception if the application logic throws an exception. */ @Override protected void initBinder(final HttpServletRequest request, final ServletRequestDataBinder binder) throws Exception { super.initBinder(request, binder); binder.registerCustomEditor(Date.class, new CustomDateEditor( new SimpleDateFormat("MM/dd/yyyy"), true)); } /** Retrieve a backing object for the current form from the given request. * * @param request The HTTP request we are processing. * * @exception Exception if the application logic throws an exception. * * @return The command bean object. */ @Override protected Object formBackingObject(final HttpServletRequest request) throws Exception { return createCommandBean(); } /** This method is injected by AOP. * * @return Returns the command bean injected. */ protected abstract Object createCommandBean(); /** Sets reference data used in the view. * * @param request The HTTP request we are processing. * * @exception Exception if the application logic throws an exception. * * @return A <code>Map</code> with the reference data. */ @Override protected Map<String, Object> referenceData(final HttpServletRequest request) throws Exception { Map<String, Object> reference = new LinkedHashMap<String, Object>(); reference.put("request", request); reference.put("baseweb", request.getAttribute("baseweb")); // Projects. List<Project> projects = timeRepository.getProjects(); Map<String, String> projectsMap = new LinkedHashMap<String, String>(); for (Project project : projects) { projectsMap.put(String.valueOf(project.getId()), project.getName()); } reference.put("projects", projectsMap); // Activities. List<Activity> activities = timeRepository.getActivities(); Map<String, String> activitiesMap = new LinkedHashMap<String, String>(); for (Activity activity : activities) { activitiesMap.put(String.valueOf(activity.getId()), activity.getName()); } reference.put("activities", activitiesMap); return reference; } }