diff --git a/src/main/java/seedu/address/logic/commands/ExportEventXmlCommand.java b/src/main/java/seedu/address/logic/commands/ExportEventXmlCommand.java new file mode 100644 index 000000000000..96fffd619b17 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/ExportEventXmlCommand.java @@ -0,0 +1,139 @@ +package seedu.address.logic.commands; + +import static java.util.Objects.requireNonNull; + +import java.io.File; +import java.util.List; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.w3c.dom.Attr; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import seedu.address.commons.core.Messages; +import seedu.address.commons.core.index.Index; +import seedu.address.logic.CommandHistory; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; +import seedu.address.model.event.Event; + +/** + * Export an Event information as an XML + */ +public class ExportEventXmlCommand extends Command { + + public static final String COMMAND_WORD = "exporteventxml"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + ": exports an XML file of the event " + + "given the file path to the xml file\n" + + "Parameters: INDEX (must be a positive integer)\n" + + "Example: " + COMMAND_WORD + " 1"; + + private static final String MESSAGE_EXPORT_EVENT_SUCCESS = "Event at %1$d exported" + + "to your Desktop."; + private static final String MESSAGE_EXPORT_EVENT_FAILED = "Event export failed, please try again."; + + private final Index index; + private final String exportTypeE = "EVENT"; + + /** + * @param index of volunteer or event in the filtered list + */ + public ExportEventXmlCommand(Index index) { + requireNonNull(index); + this.index = index; + } + + @Override + public CommandResult execute(Model model, CommandHistory history) throws CommandException { + requireNonNull(model); + List list = model.getFilteredEventList(); + + // Handle case where the index input exceeds or equals the size of the last displayed list + if (index.getZeroBased() >= list.size()) { + throw new CommandException(Messages.MESSAGE_INVALID_EVENT_DISPLAYED_INDEX); + } + + // Get the Event object whom the index corresponds to + Event selectedEvent = list.get(index.getZeroBased()); + + try { + createEventXml(model, selectedEvent); + } catch (Exception e) { + throw new CommandException(MESSAGE_EXPORT_EVENT_FAILED); + } + + return new CommandResult(MESSAGE_EXPORT_EVENT_SUCCESS); + } + + /** + * Helper method to do the file creation and data writing + * @param model model to take the entire list + * @param event the specified event given on index + * @throws Exception - any given internal errors are thrown here + */ + private void createEventXml (Model model, Event event) throws Exception { + //setting up the document builders + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + Document doc = dBuilder.newDocument(); + + //root element - currently tag as event + Element rootElement = doc.createElement(exportTypeE); + doc.appendChild(rootElement); + + //root attributes to this particular event listing the details + Attr eventNameAttr = doc.createAttribute("Name"); + eventNameAttr.setValue(event.getName().toString()); + rootElement.setAttributeNode(eventNameAttr); + + Attr eventStartDateAttr = doc.createAttribute("Start Date"); + eventStartDateAttr.setValue(event.getStartDate().toString()); + rootElement.setAttributeNode(eventStartDateAttr); + + Attr eventStartTimeAttr = doc.createAttribute("Start Time"); + eventStartTimeAttr.setValue(event.getStartTime().toString()); + rootElement.setAttributeNode(eventStartTimeAttr); + + Attr eventEndDateAttr = doc.createAttribute("End Date"); + eventEndDateAttr.setValue(event.getEndDate().toString()); + rootElement.setAttributeNode(eventEndDateAttr); + + Attr eventEndTimeAttr = doc.createAttribute("End Time"); + eventEndTimeAttr.setValue(event.getEndTime().toString()); + rootElement.setAttributeNode(eventEndTimeAttr); + + Attr eventLocationAttr = doc.createAttribute("Location"); + eventLocationAttr.setValue(event.getLocation().toString()); + rootElement.setAttributeNode(eventLocationAttr); + + Attr eventDescriptionAttr = doc.createAttribute("Description"); + eventDescriptionAttr.setValue(event.getDescription().toString()); + rootElement.setAttributeNode(eventDescriptionAttr); + + Attr eventIdAttr = doc.createAttribute("Event ID"); + eventIdAttr.setValue(event.getEventId().toString()); + rootElement.setAttributeNode(eventIdAttr); + + //elements 1 level below root - this is used to store volunteers for the event + + // Setting up transformer + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + Transformer transformer = transformerFactory.newTransformer(); + DOMSource source = new DOMSource(doc); + + // Setting up file path + File output = new File(System.getProperty("user.home") + "/Desktop/" + + event.getName().toString() + ".xml"); + + // writing to file + StreamResult result = new StreamResult(output); + transformer.transform(source, result); + } +} diff --git a/src/main/java/seedu/address/logic/commands/ExportVolunteerCsvCommand.java b/src/main/java/seedu/address/logic/commands/ExportVolunteerCsvCommand.java new file mode 100644 index 000000000000..5031da3d752d --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/ExportVolunteerCsvCommand.java @@ -0,0 +1,114 @@ +package seedu.address.logic.commands; + +import static java.util.Objects.requireNonNull; + +import java.io.File; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.List; + +import javafx.collections.ObservableList; +import seedu.address.commons.core.Messages; +import seedu.address.commons.core.index.Index; +import seedu.address.logic.CommandHistory; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; +import seedu.address.model.volunteer.Volunteer; + +/** + * Exports a person's volunteer information from SocialCare + */ +public class ExportVolunteerCsvCommand extends Command { + public static final String COMMAND_WORD = "exportvolunteercsv"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Exports a CSV file of the volunteer " + + "the specified index in the displayed volunteer list.\n" + + "You can specify more than one volunteer to add to the CSV " + + "by adding a whitespace after each index number\n" + + "Parameters: INDEX1 (must be a positive integer) INDEX2 INDEX3 ...\n" + + "Example 1: " + COMMAND_WORD + " 1 2 3 4 5 6 7"; + + private static final String MESSAGE_EXPORT_VOLUNTEER_SUCCESS = "Volunteer(s) exported as CSV " + + "to your Desktop."; + private static final String MESSAGE_EXPORT_VOLUNTEER_FAILED = "Volunteer(s) export failed, please try again."; + + private final ArrayList index; + + /** + * @param index of volunteer or event in the filtered list + */ + public ExportVolunteerCsvCommand(ArrayList index) { + requireNonNull(index); + this.index = index; + } + + + @Override + public CommandResult execute(Model model, CommandHistory history) throws CommandException { + requireNonNull(model); + List list = model.getFilteredVolunteerList(); + + //Validate the given input within available index + for ( Index i : index ) { + // Handle case where the index input exceeds or equals the size of the last displayed list + if (i.getZeroBased() >= list.size()) { + throw new CommandException(Messages.MESSAGE_INVALID_VOLUNTEER_DISPLAYED_INDEX); + } + } + + try { + createVolunteerCsv(model.getFilteredVolunteerList(), index); + } catch (Exception e) { + throw new CommandException(MESSAGE_EXPORT_VOLUNTEER_FAILED); + } + + return new CommandResult(MESSAGE_EXPORT_VOLUNTEER_SUCCESS); + + } + + /** + * Helper method to create and write the csv file given the volunteer + * @param list to contain the list of volunteers from model + * @param index to hold the list of indexes to export + */ + private void createVolunteerCsv(ObservableList list, ArrayList index) throws Exception { + // Setting up file path + File output = new File(System.getProperty("user.home") + "/Desktop/" + + Integer.toString(index.size()) + "volunteers.csv"); + + // Setting up writer & stringbuilder for appending + PrintWriter pw = new PrintWriter(output); + StringBuilder sb = new StringBuilder(); + String csvSplit = ","; + + //appending column titles + sb.append("Name" + csvSplit); + sb.append("Phone" + csvSplit); + sb.append("Address" + csvSplit); + sb.append("Email" + csvSplit); + sb.append("Birthday" + csvSplit); + sb.append("Gender" + csvSplit); + sb.append("Tags" + csvSplit); + sb.append("VolunteerID"); + sb.append(System.getProperty("line.separator")); + + for ( Index i : index ) { + Volunteer volunteer = list.get(i.getOneBased()); + + //appending volunteer information accordingly + sb.append(volunteer.getName().toString() + csvSplit); + sb.append(volunteer.getPhone().toString() + csvSplit); + sb.append(volunteer.getAddress().toString() + csvSplit); + sb.append(volunteer.getEmail().toString() + csvSplit); + sb.append(volunteer.getBirthday().toString() + csvSplit); + sb.append(volunteer.getGender().toString() + csvSplit); + sb.append(volunteer.getTags().toString() + csvSplit); + sb.append(volunteer.getVolunteerId().toString() + csvSplit); + sb.append(System.getProperty("line.separator")); + } + + pw.write(sb.toString()); + pw.close(); + } + +} diff --git a/src/main/java/seedu/address/logic/commands/ExportVolunteerXmlCommand.java b/src/main/java/seedu/address/logic/commands/ExportVolunteerXmlCommand.java new file mode 100644 index 000000000000..056935997757 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/ExportVolunteerXmlCommand.java @@ -0,0 +1,192 @@ +package seedu.address.logic.commands; + +import static java.util.Objects.requireNonNull; + +import java.io.File; +import java.util.List; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.w3c.dom.Attr; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import seedu.address.commons.core.Messages; +import seedu.address.commons.core.index.Index; +import seedu.address.logic.CommandHistory; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; +import seedu.address.model.event.Event; +import seedu.address.model.event.EventId; +import seedu.address.model.record.Record; +import seedu.address.model.volunteer.Volunteer; + +/** + * Exports a person's volunteer information from SocialCare + */ +public class ExportVolunteerXmlCommand extends Command { + + public static final String COMMAND_WORD = "exportvolunteerxml"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Exports an XML file of the volunteer " + + "the specified index in the displayed volunteer list.\n" + + "Parameters: INDEX (must be a positive integer)\n" + + "Example: " + COMMAND_WORD + " 1"; + + private static final String MESSAGE_EXPORT_VOLUNTEER_SUCCESS = "Volunteer exported for volunteer at %1$d " + + "to your Desktop."; + private static final String MESSAGE_EXPORT_VOLUNTEER_FAILED = "Volunteer export failed, please try again."; + + private final Index index; + private final String exportTypeV = "VOLUNTEER"; + + /** + * @param index of volunteer or event in the filtered list + */ + public ExportVolunteerXmlCommand(Index index) { + requireNonNull(index); + this.index = index; + } + + @Override + public CommandResult execute(Model model, CommandHistory history) throws CommandException { + requireNonNull(model); + List list = model.getFilteredVolunteerList(); + + // Handle case where the index input exceeds or equals the size of the last displayed list + if (index.getZeroBased() >= list.size()) { + throw new CommandException(Messages.MESSAGE_INVALID_VOLUNTEER_DISPLAYED_INDEX); + } + + // Get the Volunteer object whom the index corresponds to + Volunteer selectedVolunteer = list.get(index.getZeroBased()); + + try { + createVolunteerXml(model, selectedVolunteer); + } catch (Exception e) { + throw new CommandException(MESSAGE_EXPORT_VOLUNTEER_FAILED); + } + + return new CommandResult(MESSAGE_EXPORT_VOLUNTEER_SUCCESS); + + } + + /** + * Creates and write an XML of the volunteer details & events to user desktop + * @param volunteer who's data to write + * @param model to access volunteer event records + */ + private void createVolunteerXml(Model model, Volunteer volunteer) throws Exception { + //setting up the document builders + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + Document doc = dBuilder.newDocument(); + + //root element - currently tag as volunteer + Element rootElement = doc.createElement(exportTypeV); + doc.appendChild(rootElement); + + //root attributes to this particular volunteer listing the details + Attr nameAttr = doc.createAttribute("Name"); + nameAttr.setValue(volunteer.getName().toString()); + rootElement.setAttributeNode(nameAttr); + + Attr phoneAttr = doc.createAttribute("Phone"); + phoneAttr.setValue(volunteer.getPhone().toString()); + rootElement.setAttributeNode(phoneAttr); + + Attr addressAttr = doc.createAttribute("Address"); + addressAttr.setValue(volunteer.getAddress().toString()); + rootElement.setAttributeNode(addressAttr); + + Attr emailAttr = doc.createAttribute("Email"); + emailAttr.setValue(volunteer.getEmail().toString()); + rootElement.setAttributeNode(emailAttr); + + + Attr bdayAttr = doc.createAttribute("Birthday"); + bdayAttr.setValue(volunteer.getBirthday().toString()); + rootElement.setAttributeNode(bdayAttr); + + Attr genderAttr = doc.createAttribute("Gender"); + genderAttr.setValue(volunteer.getGender().toString()); + rootElement.setAttributeNode(genderAttr); + + Attr tagsAttr = doc.createAttribute("Tags"); + tagsAttr.setValue(volunteer.getTags().toString()); + rootElement.setAttributeNode(tagsAttr); + + Attr idAttr = doc.createAttribute("VolunteerID"); + idAttr.setValue(volunteer.getVolunteerId().toString()); + rootElement.setAttributeNode(idAttr); + + + //elements 1 level below root - this is used to store events + // Retrieve the volunteer's events + List eventRecords = model.getFilteredRecordList().filtered((x) -> x.getVolunteerId() + .equals(volunteer.getVolunteerId())); + + for (int i = 1; i <= eventRecords.size(); i++) { + //take note of 0 & 1 indexing difference + Element element = doc.createElement("EVENT" + Integer.toString(i)); + Record r = eventRecords.get(i - 1); + EventId eventId = r.getEventId(); + Event event = model.getFilteredEventList().filtered( e -> e.getEventId().equals(eventId)).get(0); + + //set attr + //this is used to store event details + Attr eventNameAttr = doc.createAttribute("Name"); + eventNameAttr.setValue(event.getName().toString()); + element.setAttributeNode(eventNameAttr); + + Attr eventStartDateAttr = doc.createAttribute("Start Date"); + eventStartDateAttr.setValue(event.getStartDate().toString()); + element.setAttributeNode(eventStartDateAttr); + + Attr eventStartTimeAttr = doc.createAttribute("Start Time"); + eventStartTimeAttr.setValue(event.getStartTime().toString()); + element.setAttributeNode(eventStartTimeAttr); + + Attr eventEndDateAttr = doc.createAttribute("End Date"); + eventEndDateAttr.setValue(event.getEndDate().toString()); + element.setAttributeNode(eventEndDateAttr); + + Attr eventEndTimeAttr = doc.createAttribute("End Time"); + eventEndTimeAttr.setValue(event.getEndTime().toString()); + element.setAttributeNode(eventEndTimeAttr); + + Attr eventLocationAttr = doc.createAttribute("Location"); + eventLocationAttr.setValue(event.getLocation().toString()); + element.setAttributeNode(eventLocationAttr); + + Attr eventDescriptionAttr = doc.createAttribute("Description"); + eventDescriptionAttr.setValue(event.getDescription().toString()); + element.setAttributeNode(eventDescriptionAttr); + + Attr eventIdAttr = doc.createAttribute("Event ID"); + eventIdAttr.setValue(eventId.toString()); + element.setAttributeNode(eventIdAttr); + + //append node + rootElement.appendChild(element); + } + + // Setting up transformer + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + Transformer transformer = transformerFactory.newTransformer(); + DOMSource source = new DOMSource(doc); + + // Setting up file path + File output = new File(System.getProperty("user.home") + "/Desktop/" + + volunteer.getName().toString() + ".xml"); + + // writing to file + StreamResult result = new StreamResult(output); + transformer.transform(source, result); + } +} diff --git a/src/main/java/seedu/address/logic/parser/AddressBookParser.java b/src/main/java/seedu/address/logic/parser/AddressBookParser.java index bcda20df65d1..acd576dfe459 100644 --- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java +++ b/src/main/java/seedu/address/logic/parser/AddressBookParser.java @@ -19,6 +19,9 @@ import seedu.address.logic.commands.EditRecordCommand; import seedu.address.logic.commands.ExitCommand; import seedu.address.logic.commands.ExportCertCommand; +import seedu.address.logic.commands.ExportEventXmlCommand; +import seedu.address.logic.commands.ExportVolunteerCsvCommand; +import seedu.address.logic.commands.ExportVolunteerXmlCommand; import seedu.address.logic.commands.FindCommand; import seedu.address.logic.commands.HelpCommand; import seedu.address.logic.commands.HistoryCommand; @@ -130,6 +133,9 @@ private Command parseEventCommand(String commandWord, String arguments) throws P case ManageCommand.COMMAND_WORD: return new ManageCommandParser().parse(arguments); + case ExportEventXmlCommand.COMMAND_WORD: + return new ExportEventXmlCommandParser().parse(arguments); + default: throw new ParseException(MESSAGE_UNKNOWN_COMMAND); } @@ -167,6 +173,12 @@ private Command parseVolunteerCommand(String commandWord, String arguments) thro case ExportCertCommand.COMMAND_WORD: return new ExportCertCommandParser().parse(arguments); + case ExportVolunteerCsvCommand.COMMAND_WORD: + return new ExportVolunteerCsvCommandParser().parse(arguments); + + case ExportVolunteerXmlCommand.COMMAND_WORD: + return new ExportVolunteerXmlCommandParser().parse(arguments); + default: throw new ParseException(MESSAGE_UNKNOWN_COMMAND); } diff --git a/src/main/java/seedu/address/logic/parser/ExportEventXmlCommandParser.java b/src/main/java/seedu/address/logic/parser/ExportEventXmlCommandParser.java new file mode 100644 index 000000000000..c88c0a68ef2c --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/ExportEventXmlCommandParser.java @@ -0,0 +1,38 @@ +package seedu.address.logic.parser; + +import static java.util.Objects.requireNonNull; +import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; + +import seedu.address.commons.core.index.Index; +import seedu.address.logic.commands.ExportEventXmlCommand; +import seedu.address.logic.parser.exceptions.ParseException; + + +/** + * Parses input arguments and creates a new {@code ExportEventXmlCommand} object + */ +public class ExportEventXmlCommandParser implements Parser { + + /** + * Parses the given {@code String} of arguments in the context of the {@code ExportEventXmlCommand} + * and returns a {@code ExportEventXmlCommand} object for execution. + * @param userInput as a {@code String} + * @return ExportEventXmlCommand object + * @throws ParseException if the user input does not abide by the expected format + */ + public ExportEventXmlCommand parse(String userInput) throws ParseException { + requireNonNull(userInput); + + Index index; + try { + index = ParserUtil.parseIndex(userInput); + } catch (ParseException pe) { + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, + ExportEventXmlCommand.MESSAGE_USAGE), pe); + } + + return new ExportEventXmlCommand(index); + } + + +} diff --git a/src/main/java/seedu/address/logic/parser/ExportVolunteerCsvCommandParser.java b/src/main/java/seedu/address/logic/parser/ExportVolunteerCsvCommandParser.java new file mode 100644 index 000000000000..e0b6078012b8 --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/ExportVolunteerCsvCommandParser.java @@ -0,0 +1,41 @@ +package seedu.address.logic.parser; + +import static java.util.Objects.requireNonNull; +import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; + +import java.util.ArrayList; + +import seedu.address.commons.core.index.Index; +import seedu.address.logic.commands.ExportVolunteerCsvCommand; +import seedu.address.logic.parser.exceptions.ParseException; + + +/** + * Parses input arguments and creates a new {@code ExportVolunteerCsvCommand} object + */ +public class ExportVolunteerCsvCommandParser implements Parser { + + /** + * Parses the given {@code String} of arguments in the context of the {@code ExportVolunteerCsvCommand} + * and returns a {@code ExportVolunteerCsvCommand} object for execution. + * @param userInput as a {@code String} + * @return ExportVolunteerCsvCommand object + * @throws ParseException if the user input does not abide by the expected format + */ + public ExportVolunteerCsvCommand parse(String userInput) throws ParseException { + requireNonNull(userInput); + + ArrayList index = new ArrayList(); + try { + String[] inputs = userInput.split(" "); + for ( String i : inputs ) { + index.add(ParserUtil.parseIndex(i)); + } + } catch (ParseException pe) { + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, + ExportVolunteerCsvCommand.MESSAGE_USAGE), pe); + } + + return new ExportVolunteerCsvCommand(index); + } +} diff --git a/src/main/java/seedu/address/logic/parser/ExportVolunteerXmlCommandParser.java b/src/main/java/seedu/address/logic/parser/ExportVolunteerXmlCommandParser.java new file mode 100644 index 000000000000..c472f2eb7cd3 --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/ExportVolunteerXmlCommandParser.java @@ -0,0 +1,35 @@ +package seedu.address.logic.parser; + +import static java.util.Objects.requireNonNull; +import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; + +import seedu.address.commons.core.index.Index; +import seedu.address.logic.commands.ExportVolunteerXmlCommand; +import seedu.address.logic.parser.exceptions.ParseException; + +/** + * Parses input arguments and creates a new {@code ExportVolunteerXmlCommand} object + */ +public class ExportVolunteerXmlCommandParser implements Parser { + + /** + * Parses the given {@code String} of arguments in the context of the {@code ExportVolunteerXmlCommand} + * and returns a {@code ExportVolunteerXmlCommand} object for execution. + * @param userInput as a {@code String} + * @return ExportVolunteerXmlCommand object + * @throws ParseException if the user input does not abide by the expected format + */ + public ExportVolunteerXmlCommand parse(String userInput) throws ParseException { + requireNonNull(userInput); + + Index index; + try { + index = ParserUtil.parseIndex(userInput); + } catch (ParseException pe) { + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, + ExportVolunteerXmlCommand.MESSAGE_USAGE), pe); + } + + return new ExportVolunteerXmlCommand(index); + } +}