1 19 20 package edu.umd.cs.findbugs.xml; 21 22 import java.io.IOException ; 23 import java.io.OutputStream ; 24 import java.io.OutputStreamWriter ; 25 import java.io.Writer ; 26 import java.nio.charset.Charset ; 27 28 33 public class OutputStreamXMLOutput implements XMLOutput { 34 private static final String OPENING = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; 35 private static String getStylesheetCode(String stylesheet) { 36 if (stylesheet == null) return ""; 37 return "<?xml-stylesheet type=\"text/xsl\" HREF=\"" + stylesheet + "\"?>\n"; 38 } 39 40 private static final MetaCharacterMap textMetaCharacterMap = new MetaCharacterMap(); 41 static { 42 textMetaCharacterMap.addMeta('<', "<"); 43 textMetaCharacterMap.addMeta('>', ">"); 44 textMetaCharacterMap.addMeta('&', "&"); 45 } 46 47 private class WriterQuoteMetaCharacters extends QuoteMetaCharacters { 48 public WriterQuoteMetaCharacters(String text) { 49 super(text, textMetaCharacterMap); 50 } 51 52 @Override 53 public void emitLiteral(String s) throws IOException { 54 out.write(s); 55 newLine = s.endsWith("\n"); 56 } 57 } 58 59 private Writer out; 60 private int nestingLevel; 61 private boolean newLine; 62 private String stylesheet; 63 67 public OutputStreamXMLOutput(OutputStream os) { 68 this(os, null); 69 } 70 71 public OutputStreamXMLOutput(OutputStream os, String stylesheet) { 72 this.out = new OutputStreamWriter (os, Charset.forName("UTF-8")); 73 this.nestingLevel = 0; 74 this.newLine = true; 75 } 76 public void beginDocument() throws IOException { 77 out.write(OPENING); 78 out.write(getStylesheetCode(stylesheet)); 79 out.write("\n"); 80 newLine = true; 81 } 82 83 public void openTag(String tagName) throws IOException { 84 emitTag(tagName, false); 85 } 86 87 public void openTag(String tagName, XMLAttributeList attributeList) throws IOException { 88 emitTag(tagName, attributeList.toString(), false); 89 } 90 91 public void openCloseTag(String tagName) throws IOException { 92 emitTag(tagName, true); 93 } 94 95 public void openCloseTag(String tagName, XMLAttributeList attributeList) throws IOException { 96 emitTag(tagName, attributeList.toString(), true); 97 } 98 99 public void startTag(String tagName) throws IOException { 100 indent(); 101 ++nestingLevel; 102 out.write("<" + tagName); 103 } 104 105 public void addAttribute(String name, String value) throws IOException { 106 out.write(' '); 107 out.write(name); 108 out.write('='); 109 out.write(XMLAttributeList.getQuotedAttributeValue(value)); 110 } 111 112 public void stopTag(boolean close) throws IOException { 113 if (close) { 114 out.write("/>\n"); 115 --nestingLevel; 116 newLine = true; 117 } else { 118 out.write(">"); 119 newLine = false; 120 } 121 } 122 123 private void emitTag(String tagName, boolean close) throws IOException { 124 startTag(tagName); 125 stopTag(close); 126 } 127 128 private void emitTag(String tagName, String attributes, boolean close) throws IOException { 129 startTag(tagName); 130 attributes = attributes.trim(); 131 if (attributes.length() > 0) { 132 out.write(" "); 133 out.write(attributes); 134 } 135 stopTag(close); 136 } 137 138 public void closeTag(String tagName) throws IOException { 139 --nestingLevel; 140 if (newLine) 141 indent(); 142 out.write("</" + tagName + ">\n"); 143 newLine = true; 144 } 145 146 public void writeText(String text) throws IOException { 147 new WriterQuoteMetaCharacters(text).process(); 148 } 149 150 public void writeCDATA(String cdata) throws IOException { 151 out.write("<![CDATA["); 154 out.write(cdata); 155 out.write("]]>"); 156 newLine = false; 157 } 158 159 public void finish() throws IOException { 160 out.close(); 161 } 162 163 private void indent() throws IOException { 164 if (!newLine) 165 out.write("\n"); 166 for (int i = 0; i < nestingLevel; ++i) { 167 out.write(" "); 168 } 169 } 170 } 171 172 | Popular Tags |