Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Import/Export command #232

Merged
merged 21 commits into from
Nov 6, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
167 changes: 167 additions & 0 deletions src/main/java/seedu/address/logic/commands/ExportEventXmlCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
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.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
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.LogsCenter;
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";
private static final String MESSAGE_EXPORT_EVENT_FAILED = "Event export failed, please try again.";
private static final String TRANSFORMER_ERROR = "Transformer error.";
private static final String PARSER_ERROR = "Parser error.";

private static final String DEFAULT_SAVE_PATH = System.getProperty("user.dir") + "/Event Xml/";
private static final String ALT_SAVE_PATH = System.getProperty("user.home") + "/Desktop/";
private static String SAVE_PATH = DEFAULT_SAVE_PATH;

private static final java.util.logging.Logger logger = LogsCenter.getLogger(ExportEventXmlCommand.class);


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;

//Create folder for output
File exportDir = new File(DEFAULT_SAVE_PATH);
if (!exportDir.exists()) {
try {
exportDir.mkdir();
} catch (SecurityException se) {
logger.warning("Couldn't create a relative export path next to jar file. "
+ "Defaulting to user's Desktop.");
SAVE_PATH = ALT_SAVE_PATH;
}
}
}

@Override
public CommandResult execute(Model model, CommandHistory history) throws CommandException {
requireNonNull(model);
List<Event> 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 (TransformerException e) {
throw new CommandException(MESSAGE_EXPORT_EVENT_FAILED + TRANSFORMER_ERROR);
} catch (ParserConfigurationException e) {
throw new CommandException(MESSAGE_EXPORT_EVENT_FAILED + PARSER_ERROR);
}

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 ParserConfigurationException - document builder errors
* @throws TransformerException - transformer writing error
*/
private void createEventXml(Model model, Event event) throws TransformerException,
ParserConfigurationException {
//setting up the document builders
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docuBuilder = dbFactory.newDocumentBuilder();
Document doc = docuBuilder.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(SAVE_PATH
+ event.getName().toString() + event.getEventId().toString()
+ ".xml");

// writing to file
StreamResult result = new StreamResult(output);
transformer.transform(source, result);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package seedu.address.logic.commands;

import static java.util.Objects.requireNonNull;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

import javafx.collections.ObservableList;
import seedu.address.commons.core.LogsCenter;
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: " + COMMAND_WORD + " 1 2 3 4 5 6 7";

private static final String MESSAGE_EXPORT_VOLUNTEER_SUCCESS = "Volunteer(s) exported as CSV ";
private static final String MESSAGE_EXPORT_VOLUNTEER_FAILED = "Volunteer(s) export failed, please try again.";

private static final String DEFAULT_SAVE_PATH = System.getProperty("user.dir") + "/Volunteer Csv/";
private static final String ALT_SAVE_PATH = System.getProperty("user.home") + "/Desktop/";
private static String SAVE_PATH = DEFAULT_SAVE_PATH;

private static final java.util.logging.Logger logger = LogsCenter.getLogger(ExportVolunteerCsvCommand.class);


private final ArrayList<Index> index;

/**
* @param index of volunteer or event in the filtered list
*/
public ExportVolunteerCsvCommand(ArrayList<Index> index) {
requireNonNull(index);
this.index = index;

//Create folder for output
File exportDir = new File(DEFAULT_SAVE_PATH);
if (!exportDir.exists()) {
try {
exportDir.mkdir();
} catch (SecurityException se) {
logger.warning("Couldn't create a relative export path next to jar file. "
+ "Defaulting to user's Desktop.");
SAVE_PATH = ALT_SAVE_PATH;
}
}
}


@Override
public CommandResult execute(Model model, CommandHistory history) throws CommandException {
requireNonNull(model);
List<Volunteer> 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 (FileNotFoundException e) {
throw new CommandException(index.size() + " " + MESSAGE_EXPORT_VOLUNTEER_FAILED);
}

return new CommandResult(index.size() + " " + 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<Volunteer> list,
ArrayList<Index> index) throws FileNotFoundException {
// Setting up file path
File output = new File(SAVE_PATH
+ Integer.toString(index.size()) + "volunteers.csv");

// Setting up writer & stringbuilder for appending
PrintWriter pw = new PrintWriter(output);
StringBuilder sb = new StringBuilder();
String csvSplit = ",";
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might want to test this with fields that could contain commas, like Address

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assumption on the csv entries dont have characters which messes with the tuple splits, like comma (,)and bracer ("").

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should not work under this assumption. Users should be allowed to enter commas for addresses. Try to find a way to clean the input. Maybe this link would be helpful.

https://stackoverflow.com/questions/4617935/is-there-a-way-to-include-commas-in-csv-columns-without-breaking-the-formatting


//appending column titles
sb.append("Name" + csvSplit);
sb.append("Gender" + csvSplit);
sb.append("Birthday" + csvSplit);
sb.append("Phone" + csvSplit);
sb.append("Email" + csvSplit);
sb.append("Address" + 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();
}

}
Loading