View Javadoc

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  
18  package org.apache.log4j.helpers;
19  
20  /**
21     Utility class for transforming strings.
22  
23     @author Ceki Gülcü
24     @author Michael A. McAngus 
25   */
26  public class Transform {
27  
28     private static final String CDATA_START  = "<![CDATA[";
29     private static final String CDATA_END    = "]]>";
30     private static final String CDATA_PSEUDO_END = "]]&gt;";
31     private static final String CDATA_EMBEDED_END = CDATA_END + CDATA_PSEUDO_END + CDATA_START;
32     private static final int CDATA_END_LEN = CDATA_END.length();
33  
34    /**
35     * This method takes a string which may contain HTML tags (ie,
36     * &lt;b&gt;, &lt;table&gt;, etc) and replaces any
37     * '<',  '>' , '&' or '"'
38     * characters with respective predefined entity references.
39     *
40     * @param input The text to be converted.
41     * @return The input string with the special characters replaced.
42     * */
43    static public String escapeTags(final String input) {
44      //Check if the string is null, zero length or devoid of special characters
45      // if so, return what was sent in.
46  
47      if(input == null
48         || input.length() == 0
49         || (input.indexOf('"') == -1 &&
50             input.indexOf('&') == -1 &&
51             input.indexOf('<') == -1 &&
52             input.indexOf('>') == -1)) {
53        return input;
54      }
55  
56      //Use a StringBuffer in lieu of String concatenation -- it is
57      //much more efficient this way.
58  
59      StringBuffer buf = new StringBuffer(input.length() + 6);
60      char ch = ' ';
61  
62      int len = input.length();
63      for(int i=0; i < len; i++) {
64        ch = input.charAt(i);
65        if (ch > '>') {
66            buf.append(ch);
67        } else if(ch == '<') {
68  	      buf.append("&lt;");
69        } else if(ch == '>') {
70  	      buf.append("&gt;");
71        } else if(ch == '&') {
72  	      buf.append("&amp;");
73        } else if(ch == '"') {
74  	      buf.append("&quot;");
75        } else {
76  	      buf.append(ch);
77        }
78      }
79      return buf.toString();
80    }
81  
82    /**
83    * Ensures that embeded CDEnd strings (]]>) are handled properly
84    * within message, NDC and throwable tag text.
85    *
86    * @param buf StringBuffer holding the XML data to this point.  The
87    * initial CDStart (<![CDATA[) and final CDEnd (]]>) of the CDATA
88    * section are the responsibility of the calling method.
89    * @param str The String that is inserted into an existing CDATA Section within buf.  
90    * */
91    static public void appendEscapingCDATA(final StringBuffer buf,
92                                           final String str) {
93        if (str != null) {
94            int end = str.indexOf(CDATA_END);
95            if (end < 0) {
96                buf.append(str);
97            } else {
98                int start = 0;
99                while (end > -1) {
100                   buf.append(str.substring(start, end));
101                   buf.append(CDATA_EMBEDED_END);
102                   start = end + CDATA_END_LEN;
103                   if (start < str.length()) {
104                       end = str.indexOf(CDATA_END, start);
105                   } else {
106                       return;
107                   }
108               }
109               buf.append(str.substring(start));
110           }
111       }
112   }
113 }