| OLD | NEW | 
|    1 /* |    1 /* | 
|    2  * Simplified by Andrey Novikov for AdBlock Plus |    2  * Simplified by Andrey Novikov for AdBlock Plus | 
|    3  */ |    3  */ | 
|    4  |    4  | 
|    5 /* |    5 /* | 
|    6  * Licensed to the Apache Software Foundation (ASF) under one or more |    6  * Licensed to the Apache Software Foundation (ASF) under one or more | 
|    7  * contributor license agreements.  See the NOTICE file distributed with |    7  * contributor license agreements.  See the NOTICE file distributed with | 
|    8  * this work for additional information regarding copyright ownership. |    8  * this work for additional information regarding copyright ownership. | 
|    9  * The ASF licenses this file to You under the Apache License, Version 2.0 |    9  * The ASF licenses this file to You under the Apache License, Version 2.0 | 
|   10  * (the "License"); you may not use this file except in compliance with |   10  * (the "License"); you may not use this file except in compliance with | 
| (...skipping 22 matching lines...) Expand all  Loading... | 
|   33  * @author <a href="mailto:alex@purpletech.com">Alexander Day Chaffee</a> |   33  * @author <a href="mailto:alex@purpletech.com">Alexander Day Chaffee</a> | 
|   34  * @author Antony Riley |   34  * @author Antony Riley | 
|   35  * @author Helge Tesgaard |   35  * @author Helge Tesgaard | 
|   36  * @author <a href="sean@boohai.com">Sean Brown</a> |   36  * @author <a href="sean@boohai.com">Sean Brown</a> | 
|   37  * @author <a href="mailto:ggregory@seagullsw.com">Gary Gregory</a> |   37  * @author <a href="mailto:ggregory@seagullsw.com">Gary Gregory</a> | 
|   38  * @author Phil Steitz |   38  * @author Phil Steitz | 
|   39  * @author Pete Gieser |   39  * @author Pete Gieser | 
|   40  * @since 2.0 |   40  * @since 2.0 | 
|   41  * @version $Id: StringEscapeUtils.java 612880 2008-01-17 17:34:43Z ggregory $ |   41  * @version $Id: StringEscapeUtils.java 612880 2008-01-17 17:34:43Z ggregory $ | 
|   42  */ |   42  */ | 
|   43 public class StringEscapeUtils { |   43 public class StringEscapeUtils | 
|   44  |   44 { | 
|   45     private static final char CSV_DELIMITER = ','; |   45   private static final char CSV_DELIMITER = ','; | 
|   46     private static final char CSV_QUOTE = '"'; |   46   private static final char CSV_QUOTE = '"'; | 
|   47     private static final String CSV_QUOTE_STR = String.valueOf(CSV_QUOTE); |   47   private static final String CSV_QUOTE_STR = String.valueOf(CSV_QUOTE); | 
|   48     private static final char[] CSV_SEARCH_CHARS = new char[] {CSV_DELIMITER, CS
     V_QUOTE, CharUtils.CR, CharUtils.LF}; |   48   private static final char[] CSV_SEARCH_CHARS = new char[]{CSV_DELIMITER, CSV_Q
     UOTE, CharUtils.CR, CharUtils.LF}; | 
|   49  |   49  | 
|   50     /** |   50   /** | 
|   51      * <p><code>StringEscapeUtils</code> instances should NOT be constructed in |   51    * <p><code>StringEscapeUtils</code> instances should NOT be constructed in | 
|   52      * standard programming.</p> |   52    * standard programming.</p> | 
|   53      * |   53    * | 
|   54      * <p>Instead, the class should be used as: |   54    * <p>Instead, the class should be used as: | 
|   55      * <pre>StringEscapeUtils.escapeJava("foo");</pre></p> |   55    * <pre>StringEscapeUtils.escapeJava("foo");</pre></p> | 
|   56      * |   56    * | 
|   57      * <p>This constructor is public to permit tools that require a JavaBean |   57    * <p>This constructor is public to permit tools that require a JavaBean | 
|   58      * instance to operate.</p> |   58    * instance to operate.</p> | 
|   59      */ |   59    */ | 
|   60     public StringEscapeUtils() { |   60   public StringEscapeUtils() | 
|   61       super(); |   61   { | 
|   62     } |   62     super(); | 
|   63  |   63   } | 
|   64     // Java and JavaScript |   64  | 
|   65     //-------------------------------------------------------------------------- |   65   // Java and JavaScript | 
|   66     /** |   66   //-------------------------------------------------------------------------- | 
|   67      * <p>Escapes the characters in a <code>String</code> using Java String rule
     s.</p> |   67  | 
|   68      * |   68   /** | 
|   69      * <p>Deals correctly with quotes and control-chars (tab, backslash, cr, ff,
      etc.) </p> |   69    * <p>Escapes the characters in a <code>String</code> using Java String rules.
     </p> | 
|   70      * |   70    * | 
|   71      * <p>So a tab becomes the characters <code>'\\'</code> and |   71    * <p>Deals correctly with quotes and control-chars (tab, backslash, cr, ff, e
     tc.) </p> | 
|   72      * <code>'t'</code>.</p> |   72    * | 
|   73      * |   73    * <p>So a tab becomes the characters <code>'\\'</code> and | 
|   74      * <p>The only difference between Java strings and JavaScript strings |   74    * <code>'t'</code>.</p> | 
|   75      * is that in JavaScript, a single quote must be escaped.</p> |   75    * | 
|   76      * |   76    * <p>The only difference between Java strings and JavaScript strings | 
|   77      * <p>Example: |   77    * is that in JavaScript, a single quote must be escaped.</p> | 
|   78      * <pre> |   78    * | 
|   79      * input string: He didn't say, "Stop!" |   79    * <p>Example: | 
|   80      * output string: He didn't say, \"Stop!\" |   80    * <pre> | 
|   81      * </pre> |   81    * input string: He didn't say, "Stop!" | 
|   82      * </p> |   82    * output string: He didn't say, \"Stop!\" | 
|   83      * |   83    * </pre> | 
|   84      * @param str  String to escape values in, may be null |   84    * </p> | 
|   85      * @return String with escaped values, <code>null</code> if null string inpu
     t |   85    * | 
|   86      */ |   86    * @param str String to escape values in, may be null | 
|   87     public static String escapeJava(String str) { |   87    * @return String with escaped values, <code>null</code> if null string input | 
|   88         return escapeJavaStyleString(str, false); |   88    */ | 
|   89     } |   89   public static String escapeJava(String str) | 
|   90  |   90   { | 
|   91     /** |   91     return escapeJavaStyleString(str, false); | 
|   92      * <p>Escapes the characters in a <code>String</code> using Java String rule
     s to |   92   } | 
|   93      * a <code>Writer</code>.</p> |   93  | 
|   94      *  |   94   /** | 
|   95      * <p>A <code>null</code> string input has no effect.</p> |   95    * <p>Escapes the characters in a <code>String</code> using Java String rules 
     to | 
|   96      *  |   96    * a <code>Writer</code>.</p> | 
|   97      * @see #escapeJava(java.lang.String) |   97    * | 
|   98      * @param out  Writer to write escaped string into |   98    * <p>A <code>null</code> string input has no effect.</p> | 
|   99      * @param str  String to escape values in, may be null |   99    * | 
|  100      * @throws IllegalArgumentException if the Writer is <code>null</code> |  100    * @see #escapeJava(java.lang.String) | 
|  101      * @throws IOException if error occurs on underlying Writer |  101    * @param out Writer to write escaped string into | 
|  102      */ |  102    * @param str String to escape values in, may be null | 
|  103     public static void escapeJava(Writer out, String str) throws IOException { |  103    * @throws IllegalArgumentException if the Writer is <code>null</code> | 
|  104         escapeJavaStyleString(out, str, false); |  104    * @throws IOException if error occurs on underlying Writer | 
|  105     } |  105    */ | 
|  106  |  106   public static void escapeJava(Writer out, String str) throws IOException | 
|  107     /** |  107   { | 
|  108      * <p>Escapes the characters in a <code>String</code> using JavaScript Strin
     g rules.</p> |  108     escapeJavaStyleString(out, str, false); | 
|  109      * <p>Escapes any values it finds into their JavaScript String form. |  109   } | 
|  110      * Deals correctly with quotes and control-chars (tab, backslash, cr, ff, et
     c.) </p> |  110  | 
|  111      * |  111   /** | 
|  112      * <p>So a tab becomes the characters <code>'\\'</code> and |  112    * <p>Escapes the characters in a <code>String</code> using JavaScript String 
     rules.</p> | 
|  113      * <code>'t'</code>.</p> |  113    * <p>Escapes any values it finds into their JavaScript String form. | 
|  114      * |  114    * Deals correctly with quotes and control-chars (tab, backslash, cr, ff, etc.
     ) </p> | 
|  115      * <p>The only difference between Java strings and JavaScript strings |  115    * | 
|  116      * is that in JavaScript, a single quote must be escaped.</p> |  116    * <p>So a tab becomes the characters <code>'\\'</code> and | 
|  117      * |  117    * <code>'t'</code>.</p> | 
|  118      * <p>Example: |  118    * | 
|  119      * <pre> |  119    * <p>The only difference between Java strings and JavaScript strings | 
|  120      * input string: He didn't say, "Stop!" |  120    * is that in JavaScript, a single quote must be escaped.</p> | 
|  121      * output string: He didn\'t say, \"Stop!\" |  121    * | 
|  122      * </pre> |  122    * <p>Example: | 
|  123      * </p> |  123    * <pre> | 
|  124      * |  124    * input string: He didn't say, "Stop!" | 
|  125      * @param str  String to escape values in, may be null |  125    * output string: He didn\'t say, \"Stop!\" | 
|  126      * @return String with escaped values, <code>null</code> if null string inpu
     t |  126    * </pre> | 
|  127      */ |  127    * </p> | 
|  128     public static String escapeJavaScript(String str) { |  128    * | 
|  129         return escapeJavaStyleString(str, true); |  129    * @param str String to escape values in, may be null | 
|  130     } |  130    * @return String with escaped values, <code>null</code> if null string input | 
|  131  |  131    */ | 
|  132     /** |  132   public static String escapeJavaScript(String str) | 
|  133      * <p>Escapes the characters in a <code>String</code> using JavaScript Strin
     g rules |  133   { | 
|  134      * to a <code>Writer</code>.</p> |  134     return escapeJavaStyleString(str, true); | 
|  135      *  |  135   } | 
|  136      * <p>A <code>null</code> string input has no effect.</p> |  136  | 
|  137      *  |  137   /** | 
|  138      * @see #escapeJavaScript(java.lang.String) |  138    * <p>Escapes the characters in a <code>String</code> using JavaScript String 
     rules | 
|  139      * @param out  Writer to write escaped string into |  139    * to a <code>Writer</code>.</p> | 
|  140      * @param str  String to escape values in, may be null |  140    * | 
|  141      * @throws IllegalArgumentException if the Writer is <code>null</code> |  141    * <p>A <code>null</code> string input has no effect.</p> | 
|  142      * @throws IOException if error occurs on underlying Writer |  142    * | 
|  143      **/ |  143    * @see #escapeJavaScript(java.lang.String) | 
|  144     public static void escapeJavaScript(Writer out, String str) throws IOExcepti
     on { |  144    * @param out Writer to write escaped string into | 
|  145         escapeJavaStyleString(out, str, true); |  145    * @param str String to escape values in, may be null | 
|  146     } |  146    * @throws IllegalArgumentException if the Writer is <code>null</code> | 
|  147  |  147    * @throws IOException if error occurs on underlying Writer | 
|  148     /** |  148    */ | 
|  149      * <p>Worker method for the {@link #escapeJavaScript(String)} method.</p> |  149   public static void escapeJavaScript(Writer out, String str) throws IOException | 
|  150      *  |  150   { | 
|  151      * @param str String to escape values in, may be null |  151     escapeJavaStyleString(out, str, true); | 
|  152      * @param escapeSingleQuotes escapes single quotes if <code>true</code> |  152   } | 
|  153      * @return the escaped string |  153  | 
|  154      */ |  154   /** | 
|  155     private static String escapeJavaStyleString(String str, boolean escapeSingle
     Quotes) { |  155    * <p>Worker method for the {@link #escapeJavaScript(String)} method.</p> | 
|  156         if (str == null) { |  156    * | 
|  157             return null; |  157    * @param str String to escape values in, may be null | 
 |  158    * @param escapeSingleQuotes escapes single quotes if <code>true</code> | 
 |  159    * @return the escaped string | 
 |  160    */ | 
 |  161   private static String escapeJavaStyleString(String str, boolean escapeSingleQu
     otes) | 
 |  162   { | 
 |  163     if (str == null) | 
 |  164     { | 
 |  165       return null; | 
 |  166     } | 
 |  167     try | 
 |  168     { | 
 |  169       StringWriter writer = new StringWriter(str.length() * 2); | 
 |  170       escapeJavaStyleString(writer, str, escapeSingleQuotes); | 
 |  171       return writer.toString(); | 
 |  172     } | 
 |  173     catch (IOException ioe) | 
 |  174     { | 
 |  175       // this should never ever happen while writing to a StringWriter | 
 |  176       ioe.printStackTrace(); | 
 |  177       return null; | 
 |  178     } | 
 |  179   } | 
 |  180  | 
 |  181   /** | 
 |  182    * <p>Worker method for the {@link #escapeJavaScript(String)} method.</p> | 
 |  183    * | 
 |  184    * @param out write to receieve the escaped string | 
 |  185    * @param str String to escape values in, may be null | 
 |  186    * @param escapeSingleQuote escapes single quotes if <code>true</code> | 
 |  187    * @throws IOException if an IOException occurs | 
 |  188    */ | 
 |  189   private static void escapeJavaStyleString(Writer out, String str, boolean esca
     peSingleQuote) throws IOException | 
 |  190   { | 
 |  191     if (out == null) | 
 |  192     { | 
 |  193       throw new IllegalArgumentException("The Writer must not be null"); | 
 |  194     } | 
 |  195     if (str == null) | 
 |  196     { | 
 |  197       return; | 
 |  198     } | 
 |  199     int sz; | 
 |  200     sz = str.length(); | 
 |  201     for (int i = 0; i < sz; i++) | 
 |  202     { | 
 |  203       char ch = str.charAt(i); | 
 |  204  | 
 |  205       // handle unicode | 
 |  206       if (ch > 0xfff) | 
 |  207       { | 
 |  208         out.write("\\u" + hex(ch)); | 
 |  209       } else if (ch > 0xff) | 
 |  210       { | 
 |  211         out.write("\\u0" + hex(ch)); | 
 |  212       } else if (ch > 0x7f) | 
 |  213       { | 
 |  214         out.write("\\u00" + hex(ch)); | 
 |  215       } else if (ch < 32) | 
 |  216       { | 
 |  217         switch (ch) | 
 |  218         { | 
 |  219           case '\b': | 
 |  220             out.write('\\'); | 
 |  221             out.write('b'); | 
 |  222             break; | 
 |  223           case '\n': | 
 |  224             out.write('\\'); | 
 |  225             out.write('n'); | 
 |  226             break; | 
 |  227           case '\t': | 
 |  228             out.write('\\'); | 
 |  229             out.write('t'); | 
 |  230             break; | 
 |  231           case '\f': | 
 |  232             out.write('\\'); | 
 |  233             out.write('f'); | 
 |  234             break; | 
 |  235           case '\r': | 
 |  236             out.write('\\'); | 
 |  237             out.write('r'); | 
 |  238             break; | 
 |  239           default: | 
 |  240             if (ch > 0xf) | 
 |  241             { | 
 |  242               out.write("\\u00" + hex(ch)); | 
 |  243             } else | 
 |  244             { | 
 |  245               out.write("\\u000" + hex(ch)); | 
 |  246             } | 
 |  247             break; | 
|  158         } |  248         } | 
|  159         try { |  249       } else | 
|  160             StringWriter writer = new StringWriter(str.length() * 2); |  250       { | 
|  161             escapeJavaStyleString(writer, str, escapeSingleQuotes); |  251         switch (ch) | 
|  162             return writer.toString(); |  252         { | 
|  163         } catch (IOException ioe) { |  253           case '\'': | 
|  164             // this should never ever happen while writing to a StringWriter |  254             if (escapeSingleQuote) | 
|  165             ioe.printStackTrace(); |  255             { | 
|  166             return null; |  256               out.write('\\'); | 
 |  257             } | 
 |  258             out.write('\''); | 
 |  259             break; | 
 |  260           case '"': | 
 |  261             out.write('\\'); | 
 |  262             out.write('"'); | 
 |  263             break; | 
 |  264           case '\\': | 
 |  265             out.write('\\'); | 
 |  266             out.write('\\'); | 
 |  267             break; | 
 |  268           case '/': | 
 |  269             out.write('\\'); | 
 |  270             out.write('/'); | 
 |  271             break; | 
 |  272           default: | 
 |  273             out.write(ch); | 
 |  274             break; | 
|  167         } |  275         } | 
|  168     } |  276       } | 
|  169  |  277     } | 
|  170     /** |  278   } | 
|  171      * <p>Worker method for the {@link #escapeJavaScript(String)} method.</p> |  279  | 
|  172      *  |  280   /** | 
|  173      * @param out write to receieve the escaped string |  281    * <p>Returns an upper case hexadecimal <code>String</code> for the given | 
|  174      * @param str String to escape values in, may be null |  282    * character.</p> | 
|  175      * @param escapeSingleQuote escapes single quotes if <code>true</code> |  283    * | 
|  176      * @throws IOException if an IOException occurs |  284    * @param ch The character to convert. | 
|  177      */ |  285    * @return An upper case hexadecimal <code>String</code> | 
|  178     private static void escapeJavaStyleString(Writer out, String str, boolean es
     capeSingleQuote) throws IOException { |  286    */ | 
|  179         if (out == null) { |  287   private static String hex(char ch) | 
|  180             throw new IllegalArgumentException("The Writer must not be null"); |  288   { | 
 |  289     return Integer.toHexString(ch).toUpperCase(); | 
 |  290   } | 
 |  291  | 
 |  292   /** | 
 |  293    * <p>Unescapes any Java literals found in the <code>String</code>. | 
 |  294    * For example, it will turn a sequence of <code>'\'</code> and | 
 |  295    * <code>'n'</code> into a newline character, unless the <code>'\'</code> | 
 |  296    * is preceded by another <code>'\'</code>.</p> | 
 |  297    * | 
 |  298    * @param str the <code>String</code> to unescape, may be null | 
 |  299    * @return a new unescaped <code>String</code>, <code>null</code> if null stri
     ng input | 
 |  300    */ | 
 |  301   public static String unescapeJava(String str) | 
 |  302   { | 
 |  303     if (str == null) | 
 |  304     { | 
 |  305       return null; | 
 |  306     } | 
 |  307     try | 
 |  308     { | 
 |  309       StringWriter writer = new StringWriter(str.length()); | 
 |  310       unescapeJava(writer, str); | 
 |  311       return writer.toString(); | 
 |  312     } catch (IOException ioe) | 
 |  313     { | 
 |  314       // this should never ever happen while writing to a StringWriter | 
 |  315       ioe.printStackTrace(); | 
 |  316       return null; | 
 |  317     } | 
 |  318   } | 
 |  319  | 
 |  320   /** | 
 |  321    * <p>Unescapes any Java literals found in the <code>String</code> to a | 
 |  322    * <code>Writer</code>.</p> | 
 |  323    * | 
 |  324    * <p>For example, it will turn a sequence of <code>'\'</code> and | 
 |  325    * <code>'n'</code> into a newline character, unless the <code>'\'</code> | 
 |  326    * is preceded by another <code>'\'</code>.</p> | 
 |  327    * | 
 |  328    * <p>A <code>null</code> string input has no effect.</p> | 
 |  329    * | 
 |  330    * @param out the <code>Writer</code> used to output unescaped characters | 
 |  331    * @param str the <code>String</code> to unescape, may be null | 
 |  332    * @throws IllegalArgumentException if the Writer is <code>null</code> | 
 |  333    * @throws IOException if error occurs on underlying Writer | 
 |  334    */ | 
 |  335   public static void unescapeJava(Writer out, String str) throws IOException | 
 |  336   { | 
 |  337     if (out == null) | 
 |  338     { | 
 |  339       throw new IllegalArgumentException("The Writer must not be null"); | 
 |  340     } | 
 |  341     if (str == null) | 
 |  342     { | 
 |  343       return; | 
 |  344     } | 
 |  345     int sz = str.length(); | 
 |  346     StringBuffer unicode = new StringBuffer(4); | 
 |  347     boolean hadSlash = false; | 
 |  348     boolean inUnicode = false; | 
 |  349     for (int i = 0; i < sz; i++) | 
 |  350     { | 
 |  351       char ch = str.charAt(i); | 
 |  352       if (inUnicode) | 
 |  353       { | 
 |  354         // if in unicode, then we're reading unicode | 
 |  355         // values in somehow | 
 |  356         unicode.append(ch); | 
 |  357         if (unicode.length() == 4) | 
 |  358         { | 
 |  359           // unicode now contains the four hex digits | 
 |  360           // which represents our unicode character | 
 |  361           try | 
 |  362           { | 
 |  363             int value = Integer.parseInt(unicode.toString(), 16); | 
 |  364             out.write((char) value); | 
 |  365             unicode.setLength(0); | 
 |  366             inUnicode = false; | 
 |  367             hadSlash = false; | 
 |  368           } catch (NumberFormatException nfe) | 
 |  369           { | 
 |  370             throw (IOException) new IOException("Unable to parse unicode value: 
     " + unicode).initCause(nfe); | 
 |  371           } | 
|  181         } |  372         } | 
|  182         if (str == null) { |  373         continue; | 
|  183             return; |  374       } | 
 |  375       if (hadSlash) | 
 |  376       { | 
 |  377         // handle an escaped value | 
 |  378         hadSlash = false; | 
 |  379         switch (ch) | 
 |  380         { | 
 |  381           case '\\': | 
 |  382             out.write('\\'); | 
 |  383             break; | 
 |  384           case '\'': | 
 |  385             out.write('\''); | 
 |  386             break; | 
 |  387           case '\"': | 
 |  388             out.write('"'); | 
 |  389             break; | 
 |  390           case 'r': | 
 |  391             out.write('\r'); | 
 |  392             break; | 
 |  393           case 'f': | 
 |  394             out.write('\f'); | 
 |  395             break; | 
 |  396           case 't': | 
 |  397             out.write('\t'); | 
 |  398             break; | 
 |  399           case 'n': | 
 |  400             out.write('\n'); | 
 |  401             break; | 
 |  402           case 'b': | 
 |  403             out.write('\b'); | 
 |  404             break; | 
 |  405           case 'u': | 
 |  406           { | 
 |  407             // uh-oh, we're in unicode country.... | 
 |  408             inUnicode = true; | 
 |  409             break; | 
 |  410           } | 
 |  411           default: | 
 |  412             out.write(ch); | 
 |  413             break; | 
|  184         } |  414         } | 
|  185         int sz; |  415         continue; | 
|  186         sz = str.length(); |  416       } else if (ch == '\\') | 
|  187         for (int i = 0; i < sz; i++) { |  417       { | 
|  188             char ch = str.charAt(i); |  418         hadSlash = true; | 
|  189  |  419         continue; | 
|  190             // handle unicode |  420       } | 
|  191             if (ch > 0xfff) { |  421       out.write(ch); | 
|  192                 out.write("\\u" + hex(ch)); |  422     } | 
|  193             } else if (ch > 0xff) { |  423     if (hadSlash) | 
|  194                 out.write("\\u0" + hex(ch)); |  424     { | 
|  195             } else if (ch > 0x7f) { |  425       // then we're in the weird case of a \ at the end of the | 
|  196                 out.write("\\u00" + hex(ch)); |  426       // string, let's output it anyway. | 
|  197             } else if (ch < 32) { |  427       out.write('\\'); | 
|  198                 switch (ch) { |  428     } | 
|  199                     case '\b': |  429   } | 
|  200                         out.write('\\'); |  430  | 
|  201                         out.write('b'); |  431   /** | 
|  202                         break; |  432    * <p>Unescapes any JavaScript literals found in the <code>String</code>.</p> | 
|  203                     case '\n': |  433    * | 
|  204                         out.write('\\'); |  434    * <p>For example, it will turn a sequence of <code>'\'</code> and <code>'n'</
     code> | 
|  205                         out.write('n'); |  435    * into a newline character, unless the <code>'\'</code> is preceded by anothe
     r | 
|  206                         break; |  436    * <code>'\'</code>.</p> | 
|  207                     case '\t': |  437    * | 
|  208                         out.write('\\'); |  438    * @see #unescapeJava(String) | 
|  209                         out.write('t'); |  439    * @param str the <code>String</code> to unescape, may be null | 
|  210                         break; |  440    * @return A new unescaped <code>String</code>, <code>null</code> if null stri
     ng input | 
|  211                     case '\f': |  441    */ | 
|  212                         out.write('\\'); |  442   public static String unescapeJavaScript(String str) | 
|  213                         out.write('f'); |  443   { | 
|  214                         break; |  444     return unescapeJava(str); | 
|  215                     case '\r': |  445   } | 
|  216                         out.write('\\'); |  446  | 
|  217                         out.write('r'); |  447   /** | 
|  218                         break; |  448    * <p>Unescapes any JavaScript literals found in the <code>String</code> to a | 
|  219                     default : |  449    * <code>Writer</code>.</p> | 
|  220                         if (ch > 0xf) { |  450    * | 
|  221                             out.write("\\u00" + hex(ch)); |  451    * <p>For example, it will turn a sequence of <code>'\'</code> and <code>'n'</
     code> | 
|  222                         } else { |  452    * into a newline character, unless the <code>'\'</code> is preceded by anothe
     r | 
|  223                             out.write("\\u000" + hex(ch)); |  453    * <code>'\'</code>.</p> | 
|  224                         } |  454    * | 
|  225                         break; |  455    * <p>A <code>null</code> string input has no effect.</p> | 
|  226                 } |  456    * | 
|  227             } else { |  457    * @see #unescapeJava(Writer, String) | 
|  228                 switch (ch) { |  458    * @param out the <code>Writer</code> used to output unescaped characters | 
|  229                     case '\'': |  459    * @param str the <code>String</code> to unescape, may be null | 
|  230                         if (escapeSingleQuote) { |  460    * @throws IllegalArgumentException if the Writer is <code>null</code> | 
|  231                           out.write('\\'); |  461    * @throws IOException if error occurs on underlying Writer | 
|  232                         } |  462    */ | 
|  233                         out.write('\''); |  463   public static void unescapeJavaScript(Writer out, String str) throws IOExcepti
     on | 
|  234                         break; |  464   { | 
|  235                     case '"': |  465     unescapeJava(out, str); | 
|  236                         out.write('\\'); |  466   } | 
|  237                         out.write('"'); |  467  | 
|  238                         break; |  468   //----------------------------------------------------------------------- | 
|  239                     case '\\': |  469  | 
|  240                         out.write('\\'); |  470   /** | 
|  241                         out.write('\\'); |  471    * <p>Escapes the characters in a <code>String</code> to be suitable to pass t
     o | 
|  242                         break; |  472    * an SQL query.</p> | 
|  243                     case '/': |  473    * | 
|  244                         out.write('\\'); |  474    * <p>For example, | 
|  245                         out.write('/'); |  475    * <pre>statement.executeQuery("SELECT * FROM MOVIES WHERE TITLE='" + | 
|  246                         break; |  476    *   StringEscapeUtils.escapeSql("McHale's Navy") + | 
|  247                     default : |  477    *   "'");</pre> | 
|  248                         out.write(ch); |  478    * </p> | 
|  249                         break; |  479    * | 
|  250                 } |  480    * <p>At present, this method only turns single-quotes into doubled single-quo
     tes | 
|  251             } |  481    * (<code>"McHale's Navy"</code> => <code>"McHale''s Navy"</code>). It does no
     t | 
|  252         } |  482    * handle the cases of percent (%) or underscore (_) for use in LIKE clauses.<
     /p> | 
|  253     } |  483    * | 
|  254  |  484    * see http://www.jguru.com/faq/view.jsp?EID=8881 | 
|  255     /** |  485    * | 
|  256      * <p>Returns an upper case hexadecimal <code>String</code> for the given |  486    * @param str the string to escape, may be null | 
|  257      * character.</p> |  487    * @return a new String, escaped for SQL, <code>null</code> if null string inp
     ut | 
|  258      *  |  488    */ | 
|  259      * @param ch The character to convert. |  489   public static String escapeSql(String str) | 
|  260      * @return An upper case hexadecimal <code>String</code> |  490   { | 
|  261      */ |  491     if (str == null) | 
|  262     private static String hex(char ch) { |  492     { | 
|  263         return Integer.toHexString(ch).toUpperCase(); |  493       return null; | 
|  264     } |  494     } | 
|  265  |  495     return StringUtils.replace(str, "'", "''"); | 
|  266     /** |  496   } | 
|  267      * <p>Unescapes any Java literals found in the <code>String</code>. |  497  | 
|  268      * For example, it will turn a sequence of <code>'\'</code> and |  498   //----------------------------------------------------------------------- | 
|  269      * <code>'n'</code> into a newline character, unless the <code>'\'</code> |  499  | 
|  270      * is preceded by another <code>'\'</code>.</p> |  500   /** | 
|  271      *  |  501    * <p>Returns a <code>String</code> value for a CSV column enclosed in double 
     quotes, | 
|  272      * @param str  the <code>String</code> to unescape, may be null |  502    * if required.</p> | 
|  273      * @return a new unescaped <code>String</code>, <code>null</code> if null st
     ring input |  503    * | 
|  274      */ |  504    * <p>If the value contains a comma, newline or double quote, then the | 
|  275     public static String unescapeJava(String str) { |  505    * String value is returned enclosed in double quotes.</p> | 
|  276         if (str == null) { |  506    * </p> | 
|  277             return null; |  507    * | 
|  278         } |  508    * <p>Any double quote characters in the value are escaped with another double
      quote.</p> | 
|  279         try { |  509    * | 
|  280             StringWriter writer = new StringWriter(str.length()); |  510    * <p>If the value does not contain a comma, newline or double quote, then the | 
|  281             unescapeJava(writer, str); |  511    * String value is returned unchanged.</p> | 
|  282             return writer.toString(); |  512    * </p> | 
|  283         } catch (IOException ioe) { |  513    * | 
|  284             // this should never ever happen while writing to a StringWriter |  514    * see <a href="http://en.wikipedia.org/wiki/Comma-separated_values">Wikipedia
     </a> and | 
|  285             ioe.printStackTrace(); |  515    * <a href="http://tools.ietf.org/html/rfc4180">RFC 4180</a>. | 
|  286             return null; |  516    * | 
|  287         } |  517    * @param str the input CSV column String, may be null | 
|  288     } |  518    * @return the input String, enclosed in double quotes if the value contains a
      comma, | 
|  289  |  519    * newline or double quote, <code>null</code> if null string input | 
|  290     /** |  520    * @since 2.4 | 
|  291      * <p>Unescapes any Java literals found in the <code>String</code> to a |  521    */ | 
|  292      * <code>Writer</code>.</p> |  522   public static String escapeCsv(String str) | 
|  293      * |  523   { | 
|  294      * <p>For example, it will turn a sequence of <code>'\'</code> and |  524     if (StringUtils.containsNone(str, CSV_SEARCH_CHARS)) | 
|  295      * <code>'n'</code> into a newline character, unless the <code>'\'</code> |  525     { | 
|  296      * is preceded by another <code>'\'</code>.</p> |  526       return str; | 
|  297      *  |  527     } | 
|  298      * <p>A <code>null</code> string input has no effect.</p> |  528     try | 
|  299      *  |  529     { | 
|  300      * @param out  the <code>Writer</code> used to output unescaped characters |  530       StringWriter writer = new StringWriter(); | 
|  301      * @param str  the <code>String</code> to unescape, may be null |  531       escapeCsv(writer, str); | 
|  302      * @throws IllegalArgumentException if the Writer is <code>null</code> |  532       return writer.toString(); | 
|  303      * @throws IOException if error occurs on underlying Writer |  533     } catch (IOException ioe) | 
|  304      */ |  534     { | 
|  305     public static void unescapeJava(Writer out, String str) throws IOException { |  535       // this should never ever happen while writing to a StringWriter | 
|  306         if (out == null) { |  536       ioe.printStackTrace(); | 
|  307             throw new IllegalArgumentException("The Writer must not be null"); |  537       return null; | 
|  308         } |  538     } | 
|  309         if (str == null) { |  539   } | 
|  310             return; |  540  | 
|  311         } |  541   /** | 
|  312         int sz = str.length(); |  542    * <p>Writes a <code>String</code> value for a CSV column enclosed in double q
     uotes, | 
|  313         StringBuffer unicode = new StringBuffer(4); |  543    * if required.</p> | 
|  314         boolean hadSlash = false; |  544    * | 
|  315         boolean inUnicode = false; |  545    * <p>If the value contains a comma, newline or double quote, then the | 
|  316         for (int i = 0; i < sz; i++) { |  546    * String value is written enclosed in double quotes.</p> | 
|  317             char ch = str.charAt(i); |  547    * </p> | 
|  318             if (inUnicode) { |  548    * | 
|  319                 // if in unicode, then we're reading unicode |  549    * <p>Any double quote characters in the value are escaped with another double
      quote.</p> | 
|  320                 // values in somehow |  550    * | 
|  321                 unicode.append(ch); |  551    * <p>If the value does not contain a comma, newline or double quote, then the | 
|  322                 if (unicode.length() == 4) { |  552    * String value is written unchanged (null values are ignored).</p> | 
|  323                     // unicode now contains the four hex digits |  553    * </p> | 
|  324                     // which represents our unicode character |  554    * | 
|  325                     try { |  555    * see <a href="http://en.wikipedia.org/wiki/Comma-separated_values">Wikipedia
     </a> and | 
|  326                         int value = Integer.parseInt(unicode.toString(), 16); |  556    * <a href="http://tools.ietf.org/html/rfc4180">RFC 4180</a>. | 
|  327                         out.write((char) value); |  557    * | 
|  328                         unicode.setLength(0); |  558    * @param str the input CSV column String, may be null | 
|  329                         inUnicode = false; |  559    * @param out Writer to write input string to, enclosed in double quotes if it
      contains | 
|  330                         hadSlash = false; |  560    * a comma, newline or double quote | 
|  331                     } catch (NumberFormatException nfe) { |  561    * @throws IOException if error occurs on underlying Writer | 
|  332                         throw (IOException) new IOException("Unable to parse uni
     code value: " + unicode).initCause(nfe); |  562    * @since 2.4 | 
|  333                     } |  563    */ | 
|  334                 } |  564   public static void escapeCsv(Writer out, String str) throws IOException | 
|  335                 continue; |  565   { | 
|  336             } |  566     if (StringUtils.containsNone(str, CSV_SEARCH_CHARS)) | 
|  337             if (hadSlash) { |  567     { | 
|  338                 // handle an escaped value |  568       if (str != null) | 
|  339                 hadSlash = false; |  569       { | 
|  340                 switch (ch) { |  | 
|  341                     case '\\': |  | 
|  342                         out.write('\\'); |  | 
|  343                         break; |  | 
|  344                     case '\'': |  | 
|  345                         out.write('\''); |  | 
|  346                         break; |  | 
|  347                     case '\"': |  | 
|  348                         out.write('"'); |  | 
|  349                         break; |  | 
|  350                     case 'r': |  | 
|  351                         out.write('\r'); |  | 
|  352                         break; |  | 
|  353                     case 'f': |  | 
|  354                         out.write('\f'); |  | 
|  355                         break; |  | 
|  356                     case 't': |  | 
|  357                         out.write('\t'); |  | 
|  358                         break; |  | 
|  359                     case 'n': |  | 
|  360                         out.write('\n'); |  | 
|  361                         break; |  | 
|  362                     case 'b': |  | 
|  363                         out.write('\b'); |  | 
|  364                         break; |  | 
|  365                     case 'u': |  | 
|  366                         { |  | 
|  367                             // uh-oh, we're in unicode country.... |  | 
|  368                             inUnicode = true; |  | 
|  369                             break; |  | 
|  370                         } |  | 
|  371                     default : |  | 
|  372                         out.write(ch); |  | 
|  373                         break; |  | 
|  374                 } |  | 
|  375                 continue; |  | 
|  376             } else if (ch == '\\') { |  | 
|  377                 hadSlash = true; |  | 
|  378                 continue; |  | 
|  379             } |  | 
|  380             out.write(ch); |  | 
|  381         } |  | 
|  382         if (hadSlash) { |  | 
|  383             // then we're in the weird case of a \ at the end of the |  | 
|  384             // string, let's output it anyway. |  | 
|  385             out.write('\\'); |  | 
|  386         } |  | 
|  387     } |  | 
|  388  |  | 
|  389     /** |  | 
|  390      * <p>Unescapes any JavaScript literals found in the <code>String</code>.</p
     > |  | 
|  391      * |  | 
|  392      * <p>For example, it will turn a sequence of <code>'\'</code> and <code>'n'
     </code> |  | 
|  393      * into a newline character, unless the <code>'\'</code> is preceded by anot
     her |  | 
|  394      * <code>'\'</code>.</p> |  | 
|  395      * |  | 
|  396      * @see #unescapeJava(String) |  | 
|  397      * @param str  the <code>String</code> to unescape, may be null |  | 
|  398      * @return A new unescaped <code>String</code>, <code>null</code> if null st
     ring input |  | 
|  399      */ |  | 
|  400     public static String unescapeJavaScript(String str) { |  | 
|  401         return unescapeJava(str); |  | 
|  402     } |  | 
|  403  |  | 
|  404     /** |  | 
|  405      * <p>Unescapes any JavaScript literals found in the <code>String</code> to 
     a |  | 
|  406      * <code>Writer</code>.</p> |  | 
|  407      * |  | 
|  408      * <p>For example, it will turn a sequence of <code>'\'</code> and <code>'n'
     </code> |  | 
|  409      * into a newline character, unless the <code>'\'</code> is preceded by anot
     her |  | 
|  410      * <code>'\'</code>.</p> |  | 
|  411      * |  | 
|  412      * <p>A <code>null</code> string input has no effect.</p> |  | 
|  413      *  |  | 
|  414      * @see #unescapeJava(Writer,String) |  | 
|  415      * @param out  the <code>Writer</code> used to output unescaped characters |  | 
|  416      * @param str  the <code>String</code> to unescape, may be null |  | 
|  417      * @throws IllegalArgumentException if the Writer is <code>null</code> |  | 
|  418      * @throws IOException if error occurs on underlying Writer |  | 
|  419      */ |  | 
|  420     public static void unescapeJavaScript(Writer out, String str) throws IOExcep
     tion { |  | 
|  421         unescapeJava(out, str); |  | 
|  422     } |  | 
|  423  |  | 
|  424     //----------------------------------------------------------------------- |  | 
|  425     /** |  | 
|  426      * <p>Escapes the characters in a <code>String</code> to be suitable to pass
      to |  | 
|  427      * an SQL query.</p> |  | 
|  428      * |  | 
|  429      * <p>For example, |  | 
|  430      * <pre>statement.executeQuery("SELECT * FROM MOVIES WHERE TITLE='" +  |  | 
|  431      *   StringEscapeUtils.escapeSql("McHale's Navy") +  |  | 
|  432      *   "'");</pre> |  | 
|  433      * </p> |  | 
|  434      * |  | 
|  435      * <p>At present, this method only turns single-quotes into doubled single-q
     uotes |  | 
|  436      * (<code>"McHale's Navy"</code> => <code>"McHale''s Navy"</code>). It does 
     not |  | 
|  437      * handle the cases of percent (%) or underscore (_) for use in LIKE clauses
     .</p> |  | 
|  438      * |  | 
|  439      * see http://www.jguru.com/faq/view.jsp?EID=8881 |  | 
|  440      * @param str  the string to escape, may be null |  | 
|  441      * @return a new String, escaped for SQL, <code>null</code> if null string i
     nput |  | 
|  442      */ |  | 
|  443     public static String escapeSql(String str) { |  | 
|  444         if (str == null) { |  | 
|  445             return null; |  | 
|  446         } |  | 
|  447         return StringUtils.replace(str, "'", "''"); |  | 
|  448     } |  | 
|  449  |  | 
|  450     //----------------------------------------------------------------------- |  | 
|  451  |  | 
|  452     /** |  | 
|  453      * <p>Returns a <code>String</code> value for a CSV column enclosed in doubl
     e quotes, |  | 
|  454      * if required.</p> |  | 
|  455      * |  | 
|  456      * <p>If the value contains a comma, newline or double quote, then the |  | 
|  457      *    String value is returned enclosed in double quotes.</p> |  | 
|  458      * </p> |  | 
|  459      * |  | 
|  460      * <p>Any double quote characters in the value are escaped with another doub
     le quote.</p> |  | 
|  461      * |  | 
|  462      * <p>If the value does not contain a comma, newline or double quote, then t
     he |  | 
|  463      *    String value is returned unchanged.</p> |  | 
|  464      * </p> |  | 
|  465      * |  | 
|  466      * see <a href="http://en.wikipedia.org/wiki/Comma-separated_values">Wikiped
     ia</a> and |  | 
|  467      * <a href="http://tools.ietf.org/html/rfc4180">RFC 4180</a>. |  | 
|  468      * |  | 
|  469      * @param str the input CSV column String, may be null |  | 
|  470      * @return the input String, enclosed in double quotes if the value contains
      a comma, |  | 
|  471      * newline or double quote, <code>null</code> if null string input |  | 
|  472      * @since 2.4 |  | 
|  473      */ |  | 
|  474     public static String escapeCsv(String str) { |  | 
|  475         if (StringUtils.containsNone(str, CSV_SEARCH_CHARS)) { |  | 
|  476             return str; |  | 
|  477         } |  | 
|  478         try { |  | 
|  479             StringWriter writer = new StringWriter(); |  | 
|  480             escapeCsv(writer, str); |  | 
|  481             return writer.toString(); |  | 
|  482         } catch (IOException ioe) { |  | 
|  483             // this should never ever happen while writing to a StringWriter |  | 
|  484             ioe.printStackTrace(); |  | 
|  485             return null; |  | 
|  486         } |  | 
|  487     } |  | 
|  488  |  | 
|  489     /** |  | 
|  490      * <p>Writes a <code>String</code> value for a CSV column enclosed in double
      quotes, |  | 
|  491      * if required.</p> |  | 
|  492      * |  | 
|  493      * <p>If the value contains a comma, newline or double quote, then the |  | 
|  494      *    String value is written enclosed in double quotes.</p> |  | 
|  495      * </p> |  | 
|  496      * |  | 
|  497      * <p>Any double quote characters in the value are escaped with another doub
     le quote.</p> |  | 
|  498      * |  | 
|  499      * <p>If the value does not contain a comma, newline or double quote, then t
     he |  | 
|  500      *    String value is written unchanged (null values are ignored).</p> |  | 
|  501      * </p> |  | 
|  502      * |  | 
|  503      * see <a href="http://en.wikipedia.org/wiki/Comma-separated_values">Wikiped
     ia</a> and |  | 
|  504      * <a href="http://tools.ietf.org/html/rfc4180">RFC 4180</a>. |  | 
|  505      * |  | 
|  506      * @param str the input CSV column String, may be null |  | 
|  507      * @param out Writer to write input string to, enclosed in double quotes if 
     it contains |  | 
|  508      * a comma, newline or double quote |  | 
|  509      * @throws IOException if error occurs on underlying Writer |  | 
|  510      * @since 2.4 |  | 
|  511      */ |  | 
|  512     public static void escapeCsv(Writer out, String str) throws IOException { |  | 
|  513         if (StringUtils.containsNone(str, CSV_SEARCH_CHARS)) { |  | 
|  514             if (str != null) { |  | 
|  515                 out.write(str); |  | 
|  516             } |  | 
|  517             return; |  | 
|  518         } |  | 
|  519         out.write(CSV_QUOTE); |  | 
|  520         for (int i = 0; i < str.length(); i++) { |  | 
|  521             char c = str.charAt(i); |  | 
|  522             if (c == CSV_QUOTE) { |  | 
|  523                 out.write(CSV_QUOTE); // escape double quote |  | 
|  524             } |  | 
|  525             out.write(c); |  | 
|  526         } |  | 
|  527         out.write(CSV_QUOTE); |  | 
|  528     } |  | 
|  529  |  | 
|  530     /** |  | 
|  531      * <p>Returns a <code>String</code> value for an unescaped CSV column. </p> |  | 
|  532      * |  | 
|  533      * <p>If the value is enclosed in double quotes, and contains a comma, newli
     ne  |  | 
|  534      *    or double quote, then quotes are removed.  |  | 
|  535      * </p> |  | 
|  536      * |  | 
|  537      * <p>Any double quote escaped characters (a pair of double quotes) are unes
     caped  |  | 
|  538      *    to just one double quote. </p> |  | 
|  539      * |  | 
|  540      * <p>If the value is not enclosed in double quotes, or is and does not cont
     ain a  |  | 
|  541      *    comma, newline or double quote, then the String value is returned unch
     anged.</p> |  | 
|  542      * </p> |  | 
|  543      * |  | 
|  544      * see <a href="http://en.wikipedia.org/wiki/Comma-separated_values">Wikiped
     ia</a> and |  | 
|  545      * <a href="http://tools.ietf.org/html/rfc4180">RFC 4180</a>. |  | 
|  546      * |  | 
|  547      * @param str the input CSV column String, may be null |  | 
|  548      * @return the input String, with enclosing double quotes removed and embedd
     ed double  |  | 
|  549      * quotes unescaped, <code>null</code> if null string input |  | 
|  550      * @since 2.4 |  | 
|  551      */ |  | 
|  552     public static String unescapeCsv(String str) { |  | 
|  553         if (str == null) { |  | 
|  554             return null; |  | 
|  555         } |  | 
|  556         try { |  | 
|  557             StringWriter writer = new StringWriter(); |  | 
|  558             unescapeCsv(writer, str); |  | 
|  559             return writer.toString(); |  | 
|  560         } catch (IOException ioe) { |  | 
|  561             // this should never ever happen while writing to a StringWriter |  | 
|  562             ioe.printStackTrace(); |  | 
|  563             return null; |  | 
|  564         } |  | 
|  565     } |  | 
|  566  |  | 
|  567     /** |  | 
|  568      * <p>Returns a <code>String</code> value for an unescaped CSV column. </p> |  | 
|  569      * |  | 
|  570      * <p>If the value is enclosed in double quotes, and contains a comma, newli
     ne  |  | 
|  571      *    or double quote, then quotes are removed.  |  | 
|  572      * </p> |  | 
|  573      * |  | 
|  574      * <p>Any double quote escaped characters (a pair of double quotes) are unes
     caped  |  | 
|  575      *    to just one double quote. </p> |  | 
|  576      * |  | 
|  577      * <p>If the value is not enclosed in double quotes, or is and does not cont
     ain a  |  | 
|  578      *    comma, newline or double quote, then the String value is returned unch
     anged.</p> |  | 
|  579      * </p> |  | 
|  580      * |  | 
|  581      * see <a href="http://en.wikipedia.org/wiki/Comma-separated_values">Wikiped
     ia</a> and |  | 
|  582      * <a href="http://tools.ietf.org/html/rfc4180">RFC 4180</a>. |  | 
|  583      * |  | 
|  584      * @param str the input CSV column String, may be null |  | 
|  585      * @param out Writer to write the input String to, with enclosing double quo
     tes  |  | 
|  586      * removed and embedded double quotes unescaped, <code>null</code> if null s
     tring input |  | 
|  587      * @throws IOException if error occurs on underlying Writer |  | 
|  588      * @since 2.4 |  | 
|  589      */ |  | 
|  590     public static void unescapeCsv(Writer out, String str) throws IOException { |  | 
|  591         if (str == null) { |  | 
|  592             return; |  | 
|  593         } |  | 
|  594         if (str.length() < 2) { |  | 
|  595             out.write(str); |  | 
|  596             return; |  | 
|  597         } |  | 
|  598         if ( str.charAt(0) != CSV_QUOTE || str.charAt(str.length() - 1) != CSV_Q
     UOTE ) { |  | 
|  599             out.write(str); |  | 
|  600             return; |  | 
|  601         } |  | 
|  602  |  | 
|  603         // strip quotes |  | 
|  604         String quoteless = str.substring(1, str.length() - 1); |  | 
|  605  |  | 
|  606         if ( StringUtils.containsAny(quoteless, CSV_SEARCH_CHARS) ) { |  | 
|  607             // deal with escaped quotes; ie) "" |  | 
|  608             str = StringUtils.replace(quoteless, CSV_QUOTE_STR + CSV_QUOTE_STR, 
     CSV_QUOTE_STR); |  | 
|  609         } |  | 
|  610  |  | 
|  611         out.write(str); |  570         out.write(str); | 
|  612     } |  571       } | 
 |  572       return; | 
 |  573     } | 
 |  574     out.write(CSV_QUOTE); | 
 |  575     for (int i = 0; i < str.length(); i++) | 
 |  576     { | 
 |  577       char c = str.charAt(i); | 
 |  578       if (c == CSV_QUOTE) | 
 |  579       { | 
 |  580         out.write(CSV_QUOTE); // escape double quote | 
 |  581       } | 
 |  582       out.write(c); | 
 |  583     } | 
 |  584     out.write(CSV_QUOTE); | 
 |  585   } | 
 |  586  | 
 |  587   /** | 
 |  588    * <p>Returns a <code>String</code> value for an unescaped CSV column. </p> | 
 |  589    * | 
 |  590    * <p>If the value is enclosed in double quotes, and contains a comma, newline | 
 |  591    * or double quote, then quotes are removed. | 
 |  592    * </p> | 
 |  593    * | 
 |  594    * <p>Any double quote escaped characters (a pair of double quotes) are unesca
     ped | 
 |  595    * to just one double quote. </p> | 
 |  596    * | 
 |  597    * <p>If the value is not enclosed in double quotes, or is and does not contai
     n a | 
 |  598    * comma, newline or double quote, then the String value is returned unchanged
     .</p> | 
 |  599    * </p> | 
 |  600    * | 
 |  601    * see <a href="http://en.wikipedia.org/wiki/Comma-separated_values">Wikipedia
     </a> and | 
 |  602    * <a href="http://tools.ietf.org/html/rfc4180">RFC 4180</a>. | 
 |  603    * | 
 |  604    * @param str the input CSV column String, may be null | 
 |  605    * @return the input String, with enclosing double quotes removed and embedded
      double | 
 |  606    * quotes unescaped, <code>null</code> if null string input | 
 |  607    * @since 2.4 | 
 |  608    */ | 
 |  609   public static String unescapeCsv(String str) | 
 |  610   { | 
 |  611     if (str == null) | 
 |  612     { | 
 |  613       return null; | 
 |  614     } | 
 |  615     try | 
 |  616     { | 
 |  617       StringWriter writer = new StringWriter(); | 
 |  618       unescapeCsv(writer, str); | 
 |  619       return writer.toString(); | 
 |  620     } catch (IOException ioe) | 
 |  621     { | 
 |  622       // this should never ever happen while writing to a StringWriter | 
 |  623       ioe.printStackTrace(); | 
 |  624       return null; | 
 |  625     } | 
 |  626   } | 
 |  627  | 
 |  628   /** | 
 |  629    * <p>Returns a <code>String</code> value for an unescaped CSV column. </p> | 
 |  630    * | 
 |  631    * <p>If the value is enclosed in double quotes, and contains a comma, newline | 
 |  632    * or double quote, then quotes are removed. | 
 |  633    * </p> | 
 |  634    * | 
 |  635    * <p>Any double quote escaped characters (a pair of double quotes) are unesca
     ped | 
 |  636    * to just one double quote. </p> | 
 |  637    * | 
 |  638    * <p>If the value is not enclosed in double quotes, or is and does not contai
     n a | 
 |  639    * comma, newline or double quote, then the String value is returned unchanged
     .</p> | 
 |  640    * </p> | 
 |  641    * | 
 |  642    * see <a href="http://en.wikipedia.org/wiki/Comma-separated_values">Wikipedia
     </a> and | 
 |  643    * <a href="http://tools.ietf.org/html/rfc4180">RFC 4180</a>. | 
 |  644    * | 
 |  645    * @param str the input CSV column String, may be null | 
 |  646    * @param out Writer to write the input String to, with enclosing double quote
     s | 
 |  647    * removed and embedded double quotes unescaped, <code>null</code> if null str
     ing input | 
 |  648    * @throws IOException if error occurs on underlying Writer | 
 |  649    * @since 2.4 | 
 |  650    */ | 
 |  651   public static void unescapeCsv(Writer out, String str) throws IOException | 
 |  652   { | 
 |  653     if (str == null) | 
 |  654     { | 
 |  655       return; | 
 |  656     } | 
 |  657     if (str.length() < 2) | 
 |  658     { | 
 |  659       out.write(str); | 
 |  660       return; | 
 |  661     } | 
 |  662     if (str.charAt(0) != CSV_QUOTE || str.charAt(str.length() - 1) != CSV_QUOTE) | 
 |  663     { | 
 |  664       out.write(str); | 
 |  665       return; | 
 |  666     } | 
 |  667  | 
 |  668     // strip quotes | 
 |  669     String quoteless = str.substring(1, str.length() - 1); | 
 |  670  | 
 |  671     if (StringUtils.containsAny(quoteless, CSV_SEARCH_CHARS)) | 
 |  672     { | 
 |  673       // deal with escaped quotes; ie) "" | 
 |  674       str = StringUtils.replace(quoteless, CSV_QUOTE_STR + CSV_QUOTE_STR, CSV_QU
     OTE_STR); | 
 |  675     } | 
 |  676  | 
 |  677     out.write(str); | 
 |  678   } | 
|  613  |  679  | 
|  614 } |  680 } | 
| OLD | NEW |