1 package com.thaiopensource.relaxng.impl; 2 3 import org.relaxng.datatype.Datatype; 4 5 import java.io.OutputStream ; 6 import java.io.PrintWriter ; 7 import java.util.Hashtable ; 8 import java.util.Vector ; 9 10 import com.thaiopensource.xml.util.WellKnownNamespaces; 11 import com.thaiopensource.xml.util.Name; 12 13 public class PatternDumper { 14 private boolean startTagOpen = false; 15 private final Vector tagStack = new Vector (); 16 private final PrintWriter writer; 17 private int level = 0; 18 private boolean suppressIndent = false; 19 private final Vector patternList = new Vector (); 20 private final Hashtable patternTable = new Hashtable (); 21 22 private final PatternVisitor patternVisitor = new DumpPatternVisitor(); 23 private final PatternVisitor groupPatternVisitor = new GroupDumpPatternVisitor(); 24 private final PatternVisitor choicePatternVisitor = new ChoiceDumpPatternVisitor(); 25 private final PatternVisitor interleavePatternVisitor = new InterleaveDumpPatternVisitor(); 26 private final NameClassVisitor nameClassVisitor = new DumpNameClassVisitor(); 27 private final NameClassVisitor choiceNameClassVisitor = new ChoiceDumpNameClassVisitor(); 28 29 static public void dump(PrintWriter writer, Pattern p) { 30 new PatternDumper(writer).dump(p); 31 } 32 33 static public void dump(OutputStream out, Pattern p) { 34 new PatternDumper(new PrintWriter (out)).dump(p); 35 } 36 37 private PatternDumper(PrintWriter writer) { 38 this.writer = writer; 39 } 40 41 private void dump(Pattern p) { 42 write("<?xml version=\"1.0\"?>"); 43 startElement("grammar"); 44 attribute("xmlns", WellKnownNamespaces.RELAX_NG); 45 startElement("start"); 46 p.accept(groupPatternVisitor); 47 endElement(); 48 for (int i = 0; i < patternList.size(); i++) { 49 startElement("define"); 50 Pattern tem = (Pattern)patternList.elementAt(i); 51 attribute("name", getName(tem)); 52 tem.accept(groupPatternVisitor); 53 endElement(); 54 } 55 endElement(); 56 writer.println(); 57 writer.flush(); 58 } 59 60 private String getName(Pattern p) { 61 String name = (String )patternTable.get(p); 62 if (name == null) { 63 name = "p" + patternList.size(); 64 patternList.addElement(p); 65 patternTable.put(p, name); 66 } 67 return name; 68 } 69 70 private void startElement(String name) { 71 closeStartTag(); 72 indent(level); 73 write('<'); 74 write(name); 75 push(name); 76 startTagOpen = true; 77 level++; 78 } 79 80 private void closeStartTag() { 81 if (startTagOpen) { 82 startTagOpen = false; 83 write('>'); 84 } 85 } 86 87 private void attribute(String name, String value) { 88 write(' '); 89 write(name); 90 write('='); 91 write('"'); 92 chars(value, true); 93 write('"'); 94 } 95 96 private void data(String str) { 97 if (str.length() > 0) { 98 closeStartTag(); 99 chars(str, false); 100 suppressIndent = true; 101 } 102 } 103 104 private void chars(String str, boolean isAttribute) { 105 int len = str.length(); 106 for (int i = 0; i < len; i++) { 107 char c = str.charAt(i); 108 switch (c) { 109 case '&': 110 write("&"); 111 break; 112 case '<': 113 write("<"); 114 break; 115 case '>': 116 write(">"); 117 break; 118 case '"': 119 if (isAttribute) { 120 write("""); 121 break; 122 } 123 default: 125 write(c); 126 break; 127 } 128 } 129 } 130 131 private void endElement() { 132 --level; 133 if (startTagOpen) { 134 startTagOpen = false; 135 write("/>"); 136 pop(); 137 } 138 else { 139 if (!suppressIndent) 140 indent(level); 141 write("</"); 142 write(pop()); 143 write(">"); 144 } 145 suppressIndent = false; 146 } 147 148 private void indent(int level) { 149 writer.println(); 150 for (int i = 0; i < level; i++) 151 write(" "); 152 } 153 154 private void write(String str) { 155 writer.print(str); 156 } 157 158 private void write(char c) { 159 writer.print(c); 160 } 161 162 private void push(String s) { 163 tagStack.addElement(s); 164 } 165 166 private String pop() { 167 String s = (String )tagStack.lastElement(); 168 tagStack.setSize(tagStack.size() - 1); 169 return s; 170 } 171 172 class DumpPatternVisitor implements PatternVisitor { 173 public void visitEmpty() { 174 startElement("empty"); 175 endElement(); 176 } 177 178 public void visitNotAllowed() { 179 startElement("notAllowed"); 180 endElement(); 181 } 182 183 public void visitError() { 184 startElement("error"); 185 endElement(); 186 } 187 188 public void visitGroup(Pattern p1, Pattern p2) { 189 startElement("group"); 190 p1.accept(groupPatternVisitor); 191 p2.accept(groupPatternVisitor); 192 endElement(); 193 } 194 195 public void visitInterleave(Pattern p1, Pattern p2) { 196 startElement("interleave"); 197 p1.accept(interleavePatternVisitor); 198 p2.accept(interleavePatternVisitor); 199 endElement(); 200 } 201 202 public void visitChoice(Pattern p1, Pattern p2) { 203 startElement("choice"); 204 p1.accept(choicePatternVisitor); 205 p2.accept(choicePatternVisitor); 206 endElement(); 207 } 208 209 public void visitOneOrMore(Pattern p) { 210 startElement("oneOrMore"); 211 p.accept(groupPatternVisitor); 212 endElement(); 213 } 214 215 public void visitElement(NameClass nc, Pattern content) { 216 startElement("element"); 217 nc.accept(nameClassVisitor); 218 startElement("ref"); 219 attribute("name", getName(content)); 220 endElement(); 221 endElement(); 222 } 223 224 public void visitAttribute(NameClass nc, Pattern value) { 225 startElement("attribute"); 226 nc.accept(nameClassVisitor); 227 value.accept(patternVisitor); 228 endElement(); 229 } 230 231 public void visitData(Datatype dt) { 232 startElement("text"); endElement(); 234 } 235 236 public void visitDataExcept(Datatype dt, Pattern except) { 237 startElement("text"); endElement(); 239 } 240 241 public void visitValue(Datatype dt, Object obj) { 242 startElement("value"); 243 data(obj.toString()); 246 endElement(); 247 } 248 249 public void visitText() { 250 startElement("text"); 251 endElement(); 252 } 253 254 public void visitList(Pattern p) { 255 startElement("list"); 256 p.accept(groupPatternVisitor); 257 endElement(); 258 } 259 } 260 261 class GroupDumpPatternVisitor extends DumpPatternVisitor { 262 public void visitGroup(Pattern p1, Pattern p2) { 263 p1.accept(this); 264 p2.accept(this); 265 } 266 } 267 268 class ChoiceDumpPatternVisitor extends DumpPatternVisitor { 269 public void visitChoice(Pattern p1, Pattern p2) { 270 p1.accept(this); 271 p2.accept(this); 272 } 273 } 274 275 class InterleaveDumpPatternVisitor extends DumpPatternVisitor { 276 public void visitInterleave(Pattern p1, Pattern p2) { 277 p1.accept(this); 278 p2.accept(this); 279 } 280 } 281 282 283 class DumpNameClassVisitor implements NameClassVisitor { 284 public void visitChoice(NameClass nc1, NameClass nc2) { 285 startElement("choice"); 286 nc1.accept(choiceNameClassVisitor); 287 nc2.accept(choiceNameClassVisitor); 288 endElement(); 289 } 290 291 public void visitNsName(String ns) { 292 startElement("nsName"); 293 attribute("ns", ns); 294 endElement(); 295 } 296 297 public void visitNsNameExcept(String ns, NameClass nc) { 298 startElement("nsName"); 299 startElement("except"); 300 nc.accept(choiceNameClassVisitor); 301 endElement(); 302 endElement(); 303 } 304 305 public void visitAnyName() { 306 startElement("anyName"); 307 endElement(); 308 } 309 310 public void visitAnyNameExcept(NameClass nc) { 311 startElement("anyName"); 312 startElement("except"); 313 nc.accept(choiceNameClassVisitor); 314 endElement(); 315 endElement(); 316 } 317 318 public void visitName(Name name) { 319 startElement("name"); 320 attribute("ns", name.getNamespaceUri()); 321 data(name.getLocalName()); 322 endElement(); 323 } 324 325 public void visitError() { 326 startElement("error"); 327 endElement(); 328 } 329 330 public void visitNull() { 331 visitAnyName(); 332 } 333 } 334 335 class ChoiceDumpNameClassVisitor extends DumpNameClassVisitor { 336 public void visitChoice(NameClass nc1, NameClass nc2) { 337 nc1.accept(this); 338 nc2.accept(this); 339 } 340 } 341 } 342 | Popular Tags |