Clover coverage report -
Coverage timestamp: Sun Nov 1 2009 23:08:24 UTC
file stats: LOC: 271   Methods: 24
NCLOC: 165   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
StringSerializer.java 53.6% 56.2% 58.3% 56.1%
coverage coverage
 1    /*
 2    * Licensed to the Apache Software Foundation (ASF) under one or more
 3    * contributor license agreements. See the NOTICE file distributed with
 4    * this work for additional information regarding copyright ownership.
 5    * The ASF licenses this file to You under the Apache License, Version 2.0
 6    * (the "License"); you may not use this file except in compliance with
 7    * the License. You may obtain a copy of the License at
 8    *
 9    * http://www.apache.org/licenses/LICENSE-2.0
 10    *
 11    * Unless required by applicable law or agreed to in writing, software
 12    * distributed under the License is distributed on an "AS IS" BASIS,
 13    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14    * See the License for the specific language governing permissions and
 15    * limitations under the License.
 16    *
 17    * $Id: StringSerializer.java 541508 2007-05-25 01:54:12Z vgritsenko $
 18    */
 19   
 20    package org.apache.xindice.tools.command;
 21   
 22    import org.xml.sax.Attributes;
 23    import org.xml.sax.ContentHandler;
 24    import org.xml.sax.SAXException;
 25    import org.xml.sax.ext.LexicalHandler;
 26   
 27    import java.util.HashMap;
 28    import java.util.Map;
 29    import java.util.Stack;
 30   
 31    /**
 32    * SAX content handler that produces a string from the SAX events it receives.
 33    * After calling <code>endDocument()</code>, the string becomes available by
 34    * calling <code>toString()</code>
 35    *
 36    * @author <a href="mailto:james.bates@amplexor.com">James Bates</a>
 37    * @version $Revision: 541508 $, $Date: 2007-05-24 18:54:12 -0700 (Thu, 24 May 2007) $
 38    */
 39    public class StringSerializer implements ContentHandler, LexicalHandler {
 40   
 41    /**
 42    * The encoding that should be written into the XML declaration. May be
 43    * <code>null</code> indicating no encoding should be written.
 44    */
 45    private String encoding;
 46   
 47    /**
 48    * Map containing stack of prefixes used in the XML document
 49    */
 50    private Map namespaceMap;
 51   
 52    /**
 53    * Namespace declarations that should be written out when the
 54    * next element opens
 55    */
 56    private StringBuffer namespaceDecls;
 57   
 58    /**
 59    * Are we currently inside a CDATA section?
 60    */
 61    private boolean inCDATA;
 62   
 63    /**
 64    * The document so far
 65    */
 66    private StringBuffer outputXml;
 67   
 68    /**
 69    * Creates new <code>StringSerializer</code>. The output encoding is not
 70    * specified therefore will be treated as "UTF-8".
 71    */
 72  30 public StringSerializer() {
 73  30 this(null);
 74    }
 75   
 76    /**
 77    * Creates new <code>StringSerializer</code>.
 78    *
 79    * @param encoding The encoding that should be written into the
 80    * XML declaration for the document. This encoding
 81    * is not used in any other way: when the resultant
 82    * string is written to a file, the writing application
 83    * must still take care to actually write using the
 84    * correct encoding. If <code>encoding</code> is
 85    * <code>null</code>, the encoding will be omitted
 86    * from the XML declaration.
 87    */
 88  30 public StringSerializer(String encoding) {
 89  30 this.encoding = encoding;
 90  30 this.outputXml = new StringBuffer(1024); // allocate a 1k block to start with
 91  30 this.namespaceMap = new HashMap();
 92  30 this.namespaceDecls = new StringBuffer();
 93    }
 94   
 95  30 public void startDocument() throws SAXException {
 96  30 outputXml.append("<?xml version=\"1.0\"");
 97  30 if (encoding != null) {
 98  0 outputXml.append(" encoding=\"");
 99  0 outputXml.append(encoding);
 100  0 outputXml.append('\"');
 101    }
 102  30 outputXml.append("?>");
 103    }
 104   
 105  30 public void endDocument() throws SAXException {
 106    }
 107   
 108  0 public void processingInstruction(String target, String data) throws SAXException {
 109  0 outputXml.append("<?");
 110  0 outputXml.append(target);
 111  0 outputXml.append(' ');
 112  0 outputXml.append(data);
 113  0 outputXml.append("?>");
 114    }
 115   
 116  0 public void comment(char[] data, int start, int len) throws SAXException {
 117  0 outputXml.append("<!--");
 118  0 outputXml.append(data, start, len);
 119  0 outputXml.append("-->");
 120    }
 121   
 122  267 private void xmlIze(StringBuffer sb,
 123    char[] data, int start, int len,
 124    boolean isAttValue) {
 125   
 126  267 for (int i = start; i < start + len; i++) {
 127  4455 if (data[i] == '<') {
 128  0 sb.append("&lt;");
 129  4455 } else if (data[i] == '&') {
 130  0 sb.append("&amp;");
 131  4455 } else if ((data[i] == '"') && (isAttValue)) {
 132  0 sb.append("&quot;");
 133    } else {
 134  4455 sb.append(data[i]);
 135    }
 136    }
 137    }
 138   
 139  63 private void writeAttribute(StringBuffer sb, String attName, String attValue) {
 140  63 sb.append(' ');
 141  63 sb.append(attName);
 142  63 sb.append("=\"");
 143  63 xmlIze(sb, attValue.toCharArray(), 0, attValue.length(), true);
 144  63 sb.append('\"');
 145    }
 146   
 147  63 public void startPrefixMapping(String prefix, String uri) throws SAXException {
 148  63 Stack uriStack = (Stack) namespaceMap.get(prefix);
 149  63 if (uriStack == null) {
 150  36 uriStack = new Stack();
 151  36 namespaceMap.put(prefix, uriStack);
 152    }
 153   
 154  63 uriStack.push(uri);
 155   
 156  63 if (!prefix.equals("")) {
 157  45 writeAttribute(namespaceDecls, "xmlns:" + prefix, uri);
 158    } else {
 159  18 writeAttribute(namespaceDecls, "xmlns", uri);
 160    }
 161    }
 162   
 163  63 public void endPrefixMapping(String prefix) throws SAXException {
 164  63 Stack uriStack = (Stack) namespaceMap.get(prefix);
 165  63 uriStack.pop();
 166    }
 167   
 168  0 public void ignorableWhitespace(char[] data, int start, int len) throws SAXException {
 169  0 outputXml.append(data, start, len);
 170    }
 171   
 172  96 private String getPrefix(String qName) {
 173  96 if (qName.indexOf(':') != -1) {
 174  63 return qName.substring(0, qName.indexOf(':'));
 175    } else {
 176  33 return "";
 177    }
 178    }
 179   
 180  96 public void startElement(String ns, String localName, String qName, Attributes att)
 181    throws SAXException {
 182   
 183    /* First: check element name qualification */
 184  96 String prefix = getPrefix(qName);
 185   
 186  96 if ((!(prefix.equals("") || prefix.equals("xml")))
 187    && namespaceMap.get(prefix) == null) {
 188   
 189  0 writeAttribute(namespaceDecls, "xmlns:" + prefix, ns);
 190    }
 191   
 192  96 outputXml.append('<');
 193  96 outputXml.append(qName);
 194  96 outputXml.append(namespaceDecls);
 195  96 namespaceDecls = new StringBuffer();
 196   
 197  96 for (int i = 0; i < att.getLength(); i++) {
 198   
 199  0 String attNamespaceUri = att.getURI(i);
 200  0 String attQName = att.getQName(i);
 201  0 String attValue = att.getValue(i);
 202   
 203  0 String attPrefix = getPrefix(attQName);
 204  0 if (!(attPrefix.equals("") || attPrefix.equals("xml"))) {
 205   
 206  0 if (namespaceMap.get(attPrefix) == null) {
 207  0 writeAttribute(outputXml, "xmlns:" + attPrefix, attNamespaceUri);
 208    }
 209    }
 210   
 211  0 writeAttribute(outputXml, attQName, attValue);
 212    }
 213   
 214  96 outputXml.append('>');
 215    }
 216   
 217  96 public void endElement(String ns, String localName, String qName)
 218    throws SAXException {
 219  96 outputXml.append("</");
 220  96 outputXml.append(qName);
 221  96 outputXml.append('>');
 222    }
 223   
 224  0 public void skippedEntity(String entity) throws SAXException {
 225  0 if (entity.startsWith("%")) {
 226  0 outputXml.append(entity);
 227  0 outputXml.append(';');
 228    } else {
 229  0 outputXml.append('&');
 230  0 outputXml.append(entity);
 231  0 outputXml.append(';');
 232    }
 233    }
 234   
 235  204 public void characters(char[] data, int start, int len) throws SAXException {
 236  204 if (inCDATA) {
 237  0 outputXml.append(data, start, len);
 238    } else {
 239  204 xmlIze(outputXml, data, start, len, false);
 240    }
 241    }
 242   
 243  22 public void setDocumentLocator(org.xml.sax.Locator locator) {
 244    }
 245   
 246  0 public void startCDATA() throws SAXException {
 247  0 outputXml.append("<![CDATA[");
 248  0 inCDATA = true;
 249    }
 250   
 251  0 public void endCDATA() throws SAXException {
 252  0 inCDATA = false;
 253  0 outputXml.append("]]>");
 254    }
 255   
 256  0 public void startEntity(String entity) throws SAXException {
 257    }
 258   
 259  0 public void endEntity(String entity) throws SAXException {
 260    }
 261   
 262  0 public void startDTD(String docType, String systemID, String publicID) throws SAXException {
 263    }
 264   
 265  0 public void endDTD() throws SAXException {
 266    }
 267   
 268  30 public String toString() {
 269  30 return outputXml.toString();
 270    }
 271    }