Clover coverage report -
Coverage timestamp: Sun Nov 1 2009 23:08:24 UTC
file stats: LOC: 225   Methods: 9
NCLOC: 130   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
XMLUtilities.java 34.1% 51.3% 66.7% 46.6%
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: XMLUtilities.java 635409 2008-03-10 00:52:12Z natalia $
 18    */
 19   
 20    package org.apache.xindice.util;
 21   
 22    /**
 23    * Set of XML-related utilities.
 24    *
 25    * @version $Revision: 635409 $, $Date: 2008-03-10 00:52:12 +0000 (Mon, 10 Mar 2008) $
 26    */
 27    public class XMLUtilities {
 28    private static final String REPLACEMENT = "�";
 29   
 30    /**
 31    * Converts input text into its XML representation by escaping all special symbols,
 32    * if any are present.
 33    *
 34    * @param value Input array
 35    * @param offset Start position in the array
 36    * @param length Number of characters to process
 37    * @param strict Method will throw an exception when it encounter illegal surrogate
 38    * character if <code>strict</code> is true, otherwise illegal surrogate character
 39    * will be replaced by character \uFFFD.
 40    * @return String with all the special symbols escaped
 41    * @throws XindiceRuntimeException If <code>strict</code> is true and <code>value</code>
 42    * contains illegal surrogate character
 43    */
 44  0 public static String escape(char[] value, int offset, int length, boolean strict) {
 45  0 StringBuffer buf = new StringBuffer();
 46  0 int start = offset;
 47  0 int blockLength = 0;
 48   
 49  0 for (int i = offset; i < length; i++) {
 50  0 String outval = escape(value[i], strict);
 51   
 52  0 if (outval == null) {
 53  0 if (isLeadingSurrogate(value[i])) {
 54  0 if (i + 1 < length && isTrailingSurrogate(value[i + 1])) {
 55  0 outval = getSurrogateValue(value[i], value[i + 1]);
 56  0 i++;
 57    } else {
 58  0 if (strict) {
 59  0 throw new XindiceRuntimeException("Leading surrogate &#" + Integer.toString(value[i]) + ";" +
 60    "must be followed by trailing surrogate");
 61    } else {
 62  0 outval = REPLACEMENT;
 63    }
 64    }
 65    } else {
 66  0 blockLength++;
 67    }
 68    }
 69   
 70  0 if (outval != null) {
 71  0 if (blockLength > 0) {
 72  0 buf.append(value, start, blockLength);
 73    }
 74  0 buf.append(outval);
 75  0 start = i + 1;
 76  0 blockLength = 0;
 77    }
 78    }
 79   
 80  0 if (blockLength > 0 && start > offset) {
 81  0 buf.append(value, start, blockLength);
 82    }
 83   
 84  0 return buf.length() > 0 ? buf.toString() : new String(value, offset, length);
 85    }
 86   
 87    /**
 88    * Converts input text into its XML representation by escaping all special symbols,
 89    * if any are present.
 90    *
 91    * @param value Input array
 92    * @param offset Start position in the array
 93    * @param length Number of characters to process
 94    * @return String with all the special symbols escaped
 95    */
 96  0 public static String escape(char[] value, int offset, int length) {
 97  0 return escape(value, offset, length, false);
 98    }
 99   
 100    /**
 101    * Converts input text into its XML representation by escaping all special symbols,
 102    * if any are present.
 103    *
 104    * @param text Input string
 105    * @param strict Method will throw an exception when it encounter illegal surrogate
 106    * character if <code>strict</code> is true, otherwise illegal surrogate character
 107    * will be replaced by character \uFFFD.
 108    * @return String with all the special symbols escaped
 109    * @throws XindiceRuntimeException If <code>strict</code> is true and <code>text</code>
 110    * contains illegal surrogate character
 111    */
 112  39449 public static String escape(String text, boolean strict) {
 113  39449 StringBuffer buf = null;
 114  39449 int length = text.length();
 115   
 116  39449 for (int i = 0; i < length; i++) {
 117  455181 char ch = text.charAt(i);
 118  455181 String outval = escape(ch, strict);
 119   
 120  455181 if (outval == null) {
 121  455113 if (isLeadingSurrogate(ch)) {
 122  0 if (i + 1 < length && isTrailingSurrogate(text.charAt(i + 1))) {
 123  0 outval = getSurrogateValue(ch, text.charAt(i + 1));
 124   
 125  0 if (buf == null) {
 126  0 buf = new StringBuffer(text.substring(0, i));
 127    }
 128  0 i++;
 129    } else {
 130  0 if (strict) {
 131  0 throw new XindiceRuntimeException("Leading surrogate &#" + Integer.toString(ch) + ";" +
 132    "must be followed by trailing surrogate");
 133    } else {
 134  0 outval = REPLACEMENT;
 135    }
 136    }
 137    }
 138    }
 139   
 140  455181 if (outval != null && buf == null) {
 141  68 buf = new StringBuffer(text.substring(0, i));
 142    }
 143   
 144  455181 if (outval != null) {
 145  68 buf.append(outval);
 146  455113 } else if (buf != null) {
 147  148 buf.append(ch);
 148    }
 149    }
 150   
 151  39449 return buf != null ? buf.toString() : text;
 152    }
 153   
 154    /**
 155    * Converts input text into its XML representation by escaping all special symbols,
 156    * if any are present.
 157    *
 158    * @param text Input string
 159    * @return String with all the special symbols escaped
 160    */
 161  39449 public static String escape(String text) {
 162  39449 return escape(text, false);
 163    }
 164   
 165  455181 private static String escape(char ch, boolean strict) {
 166  455181 String outval = null;
 167   
 168  455181 switch (ch) {
 169  6 case '&':
 170  6 outval = "&amp;";
 171  6 break;
 172  38 case '\'':
 173  38 outval = "&apos;";
 174  38 break;
 175  12 case '\"':
 176  12 outval = "&quot;";
 177  12 break;
 178  6 case '<':
 179  6 outval = "&lt;";
 180  6 break;
 181  6 case '>':
 182  6 outval = "&gt;";
 183  6 break;
 184  455113 default:
 185  455113 if (isTrailingSurrogate(ch)) {
 186  0 if (strict) {
 187  0 throw new XindiceRuntimeException("Trailing surrogate &#" + Integer.toString(ch) +
 188    "; must follow leading surrogate");
 189    } else {
 190  0 outval = REPLACEMENT;
 191    }
 192  455113 } else if (!isLeadingSurrogate(ch) && !isLegal(ch)) {
 193  0 outval = "&#" + Integer.toString(ch) + ";";
 194    }
 195  455113 break;
 196    }
 197   
 198  455181 return outval;
 199    }
 200   
 201  455113 private static boolean isLegal(char ch) {
 202  455113 return ch == 0x9 || ch == 0xA || ch == 0xD ||
 203    (ch >= 0x20 && ch <= 0xD7FF) ||
 204    (ch >= 0xE000 && ch <= 0xFFFD);
 205    }
 206   
 207    /**
 208    * Converts UTF-16 surrogate pair to UTF-8
 209    * @param high Leading surrogate
 210    * @param low Trailing surrogate
 211    * @return String with escaped 4-byte value
 212    */
 213  0 private static String getSurrogateValue(char high, char low) {
 214  0 int val = (high & 0x3FF) << 10 | (low & 0x3FF) + 0x10000;
 215  0 return "&#" + Integer.toString(val) + ";";
 216    }
 217   
 218  910226 private static boolean isLeadingSurrogate(char ch) {
 219  910226 return ch >= 0xD800 && ch <= 0xDBFF;
 220    }
 221   
 222  455113 private static boolean isTrailingSurrogate(char ch) {
 223  455113 return ch >= 0xDC00 && ch <= 0xDFFF;
 224    }
 225    }