package com.github.dtschust.zork.parser; import com.github.dtschust.zork.*; import org.w3c.dom.CharacterData; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import java.io.File; public class ZorkReader { private final String filename; public ZorkReader(String filename) { this.filename = filename; } public ZorkGame build(){ int j, k, l; ZorkGame data = new ZorkGame(); File file = new File(filename); if (!file.canRead()) { System.out.println("Error opening file. Exiting..."); throw new RuntimeException(); } try { /* Open the xml file*/ DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); Document doc = builder.parse(file); Element rootElement = doc.getDocumentElement(); /* Every single first generation child is a room, container, creature, or item. So load them in*/ NodeList nodes = rootElement.getChildNodes(); for (k = 0; k < nodes.getLength(); k++) { Node node = nodes.item(k); Element element; if (node instanceof Element) { element = (Element) node; String tagType = element.getTagName(); /* If it's a room ... */ if (tagType.equals("room")) { ZorkRoom tempRoom = new ZorkRoom(); /*Get all possible Room attributes*/ NodeList name = element.getElementsByTagName("name"); tempRoom.name = getString((Element) name.item(0)); NodeList type = element.getElementsByTagName("type"); if (type.getLength() > 0) { tempRoom.type = getString((Element) type.item(0)); } else { tempRoom.type = "regular"; } NodeList status = element.getElementsByTagName("status"); if (status.getLength() > 0) { tempRoom.status = getString((Element) type.item(0)); } else { tempRoom.status = ""; } NodeList description = element.getElementsByTagName("description"); tempRoom.description = getString((Element) description.item(0)); NodeList items = element.getElementsByTagName("item"); for (j = 0; j < items.getLength(); j++) { Element item = (Element) items.item(j); String itemName = getString(item); tempRoom.item.put(itemName, itemName); } NodeList creatures = element.getElementsByTagName("creature"); for (j = 0; j < creatures.getLength(); j++) { Element creature = (Element) creatures.item(j); String creatureName = getString(creature); tempRoom.creature.put(creatureName, creatureName); } NodeList triggers = element.getElementsByTagName("trigger"); for (j = 0; j < triggers.getLength(); j++) { ZorkTrigger tempTrigger = new ZorkTrigger(); Element trigger = (Element) triggers.item(j); NodeList commands = trigger.getElementsByTagName("command"); for (l = 0; l < commands.getLength(); l++) { Element command = (Element) commands.item(l); ZorkCommand tempCommand = new ZorkCommand(getString(command)); tempTrigger.conditions.add(tempCommand); tempTrigger.hasCommand = true; } NodeList conditions = trigger.getElementsByTagName("condition"); for (l = 0; l < conditions.getLength(); l++) { Element condition = (Element) conditions.item(l); NodeList object = condition.getElementsByTagName("object"); NodeList has = condition.getElementsByTagName("has"); if (has.getLength() > 0) { ZorkConditionHas tempConditionHas = new ZorkConditionHas(); tempConditionHas.has = getString((Element) has.item(0)); tempConditionHas.object = getString((Element) object.item(0)); NodeList owner = condition.getElementsByTagName("owner"); tempConditionHas.owner = getString((Element) owner.item(0)); tempTrigger.conditions.add(tempConditionHas); } else { ZorkConditionStatus tempConditionStatus = new ZorkConditionStatus(); tempConditionStatus.object = getString((Element) object.item(0)); NodeList sstatus = condition.getElementsByTagName("status"); tempConditionStatus.status = getString((Element) sstatus.item(0)); tempTrigger.conditions.add(tempConditionStatus); } } NodeList ttype = element.getElementsByTagName("type"); if (ttype.getLength() > 0) { tempTrigger.type = getString((Element) ttype.item(0)); } else { tempTrigger.type = "single"; } NodeList prints = trigger.getElementsByTagName("print"); for (l = 0; l < prints.getLength(); l++) { Element print = (Element) prints.item(l); tempTrigger.print.add(getString(print)); } NodeList actions = trigger.getElementsByTagName("action"); for (l = 0; l < actions.getLength(); l++) { Element action = (Element) actions.item(l); tempTrigger.action.add(getString(action)); } tempRoom.trigger.add(tempTrigger); } NodeList containers = element.getElementsByTagName("container"); for (j = 0; j < containers.getLength(); j++) { Element container = (Element) containers.item(j); String containerName = getString(container); tempRoom.container.put(containerName, containerName); } NodeList borders = element.getElementsByTagName("border"); for (j = 0; j < borders.getLength(); j++) { Element border = (Element) borders.item(j); String borderdirection = getString((Element) border.getElementsByTagName("direction").item(0)); String bordername = getString((Element) border.getElementsByTagName("name").item(0)); tempRoom.border.put(borderdirection, bordername); } /*Add this room to the rooms hashmap, put it in the generic objects hashmap, and store it's type in the objectlookup hashmap*/ data.Rooms.put(tempRoom.name, tempRoom); data.Objects.put(tempRoom.name, tempRoom); data.ObjectLookup.put(tempRoom.name, "room"); } /* If it's an item... */ else if (tagType.equals("item")) { ZorkItem tempItem = new ZorkItem(); /* Get all possible item attributes*/ NodeList name = element.getElementsByTagName("name"); if (name.getLength() > 0) tempItem.name = getString((Element) name.item(0)); NodeList status = element.getElementsByTagName("status"); if (status.getLength() > 0) { tempItem.status = getString((Element) status.item(0)); } else { tempItem.status = ""; } NodeList description = element.getElementsByTagName("description"); if (description.getLength() > 0) tempItem.description = getString((Element) description.item(0)); NodeList writing = element.getElementsByTagName("writing"); if (writing.getLength() > 0) tempItem.writing = getString((Element) writing.item(0)); NodeList turnon = element.getElementsByTagName("turnon"); if (turnon.getLength() > 0) { NodeList prints = element.getElementsByTagName("print"); for (j = 0; j < prints.getLength(); j++) { tempItem.turnOnPrint.add(getString((Element) prints.item(j))); } NodeList actions = element.getElementsByTagName("action"); for (j = 0; j < actions.getLength(); j++) { tempItem.turnOnAction.add(getString((Element) actions.item(j))); } } NodeList triggers = element.getElementsByTagName("trigger"); for (j = 0; j < triggers.getLength(); j++) { ZorkTrigger tempTrigger = new ZorkTrigger(); Element trigger = (Element) triggers.item(j); NodeList commands = trigger.getElementsByTagName("command"); for (l = 0; l < commands.getLength(); l++) { Element command = (Element) commands.item(l); ZorkCommand tempCommand = new ZorkCommand(getString(command)); tempTrigger.conditions.add(tempCommand); tempTrigger.hasCommand = true; } NodeList conditions = trigger.getElementsByTagName("condition"); for (l = 0; l < conditions.getLength(); l++) { Element condition = (Element) conditions.item(l); NodeList object = condition.getElementsByTagName("object"); NodeList has = condition.getElementsByTagName("has"); if (has.getLength() > 0) { ZorkConditionHas tempConditionHas = new ZorkConditionHas(); tempConditionHas.has = getString((Element) has.item(0)); tempConditionHas.object = getString((Element) object.item(0)); NodeList owner = condition.getElementsByTagName("owner"); tempConditionHas.owner = getString((Element) owner.item(0)); tempTrigger.conditions.add(tempConditionHas); } else { ZorkConditionStatus tempConditionStatus = new ZorkConditionStatus(); tempConditionStatus.object = getString((Element) object.item(0)); NodeList sstatus = condition.getElementsByTagName("status"); tempConditionStatus.status = getString((Element) sstatus.item(0)); tempTrigger.conditions.add(tempConditionStatus); } } NodeList ttype = element.getElementsByTagName("type"); if (ttype.getLength() > 0) { tempTrigger.type = getString((Element) ttype.item(0)); } else { tempTrigger.type = "single"; } NodeList prints = trigger.getElementsByTagName("print"); for (l = 0; l < prints.getLength(); l++) { Element print = (Element) prints.item(l); tempTrigger.print.add(getString(print)); } NodeList actions = trigger.getElementsByTagName("action"); for (l = 0; l < actions.getLength(); l++) { Element action = (Element) actions.item(l); tempTrigger.action.add(getString(action)); } tempItem.trigger.add(tempTrigger); } /* Put each item in the items hashmap, the generic objects hashmap, and store its type in objectlookup*/ data.Items.put(tempItem.name, tempItem); data.Objects.put(tempItem.name, tempItem); data.ObjectLookup.put(tempItem.name, "item"); } /* If it's a container... */ else if (tagType.equals("container")) { ZorkContainer tempCont = new ZorkContainer(); /*Get all possible container attributes*/ NodeList name = element.getElementsByTagName("name"); if (name.getLength() > 0) tempCont.name = getString((Element) name.item(0)); NodeList status = element.getElementsByTagName("status"); if (status.getLength() > 0) tempCont.status = getString((Element) status.item(0)); /*Initially assume a closed container*/ tempCont.isOpen = false; NodeList description = element.getElementsByTagName("description"); if (description.getLength() > 0) tempCont.description = getString((Element) description.item(0)); NodeList accepts = element.getElementsByTagName("accept"); for (j = 0; j < accepts.getLength(); j++) { /* If container has an accepts attribute, then it is always open*/ tempCont.isOpen = true; tempCont.accept.add(getString((Element) accepts.item(j))); } NodeList citems = element.getElementsByTagName("item"); for (j = 0; j < citems.getLength(); j++) { Element item = (Element) citems.item(j); String itemName = getString(item); tempCont.item.put(itemName, itemName); } NodeList triggers = element.getElementsByTagName("trigger"); for (j = 0; j < triggers.getLength(); j++) { ZorkTrigger tempTrigger = new ZorkTrigger(); Element trigger = (Element) triggers.item(j); NodeList commands = trigger.getElementsByTagName("command"); for (l = 0; l < commands.getLength(); l++) { Element command = (Element) commands.item(l); ZorkCommand tempCommand = new ZorkCommand(getString(command)); tempTrigger.conditions.add(tempCommand); tempTrigger.hasCommand = true; } NodeList conditions = trigger.getElementsByTagName("condition"); for (l = 0; l < conditions.getLength(); l++) { Element condition = (Element) conditions.item(l); NodeList object = condition.getElementsByTagName("object"); NodeList has = condition.getElementsByTagName("has"); if (has.getLength() > 0) { ZorkConditionHas tempConditionHas = new ZorkConditionHas(); tempConditionHas.has = getString((Element) has.item(0)); tempConditionHas.object = getString((Element) object.item(0)); NodeList owner = condition.getElementsByTagName("owner"); tempConditionHas.owner = getString((Element) owner.item(0)); tempTrigger.conditions.add(tempConditionHas); } else { ZorkConditionStatus tempConditionStatus = new ZorkConditionStatus(); tempConditionStatus.object = getString((Element) object.item(0)); NodeList sstatus = condition.getElementsByTagName("status"); tempConditionStatus.status = getString((Element) sstatus.item(0)); tempTrigger.conditions.add(tempConditionStatus); } } NodeList ttype = element.getElementsByTagName("type"); if (ttype.getLength() > 0) { tempTrigger.type = getString((Element) ttype.item(0)); } else { tempTrigger.type = "single"; } NodeList prints = trigger.getElementsByTagName("print"); for (l = 0; l < prints.getLength(); l++) { Element print = (Element) prints.item(l); tempTrigger.print.add(getString(print)); } NodeList actions = trigger.getElementsByTagName("action"); for (l = 0; l < actions.getLength(); l++) { Element action = (Element) actions.item(l); tempTrigger.action.add(getString(action)); } tempCont.trigger.add(tempTrigger); } /* Put each container in the containers hashmap, the generic object hashmap, and the objectlookup hashmap*/ data.Containers.put(tempCont.name, tempCont); data.Objects.put(tempCont.name, tempCont); data.ObjectLookup.put(tempCont.name, "container"); } /* And finally, if it's a creature...*/ else if (tagType.equals("creature")) { ZorkCreature tempCreature = new ZorkCreature(); /* Get all possible creature attributes*/ NodeList name = element.getElementsByTagName("name"); if (name.getLength() > 0) tempCreature.name = getString((Element) name.item(0)); NodeList status = element.getElementsByTagName("status"); if (status.getLength() > 0) tempCreature.status = getString((Element) status.item(0)); NodeList description = element.getElementsByTagName("description"); if (description.getLength() > 0) tempCreature.description = getString((Element) description.item(0)); NodeList vulns = element.getElementsByTagName("vulnerability"); for (j = 0; j < vulns.getLength(); j++) { String vulnString = getString((Element) vulns.item(j)); tempCreature.vulnerability.put(vulnString, vulnString); } NodeList attacks = element.getElementsByTagName("attack"); for (j = 0; j < attacks.getLength(); j++) { Element attack = (Element) attacks.item(j); NodeList conditions = attack.getElementsByTagName("condition"); for (l = 0; l < conditions.getLength(); l++) { Element condition = (Element) conditions.item(l); NodeList object = condition.getElementsByTagName("object"); NodeList has = condition.getElementsByTagName("has"); if (has.getLength() > 0) { ZorkConditionHas tempConditionHas = new ZorkConditionHas(); tempConditionHas.has = getString((Element) has.item(0)); tempConditionHas.object = getString((Element) object.item(0)); NodeList owner = condition.getElementsByTagName("owner"); tempConditionHas.owner = getString((Element) owner.item(0)); tempCreature.conditions.add(tempConditionHas); } else { ZorkConditionStatus tempConditionStatus = new ZorkConditionStatus(); tempConditionStatus.object = getString((Element) object.item(0)); NodeList sstatus = condition.getElementsByTagName("status"); tempConditionStatus.status = getString((Element) sstatus.item(0)); tempCreature.conditions.add(tempConditionStatus); } } NodeList prints = attack.getElementsByTagName("print"); for (l = 0; l < prints.getLength(); l++) { Element print = (Element) prints.item(l); tempCreature.print.add(getString(print)); } NodeList actions = attack.getElementsByTagName("action"); for (l = 0; l < actions.getLength(); l++) { Element action = (Element) actions.item(l); tempCreature.action.add(getString(action)); } } NodeList triggers = element.getElementsByTagName("trigger"); for (j = 0; j < triggers.getLength(); j++) { ZorkTrigger tempTrigger = new ZorkTrigger(); Element trigger = (Element) triggers.item(j); NodeList commands = trigger.getElementsByTagName("command"); for (l = 0; l < commands.getLength(); l++) { Element command = (Element) commands.item(l); ZorkCommand tempCommand = new ZorkCommand(getString(command)); tempTrigger.conditions.add(tempCommand); tempTrigger.hasCommand = true; } NodeList conditions = trigger.getElementsByTagName("condition"); for (l = 0; l < conditions.getLength(); l++) { Element condition = (Element) conditions.item(l); NodeList object = condition.getElementsByTagName("object"); NodeList has = condition.getElementsByTagName("has"); if (has.getLength() > 0) { ZorkConditionHas tempConditionHas = new ZorkConditionHas(); tempConditionHas.has = getString((Element) has.item(0)); tempConditionHas.object = getString((Element) object.item(0)); NodeList owner = condition.getElementsByTagName("owner"); tempConditionHas.owner = getString((Element) owner.item(0)); tempTrigger.conditions.add(tempConditionHas); } else { ZorkConditionStatus tempConditionStatus = new ZorkConditionStatus(); tempConditionStatus.object = getString((Element) object.item(0)); NodeList sstatus = condition.getElementsByTagName("status"); tempConditionStatus.status = getString((Element) sstatus.item(0)); tempTrigger.conditions.add(tempConditionStatus); } } NodeList ttype = element.getElementsByTagName("type"); if (ttype.getLength() > 0) { tempTrigger.type = getString((Element) ttype.item(0)); } else { tempTrigger.type = "single"; } NodeList prints = trigger.getElementsByTagName("print"); for (l = 0; l < prints.getLength(); l++) { Element print = (Element) prints.item(l); tempTrigger.print.add(getString(print)); } NodeList actions = trigger.getElementsByTagName("action"); for (l = 0; l < actions.getLength(); l++) { Element action = (Element) actions.item(l); tempTrigger.action.add(getString(action)); } tempCreature.trigger.add(tempTrigger); } /* Put each creature in the creatures hashmap, the generic object hashmap, and the objectlookup hashmap*/ data.Creatures.put(tempCreature.name, tempCreature); data.Objects.put(tempCreature.name, tempCreature); data.ObjectLookup.put(tempCreature.name, "creature"); } } } } catch (Exception e) { System.out.println("Invalid XML file, exiting"); System.exit(-1); //e.printStackTrace(); } return data; } /* Get a string from an element (XML parsing stuff)*/ public static String getString(Element e) { Node child = e.getFirstChild(); if (child instanceof CharacterData) { CharacterData cd = (CharacterData) child; return cd.getData(); } return "?"; } }