package tudu.web.dwr.impl; import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.directwebremoting.WebContextFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.orm.ObjectRetrievalFailureException; import org.springframework.stereotype.Component; import tudu.domain.model.Todo; import tudu.domain.model.TodoList; import tudu.domain.model.User; import tudu.domain.model.comparator.*; import tudu.service.TodoListsManager; import tudu.service.TodosManager; import tudu.service.UserManager; import tudu.web.dwr.TodosDwr; import tudu.web.dwr.bean.RemoteTodo; import tudu.web.dwr.bean.RemoteTodoList; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import java.io.IOException; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; /** * Implementation of the tudu.service.TodosManager interface. * * @author Julien Dubois */ @Component("todosDwr") public class TodosDwrImpl implements TodosDwr { private static final String TODO_LIST_SORT_BY = "TODO_LIST_SORT_BY"; private static final String SORT_BY_PRIORITY = "priority"; private static final String SORT_BY_PRIORITY_ASC = "priority_asc"; private static final String SORT_BY_DESCRIPTION = "description"; private static final String SORT_BY_DESCRIPTION_ASC = "description_asc"; private static final String SORT_BY_DUE_DATE = "due_date"; private static final String SORT_BY_DUE_DATE_ASC = "due_date_asc"; private static final String SORT_BY_ASSIGNED_USER = "assigned_user"; private static final String SORT_BY_ASSIGNED_USER_ASC = "assigned_user_asc"; private final Log log = LogFactory.getLog(TodosDwrImpl.class); @Autowired private UserManager userManager; @Autowired private TodosManager todosManager; @Autowired private TodoListsManager todoListsManager; /** * @see tudu.web.dwr.TodosDwr#getCurrentTodoLists(java.util.Date) */ public RemoteTodoList[] getCurrentTodoLists(Date menuDate) { User user = userManager.getCurrentUser(); Collection<TodoList> todoLists = user.getTodoLists(); if (menuDate != null) { boolean aListHasBeenUpdated = false; for (TodoList todoList : todoLists) { if (todoList.getLastUpdate().after(menuDate)) { aListHasBeenUpdated = true; } } if (!aListHasBeenUpdated) { return null; } } Collection<RemoteTodoList> remoteTodoLists = new TreeSet<RemoteTodoList>(); for (TodoList todoList : todoLists) { RemoteTodoList remoteTodoList = new RemoteTodoList(); remoteTodoList.setListId(todoList.getListId()); remoteTodoList.setName(todoList.getName()); int completed = 0; for (Todo todo : todoList.getTodos()) { if (todo.isCompleted()) { completed++; } } remoteTodoList.setDescription(todoList.getName() + " (" + completed + "/" + todoList.getTodos().size() + ")"); remoteTodoLists.add(remoteTodoList); } return remoteTodoLists.toArray(new RemoteTodoList[remoteTodoLists .size()]); } /** * @see tudu.web.dwr.TodosDwr#forceGetCurrentTodoLists() */ public RemoteTodoList[] forceGetCurrentTodoLists() { return this.getCurrentTodoLists(null); } /** * @see tudu.web.dwr.TodosDwr#getTodoById(java.lang.String) */ public RemoteTodo getTodoById(String todoId) { Todo todo = todosManager.findTodo(todoId); RemoteTodo remoteTodo = new RemoteTodo(); String unescapedDescription = StringEscapeUtils.unescapeHtml(todo .getDescription()); remoteTodo.setDescription(unescapedDescription); remoteTodo.setPriority(todo.getPriority()); if (todo.getDueDate() != null) { String formattedDate = getDateFormatter().format(todo.getDueDate()); remoteTodo.setDueDate(formattedDate); } else { remoteTodo.setDueDate(""); } remoteTodo.setHasNotes(todo.isHasNotes()); if (remoteTodo.isHasNotes()) { remoteTodo.setNotes(todo.getNotes()); } if (todo.getAssignedUser() != null) { remoteTodo.setAssignedUserLogin(todo.getAssignedUser().getLogin()); } return remoteTodo; } /** * @see tudu.web.dwr.TodosDwr#renderTodos(java.lang.String, java.util.Date) */ public String renderTodos(String listId, Date tableDate) { HttpServletRequest request = WebContextFactory.get() .getHttpServletRequest(); if (listId != null && !listId.equals("")) { TodoList todoList = todoListsManager.findTodoList(listId); if (tableDate != null && todoList.getLastUpdate().before(tableDate)) { return ""; } request.setAttribute("todoList", todoList); Set<Todo> todos = todoList.getTodos(); String sorter = (String) request.getSession().getAttribute( TODO_LIST_SORT_BY); Set<Todo> sortedTodos; String descriptionClass = "sortable"; String priorityClass = "sortable"; String dueDateClass = "sortable"; String assignedUserClass = "sortable"; if (sorter != null) { if (sorter.equals(SORT_BY_DESCRIPTION)) { descriptionClass = "sorted"; sortedTodos = new TreeSet<Todo>( new TodoByDescriptionComparator()); } else if (sorter.equals(SORT_BY_DESCRIPTION_ASC)) { descriptionClass = "sorted_asc"; sortedTodos = new TreeSet<Todo>( new TodoByDescriptionAscComparator()); } else if (sorter.equals(SORT_BY_DUE_DATE)) { dueDateClass = "sorted"; sortedTodos = new TreeSet<Todo>( new TodoByDueDateComparator()); } else if (sorter.equals(SORT_BY_DUE_DATE_ASC)) { dueDateClass = "sorted_asc"; sortedTodos = new TreeSet<Todo>( new TodoByDueDateAscComparator()); } else if (sorter.equals(SORT_BY_ASSIGNED_USER)) { assignedUserClass = "sorted"; sortedTodos = new TreeSet<Todo>( new TodoByAssignedUserComparator()); } else if (sorter.equals(SORT_BY_ASSIGNED_USER_ASC)) { assignedUserClass = "sorted_asc"; sortedTodos = new TreeSet<Todo>( new TodoByAssignedUserAscComparator()); } else if (sorter.equals(SORT_BY_PRIORITY_ASC)) { priorityClass = "sorted_asc"; sortedTodos = new TreeSet<Todo>( new TodoByPriorityAscComparator()); } else { priorityClass = "sorted"; sortedTodos = new TreeSet<Todo>(); } } else { priorityClass = "sorted"; sortedTodos = new TreeSet<Todo>(); } String hideOlderTodos = (String) request.getSession().getAttribute( "hideOlderTodos"); if (hideOlderTodos == null) { hideOlderTodos = "true"; request.getSession().setAttribute("hideOlderTodos", hideOlderTodos); } if (hideOlderTodos.equals("true")) { Calendar oneDayAgo = Calendar.getInstance(); oneDayAgo.set(Calendar.DATE, oneDayAgo.get(Calendar.DATE) - 1); oneDayAgo.set(Calendar.HOUR, 0); oneDayAgo.set(Calendar.MINUTE, 0); oneDayAgo.set(Calendar.SECOND, 0); int hiddenTodos = 0; for (Todo todo : todos) { if (todo.getCompletionDate() == null || todo.getCompletionDate().after( oneDayAgo.getTime())) { sortedTodos.add(todo); } else { hiddenTodos++; } } request.setAttribute("hiddenTodos", hiddenTodos); } else { sortedTodos.addAll(todos); } request.setAttribute("todos", sortedTodos); request.setAttribute("descriptionClass", descriptionClass); request.setAttribute("priorityClass", priorityClass); request.setAttribute("dueDateClass", dueDateClass); request.setAttribute("assignedUserClass", assignedUserClass); int nbCompleted = 0; for (Todo todo : todos) { if (todo.isCompleted()) { nbCompleted++; } } if (todos.size() != 0) { request.setAttribute("completion", nbCompleted * 100 / todos.size()); } else { request.setAttribute("completion", 100); } } else { return ""; } try { return WebContextFactory.get().forwardToString( "/WEB-INF/fragments/todos_table.jsp"); } catch (ServletException e) { log.error("ServletException : " + e); return ""; } catch (IOException ioe) { log.error("IOException : " + ioe); return ""; } } /** * @see tudu.web.dwr.TodosDwr#renderNextDays() */ public String renderNextDays() { HttpServletRequest request = WebContextFactory.get() .getHttpServletRequest(); request.setAttribute("filter", "nextDays"); request.setAttribute("todos", todosManager.findUrgentTodos()); return renderFilter(); } public String renderAssignedToMe() { HttpServletRequest request = WebContextFactory.get() .getHttpServletRequest(); request.setAttribute("filter", "assignedToMe"); request.setAttribute("todos", todosManager.findAssignedTodos()); return renderFilter(); } /** * Render the filtered data. */ private String renderFilter() { try { return WebContextFactory.get().forwardToString( "/WEB-INF/fragments/todos_table_filter.jsp"); } catch (ServletException e) { log.error("ServletException : " + e); return ""; } catch (IOException ioe) { log.error("IOException : " + ioe); return ""; } } /** * @see tudu.web.dwr.TodosDwr#forceRenderTodos(java.lang.String) */ public String forceRenderTodos(String listId) { return this.renderTodos(listId, null); } /** * Sort the List according to the "sorter" passed as parameter. * <p> * If the provided "sorter" is equals to the current list "sorter", then the * user must have clicked again on the sort button : in that case he wants * to sort the list the other way around (ascending). * </p> * * @see tudu.web.dwr.TodosDwr#sortAndRenderTodos(java.lang.String, * java.lang.String) */ public String sortAndRenderTodos(String listId, String sorter) { HttpSession session = WebContextFactory.get().getHttpServletRequest() .getSession(); String currentSorter = (String) session.getAttribute(TODO_LIST_SORT_BY); if (currentSorter != null && currentSorter.equals(sorter) && !currentSorter.endsWith("_asc")) { sorter += "_asc"; } else if (currentSorter == null && sorter.equals(SORT_BY_PRIORITY)) { sorter += "_asc"; } session.setAttribute(TODO_LIST_SORT_BY, sorter); return this.forceRenderTodos(listId); } /** * @see tudu.web.dwr.TodosDwr#addTodo(java.lang.String, java.lang.String, * java.lang.String, java.lang.String, java.lang.String, * java.lang.String) */ public String addTodo(String listId, String description, String priority, String dueDate, String notes, String assignedUserLogin) { Todo todo = new Todo(); String escapedDescription = StringEscapeUtils.escapeHtml(description); todo.setDescription(escapedDescription); int priorityInt = 0; try { priorityInt = Integer.valueOf(priority); } catch (NumberFormatException e) { // The priority is not a number. } todo.setPriority(priorityInt); try { Date due = getDateFormatter().parse(dueDate); todo.setDueDate(due); } catch (ParseException e) { // The date is not correct } inputNotes(todo, notes); inputAssignedUser(todo, assignedUserLogin); todosManager.createTodo(listId, todo); return forceRenderTodos(listId); } /** * @see tudu.web.dwr.TodosDwr#reopenTodo(java.lang.String) */ public String reopenTodo(String todoId) { Todo todo = todosManager.reopenTodo(todoId); return forceRenderTodos(todo.getTodoList().getListId()); } /** * @see tudu.web.dwr.TodosDwr#completeTodo(java.lang.String) */ public String completeTodo(String todoId) { Todo todo = todosManager.completeTodo(todoId); return forceRenderTodos(todo.getTodoList().getListId()); } /** * @see tudu.web.dwr.TodosDwr#editTodo(java.lang.String, java.lang.String, * java.lang.String, java.lang.String, java.lang.String, * java.lang.String) */ public String editTodo(String todoId, String description, String priority, String dueDate, String notes, String assignedUserLogin) { Todo todo = todosManager.findTodo(todoId); String escapedDescription = StringEscapeUtils.escapeHtml(description); todo.setDescription(escapedDescription); int priorityInt = 0; try { priorityInt = Integer.parseInt(priority); } catch (NumberFormatException e) { // The priority is not a number. } todo.setPriority(priorityInt); if (dueDate == null || dueDate.equals("")) { todo.setDueDate(null); } else { try { Date due = getDateFormatter().parse(dueDate); todo.setDueDate(due); } catch (ParseException e) { // The date is not correct } } inputNotes(todo, notes); inputAssignedUser(todo, assignedUserLogin); todosManager.updateTodo(todo); return forceRenderTodos(todo.getTodoList().getListId()); } /** * @see tudu.web.dwr.TodosDwr#quickEditTodo(java.lang.String, java.lang.String) */ public String quickEditTodo(String todoId, String description) { Todo todo = todosManager.findTodo(todoId); String escapedDescription = StringEscapeUtils.escapeHtml(description); todo.setDescription(escapedDescription); todosManager.updateTodo(todo); return forceRenderTodos(todo.getTodoList().getListId()); } /** * @see tudu.web.dwr.TodosDwr#deleteTodo(java.lang.String) */ public String deleteTodo(String todoId) { Todo todo = todosManager.findTodo(todoId); String listId = todo.getTodoList().getListId(); todosManager.deleteTodo(todoId); return forceRenderTodos(listId); } /** * @see tudu.web.dwr.TodosDwr#deleteAllCompletedTodos(java.lang.String) */ public String deleteAllCompletedTodos(String listId) { todosManager.deleteAllCompletedTodos(listId); return forceRenderTodos(listId); } /** * @see tudu.web.dwr.TodosDwr#showOlderTodos(java.lang.String) */ public String showOlderTodos(String listId) { HttpSession session = WebContextFactory.get().getHttpServletRequest() .getSession(); session.setAttribute("hideOlderTodos", "false"); return forceRenderTodos(listId); } /** * @see tudu.web.dwr.TodosDwr#hideOlderTodos(java.lang.String) */ public String hideOlderTodos(String listId) { HttpSession session = WebContextFactory.get().getHttpServletRequest() .getSession(); session.setAttribute("hideOlderTodos", "true"); return forceRenderTodos(listId); } /** * Find a Date Formatter. * * @return the Date formatter */ protected SimpleDateFormat getDateFormatter() { String dateFormat = (String) WebContextFactory.get().getSession() .getAttribute("dateFormat"); if (dateFormat == null) { dateFormat = userManager.getCurrentUser().getDateFormat(); WebContextFactory.get().getSession().setAttribute("dateFormat", dateFormat); } return new SimpleDateFormat(dateFormat); } /** * Insert notes into the todo. * * @param todo * The Todo * @param notes * The notes */ protected void inputNotes(Todo todo, String notes) { if (notes != null && !notes.equals("")) { todo.setHasNotes(true); if (notes.length() > 10000) { todo.setNotes(notes.substring(0, 10000)); } else { todo.setNotes(notes); } } else { todo.setHasNotes(false); todo.setNotes(null); } } /** * Insert the assigned user into the todo. * * @param todo * The Todo * @param assignedUserLogin * The login of the assigned user */ private void inputAssignedUser(Todo todo, String assignedUserLogin) { if (assignedUserLogin != null && !assignedUserLogin.equals("")) { try { User assignedUser = userManager.findUser(assignedUserLogin); todo.setAssignedUser(assignedUser); } catch (ObjectRetrievalFailureException orfe) { todo.setAssignedUser(null); } } else { todo.setAssignedUser(null); } } }