1 10 package mondrian.xmla.impl; 11 12 import java.io.OutputStream ; 13 import java.io.OutputStreamWriter ; 14 import java.io.PrintWriter ; 15 import java.io.UnsupportedEncodingException ; 16 import java.io.Writer ; 17 import java.util.Stack ; 18 19 import mondrian.xmla.SaxWriter; 20 21 import org.eigenbase.xom.XMLUtil; 22 import org.eigenbase.xom.XOMUtil; 23 import org.xml.sax.Attributes ; 24 25 32 public class DefaultSaxWriter implements SaxWriter { 33 34 private static final int STATE_IN_TAG = 0; 35 36 private static final int STATE_END_ELEMENT = 1; 37 38 private static final int STATE_AFTER_TAG = 2; 39 40 private static final int STATE_CHARACTERS = 3; 41 42 private final PrintWriter writer; 43 private int indent; 44 private String indentStr = " "; 45 private final Stack stack = new Stack (); 46 private int state = STATE_END_ELEMENT; 47 48 49 52 public DefaultSaxWriter(OutputStream stream) { 53 this(new OutputStreamWriter (stream)); 54 } 55 public DefaultSaxWriter(OutputStream stream, String xmlEncoding) 56 throws UnsupportedEncodingException { 57 this(new OutputStreamWriter (stream, xmlEncoding)); 58 } 59 60 66 public DefaultSaxWriter(Writer writer) { 67 this(new PrintWriter (writer), 0); 68 } 69 70 75 public DefaultSaxWriter(PrintWriter writer, int initialIndent) { 76 this.writer = writer; 77 this.indent = initialIndent; 78 } 79 80 private void _startElement( 81 String namespaceURI, String localName, 82 String qName, Attributes atts){ 83 _checkTag(); 84 if (indent > 0) { 85 writer.println(); 86 } 87 for (int i = 0; i < indent; i++) { 88 writer.write(indentStr); 89 } 90 indent++; 91 writer.write('<'); 92 writer.write(qName); 93 for (int i = 0; i < atts.getLength(); i++) { 94 XMLUtil.printAtt(writer, atts.getQName(i), atts.getValue(i)); 95 } 96 state = STATE_IN_TAG; 97 } 98 99 private void _checkTag() { 100 if (state == STATE_IN_TAG) { 101 state = STATE_AFTER_TAG; 102 writer.print(">"); 103 } 104 } 105 106 private void _endElement( 107 String namespaceURI, String localName, String qName){ 108 indent--; 109 if (state == STATE_IN_TAG) { 110 writer.write("/>"); 111 } else { 112 if (state != STATE_CHARACTERS) { 113 writer.println(); 114 for (int i = 0; i < indent; i++) { 115 writer.write(indentStr); 116 } 117 } 118 writer.write("</"); 119 writer.write(qName); 120 writer.write('>'); 121 } 122 state = STATE_END_ELEMENT; 123 } 124 125 private void _characters(char ch[], int start, int length) { 126 _checkTag(); 127 128 String s = new String (ch, start, length); 131 if (XOMUtil.stringHasXMLSpecials(s)) { 132 XMLUtil.stringEncodeXML(s, writer); 133 142 } else { 143 writer.print(s); 144 } 145 146 state = STATE_CHARACTERS; 147 } 148 149 150 153 public void characters(String s) { 154 if (s != null && s.length() > 0) { 155 _characters(s.toCharArray(), 0, s.length()); 156 } 157 } 158 159 public void element(String tagName, String [] attributes) { 160 startElement(tagName, attributes); 161 endElement(); 162 } 163 164 public void startElement(String tagName){ 165 _startElement(null, null, tagName, EmptyAttributes); 166 stack.push(tagName); 167 } 168 169 public void startElement(String tagName, String [] attributes) { 170 _startElement(null, null, tagName, new StringAttributes(attributes)); 171 stack.push(tagName); 172 } 173 174 public void endElement() { 175 String tagName = (String ) stack.pop(); 176 _endElement(null, null, tagName); 177 } 178 179 public void startDocument() { 180 if (stack.size() != 0) { 181 throw new IllegalStateException ("Document already started"); 182 } 183 } 184 185 public void endDocument() { 186 if (stack.size() != 0) { 187 throw new IllegalStateException ("Document may have unbalanced elements"); 188 } 189 writer.flush(); 190 } 191 192 public void completeBeforeElement(String tagName) { 193 if (stack.indexOf(tagName) == -1) { 194 return; 195 } 196 197 String currentTagName = (String ) stack.peek(); 198 while (!tagName.equals(currentTagName)) { 199 _endElement(null, null, currentTagName); 200 stack.pop(); 201 currentTagName = (String ) stack.peek(); 202 } 203 } 204 205 public void verbatim(String text) { 206 _checkTag(); 207 writer.print(text); 208 } 209 210 public void flush() { 211 writer.flush(); 212 } 213 214 static private final Attributes EmptyAttributes = new Attributes () { 215 public int getLength() { 216 return 0; 217 } 218 219 public String getURI(int index) { 220 return null; 221 } 222 223 public String getLocalName(int index) { 224 return null; 225 } 226 227 public String getQName(int index) { 228 return null; 229 } 230 231 public String getType(int index) { 232 return null; 233 } 234 235 public String getValue(int index) { 236 return null; 237 } 238 239 public int getIndex(String uri, String localName) { 240 return 0; 241 } 242 243 public int getIndex(String qName) { 244 return 0; 245 } 246 247 public String getType(String uri, String localName) { 248 return null; 249 } 250 251 public String getType(String qName) { 252 return null; 253 } 254 255 public String getValue(String uri, String localName) { 256 return null; 257 } 258 259 public String getValue(String qName) { 260 return null; 261 } 262 }; 263 264 267 public static class StringAttributes implements Attributes { 268 private final String [] strings; 269 270 public StringAttributes(String [] strings) { 271 this.strings = strings; 272 } 273 274 public int getLength() { 275 return strings.length / 2; 276 } 277 278 public String getURI(int index) { 279 return null; 280 } 281 282 public String getLocalName(int index) { 283 return null; 284 } 285 286 public String getQName(int index) { 287 return strings[index * 2]; 288 } 289 290 public String getType(int index) { 291 return null; 292 } 293 294 public String getValue(int index) { 295 return strings[index * 2 + 1]; 296 } 297 298 public int getIndex(String uri, String localName) { 299 return -1; 300 } 301 302 public int getIndex(String qName) { 303 final int count = strings.length / 2; 304 for (int i = 0; i < count; i++) { 305 String string = strings[i * 2]; 306 if (string.equals(qName)) { 307 return i; 308 } 309 } 310 return -1; 311 } 312 313 public String getType(String uri, String localName) { 314 return null; 315 } 316 317 public String getType(String qName) { 318 return null; 319 } 320 321 public String getValue(String uri, String localName) { 322 return null; 323 } 324 325 public String getValue(String qName) { 326 final int index = getIndex(qName); 327 if (index < 0) { 328 return null; 329 } else { 330 return strings[index * 2 + 1]; 331 } 332 } 333 } 334 } 335 336 | Popular Tags |