package tudu.service.impl; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hibernate.Hibernate; import org.jdom.Document; import org.jdom.Element; import org.jdom.JDOMException; import org.jdom.input.SAXBuilder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.orm.ObjectRetrievalFailureException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import tudu.domain.Todo; import tudu.domain.TodoList; import tudu.domain.User; import tudu.security.PermissionDeniedException; import tudu.service.TodoListsService; import tudu.service.UserService; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import java.io.IOException; import java.io.InputStream; import java.util.Calendar; import java.util.Date; import java.util.List; /** * Implementation of the tudu.service.TodoListsService interface. * * @author Julien Dubois */ @Service @Transactional public class TodoListsServiceImpl implements TodoListsService { private final Log log = LogFactory.getLog(TodoListsServiceImpl.class); @PersistenceContext private EntityManager em; @Autowired private UserService userService; /** * Create a new Todo List. * * @see tudu.service.TodoListsService#createTodoList(tudu.domain.TodoList) */ public void createTodoList(final TodoList todoList) { if (log.isDebugEnabled()) { log.debug("Creating a new Todo List with name " + todoList.getName()); } todoList.setLastUpdate(Calendar.getInstance().getTime()); User user = userService.getCurrentUser(); todoList.getUsers().add(user); em.persist(todoList); user.getTodoLists().add(todoList); } /** * @see tudu.service.TodoListsService#findTodoList(java.lang.String) */ @Transactional(readOnly = true) public TodoList findTodoList(String listId) { TodoList todoList = em.find(TodoList.class, listId); if (todoList == null) { throw new ObjectRetrievalFailureException(TodoList.class, listId); } User user = userService.getCurrentUser(); if (!user.getTodoLists().contains(todoList)) { if (log.isInfoEnabled()) { log.info("Permission denied when finding Todo List ID '" + listId + "' for User '" + user.getLogin() + "'"); } throw new PermissionDeniedException( "Permission denied to access this Todo List."); } return todoList; } /** * @see tudu.service.TodoListsService#unsecuredFindTodoList(java.lang.String) */ @Transactional(readOnly = true) public TodoList unsecuredFindTodoList(String listId) { TodoList todoList = em.find(TodoList.class, listId); Hibernate.initialize(todoList.getTodos()); return todoList; } /** * Updates the Todo List last update date. * * @see tudu.service.TodoListsService#updateTodoList(tudu.domain.TodoList) */ public void updateTodoList(final TodoList todoList) { todoList.setLastUpdate(Calendar.getInstance().getTime()); } /** * Delete a Todo List. * * @see tudu.service.TodoListsService#deleteTodoList(java.lang.String) */ public void deleteTodoList(final String listId) { TodoList todoList = this.findTodoList(listId); for (User user : todoList.getUsers()) { user.getTodoLists().remove(todoList); } for (Todo todo : todoList.getTodos()) { em.remove(todo); } em.remove(todoList); } /** * @see tudu.service.TodoListsService#addTodoListUser(java.lang.String, * java.lang.String) */ public void addTodoListUser(String listId, String login) { TodoList todoList = this.findTodoList(listId); User targetUser = userService.findUser(login); todoList.getUsers().add(targetUser); targetUser.getTodoLists().add(todoList); this.updateTodoList(todoList); } /** * @see tudu.service.TodoListsService#deleteTodoListUser(java.lang.String, * java.lang.String) */ public void deleteTodoListUser(String listId, String login) { TodoList todoList = this.findTodoList(listId); User targetUser = userService.findUser(login); for (Todo todo : todoList.getTodos()) { if (todo.getAssignedUser() != null && todo.getAssignedUser().equals(targetUser)) { todo.setAssignedUser(null); } } todoList.getUsers().remove(targetUser); targetUser.getTodoLists().remove(todoList); this.updateTodoList(todoList); } public Document backupTodoList(String listId) { TodoList todoList = findTodoList(listId); Document doc = new Document(); Element todoListElement = new Element("todolist"); todoListElement.addContent(new Element("title").addContent(todoList .getName())); todoListElement.addContent(new Element("rss").addContent(String .valueOf(todoList.isRssAllowed()))); Element todosElement = new Element("todos"); for (Todo todo : todoList.getTodos()) { Element todoElement = new Element("todo"); todoElement.setAttribute("id", todo.getTodoId()); todoElement.addContent(new Element("creationDate").addContent(Long .toString(todo.getCreationDate().getTime()))); todoElement.addContent(new Element("description").addContent(todo .getDescription())); todoElement.addContent(new Element("priority").addContent(Integer .toString(todo.getPriority()))); if (todo.getDueDate() != null) { todoElement.addContent(new Element("dueDate").addContent(Long .toString(todo.getDueDate().getTime()))); } todoElement.addContent(new Element("completed").addContent(Boolean .toString(todo.isCompleted()))); if (todo.isCompleted() && todo.getCompletionDate() != null) { todoElement.addContent(new Element("completionDate") .addContent(Long.toString(todo.getCompletionDate() .getTime()))); } todoElement.addContent(new Element("notes").addContent(todo .getNotes())); todosElement.addContent(todoElement); } todoListElement.addContent(todosElement); doc.addContent(todoListElement); return doc; } /** * @see tudu.service.TodoListsService#restoreTodoList(java.lang.String, * java.lang.String, java.io.InputStream) */ public void restoreTodoList(String restoreChoice, String listId, InputStream todoListContent) throws JDOMException, IOException { SAXBuilder saxBuilder = new SAXBuilder(); Document doc = saxBuilder.build(todoListContent); Element rootElement = doc.getRootElement(); String title = rootElement.getChildText("title"); String rss = rootElement.getChildText("rss"); if (restoreChoice.equals("create")) { TodoList todoList = new TodoList(); todoList.setName(title); todoList.setRssAllowed(Boolean.parseBoolean(rss)); this.createTodoList(todoList); importTodosFromXml(todoList, rootElement); } else if (restoreChoice.equals("replace")) { TodoList todoList = this.findTodoList(listId); for (Todo todo : todoList.getTodos()) { em.remove(todo); } todoList.getTodos().clear(); todoList.setName(title); todoList.setRssAllowed(Boolean.parseBoolean(rss)); importTodosFromXml(todoList, rootElement); this.updateTodoList(todoList); } else if (restoreChoice.equals("merge")) { TodoList todoList = this.findTodoList(listId); importTodosFromXml(todoList, rootElement); this.updateTodoList(todoList); } else { log.error("Wrong choice of RestoreController option"); } } /** * Import Todos from a JDOM document. * * @param todoList The current Todo List * @param rootElement The root element of the JDOM document. */ @SuppressWarnings("unchecked") private void importTodosFromXml(TodoList todoList, Element rootElement) { Element todosElement = rootElement.getChild("todos"); List todos = todosElement.getChildren(); for (Object todoObject : todos) { Element todoElement = (Element) todoObject; Todo todo = new Todo(); Date creationDate = new Date(Long.parseLong(todoElement .getChildText("creationDate"))); todo.setCreationDate(creationDate); todo.setDescription(todoElement.getChildText("description")); todo.setPriority(Integer.valueOf(todoElement .getChildText("priority"))); todo.setCompleted(Boolean.parseBoolean(todoElement .getChildText("completed"))); String completionDate = todoElement.getChildText("completionDate"); if (completionDate != null) { todo .setCompletionDate(new Date(Long .parseLong(completionDate))); } String dueDate = todoElement.getChildText("dueDate"); if (dueDate != null) { todo.setDueDate(new Date(Long.parseLong(dueDate))); } String notes = todoElement.getChildText("notes"); if (notes == null || notes.length() == 0) { todo.setHasNotes(false); } else { todo.setNotes(notes); todo.setHasNotes(true); } todo.setTodoList(todoList); todoList.getTodos().add(todo); em.persist(todo); } } }