1 package jfun.yan.xml; 2 3 import java.util.ArrayList ; 4 import java.util.List ; 5 import java.util.Stack ; 6 7 8 9 import org.xml.sax.SAXException ; 10 import org.xml.sax.SAXParseException ; 11 import org.xml.sax.helpers.DefaultHandler ; 12 13 import org.xml.sax.Locator ; 14 15 class SimpleHandler extends DefaultHandler { 16 private final class TagBuilder{ 17 private final Location loc; 18 private final List nodes = new ArrayList (); 19 private final Attributes attrs; 20 private final String uri; 21 private final String name; 22 private final String qname; 23 public String toString(){ 24 return name; 25 } 26 TagBuilder(Location loc, String uri, String name, String qname, 27 Attributes attrs) { 28 this.attrs = attrs; 29 this.loc = loc; 30 this.name = name; 31 this.qname = qname; 32 this.uri = uri; 33 } 34 void addNode(Node node){ 35 nodes.add(node); 36 } 37 void collectText(TextBuilder tbuilder){ 38 if(!tbuilder.isWhitespace()){ 39 nodes.add(tbuilder.toNode()); 41 } 42 } 43 Tag getResult(TextBuilder tbuilder){ 44 if(tbuilder != null){ 45 if(!tbuilder.isWhitespace() || nodes.isEmpty()){ 46 nodes.add(tbuilder.toNode()); 47 } 48 } 49 return new Tag(loc, name, attrs, nodes); 50 } 51 } 52 public Location getLocation(){ 53 return MyUtil.toLocation(loc); 54 } 55 private Locator loc; 56 private final Stack builders = new Stack (); 57 private TagBuilder builder = null; 58 private Node result; 59 60 private static final class TextBuilder{ 61 private final StringBuffer buf = new StringBuffer (); 62 private final Location loc; 63 private boolean whitespace = true; 64 65 TextBuilder(Location loc) { 66 this.loc = loc; 67 } 68 public Location getLocation() { 69 return loc; 70 } 71 boolean isWhitespace() { 72 return whitespace; 73 } 74 void setWhitespace(boolean whitespace) { 75 this.whitespace = whitespace; 76 } 77 void addText(String s){ 78 if(s.trim().length()>0){ 79 whitespace = false; 80 } 81 buf.append(s); 82 } 83 public CharacterData toNode(){ 84 return new CharacterData(loc, buf.toString()); 85 } 86 } 87 private TextBuilder tbuilder = null; 88 private void addText(String s){ 89 if(s.length()==0) return; 90 if(tbuilder==null){ 91 tbuilder = new TextBuilder(getLocation()); 92 } 93 tbuilder.addText(s); 94 } 95 private TextBuilder readText(){ 96 if(tbuilder==null) return null; 97 final TextBuilder ret = tbuilder; 98 tbuilder = null; 99 return ret; 100 } 101 public void characters(char[] chars, int start, int length){ 102 final String text = new String (chars, start, length); 103 addText(text); 104 128 } 129 130 public void endElement(String uri, String name, String qname) throws SAXException { 131 if(builder == null) 132 throw new IllegalStateException ("not opening tag for "+name); 133 Tag tag = builder.getResult(readText()); 134 135 if(builders.isEmpty()){ 136 result = tag; 138 } 139 else{ 140 this.builder = (TagBuilder)builders.pop(); 141 this.builder.addNode(tag); 142 } 143 } 144 145 public void setDocumentLocator(org.xml.sax.Locator loc) { 146 this.loc = loc; 147 } 148 private static Attributes convert(org.xml.sax.Attributes attrs){ 149 final int sz = attrs.getLength(); 150 final Attributes result = new Attributes(sz); 151 for(int i=0; i<sz; i++){ 152 result.add(attrs.getQName(i), attrs.getValue(i)); 153 } 154 return result; 155 } 156 private void collectText(TextBuilder tbuilder){ 157 if(tbuilder!=null){ 158 if(builder==null){ 159 if(tbuilder.isWhitespace()){ 160 return; 162 } 163 throw new IllegalStateException ("text outside of a tag unrecoginized"); 164 } 165 else{ 166 builder.collectText(tbuilder); 167 } 168 } 169 } 170 public void startElement(String uri, String name, String qname, 171 org.xml.sax.Attributes attrs){ 172 176 collectText(readText()); 177 if(builder != null){ 178 builders.push(builder); 179 } 180 builder = new TagBuilder(getLocation(), uri, name, qname, convert(attrs)); 181 } 182 183 public void error(SAXParseException e) throws SAXException { 184 throw new ConfigurationException("xml error: "+e.getMessage(), 185 e, getLocation()); 186 } 187 188 public void fatalError(SAXParseException e) throws SAXException { 189 throw new ConfigurationException("fatal xml error: "+e.getMessage(), 190 e, getLocation()); 191 } 192 193 public void warning(SAXParseException e) throws SAXException { 194 System.err.println(e.getMessage()); 195 super.warning(e); 196 } 197 198 public Node getResult(){ 199 return result; 200 } 201 } 202 | Popular Tags |