package thaw.plugins.signatures; import java.io.File; import java.io.FileOutputStream; import java.util.Vector; import java.util.Iterator; import thaw.core.Logger; /* DOM */ import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.DOMImplementation; import org.w3c.dom.Document; import org.w3c.dom.Element; /* SAX */ import org.xml.sax.*; import org.xml.sax.helpers.DefaultHandler; import javax.xml.parsers.SAXParserFactory; import javax.xml.parsers.SAXParser; import java.io.FileInputStream; public class TrustListParser { private TrustListParser() { } /*********************** EXPORT ******************************/ public static boolean exportTrustList(Vector identities, File outputFile) { try { FileOutputStream out = new FileOutputStream(outputFile); StreamResult streamResult; streamResult = new StreamResult(out); Document xmlDoc; final DocumentBuilderFactory xmlFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder xmlBuilder; try { xmlBuilder = xmlFactory.newDocumentBuilder(); } catch(final javax.xml.parsers.ParserConfigurationException e) { Logger.error(new TrustListParser(), "Unable to generate the index because : "+e.toString()); return false; } final DOMImplementation impl = xmlBuilder.getDOMImplementation(); xmlDoc = impl.createDocument(null, "trustList", null); final Element rootEl = xmlDoc.getDocumentElement(); /**** DOM Tree generation ****/ fillInRootElement(identities, rootEl, xmlDoc); /* Serialization */ final DOMSource domSource = new DOMSource(xmlDoc); final TransformerFactory transformFactory = TransformerFactory.newInstance(); Transformer serializer; try { serializer = transformFactory.newTransformer(); } catch(final javax.xml.transform.TransformerConfigurationException e) { Logger.error(new TrustListParser(), "Unable to save index because: "+e.toString()); return false; } serializer.setOutputProperty(OutputKeys.ENCODING,"UTF-8"); serializer.setOutputProperty(OutputKeys.INDENT,"yes"); /* final step */ try { serializer.transform(domSource, streamResult); } catch(final javax.xml.transform.TransformerException e) { Logger.error(new TrustListParser(), "Unable to save index because: "+e.toString()); return false; } out.close(); return true; } catch(java.io.FileNotFoundException e) { Logger.error(new TrustListParser(), "File not found exception ?!"); } catch(java.io.IOException e) { Logger.error(new TrustListParser(), "IOException while generating the index: "+e.toString()); } return false; } /** * Use it only if you know what you're doing * @param identities * @param rootEl * @param xmlDoc * @return */ public static boolean fillInRootElement(Vector identities, Element rootEl, Document xmlDoc) { //rootEl.appendChild(getXMLHeader(xmlDoc)); for (Iterator it = identities.iterator(); it.hasNext();) { Identity id = (Identity)it.next(); if (id.getTrustLevel() != 0 /* no just 'SIGNED' */ && id.getTrustLevel() != Identity.trustLevelInt[0]) /* and no dev */ rootEl.appendChild(getXMLIdentity(id, xmlDoc)); } return true; } private static Element getXMLIdentity(Identity id, Document xmlDoc) { Element idEl = xmlDoc.createElement("identity"); Element nickEl = xmlDoc.createElement("nick"); nickEl.appendChild(xmlDoc.createTextNode(id.getNick())); idEl.appendChild(nickEl); Element publicKeyEl = xmlDoc.createElement("publicKey"); publicKeyEl.appendChild(xmlDoc.createTextNode(id.getPublicKey())); idEl.appendChild(publicKeyEl); Element trustLevelEl = xmlDoc.createElement("trustLevel"); trustLevelEl.appendChild(xmlDoc.createTextNode(Integer.toString(id.getTrustLevel()*10))); idEl.appendChild(trustLevelEl); return idEl; } /*********************** IMPORT ****************************************/ public static interface TrustListContainer { public void start(); /** * Identity is used here just as a container. * no ref to the db was provided to these identity * @param i */ public void updateIdentity(Identity i); public void end(); } /** * public so you can override it if you want * @author jflesch */ public static class TrustListHandler extends DefaultHandler { private TrustListContainer container; public TrustListHandler(TrustListContainer container) { setTrustListContainer(container); } protected void setTrustListContainer(TrustListContainer container) { this.container = container; } public void startDocument() throws SAXException { if (container != null) container.start(); } private boolean nickTag = false; private boolean publicKeyTag = false; private boolean trustLevelTag = false; private String nick = null; private String publicKey = null; private String trustLevel = null; public void startElement(String nameSpaceURI, String localName, String rawName, Attributes attrs) throws SAXException { if (rawName == null) { rawName = localName; } if (rawName == null) return; if ("identity".equals(rawName)) { nickTag = false; publicKeyTag = false; trustLevelTag = false; nick = null; publicKey = null; trustLevel = null; } else if ("nick".equals(rawName)) { nickTag = true; } else if ("publicKey".equals(rawName)) { publicKeyTag = true; } else if ("trustLevel".equals(rawName)) { trustLevelTag = true; } } /** * Called when a closing tag is met * @see org.xml.sax.ContentHandler#endElement(java.lang.String, java.lang.String, java.lang.String) */ public void endElement(String nameSpaceURI, String localName, String rawName) throws SAXException { if (rawName == null) { rawName = localName; } if (rawName == null) return; if ("identity".equals(rawName)) { if (nick != null && publicKey != null && trustLevel != null && container != null) { Identity i = new Identity(null, -1, nick, publicKey, null, false, Integer.parseInt(trustLevel)/10); container.updateIdentity(i); } publicKey = null; } else if ("nick".equals(rawName)) { nickTag = false; } else if ("publicKey".equals(rawName)) { publicKeyTag = false; } else if ("trustLevel".equals(rawName)) { trustLevelTag = false; } } public void characters(char[] ch, int start, int end) throws SAXException { String txt = new String(ch, start, end); if (nickTag) nick = txt; else if (publicKeyTag) publicKey = txt; else if (trustLevelTag) trustLevel = txt; } public void endDocument() throws SAXException { if (container != null) container.end(); } } public static void importTrustList(TrustListContainer container, File inputFile) { importTrustList(new TrustListHandler(container), inputFile); } public static void importTrustList(TrustListHandler handler, File inputFile) { try { FileInputStream stream = new FileInputStream(inputFile); // Use the default (non-validating) parser SAXParserFactory factory = SAXParserFactory.newInstance(); // Parse the input SAXParser saxParser = factory.newSAXParser(); Logger.notice(handler, "Parsing index ..."); saxParser.parse(stream, handler); Logger.notice(handler, "Parsing done"); stream.close(); } catch(final java.io.FileNotFoundException e) { Logger.error(new TrustListParser(), "Unable to load XML: FileNotFoundException ('"+inputFile.getPath()+"') ! : "+e.toString()); } catch(java.io.IOException e) { Logger.error(new TrustListParser(), "IOException while parsing the index: "+e.toString()); } catch(javax.xml.parsers.ParserConfigurationException e) { Logger.notice(new TrustListParser(), "Error (1) while parsing index: "+e.toString()); } catch(org.xml.sax.SAXException e) { Logger.notice(new TrustListParser(), "Error (2) while parsing index: "+e.toString()); } catch(Exception e) { Logger.notice(new TrustListParser(), "Error (4) while parsing index: "+e.toString()); } } }