Clover Coverage Report - Atlassian Core
Coverage timestamp: Sun Nov 30 2008 18:33:35 CST
58   239   35   4.83
20   149   0.6   4
12     2.92  
3    
 
 
  XMLUtils       Line # 16 57 34 51.1% 0.5113636
  XMLUtils.TransformPolicy       Line # 224 0 0 - -1.0
  XMLUtils.ReplacePolicy       Line # 230 1 1 100% 1.0
 
  (2)
 
1    /*
2    * Created by IntelliJ IDEA.
3    * User: Administrator
4    * Date: 20/02/2002
5    * Time: 16:48:36
6    * To change template for new class use
7    * Code Style | Class Templates options (Tools | IDE Options).
8    */
9    package com.atlassian.core.util;
10   
11    import org.w3c.dom.Element;
12    import org.w3c.dom.Node;
13    import org.w3c.dom.NodeList;
14    import org.w3c.dom.Text;
15   
 
16    public class XMLUtils
17    {
18    /**
19    * With a given parent XML Element, find the text contents of the child element with supplied name.
20    */
 
21  4 toggle public static String getContainedText(Node parent, String childTagName)
22    {
23  4 try
24    {
25  4 Node tag = ((Element) parent).getElementsByTagName(childTagName).item(0);
26  4 return ((Text) tag.getFirstChild()).getData();
27    }
28    catch (Exception e)
29    {
30  0 return null;
31    }
32    }
33   
34    /**
35    * Given one element, get a single named child element of it.
36    */
 
37  0 toggle public static Element getSingleChildElement(Element el, String name)
38    {
39  0 NodeList children = el.getChildNodes();
40  0 for (int i = 0; i < children.getLength(); i++)
41    {
42  0 Node node = children.item(i);
43  0 if (node.getNodeType() == Node.ELEMENT_NODE && name.equals(node.getNodeName()))
44    {
45  0 return (Element) node;
46    }
47    }
48   
49  0 return null;
50    }
51   
52    /**
53    * Get an attribute of a given element, with a default value if the attribute is not present or blank.
54    */
 
55  0 toggle public static String getAttributeWithDefault(Element element, String attributeName, String defaultValue)
56    {
57  0 String group = element.getAttribute(attributeName);
58   
59  0 if (group == null || "".equals(group.trim()))
60    {
61  0 group = defaultValue;
62    }
63   
64  0 return group;
65    }
66   
67    /**
68    * Escapes a string so it may be returned as text content or attribute value. Non printable characters are escaped
69    * using character references. Where the format specifies a deault entity reference, that reference is used (e.g.
70    * <tt>&amp;lt;</tt>).
71    *
72    * @param source the string to escape or "" for null.
73    * @param policy how to handle invalid XML characters
74    * @since 3.19 / 3.10.1
75    */
 
76  19 toggle public static String escape(final String source, final TransformPolicy policy)
77    {
78  19 if (source == null)
79    {
80  0 return "";
81    }
82   
83  19 StringBuffer pBuffer = new StringBuffer(source.length() + 30); // lets allocate a stringbuffer that is roughly the same length
84   
85  38 for (int i = 0; i < source.length(); ++i)
86    {
87  19 transform(pBuffer, source.charAt(i), policy);
88    }
89   
90  19 return pBuffer.toString();
91    }
92   
93    /**
94    * Escape an XML string using a default policy of replacing invalid XML characters.
95    */
 
96  19 toggle public static String escape(final String source)
97    {
98  19 return escape(source, new ReplacePolicy());
99    }
100   
101   
 
102  0 toggle public static String escapeForCdata(String source)
103    {
104  0 if (source == null)
105    {
106  0 return null;
107    }
108   
109  0 StringBuffer sb = new StringBuffer();
110   
111  0 int index;
112  0 int oldIndex = 0;
113  0 while ((index = source.indexOf("]]>", oldIndex)) > -1)
114    {
115  0 sb.append(source.substring(oldIndex, index));
116  0 oldIndex = index + 3;
117  0 sb.append("]]]]><![CDATA[>");
118    }
119   
120  0 sb.append(source.substring(oldIndex));
121  0 return sb.toString();
122    }
123   
124    /**
125    * Identifies the last printable character in the Unicode range that is supported by the encoding used with this
126    * serializer. For 8-bit encodings this will be either 0x7E or 0xFF. For 16-bit encodings this will be 0xFFFF.
127    * Characters that are not printable will be escaped using character references.
128    */
129    static private int _lastPrintable = 0x7E;
130   
131    /**
132    * Encode special XML characters into the equivalent character references. These five are defined by default for all
133    * XML documents. Converts '<', '>', '"'. and '\'' to "lt", "gt", "quot", or "apos".
134    */
 
135  11 toggle static private String getEntityRef(char ch)
136    {
137  11 switch (ch)
138    {
139  1 case '<':
140  1 return "lt";
141  1 case '>':
142  1 return "gt";
143  1 case '"':
144  1 return "quot";
145  1 case '\'':
146  1 return "apos";
147  1 case '&':
148  1 return "amp";
149    }
150   
151  6 return null;
152    }
153   
154    /**
155    * If there is a suitable entity reference for this character, return it. The list of available entity references is
156    * almost but not identical between XML and HTML. This uses a default transformation policy of replacing invalid XML
157    * characters.
158    */
 
159  0 toggle public static String escape(final char ch)
160    {
161  0 return escape(ch, new ReplacePolicy());
162    }
163   
164    /**
165    * Escape XML characters with a user specified transformation policy for invalid characters.
166    *
167    * @since 3.19 / 3.10.1
168    */
 
169  0 toggle public static String escape(final char ch, final TransformPolicy policy)
170    {
171  0 final StringBuffer sb = new StringBuffer();
172  0 transform(sb, ch, policy);
173  0 return sb.toString();
174    }
175   
176    /**
177    * Append escaped version of character to the end of the StringBuffer
178    */
 
179  19 toggle private static void transform(final StringBuffer sb, final char ch, final TransformPolicy policy)
180    {
181  19 if (!validXml(ch))
182    {
183  8 sb.append(policy.handle(ch));
184    }
185    else
186    {
187  11 String charRef = getEntityRef(ch);
188  11 if (charRef != null)
189    {
190  5 sb.append("&").append(charRef).append(";");
191    }
192  6 else if ((ch >= ' ' && ch <= _lastPrintable && ch != 0xF7) ||
193    ch == '\n' || ch == '\r' || ch == '\t')
194    {
195    // If the character is not printable, print as character reference.
196    // Non printables are below ASCII space but not tab or line
197    // terminator, ASCII delete, or above a certain Unicode threshold.
198  4 sb.append(ch);
199    }
200    else
201    {
202  2 sb.append("&#").append(Integer.toString(ch)).append(";");
203    }
204    }
205    }
206   
207    /**
208    * @since 3.19 / 3.10.1
209    */
210    // http://www.w3.org/TR/REC-xml/#charsets
 
211  19 toggle public static boolean validXml(final char ch)
212    {
213  19 return ((ch == 0x9) ||
214    (ch == 0xA) ||
215    (ch == 0xD) ||
216    ((ch >= 0x20) && (ch <= 0xD7FF)) ||
217    ((ch >= 0xE000) && (ch <= 0xFFFD)) ||
218    ((ch >= 0x10000) && (ch <= 0x10FFFF)));
219    }
220   
221    /**
222    * @since 3.19 / 3.10.1
223    */
 
224    public interface TransformPolicy
225    {
226    String handle(final char input);
227    }
228   
229    // Replace bad XML input with a fixed character
 
230    public static class ReplacePolicy implements TransformPolicy
231    {
 
232  8 toggle public String handle(final char input)
233    {
234    // the unicode REPLACEMENT CHARACTER: ?
235  8 return "\uFFFD";
236    }
237    }
238   
239    }