package com.vapourdrive.harderstart.recipe.cuttingtable; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import net.minecraft.item.ItemAxe; import net.minecraft.item.ItemPickaxe; import net.minecraft.item.ItemSpade; import net.minecraft.item.ItemStack; import org.apache.logging.log4j.Level; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import com.vapourdrive.harderstart.HarderStart; import com.vapourdrive.harderstart.items.CuttingKnifeBase; import com.vapourdrive.harderstart.utils.ItemStackUtils; public class CuttingTableRecipeParser { /** * preps the file from the name instantiates DOM documentbuilderfactory and * document builder sends the document to get parsed * * @param fileName */ public static void init(String fileName) { try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setIgnoringComments(true); factory.setIgnoringElementContentWhitespace(true); DocumentBuilder builder = factory.newDocumentBuilder(); File file = new File(HarderStart.configPath + fileName); if (file.exists()) { Document document = builder.parse(file); document.getDocumentElement().normalize(); processDocument(document, fileName); } else { HarderStart.log.log(Level.WARN, "Could not find recipe file for CuttingTable"); } } catch (ParserConfigurationException e) { HarderStart.log.log(Level.ERROR, "ParsingConfigurationException fired"); } catch (SAXException e) { HarderStart.log.log(Level.ERROR, "SAX exception fired"); } catch (IOException e) { HarderStart.log.log(Level.ERROR, "IOException fired"); } } /** * Creates a nodelist of recipes (from tag "recipe") loops through the list * of recipe nodes sending them for reading * * @param document * @param fileName */ public static void processDocument(Document document, String fileName) { NodeList rootNodes = document.getElementsByTagName("recipe"); HarderStart.log.log(Level.INFO, "Starting to read recipe file " + fileName); for (int i = 0; i < rootNodes.getLength(); i++) { Node currentNode = rootNodes.item(i); Element recipeElement = (Element) currentNode; String recipeName = recipeElement.getAttribute("name"); if (CuttingTableRecipeFiller.recipeList.contains(recipeName)) { HarderStart.log.log(Level.INFO, "Recipe already registered, skipping recipe: " + recipeName); } else { handleRecipeNode(recipeElement, recipeName); CuttingTableRecipeFiller.recipeList.add(recipeName); } } HarderStart.log.log(Level.INFO, "Finished reading recipe file " + fileName); return; } /** * Breaks recipe node up into tool class, input and output * * @param recipeElement * @param recipeName */ public static void handleRecipeNode(Element recipeElement, String recipeName) { Class toolType; ItemStack ingredient = null; ItemStack[] results = new ItemStack[] {}; Node tool = recipeElement.getElementsByTagName("tool").item(0); toolType = getToolClassFromNode(tool); Node input = recipeElement.getElementsByTagName("input").item(0); if (input != null) { ingredient = getInputFromNode(input, recipeName); } else { HarderStart.log.log(Level.WARN, recipeName + " input node is not found"); } Node outputs = recipeElement.getElementsByTagName("outputs").item(0); if (outputs != null) { results = getResultsFromNode(outputs, recipeName); } else { HarderStart.log.log(Level.WARN, "outputs node is not found"); } if (ingredient != null && results != null && results.length > 0) { if (!addRecipe(toolType, ingredient, results, recipeName)) { HarderStart.log.log(Level.WARN, "Failed to add recipe: " + recipeName); } } return; } /** * switches through input number to determine desired tool * * @param tool * @return */ public static Class getToolClassFromNode(Node tool) { if (tool != null) { if (tool.getNodeType() == Node.ELEMENT_NODE) { int toolIndex = 0; Element toolElement = (Element) tool; toolIndex = Integer.parseInt(toolElement.getTextContent()); switch (toolIndex) { case 0: return CuttingKnifeBase.class; case 1: return ItemAxe.class; case 2: return ItemPickaxe.class; case 3: return ItemSpade.class; } } } return CuttingKnifeBase.class; } /** * Breaks itemstack node up into modID, name, number and meta * * @param input * @param recipeName * @return */ public static ItemStack getInputFromNode(Node input, String recipeName) { ItemStack returnStack = null; if (input.getNodeType() == Node.ELEMENT_NODE) { Element inputElement = (Element) input; Node itemstack = inputElement.getElementsByTagName("itemStack").item(0); if (itemstack.getNodeType() == Node.ELEMENT_NODE) { Element elementItemStack = (Element) itemstack; returnStack = getValidStack(elementItemStack.getAttribute("modID"), elementItemStack.getAttribute("itemName"), null, elementItemStack.getAttribute("itemMeta"), recipeName); } } return returnStack; } /** * Same as getInputFromNode except with a loop and nodelist for the * itemstacks * * @param outputs * @param recipeName * @return */ public static ItemStack[] getResultsFromNode(Node outputs, String recipeName) { List<ItemStack> resultList = new ArrayList<ItemStack>(); if (outputs.getNodeType() == Node.ELEMENT_NODE) { ItemStack stack; Element outputsElement = (Element) outputs; NodeList stacklist = outputsElement.getElementsByTagName("itemStack"); for (int i = 0; (i < stacklist.getLength() && i < 4); i++) { Node currentStack = stacklist.item(i); if (currentStack.getNodeType() == Node.ELEMENT_NODE) { Element elementItemStack = (Element) currentStack; stack = getValidStack(elementItemStack.getAttribute("modID"), elementItemStack.getAttribute("itemName"), elementItemStack.getAttribute("number"), elementItemStack.getAttribute("itemMeta"), recipeName); if (stack == null) { HarderStart.log.log(Level.WARN, recipeName + " Itemstack is not valid, output is null"); return null; } else { resultList.add(stack); } } else { HarderStart.log.log(Level.WARN, recipeName + " Itemstack node could not be cast to element"); } } ItemStack[] returnStack = new ItemStack[resultList.size()]; resultList.toArray(returnStack); return returnStack; } else { HarderStart.log.log(Level.WARN, recipeName + " output node was not valid element, returning null"); return null; } } /** * Takes strings from the itemstack tag Exists to deal pleasantly with * possible null values for number and metadata * * @param modID * @param itemName * @param number * @param metadata * @param recipeName * @return */ public static ItemStack getValidStack(String modID, String itemName, String number, String metadata, String recipeName) { ItemStack bufferStack; ItemStack returnStack = null; int numberInt = 1; int metadataInt = 0; if (number != null && number != "") { numberInt = Integer.parseInt(number); } if (metadata != null && metadata != "") { metadataInt = Integer.parseInt(metadata); } bufferStack = ItemStackUtils.getItemStackFromString(modID, itemName, numberInt); if (bufferStack != null) { if (metadata != null && metadata != "") { returnStack = new ItemStack(bufferStack.getItem(), numberInt, metadataInt); } else { returnStack = new ItemStack(bufferStack.getItem(), numberInt); } } else { HarderStart.log.log(Level.WARN, recipeName + " contains a null itemstack"); HarderStart.log.log(Level.WARN, "check that '" + modID + "' and '" + itemName + "' are valid"); } return returnStack; } /** * Sends off the info to get added in as a recipe * * @param tool * @param ingredient * @param results * @param recipeName * @return */ public static boolean addRecipe(Class tool, ItemStack ingredient, ItemStack[] results, String recipeName) { CuttingTableRecipeManager.getInstance().addCutRecipe(tool, ingredient, results); return true; } }