[Jreepad-CVS] jreepad/src/jreepad/io AutoDetectReader.java, 1.3, 1.4 XmlReader.java, 1.4, 1.5 XmlWr
Brought to you by:
danstowell
From: PeWu <pe...@us...> - 2007-09-28 21:54:46
|
Update of /cvsroot/jreepad/jreepad/src/jreepad/io In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv31373/src/jreepad/io Modified Files: AutoDetectReader.java XmlReader.java XmlWriter.java Log Message: Using SAX for reading and writing XML Index: AutoDetectReader.java =================================================================== RCS file: /cvsroot/jreepad/jreepad/src/jreepad/io/AutoDetectReader.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** AutoDetectReader.java 28 Sep 2007 14:29:22 -0000 1.3 --- AutoDetectReader.java 28 Sep 2007 21:54:41 -0000 1.4 *************** *** 58,76 **** if (currentLine.startsWith("<?xml")) { - // Try and find out what character encoding to use - int encPos = currentLine.indexOf("encoding="); - String xmlEncoding = null; - if (encPos != -1) - { - xmlEncoding = currentLine.substring(encPos + 10); - encPos = xmlEncoding.indexOf("\""); - if (encPos == -1) - encPos = xmlEncoding.indexOf("'"); - if (encPos != -1) - xmlEncoding = xmlEncoding.substring(0, encPos); - // System.out.println("Start of XML loading: decided on the following character - // encoding: " + xmlEncoding); - } - xmlReader.setEncoding(xmlEncoding); return xmlReader.read(in); } --- 58,61 ---- Index: XmlReader.java =================================================================== RCS file: /cvsroot/jreepad/jreepad/src/jreepad/io/XmlReader.java,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** XmlReader.java 3 Apr 2007 12:41:30 -0000 1.4 --- XmlReader.java 28 Sep 2007 21:54:41 -0000 1.5 *************** *** 20,27 **** package jreepad.io; - import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; ! import java.io.InputStreamReader; import jreepad.JreepadArticle; --- 20,29 ---- package jreepad.io; import java.io.IOException; import java.io.InputStream; ! ! import javax.xml.parsers.ParserConfigurationException; ! import javax.xml.parsers.SAXParser; ! import javax.xml.parsers.SAXParserFactory; import jreepad.JreepadArticle; *************** *** 30,33 **** --- 32,39 ---- import jreepad.JreepadTreeModel; + import org.xml.sax.Attributes; + import org.xml.sax.SAXException; + import org.xml.sax.helpers.DefaultHandler; + /** * Reads XML input into Jreepad. *************** *** 37,273 **** public class XmlReader implements JreepadReader { ! private String encoding; ! ! public XmlReader() ! { ! this(null); ! } ! ! public XmlReader(String encoding) ! { ! this.encoding = encoding; ! } public JreepadTreeModel read(InputStream in) throws IOException { ! BufferedReader reader = new BufferedReader(new InputStreamReader(in, encoding)); ! ! String currentLine; ! String currentXmlContent = ""; ! int nodeTagOffset = 0; ! ! // Spool until we're at the very first node ! while ((currentLine = reader.readLine()) != null ! && (nodeTagOffset = currentXmlContent.indexOf("<node")) == -1 ! && (nodeTagOffset == -1 || currentXmlContent.indexOf('>', nodeTagOffset) == -1)) { ! currentXmlContent += (currentLine + "\n"); } - if (currentLine != null) - currentXmlContent += (currentLine + "\n"); - - // System.out.println("XMLparse: I've spooled to the first node and content is now: " + - // currentXmlContent); - - // So currentXmlContent now contains all of the opening tag, including its attributes etc - // Strip off anything BEFORE the node opening - currentXmlContent = currentXmlContent.substring(nodeTagOffset); - - // System.out.println("XMLparse: I've stripped anything before the first node and content is - // now: " + currentXmlContent); ! JreepadTreeModel document = new JreepadTreeModel(readNode(reader, currentXmlContent, 0).node); document.setFileType(JreepadPrefs.FILETYPE_XML); - document.setEncoding(encoding); return document; } ! // This function should return any XML string content that remains unprocessed ! // Also returns newly created node ! ReturnValue readNode(BufferedReader reader, String currentXmlContent, int depth) ! throws IOException { ! // System.out.println("XMLparse recursive: depth "+depth); ! ! // String currentXmlContent should BEGIN with the <node> tag. This is assumed, and if not ! // true may cause problems! ! String currentLine; ! int titleOffset, typeOffset, startTagOffset, endTagOffset; ! String title, typeString, content = ""; ! JreepadNode node = new JreepadNode(); ! ! // Extract the attributes ! titleOffset = currentXmlContent.indexOf("title="); ! typeOffset = currentXmlContent.indexOf("type="); ! if (titleOffset != -1) ! title = currentXmlContent.substring(titleOffset + 7, currentXmlContent.indexOf('"', ! titleOffset + 7)); ! else ! title = "<Untitled node>"; ! if (typeOffset != -1) ! typeString = currentXmlContent.substring(typeOffset + 6, currentXmlContent.indexOf('"', ! typeOffset + 6)); ! else ! typeString = "text/plain"; ! ! if (typeString.equals("text/csv")) ! node.getArticle().setArticleMode(JreepadArticle.ARTICLEMODE_CSV); ! else if (typeString.equals("text/html")) ! node.getArticle().setArticleMode(JreepadArticle.ARTICLEMODE_HTML); ! else if (typeString.equals("text/textile")) ! node.getArticle().setArticleMode(JreepadArticle.ARTICLEMODE_TEXTILEHTML); ! //else if (typeString.equals("application/x-jreepad-softlink")) ! // node.setArticleMode(JreepadArticle.ARTICLEMODE_SOFTLINK); ! else ! node.getArticle().setArticleMode(JreepadArticle.ARTICLEMODE_ORDINARY); ! ! node.setTitle(xmlUnescapeChars(title)); ! ! // OK, so we've interpreted the attributes etc. Now we need to trim the opening tag away ! currentXmlContent = currentXmlContent.substring(currentXmlContent.indexOf('>') + 1); ! ! // System.out.println("XMLparse: I've stripped off the <node> tag and content is now: " + ! // currentXmlContent); ! ! boolean readingContent = true; // Once the baby nodes come in, we're not interested in ! // adding any more to the content ! while ((currentLine = reader.readLine()) != null) { ! // System.out.println("XMLparserecursive: Here's a line: " + currentLine); ! currentLine += "\n"; // We want to keep the newlines, but the BufferedReader doesn't ! // give us them ! ! // We're reading CONTENT into the current node. ! currentXmlContent += currentLine; ! ! // System.out.println("\n\nThe content that I'm currently trying to process ! // is:\n"+currentXmlContent); ! ! // Look out for <node which tells us we're starting a child ! startTagOffset = currentXmlContent.indexOf("<node"); ! // Look out for </node> which tells us we're finishing this node and returning to the ! // parent ! endTagOffset = currentXmlContent.indexOf("</node>"); ! ! while (!(startTagOffset == -1 || endTagOffset == -1)) ! { ! if (startTagOffset == -1 || endTagOffset < startTagOffset) ! { ! // Process the nearest end tag ! if (readingContent) ! content += xmlUnescapeChars(currentXmlContent.substring(0, endTagOffset)); ! String returnFromBaby = currentXmlContent.substring(endTagOffset + 7); ! // System.out.println("\n\nBaby intends to return:"+returnFromBaby); ! node.getArticle().setContent(content); ! return new ReturnValue(returnFromBaby, node); ! } ! else ! { ! if (readingContent) ! { ! content += xmlUnescapeChars(currentXmlContent.substring(0, startTagOffset)); ! node.getArticle().setContent(content); ! } ! ! // Having found a child node, we want to STOP adding anything to the current ! // node's content (e.g. newlines...) ! readingContent = false; ! ! // Process the nearest start tag ! // System.out.println("\n\nJust before passing to baby: content ! // is:\n"+currentXmlContent); ! ReturnValue returnValue = readNode(reader, currentXmlContent ! .substring(startTagOffset), depth + 1); ! currentXmlContent = returnValue.xmlContent; ! // System.out.println("\n\nJust after passing to baby: content ! // is:\n"+currentXmlContent); ! node.add(returnValue.node); ! } ! ! startTagOffset = currentXmlContent.indexOf("<node"); ! endTagOffset = currentXmlContent.indexOf("</node>"); ! } ! ! } // End while ! ! // Just make sure we haven't wasted any content... ! endTagOffset = currentXmlContent.indexOf('<'); ! if (readingContent && (endTagOffset != -1)) ! content += xmlUnescapeChars(currentXmlContent.substring(0, endTagOffset)); ! node.getArticle().setContent(content); ! // System.out.println("THE MAIN WHILE LOOP HAS ENDED. SPARE CONTENT:\n" + ! // currentXmlContent); ! return new ReturnValue("", node); ! } ! ! private static String xmlUnescapeChars(String in) ! { ! char[] c = in.toCharArray(); ! StringBuffer ret = new StringBuffer(); ! StringBuffer entity = new StringBuffer(); ! String ent; ! int i, j; ! OuterLoop: for (i = 0; i < c.length; i++) ! if (c[i] == '&') ! { ! entity = new StringBuffer(); ! for (j = 0; j < 8; j++) // Add things into the entity buffer until we hit a ! // semicolon ! { ! i++; ! if (i == c.length) ! { ! ret.append('&' + entity.toString()); ! continue OuterLoop; ! } ! else if (c[i] != ';') ! entity.append(c[i]); ! else ! break; // Reached end of the entity (or end of the whole string!) ! } ! ent = entity.toString(); ! if (ent.equals("lt")) ! ret.append("<"); ! else if (ent.equals("gt")) ! ret.append(">"); ! else if (ent.equals("amp")) ! ret.append("&"); ! else if (ent.equals("quot")) ! ret.append("\""); ! else ! ret.append('&' + ent + ';'); ! } ! else ! ret.append(c[i]); ! return ret.toString(); ! } ! public String getEncoding() ! { ! return encoding; ! } ! public void setEncoding(String encoding) ! { ! this.encoding = encoding; ! } ! /** ! * Container class to make it possible to return two objects from readNode(). ! */ ! private static class ReturnValue ! { ! public String xmlContent; ! public JreepadNode node; ! public ReturnValue(String xmlContent, JreepadNode node) { ! this.xmlContent = xmlContent; ! this.node = node; } } --- 43,131 ---- public class XmlReader implements JreepadReader { ! public static final String NODE_TAG = "node"; ! public static final String TITLE_ATTRIBUTE = "title"; ! public static final String TYPE_ATTRIBUTE = "type"; public JreepadTreeModel read(InputStream in) throws IOException { ! SAXParserFactory factory = SAXParserFactory.newInstance(); ! Handler handler = null; ! try { ! SAXParser parser = factory.newSAXParser(); ! handler = new Handler(); ! parser.parse(in, handler); ! } ! catch (ParserConfigurationException e) ! { ! throw new IOException(e); ! } ! catch (SAXException e) ! { ! throw new IOException(e); } ! JreepadTreeModel document = new JreepadTreeModel(handler.getRoot()); document.setFileType(JreepadPrefs.FILETYPE_XML); return document; } ! private class Handler extends DefaultHandler { + JreepadNode root = null; + JreepadNode currentNode = null; + StringBuffer content = null; + int articleMode; ! public void characters(char[] ch, int start, int length) throws SAXException { ! if (content != null) ! content.append(ch, start, length); ! } ! public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException ! { ! if (!qName.equals(NODE_TAG)) ! throw new SAXException("Unknown tag " + qName); ! // Save node content ! if (currentNode != null && content != null) ! currentNode.getArticle().setContent(content.toString()); ! content = new StringBuffer(); ! String title = attributes.getValue(TITLE_ATTRIBUTE); ! String type = attributes.getValue(TYPE_ATTRIBUTE); ! JreepadNode newNode = new JreepadNode(title, ""); ! if (currentNode != null) ! currentNode.add(newNode); ! currentNode = newNode; ! if (root == null) ! root = currentNode; ! int articleMode = JreepadArticle.ARTICLEMODE_ORDINARY; ! if (type.equals("text/csv")) ! articleMode = JreepadArticle.ARTICLEMODE_CSV; ! else if (type.equals("text/html")) ! articleMode = JreepadArticle.ARTICLEMODE_HTML; ! else if (type.equals("text/textile")) ! articleMode = JreepadArticle.ARTICLEMODE_TEXTILEHTML; ! //else if (type.equals("application/x-jreepad-softlink")) ! // articleMode = JreepadArticle.ARTICLEMODE_SOFTLINK; ! currentNode.getArticle().setArticleMode(articleMode); ! } ! public void endElement(String uri, String localName, String qName) throws SAXException ! { ! if (content != null) ! currentNode.getArticle().setContent(content.toString()); ! currentNode = currentNode.getParentNode(); ! content = null; ! } ! public JreepadNode getRoot() { ! return root; } } Index: XmlWriter.java =================================================================== RCS file: /cvsroot/jreepad/jreepad/src/jreepad/io/XmlWriter.java,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** XmlWriter.java 26 Mar 2007 11:49:24 -0000 1.5 --- XmlWriter.java 28 Sep 2007 21:54:41 -0000 1.6 *************** *** 22,33 **** import java.io.IOException; import java.io.OutputStream; - import java.io.OutputStreamWriter; - import java.io.Writer; import java.util.Enumeration; import jreepad.JreepadArticle; import jreepad.JreepadNode; import jreepad.JreepadTreeModel; /** * Writes the Jreepad tree as XML. --- 22,40 ---- import java.io.IOException; import java.io.OutputStream; import java.util.Enumeration; + import javax.xml.transform.TransformerConfigurationException; + import javax.xml.transform.sax.SAXTransformerFactory; + import javax.xml.transform.sax.TransformerHandler; + import javax.xml.transform.stream.StreamResult; + import jreepad.JreepadArticle; import jreepad.JreepadNode; import jreepad.JreepadTreeModel; + import org.xml.sax.ContentHandler; + import org.xml.sax.SAXException; + import org.xml.sax.helpers.AttributesImpl; + /** * Writes the Jreepad tree as XML. *************** *** 38,46 **** implements JreepadWriter { ! private String encoding; ! public XmlWriter(String encoding) { ! this.encoding = encoding; } --- 45,58 ---- implements JreepadWriter { ! public static final String NODE_TAG = "node"; ! public static final String TITLE_ATTRIBUTE = "title"; ! public static final String TYPE_ATTRIBUTE = "type"; ! public static final String NSU = ""; ! private AttributesImpl attributes = new AttributesImpl(); ! public XmlWriter() { ! attributes.addAttribute("", "", TITLE_ATTRIBUTE, "", ""); ! attributes.addAttribute("", "", TYPE_ATTRIBUTE, "", ""); } *************** *** 48,117 **** throws IOException { ! Writer writer = new OutputStreamWriter(out, encoding); ! writer.write("<?xml version=\"1.0\" encoding=\"" + encoding + "\"?>\n"); ! writeNode(writer, document.getRootNode(), 0, true); ! writer.close(); } ! private void writeNode(Writer writer, JreepadNode node, int depth, boolean includeChildren) throws IOException { ! writer.write("<node "); ! if (depth == 0) ! writer.write("xmlns=\"http://jreepad.sourceforge.net/formats\" "); ! writer.write("title=\"" + xmlEscapeChars(node.getTitle()) + "\" type=\""); switch (node.getArticle().getArticleMode()) { case JreepadArticle.ARTICLEMODE_HTML: ! writer.write("text/html"); break; case JreepadArticle.ARTICLEMODE_TEXTILEHTML: ! writer.write("text/textile"); break; case JreepadArticle.ARTICLEMODE_CSV: ! writer.write("text/csv"); break; default: ! writer.write("text/plain"); break; } - writer.write("\">"); - writer.write(xmlEscapeChars(node.getContent())); - if (includeChildren) - { - Enumeration kids = node.children(); - while (kids.hasMoreElements()) - writeNode(writer, (JreepadNode)kids.nextElement(), depth + 1, - includeChildren); - } - writer.write("</node>\n"); - } ! public String getEncoding() ! { ! return encoding; ! } ! public void setEncoding(String encoding) ! { ! this.encoding = encoding; ! } ! private static String xmlEscapeChars(String in) ! { ! char[] c = in.toCharArray(); ! StringBuffer ret = new StringBuffer(); ! for (int i = 0; i < c.length; i++) ! if (c[i] == '<') ! ret.append("<"); ! else if (c[i] == '>') ! ret.append(">"); ! else if (c[i] == '&') ! ret.append("&"); ! else if (c[i] == '"') ! ret.append("""); ! else ! ret.append(c[i]); ! return ret.toString(); } } --- 60,124 ---- throws IOException { ! StreamResult result = new StreamResult(out); ! SAXTransformerFactory factory = (SAXTransformerFactory)SAXTransformerFactory.newInstance(); ! TransformerHandler handler; ! try ! { ! handler = factory.newTransformerHandler(); ! } ! catch (TransformerConfigurationException e) ! { ! throw new IOException(e); ! } ! handler.setResult(result); ! ! try ! { ! write(handler, document); ! } ! catch (SAXException e) ! { ! throw new IOException(e); ! } } ! private void write(ContentHandler handler, JreepadTreeModel document) throws SAXException { ! handler.startDocument(); ! writeNode(handler, document.getRootNode()); ! handler.endDocument(); ! } + private void writeNode(ContentHandler handler, JreepadNode node) throws SAXException + { + String type; switch (node.getArticle().getArticleMode()) { case JreepadArticle.ARTICLEMODE_HTML: ! type = "text/html"; break; case JreepadArticle.ARTICLEMODE_TEXTILEHTML: ! type = "text/textile"; break; case JreepadArticle.ARTICLEMODE_CSV: ! type = "text/csv"; break; default: ! type = "text/plain"; break; } ! attributes.setValue(0, node.getTitle()); ! attributes.setValue(1, type); ! handler.startElement(NSU, NODE_TAG, NODE_TAG, attributes); ! String content = node.getContent(); ! handler.characters(content.toCharArray(), 0, content.length()); ! Enumeration kids = node.children(); ! while (kids.hasMoreElements()) ! writeNode(handler, (JreepadNode)kids.nextElement()); ! ! handler.endElement(NSU, NODE_TAG, NODE_TAG); } } |