package crazypants.enderio.machine.painter; import java.io.File; import java.io.IOException; import java.io.StringReader; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.DefaultHandler; import crazypants.enderio.Log; import crazypants.enderio.config.Config; import crazypants.enderio.machine.recipe.RecipeConfig; import crazypants.enderio.machine.recipe.RecipeConfigParser; import crazypants.enderio.machine.recipe.RecipeInput; public class PaintSourceParser extends DefaultHandler { private static final String CORE_FILE_NAME = "PainterPaintSources_Core.xml"; private static final String CUSTOM_FILE_NAME = "PainterPaintSources_User.xml"; public static void loadConfig() { File coreFile = new File(Config.configDirectory, CORE_FILE_NAME); String defaultVals = null; try { defaultVals = RecipeConfig.readRecipes(coreFile, CORE_FILE_NAME, true); } catch (IOException e) { Log.error("Could not load painter lists " + coreFile + " from EnderIO jar: " + e.getMessage()); e.printStackTrace(); return; } if(!coreFile.exists()) { Log.error("Could not load default lists from " + coreFile + " as the file does not exist."); return; } try { parse(defaultVals); } catch (Exception e) { Log.error("Could not parse default lists from " + coreFile + ": " + e); } File userFile = new File(Config.configDirectory, CUSTOM_FILE_NAME); String userConfigStr = null; try { userConfigStr = RecipeConfig.readRecipes(userFile, CUSTOM_FILE_NAME, false); if(userConfigStr == null || userConfigStr.trim().length() == 0) { Log.error("Empty user config file: " + userFile.getAbsolutePath()); } else { parse(userConfigStr); } } catch (Exception e) { Log.error("Could not load user defined painter lists from file: " + CUSTOM_FILE_NAME); e.printStackTrace(); } } public static void parse(String str) throws Exception { StringReader reader = new StringReader(str); InputSource is = new InputSource(reader); try { parse(is); } finally { reader.close(); } } private static void parse(InputSource is) throws Exception { PaintSourceParser parser = new PaintSourceParser(); SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setNamespaceAware(true); SAXParser saxParser = spf.newSAXParser(); XMLReader xmlReader = saxParser.getXMLReader(); xmlReader.setContentHandler(parser); xmlReader.parse(is); } public static final String ELEMENT_WHITELIST = "whitelist"; public static final String ELEMENT_BLACKLIST = "blacklist"; public static final String ELEMENT_ITEM_STACK = "itemStack"; private static final String AT_REMOVE = "remove"; private boolean isWhitelist = false; private boolean isBlacklist = false; @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if(ELEMENT_WHITELIST.equals(localName)) { isWhitelist = true; isBlacklist = false; return; } if(ELEMENT_BLACKLIST.equals(localName)) { isWhitelist = false; isBlacklist = true; return; } if(ELEMENT_ITEM_STACK.equals(localName)) { if(!isWhitelist && !isBlacklist) { Log.warn("PaintSourceParser: Item stack found outside of whitlist/blacklist elements. It will be ignored"); return; } RecipeInput stack = RecipeConfigParser.getItemStack(attributes); if(stack == null) { return; } boolean isRemove = RecipeConfigParser.getBooleanValue(AT_REMOVE, attributes, false); if(isBlacklist) { if(isRemove) { PaintSourceValidator.instance.removeFromBlackList(stack); } else { PaintSourceValidator.instance.addToBlacklist(stack); } } else { if(isRemove) { PaintSourceValidator.instance.removeFromWhitelist(stack); } else { PaintSourceValidator.instance.addToWhitelist(stack); } } } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { if(ELEMENT_WHITELIST.equals(localName)) { isWhitelist = false; return; } if(ELEMENT_BLACKLIST.equals(localName)) { isBlacklist = false; return; } } }