Created
June 17, 2015 19:27
-
-
Save john-h-kastner/ecaeeb4ee6ab06f675aa to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package todo; | |
| import java.util.stream.Stream; | |
| public class Command { | |
| private static final Command NO_OP = new Command("",new String[0]); | |
| private final String command; | |
| private final String[] arguments; | |
| public Command(String command, String[] arguments){ | |
| this.command = command; | |
| this.arguments = arguments; | |
| } | |
| public String getCommandString(){ | |
| return command; | |
| } | |
| public String[] getArguments(){ | |
| String[] argsCopy = new String[arguments.length]; | |
| System.arraycopy(arguments,0,argsCopy,0,arguments.length); | |
| return argsCopy; | |
| } | |
| public static Command of(String commandString){ | |
| if(commandString == null){ | |
| return Command.NO_OP; | |
| } | |
| String[] split = commandString.split("\\("); | |
| String command = split[0].trim(); | |
| String[] args; | |
| if(split.length > 1) { | |
| args = splitArguments(split[1]); | |
| } else { | |
| args = new String[0]; | |
| } | |
| return new Command(command,args); | |
| } | |
| private static String[] splitArguments(String argumentString){ | |
| String[] args = argumentString.split("(,|\\)\\s*$)"); | |
| for(int i=0;i<args.length;i++){ | |
| args[i] = args[i].trim(); | |
| } | |
| return args; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package todo; | |
| import java.util.stream.Stream; | |
| import java.util.List; | |
| import java.util.ArrayList; | |
| public class Item { | |
| private String description; | |
| private String[] categories; | |
| public Item(String description){ | |
| this(description,new String[0]); | |
| } | |
| public Item(String description,String[] categories){ | |
| this.description = description; | |
| this.categories = categories.clone(); | |
| } | |
| public void setDescription(String description){ | |
| this.description = description; | |
| } | |
| public String getDescription(){ | |
| return description; | |
| } | |
| public String[] getCategories(){ | |
| return categories.clone(); | |
| } | |
| @Override | |
| public String toString(){ | |
| return description; | |
| } | |
| public boolean inCategory(String category){ | |
| return Stream.of(categories) | |
| .anyMatch(c -> category.equals(c)); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | |
| <todo> | |
| <item> | |
| <description>A pixel is not a pixel is not a pixel</description> | |
| <category>programming</category> | |
| </item> | |
| <item> | |
| <description>The Scheme Programming Language</description> | |
| <category>programming</category> | |
| </item> | |
| <item> | |
| <description>Memory in C</description> | |
| </item> | |
| <item> | |
| <description>Haskell's School of Music</description> | |
| <category>programming</category> | |
| <category>music</category> | |
| </item> | |
| <item> | |
| <description>Algorithmic Symphonies from one line of code</description> | |
| <category>programming</category> | |
| <category>music</category> | |
| </item> | |
| <item> | |
| <description>Modes in Folk Music</description> | |
| <category>music</category> | |
| </item> | |
| <item> | |
| <description>The use of the Melodic Minor Scale</description> | |
| <category>music</category> | |
| </item> | |
| </todo> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package todo; | |
| import java.util.Iterator; | |
| import java.util.Collection; | |
| import java.util.stream.Collectors; | |
| public class ToDoList implements Iterable<Item>{ | |
| private final Collection<Item> items; | |
| public ToDoList() { | |
| items = new java.util.ArrayList<>(); | |
| } | |
| public ToDoList(Collection<Item> items){ | |
| this.items = items; | |
| } | |
| public void addItem(Item item){ | |
| items.add(item); | |
| } | |
| public void deleteItem(Item item){ | |
| items.remove(item); | |
| } | |
| public void viewList(){ | |
| System.out.println(this); | |
| } | |
| private Collection<Item> inCategory(String category){ | |
| return items.stream() | |
| .filter(i -> i.inCategory(category)) | |
| .collect(Collectors.toList()); | |
| } | |
| public void viewList(String category){ | |
| System.out.println(ToDoList.toString(inCategory(category))); | |
| } | |
| public void renameItem(String from, String to){ | |
| items.stream() | |
| .filter(i -> i.getDescription().equals(from)) | |
| .findFirst() | |
| .ifPresent(i -> i.setDescription(to)); | |
| } | |
| @Override | |
| public Iterator<Item> iterator(){ | |
| return items.iterator(); | |
| } | |
| @Override | |
| public String toString(){ | |
| return ToDoList.toString(items); | |
| } | |
| private static String toString(Collection<Item> items){ | |
| return " - " + items.stream() | |
| .map(Item::getDescription) | |
| .collect(Collectors.joining("\n - ")); | |
| } | |
| public static void main(String[] args) throws Exception{ | |
| String file = args[0]; | |
| ToDoList list = XmlToDoList.fromXmlList(XmlToDoList.readXml(file)); | |
| ToDoRepl.BASIC_REPL.startWith(list); | |
| XmlToDoList.saveXml(XmlToDoList.toXmlList(list),file); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package todo; | |
| import java.util.HashMap; | |
| import java.util.Map; | |
| import java.util.function.BiPredicate; | |
| import java.io.BufferedReader; | |
| import java.io.InputStreamReader; | |
| import java.io.IOException; | |
| public class ToDoRepl { | |
| public final static ToDoRepl BASIC_REPL; | |
| private final static Map<String,BiPredicate<String[],ToDoList>> BASIC_REPL_COMMMANDS; | |
| static { | |
| BASIC_REPL_COMMMANDS = new HashMap<>(); | |
| BASIC_REPL_COMMMANDS.put("addItem", (arguments,todo) -> { | |
| if(arguments.length == 1){ | |
| todo.addItem(new Item(arguments[0])); | |
| } else { | |
| String[] categories = new String[arguments.length-1]; | |
| System.arraycopy(arguments,1,categories,0,categories.length); | |
| todo.addItem(new Item(arguments[0],categories)); | |
| } | |
| return true; | |
| }); | |
| BASIC_REPL_COMMMANDS.put("deleteItem", (arguments,todo) -> { | |
| if(arguments.length != 1){ | |
| ToDoRepl.reportError("deleteItem accepts exactly 1 argument"); | |
| } else { | |
| todo.deleteItem(new Item(arguments[0])); | |
| } | |
| return true; | |
| }); | |
| BASIC_REPL_COMMMANDS.put("viewList", (arguments,todo) -> { | |
| if(arguments.length == 0){ | |
| todo.viewList(); | |
| } else { | |
| for(int i=0;i<arguments.length;i++){ | |
| todo.viewList(arguments[i]); | |
| } | |
| } | |
| return true; | |
| }); | |
| BASIC_REPL_COMMMANDS.put("updateItem", (arguments,todo) -> { | |
| if(arguments.length != 2){ | |
| ToDoRepl.reportError("updateItem accepts exactly 1 argument"); | |
| } else { | |
| todo.renameItem(arguments[0],arguments[1]); | |
| } | |
| return true; | |
| }); | |
| BASIC_REPL_COMMMANDS.put("exit", (arguments,todo) -> false); | |
| BASIC_REPL = new ToDoRepl(BASIC_REPL_COMMMANDS); | |
| } | |
| public static void reportError(String message){ | |
| System.out.println("Error occurred in ToDoRepl environment: " + message); | |
| } | |
| private final Map<String,BiPredicate<String[],ToDoList>> myCommands; | |
| public ToDoRepl(Map<String,BiPredicate<String[],ToDoList>> commands){ | |
| myCommands = commands; | |
| } | |
| public void startWith(ToDoList list){ | |
| try ( | |
| InputStreamReader inputReader = new InputStreamReader(System.in); | |
| BufferedReader input = new BufferedReader(inputReader) | |
| ) { | |
| boolean loopRunning = true; | |
| String inputString; | |
| do { | |
| inputString = input.readLine(); | |
| Command parsedCommand = Command.of(inputString); | |
| String commandString = parsedCommand.getCommandString(); | |
| String[] commandArguments = parsedCommand.getArguments(); | |
| if(myCommands.containsKey(commandString)){ | |
| loopRunning = myCommands.get(commandString).test(commandArguments,list); | |
| } | |
| } while(loopRunning); | |
| } catch (IOException ioe){ | |
| System.out.println("IOException occurred in interactive mode!\n REPL environment has been quit!"); | |
| } | |
| } | |
| } | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package todo; | |
| import java.io.FileOutputStream; | |
| import java.io.IOException; | |
| import javax.xml.parsers.*; | |
| import javax.xml.transform.*; | |
| import javax.xml.transform.dom.*; | |
| import javax.xml.transform.stream.*; | |
| import org.xml.sax.*; | |
| import org.w3c.dom.*; | |
| public class XmlToDoList { | |
| public static ToDoList fromXmlList(Document xmlDocument){ | |
| ToDoList constructedList = new ToDoList(); | |
| Element listElement = xmlDocument.getDocumentElement(); | |
| if(listElement == null) | |
| return constructedList; | |
| NodeList itemNodes = listElement.getElementsByTagName("item"); | |
| for(int i = 0; i<itemNodes.getLength();i++){ | |
| Node itemNode = itemNodes.item(i); | |
| constructedList.addItem(fromElement((Element) itemNode)); | |
| } | |
| return constructedList; | |
| } | |
| private static Item fromElement(Element itemElement){ | |
| String description = itemElement.getElementsByTagName("description").item(0).getTextContent(); | |
| NodeList categoryNodes = itemElement.getElementsByTagName("category"); | |
| String[] categories = new String[categoryNodes.getLength()]; | |
| for(int i=0;i<categories.length;i++){ | |
| categories[i] = categoryNodes.item(i).getTextContent(); | |
| } | |
| return new Item(description,categories); | |
| } | |
| public static Document toXmlList(ToDoList list) throws ParserConfigurationException { | |
| DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); | |
| Document dom = builder.newDocument(); | |
| Element rootElement = dom.createElement("todo"); | |
| for(Item item:list){ | |
| Element itemElement = buildItemElement(dom,item); | |
| rootElement.appendChild(itemElement); | |
| } | |
| dom.appendChild(rootElement); | |
| return dom; | |
| } | |
| private static Element buildItemElement(Document dom,Item item){ | |
| Element itemElement = dom.createElement("item"); | |
| Element itemDescription = dom.createElement("description"); | |
| itemDescription.appendChild(dom.createTextNode(item.getDescription())); | |
| itemElement.appendChild(itemDescription); | |
| for(String str:item.getCategories()){ | |
| Element categoryElement = dom.createElement("category"); | |
| categoryElement.appendChild(dom.createTextNode(str)); | |
| itemElement.appendChild(categoryElement); | |
| } | |
| return itemElement; | |
| } | |
| public static void saveXml(Document xml, String file) throws TransformerException, IOException { | |
| Transformer tr = TransformerFactory.newInstance().newTransformer(); | |
| tr.setOutputProperty(OutputKeys.INDENT, "yes"); | |
| tr.setOutputProperty(OutputKeys.METHOD, "xml"); | |
| tr.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); | |
| tr.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); | |
| tr.transform(new DOMSource(xml),new StreamResult(new FileOutputStream(file))); | |
| } | |
| public static Document readXml(String file) throws ParserConfigurationException,SAXException { | |
| DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); | |
| DocumentBuilder db = dbf.newDocumentBuilder(); | |
| Document dom; | |
| try { | |
| dom = db.parse(file); | |
| } catch (IOException ioe){ | |
| dom = db.newDocument(); | |
| } | |
| return dom; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment