diff --git a/src/main/java/seedu/todo/controllers/FindController.java b/src/main/java/seedu/todo/controllers/FindController.java index 4270d90554c0..40acafdcfa10 100644 --- a/src/main/java/seedu/todo/controllers/FindController.java +++ b/src/main/java/seedu/todo/controllers/FindController.java @@ -1,21 +1,11 @@ package seedu.todo.controllers; -import java.time.LocalDateTime; -import java.time.ZoneId; -import java.util.Arrays; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; +import java.util.ArrayList; import java.util.List; -import java.util.Map; - -import com.joestelmach.natty.DateGroup; -import com.joestelmach.natty.Parser; +import java.util.function.Predicate; import seedu.todo.commons.exceptions.ParseException; -import seedu.todo.commons.util.DateUtil; import seedu.todo.commons.util.StringUtil; -import seedu.todo.controllers.concerns.Tokenizer; import seedu.todo.controllers.concerns.Renderer; import seedu.todo.models.Event; import seedu.todo.models.Task; @@ -24,19 +14,18 @@ /** * Controller to find task/event by keyword * - * @@author Tiong YaoCong A0139922Y + * @@author A0093907W * */ public class FindController implements Controller { private static final String NAME = "Find"; - private static final String DESCRIPTION = "Find all tasks and events based on the provided keywords.\n" + - "This command will be search with non-case sensitive keywords."; - private static final String COMMAND_SYNTAX = "find [name] or/and [on date]"; + private static final String DESCRIPTION = "Find tasks and events based on the provided keyword.\n"; + private static final String COMMAND_SYNTAX = "find "; private static final String COMMAND_WORD = "find"; - private static final String MESSAGE_LISTING_SUCCESS = "A total of %s found!"; - private static final String MESSAGE_LISTING_FAILURE = "No task or event found!"; + private static final String MESSAGE_LISTING_SUCCESS = "A total of %s %s and %s %s found!"; + private static final String MESSAGE_LISTING_FAILURE = "No tasks or events found!"; private static CommandDefinition commandDefinition = new CommandDefinition(NAME, DESCRIPTION, COMMAND_SYNTAX); @@ -49,330 +38,26 @@ public static CommandDefinition getCommandDefinition() { public float inputConfidence(String input) { return (input.toLowerCase().startsWith(COMMAND_WORD)) ? 1 : 0; } - - private static Map getTokenDefinitions() { - Map tokenDefinitions = new HashMap(); - tokenDefinitions.put("default", new String[] {"find"}); - tokenDefinitions.put("eventType", new String[] { "event", "events", "task", "tasks"}); - tokenDefinitions.put("status", new String[] { "complete" , "completed", "uncomplete", "uncompleted"}); - tokenDefinitions.put("time", new String[] { "at", "by", "on", "time" }); - tokenDefinitions.put("timeFrom", new String[] { "from" }); - tokenDefinitions.put("timeTo", new String[] { "to", "before" }); - tokenDefinitions.put("name", new String[] { "name" }); - tokenDefinitions.put("tag", new String [] { "tag" }); - return tokenDefinitions; - } @Override public void process(String input) throws ParseException { + input = input.replaceFirst(COMMAND_WORD, "").trim(); - Map parsedResult; - parsedResult = Tokenizer.tokenize(getTokenDefinitions(), input); - - HashSet itemNameList = new HashSet(); - HashSet tagNameList = new HashSet(); - - parseExactFindCommand(parsedResult, itemNameList); - - parseName(parsedResult, itemNameList); //parse additional name enter by user - parseTag(parsedResult, tagNameList); - - // Task or event? - boolean listAll = parseListAllType(parsedResult); - - boolean isTask = true; //default - //if listing all type , set isTask and isEvent true - if (!listAll) { - isTask = parseIsTask(parsedResult); - } - - boolean listAllStatus = parseListAllStatus(parsedResult); - boolean isCompleted = false; //default - //if listing all status, isCompleted will be ignored, listing both complete and uncomplete - if (!listAllStatus) { - isCompleted = !parseIsUncomplete(parsedResult); - } - - String[] parsedDates = parseDates(parsedResult); - if (parsedDates == null && listAllStatus == true && listAll == true - && itemNameList.size() == 0 && tagNameList.size() == 0) { - //display error message, no keyword provided - String disambiguationString = String.format("%s %s %s %s %s", COMMAND_WORD, "" , - "", "", ""); - Renderer.renderDisambiguation(disambiguationString, input); - return ; - } - - LocalDateTime dateOn = null; - LocalDateTime dateFrom = null; - LocalDateTime dateTo = null; - - if (parsedDates != null) { - String naturalOn = parsedDates[0]; - String naturalFrom = parsedDates[1]; - String naturalTo = parsedDates[2]; - - // Parse natural date using Natty. - dateOn = naturalOn == null ? null : parseNatural(naturalOn); - dateFrom = naturalFrom == null ? null : parseNatural(naturalFrom); - dateTo = naturalTo == null ? null : parseNatural(naturalTo); - } - //setting up view - setupView(isTask, listAll, isCompleted, listAllStatus, dateOn, dateFrom, dateTo, itemNameList, tagNameList); - - } - - /** - * Setting up the view - * - * @param isTask - * true if CalendarItem should be a Task, false if Event - * @param isEvent - * true if CalendarItem should be a Event, false if Task - * @param listAll - * true if listing all type, isTask or isEvent are ignored - * @param isCompleted - * true if user request completed item - * @param listAllStatus - * true if user did not request any status, isCompleted is ignored - * @param dateOn - * Date if user specify for a certain date - * @param dateFrom - * Due date for Task or start date for Event - * @param dateTo - * End date for Event - * @param itemNameList - * String of Calendar Item name that user enter as keyword - * @param tagNameList - * String of Tag Name that user enter as keyword - */ - private void setupView(boolean isTask, boolean listAll, boolean isCompleted, - boolean listAllStatus, LocalDateTime dateOn, LocalDateTime dateFrom, - LocalDateTime dateTo, HashSet itemNameList, HashSet tagNameList) { - TodoListDB db = TodoListDB.getInstance(); - List tasks = null; - List events = null; - // isTask and isEvent = true, list all type - if (listAll) { - //no event or task keyword found - isTask = false; - tasks = setupTaskView(isCompleted, listAllStatus, dateOn, dateFrom, dateTo, itemNameList, tagNameList, db); - events = setupEventView(isCompleted, listAllStatus, dateOn, dateFrom, dateTo, itemNameList, tagNameList, db); - } - - if (isTask) { - tasks = setupTaskView(isCompleted, listAllStatus, dateOn, dateFrom, dateTo, itemNameList, tagNameList, db); - } else { - events = setupEventView(isCompleted, listAllStatus, dateOn, dateFrom, dateTo, itemNameList, tagNameList, db); - } - - // Update console message - int numTasks = 0; - int numEvents = 0; - - if (tasks != null) { - numTasks = tasks.size(); - } + List> taskPredicates = new ArrayList>(); + taskPredicates.add(Task.predByName(input)); + List tasks = Task.where(taskPredicates); - if(events != null) { - numEvents = events.size(); - } - - String consoleMessage = MESSAGE_LISTING_FAILURE; - if (numTasks != 0 || numEvents != 0) { - consoleMessage = String.format(MESSAGE_LISTING_SUCCESS, formatDisplayMessage(numTasks, numEvents)); - } - - Renderer.renderSelected(db, consoleMessage, tasks, events); - - } - - private String formatDisplayMessage (int numTasks, int numEvents) { - if (numTasks != 0 && numEvents != 0) { - return String.format("%s and %s", formatTaskMessage(numTasks), formatEventMessage(numEvents)); - } else if (numTasks != 0) { - return formatTaskMessage(numTasks); - } else { - return formatEventMessage(numEvents); - } - } - - private String formatEventMessage (int numEvents) { - return String.format("%d %s", numEvents, StringUtil.pluralizer(numEvents, "event", "events")); - } - - private String formatTaskMessage (int numTasks) { - return String.format("%d %s", numTasks, StringUtil.pluralizer(numTasks, "task", "tasks")); - } - - private List setupEventView(boolean isCompleted, boolean listAllStatus, LocalDateTime dateOn, - LocalDateTime dateFrom, LocalDateTime dateTo, HashSet itemNameList, HashSet tagNameList, TodoListDB db) { - final LocalDateTime NO_DATE = null; - if (dateFrom == null && dateTo == null && dateOn == null) { - if (listAllStatus && itemNameList.size() == 0 && tagNameList.size() == 0) { - System.out.println("error"); //TODO : Nothing found - return null; - } else if (listAllStatus && (itemNameList.size() != 0 || tagNameList.size() != 0)) { - return db.getEventByName(db.getAllEvents(), itemNameList, tagNameList); - } - else if (isCompleted) { - return db.getEventByRangeWithName(NO_DATE, LocalDateTime.now(), itemNameList, tagNameList); - } else { - return db.getEventByRangeWithName(LocalDateTime.now(), NO_DATE, itemNameList, tagNameList); - } - } else if (dateOn != null) { //by keyword found - return db.getEventbyDateWithName(dateOn, itemNameList, tagNameList); - } else { - return db.getEventByRangeWithName(dateFrom, dateTo, itemNameList, tagNameList); - } - } - - private List setupTaskView(boolean isCompleted, boolean listAllStatus, LocalDateTime dateOn, - LocalDateTime dateFrom, LocalDateTime dateTo, HashSet itemNameList, HashSet tagNameList, TodoListDB db) { - if (dateFrom == null && dateTo == null && dateOn == null) { - if (listAllStatus && itemNameList.size() == 0 && tagNameList.size() == 0) { - System.out.println("error"); //TODO : Nothing found - return null; - } else { - //getting all task by the name, dateFrom and dateTo will be null - return db.getTaskByRangeWithName(dateFrom, dateTo, isCompleted, listAllStatus, itemNameList, tagNameList); - } - } else if (dateOn != null) { //by keyword found - return db.getTaskByDateWithStatusAndName(dateOn, isCompleted, listAllStatus, itemNameList, tagNameList); - } else { - return db.getTaskByRangeWithName(dateFrom, dateTo, isCompleted, listAllStatus, itemNameList, tagNameList); - } - } - - /** - * Extract the name keyword enter by the user and put in the hashset of name keywords - * @param parsedResult - */ - private void parseExactFindCommand(Map parsedResult, HashSet itemNameList) { - if (parsedResult.get("default")[1] != null) { - String[] result = parsedResult.get("default")[1].trim().split(" "); - for (int i = 0; i < result.length; i ++) { - itemNameList.add(result[i]); - } - } - } - - /** - * Extract the name keyword enter by the user and put in the hashset of name keywords - * @param parsedResult, tagNameList to store all the keywords - */ - - private void parseName(Map parsedResult, HashSet itemNameList) { - if (parsedResult.get("name") != null && parsedResult.get("name")[1] != null) { - String[] result = parsedResult.get("name")[1].trim().split(" "); - for (int i = 0; i < result.length; i ++) { - itemNameList.add(result[i].trim()); - } - } - } - - /** - * Extract the tag name keyword enter by the user and put in the hashset of tag keywords - * @param parsedResult, tagNameList to store all the keywords - */ - - private void parseTag(Map parsedResult, HashSet tagNameList) { - if (parsedResult.get("tag") != null && parsedResult.get("tag")[1] != null) { - String[] result = parsedResult.get("tag")[1].trim().split(","); - for (int i = 0; i < result.length; i ++) { - tagNameList.add(result[i].trim()); - } - } - } - - /** - * Parse a natural date into a LocalDateTime object. - * - * @param natural - * @return LocalDateTime object - */ - private LocalDateTime parseNatural(String natural) { - Parser parser = new Parser(); - List groups = parser.parse(natural); - Date date = null; - try { - date = groups.get(0).getDates().get(0); - } catch (IndexOutOfBoundsException e) { - System.out.println("Error!"); // TODO - return null; - } - LocalDateTime ldt = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()); - return DateUtil.floorDate(ldt); - } - - /** - * Extracts the intended CalendarItem type specify from parsedResult. - * - * @param parsedResult - * @return true if Task or event is not specify, false if either Task or Event specify - */ - private boolean parseListAllType (Map parsedResult) { - return !(parsedResult.get("eventType") != null); - } - - /** - * Extracts the intended status type specify from parsedResult. - * - * @param parsedResult - * @return true if Task or event is not specify, false if either Task or Event specify - */ - private boolean parseListAllStatus (Map parsedResult) { - return !(parsedResult.get("status") != null); - } - - /** - * Extracts the intended CalendarItem status from parsedResult. - * - * @param parsedResult - * @return true if uncomplete, false if complete - */ - private boolean parseIsUncomplete (Map parsedResult) { - return parsedResult.get("status")[0].contains("uncomplete"); - } - - /** - * Extracts the intended CalendarItem type from parsedResult. - * - * @param parsedResult - * @return true if Task, false if Event - */ - private boolean parseIsTask (Map parsedResult) { - return parsedResult.get("eventType")[0].contains("task"); - } - - /** - * Extracts the natural dates from parsedResult. - * - * @param parsedResult - * @return { naturalOn, naturalFrom, naturalTo } - */ - private String[] parseDates(Map parsedResult) { - String naturalFrom = null; - String naturalTo = null; - String naturalOn = null; + List> eventPredicates = new ArrayList>(); + eventPredicates.add(Event.predByName(input)); + List events = Event.where(eventPredicates); - if (parsedResult.get("time") == null) { - if (parsedResult.get("timeFrom") != null) { - naturalFrom = parsedResult.get("timeFrom")[1]; - } - if (parsedResult.get("timeTo") != null) { - naturalTo = parsedResult.get("timeTo")[1]; - } + if (tasks.size() == 0 && events.size() == 0) { + Renderer.renderIndex(TodoListDB.getInstance(), MESSAGE_LISTING_FAILURE); } else { - naturalOn = parsedResult.get("time")[1]; + String consoleMessage = String.format(MESSAGE_LISTING_SUCCESS, + tasks.size(), StringUtil.pluralizer(tasks.size(), "task", "tasks"), + events.size(), StringUtil.pluralizer(events.size(), "event", "events")); + Renderer.renderSelected(TodoListDB.getInstance(), consoleMessage, tasks, events); } - - if (naturalFrom == null && naturalTo == null && naturalOn == null) { - // no date found - return null; - } - return new String[] { naturalOn, naturalFrom, naturalTo }; } - - }