Project Report: fawkez

Packagesummary org.jcoderz.commons.util

org.jcoderz.commons.util.XmlUtil

LineHitsNoteSource
1  /*
2   * $Id: XmlUtil.java 1633 2010-05-26 18:16:57Z amandel $
3   *
4   * Copyright 2006, The jCoderZ.org Project. All rights reserved.
5   *
6   * Redistribution and use in source and binary forms, with or without
7   * modification, are permitted provided that the following conditions are
8   * met:
9   *
10   *    * Redistributions of source code must retain the above copyright
11   *      notice, this list of conditions and the following disclaimer.
12   *    * Redistributions in binary form must reproduce the above
13   *      copyright notice, this list of conditions and the following
14   *      disclaimer in the documentation and/or other materials
15   *      provided with the distribution.
16   *    * Neither the name of the jCoderZ.org Project nor the names of
17   *      its contributors may be used to endorse or promote products
18   *      derived from this software without specific prior written
19   *      permission.
20   *
21   * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND
22   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24   * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS
25   * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28   * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29   * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30   * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31   * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32   */
33  package org.jcoderz.commons.util;
34  
35  import java.io.File;
36  import java.io.FileOutputStream;
37  import java.io.IOException;
38  import javax.xml.transform.stream.StreamResult;
39  import org.xml.sax.Attributes;
40  
41  /**
42   * This class holds utility methods for common xml topics.
43   *
44   * @author Andreas Mandel
45   */
46  public final class XmlUtil
47  {
48     /**
49      * Immutable and always empty version of a
50      * {@link org.xml.sax.Attributes} object.
51      */
52100     public static final Attributes EMPTY_ATTRIBUTES = new EmptyAttribute();
53  
54      private static final int INDENT = 2;
55      private static final String SPACES = " ";
56  
57     /** No instances. */
58     private XmlUtil ()
590    {
60        // No instances.
610    }
62  
63     /**
64      * Immutable implementation of a empty attribute list.
65      * @see Attributes
66      */
67100    private static final class EmptyAttribute
68           implements Attributes
69     {
70         /** {@inheritDoc} */
71        public int getLength ()
72        {
730          return 0;
74        }
75  
76        /** {@inheritDoc} */
77        public String getLocalName (int index)
78        {
790          return null;
80        }
81  
82        /** {@inheritDoc} */
83        public String getQName (int index)
84        {
850          return null;
86        }
87  
88        /** {@inheritDoc} */
89        public String getType (int index)
90        {
910          return null;
92        }
93  
94        /** {@inheritDoc} */
95        public String getURI (int index)
96        {
970          return null;
98        }
99  
100        /** {@inheritDoc} */
101        public String getValue (int index)
102        {
1030          return null;
104        }
105  
106        /** {@inheritDoc} */
107        public int getIndex (String qName)
108        {
1090          return -1;
110        }
111  
112        /** {@inheritDoc} */
113        public String getType (String qName)
114        {
1150          return null;
116        }
117  
118        /** {@inheritDoc} */
119        public String getValue (String qName)
120        {
1210          return null;
122        }
123  
124        /** {@inheritDoc} */
125        public int getIndex (String uri, String localName)
126        {
1270          return -1;
128        }
129  
130        /** {@inheritDoc} */
131        public String getType (String uri, String localName)
132        {
1330          return null;
134        }
135  
136        /** {@inheritDoc} */
137        public String getValue (String uri, String localName)
138        {
1390          return null;
140        }
141     }
142  
143     /**
144      * Encode a string so that it can be safely used as attribute value in
145      * XML output.
146      * @param attribute the attribute value to be encoded.
147      * @return a string representing the attribute value that can be safely
148      *         used in XML output.
149      */
150     public static String attributeEscape (String attribute)
151     {
1520       final StringBuffer sb = new StringBuffer();
1530       if (attribute != null)
154        {
155           char c;
1560          final int l = attribute.length();
1570          for (int i = 0; i < l; i++)
158           {
1590             c = attribute.charAt(i);
1600             switch (c)
161              {
162                 case '<':
1630                   sb.append("&lt;");
1640                   break;
165                 case '>':
1660                    sb.append("&gt;");
1670                    break;
168                 case '\'':
1690                   sb.append("&apos;");
1700                   break;
171                 case '"':
1720                    sb.append("&quot;");
1730                    break;
174                 case '&':
1750                   sb.append("&amp;");
1760                   break;
177                 default :
1780                   if (c > Byte.MAX_VALUE
179                        || Character.isISOControl(c))
180                    {
1810                      sb.append("&#x");
1820                      sb.append(Integer.toHexString(c));
1830                      sb.append(';');
184                    }
185                    else
186                    {
1870                      sb.append(c);
188                    }
189              }
190           }
191        }
1920       return sb.toString();
193     }
194  
195     /**
196      * Encode a string so that it can be safely used as text in an element
197      * for XML output.
198      * @param text the element text body.
199      * @return a string so that it can be safely used as text in an element
200      *       for XML output.
201      */
202     public static String escape (String text)
203     {
204100       final StringBuffer sb = new StringBuffer();
205100       if (text != null)
206        {
207           char c;
208100          final int l = text.length();
209100          for (int i = 0; i < l; i++)
210           {
211100             c = text.charAt(i);
212100             switch (c)
213              {
214                 case '<':
2150                   sb.append("&lt;");
2160                   break;
217                 case '>': // only needed to avoid ]]>
2180                    sb.append("&gt;");
2190                    break;
220                 case '&':
2210                   sb.append("&amp;");
2220                   break;
223                 default :
224100                   if (c > Byte.MAX_VALUE)
225                    {
2260                      sb.append("&#x");
2270                      sb.append(Integer.toHexString(c));
2280                      sb.append(';');
229                    }
230                    else
231                    {
232100                      sb.append(c);
233                    }
234              }
235           }
236        }
237100       return sb.toString();
238     }
239  
240     /**
241      * Simple xml formatter.
242      * This code might fail for several input. In this case the
243      * original input is returned.
244      * @param org the input to be formated.
245      * @return the input in xml formated (human readable) form or the
246      *   input string.
247      */
248 (1)   public static String formatXml (String org)
249     {
250100       String result = org;
251        try
252        {
253100          final String in = org.trim();
254100          if (in.charAt(0) == '<') // && sb.charAt(1) == '?')
255           {
256100              final StringBuffer sb = new StringBuffer();
257100              boolean nestedTag = false;
258100              int indent = 0;
259100              for (int t = 0; t < in.length(); t++)
260               {
261100                char c = in.charAt(t);
262  
263100                switch (c)
264                 {
265                    case '<':
266100                      t++;
267100                      c = in.charAt(t);
268100                      switch (c)
269                       {
270                          case '/':
271100                            if (!nestedTag)
272                             {
2730                               indent -= INDENT;
2740                               sb.append("</");
275                             }
276                             else
277                             {
278100                               sb.append('\n');
279100                               indent -= INDENT;
280100                               indent(indent, sb);
281100                               sb.append("</");
282                             }
283100                            nestedTag = true;
284100                            break;
285                          case '?':
286                          case '!':
2870                            if (t != 1)
288                             {
2890                                sb.append('\n');
290                             }
2910                            sb.append('<');
2920                            sb.append(c);
2930                            break;
294                          default:
295100                            nestedTag = false;
296100                            if (sb.length() > 0)
297                             {
298100                                sb.append('\n');
299                             }
300100                            indent(indent, sb);
301100                            sb.append('<');
302100                            sb.append(c);
303100                            indent += INDENT;
304100                            break;
305                       }
306                       break;
307                    case '/':
308100                       sb.append(c);
309100                      if (in.charAt(t + 1) == '>')
310                       {
311100                         indent -= INDENT;
312100                         nestedTag = true;
313                       }
314                       break;
315                    case '\n':
316                    case '\r':
3170                      break;
318                    case '>':
319                    default:
320100                       sb.append(c);
321                       break;
322                 }
323              }
324100             result = sb.toString();
325           }
326        }
3270       catch (Exception ex)
328        {
3290          result = org;
330 (2)         // CHECKME: Nicer exception handling no formated output...
331100       }
332100       return result;
333     }
334  
335      /**
336       * Creae a stream result based on a File.
337       * Other than the default implementation not only the File is used to
338       * initialize the result, but also a Stream is opened and initialized.
339       * This works around an issue with whitespaces in the pathname which
340       * otherwise would lead to a file not found exception
341       * <pre>
342 (3)     * Error during transformation: javax.xml.transform.TransformerException: java.io.FileNotFoundException: ...%20...
343 (4)     *   at org.apache.xalan.transformer.TransformerImpl.createSerializationHandler(TransformerImpl.java:1218)
344 (5)     *   at org.apache.xalan.transformer.TransformerImpl.createSerializationHandler(TransformerImpl.java:1060)
345 (6)     *   at org.apache.xalan.transformer.TransformerImpl.transform(TransformerImpl.java:1268)
346 (7)     *   at org.apache.xalan.transformer.TransformerImpl.transform(TransformerImpl.java:1251)
347       *   ....
348       * </pre>.
349       * The caller must ensure that the created outputstream is closed.
350       * @param outFile the file to be used in the stream result.
351       * @return a new StreamResult piontint to the given File.
352       * @throws IOException in case of an issue while creating the stream.
353       */
354 (8)    public static StreamResult createStreamResult(File outFile)
355          throws IOException
356      {
357100         final StreamResult result = new StreamResult(outFile);
358          // set the stream directly to avoid issues with blanks in the
359          // filename.
360100(9)        result.setOutputStream(new FileOutputStream(outFile));
361100         return result;
362      }
363  
364     private static void indent (final int i, StringBuffer b)
365     {
366100        if (i > SPACES.length())
367         {
3680            b.append(SPACES);
3690            indent(i - SPACES.length(), b);
370         }
371         else
372         {
373100            b.append(SPACES.substring(0, i));
374         }
375100    }
376  
377  
378  }

Findings in this File

c (1) 248 : 4 Cyclomatic Complexity is 16 (max allowed is 12).
i (2) 330 : 0 Comment matches to-do format '(TODO|FIXME|CHECKME)'.
c (3) 342 : 0 Line is longer than 80 characters.
c (4) 343 : 0 Line is longer than 80 characters.
c (5) 344 : 0 Line is longer than 80 characters.
c (6) 345 : 0 Line is longer than 80 characters.
c (7) 346 : 0 Line is longer than 80 characters.
c (8) 354 : 50 '(' is not preceded with whitespace.
w (9) 360 : 0 Method org.jcoderz.commons.util.XmlUtil.createStreamResult(File) may fail to clean up stream or resource of type java.io.OutputStream