View Javadoc
1   package gboat2.base.core.util;
2   
3   /*
4    * 处理javascript中的特殊字符:中文、回车、换行、制表符、双引号。
5    * 注:原类处理了单引号,在本地会引起问题,故重写了此类,去掉了对单引号的转义
6    * Licensed to the Apache Software Foundation (ASF) under one
7    * or more contributor license agreements.  See the NOTICE file
8    * distributed with this work for additional information
9    * regarding copyright ownership.  The ASF licenses this file
10   * to you under the Apache License, Version 2.0 (the
11   * "License"); you may not use this file except in compliance
12   * with the License.  You may obtain a copy of the License at
13   *
14   *   http://www.apache.org/licenses/LICENSE-2.0
15   *
16   * Unless required by applicable law or agreed to in writing,
17   * software distributed under the License is distributed on an
18   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
19   * KIND, either express or implied.  See the License for the
20   * specific language governing permissions and limitations
21   * under the License.    
22   */
23  
24  import gboat2.base.bridge.exception.DefaultGboatNestedException;
25  
26  import java.io.IOException;
27  import java.io.StringWriter;
28  import java.io.Writer;
29  import java.util.Locale;
30  
31  import org.apache.velocity.app.event.implement.EscapeReference;
32  
33  /**
34   * Escapes the characters in a String to be suitable for use in JavaScript.
35   * @see <a href="http://jakarta.apache.org/commons/lang/api/org/apache/commons/lang/StringEscapeUtils.html#escapeJavaScript(java.lang.String)">StringEscapeUtils</a>
36   * @author wglass
37   * @since 1.5
38   */
39  public class EscapeJavaScriptReference extends EscapeReference
40  {
41  
42      /**
43       * Escapes the characters in a String to be suitable for use in JavaScript.
44       * 
45       * @param text
46       * @return An escaped String.
47       * @see <a href="http://jakarta.apache.org/commons/lang/api/org/apache/commons/lang/StringEscapeUtils.html#escapeJavaScript(java.lang.String)">StringEscapeUtils</a>
48       */
49      protected String escape(Object text)
50      {
51          return this.escapeJavaScriptString(text.toString());
52      }
53  
54      /**
55       * @return attribute "eventhandler.escape.javascript.match"
56       */
57      protected String getMatchAttribute()
58      {
59          return "eventhandler.escape.javascript.match";
60      }
61      
62      
63      private String escapeJavaScriptString(String str){
64      	 if (str == null) {
65               return null;
66           }
67           try {
68               StringWriter writer = new StringWriter(str.length() * 2);
69               escapeJavaStyleString(writer, str, true, true);
70               return writer.toString();
71           } catch (IOException ioe) {
72               // this should never ever happen while writing to a StringWriter
73               throw new DefaultGboatNestedException(ioe);
74           }
75      	
76      }
77      
78      private static void escapeJavaStyleString(Writer out, String str, boolean escapeSingleQuote,
79              boolean escapeForwardSlash) throws IOException {
80          if (out == null) {
81              throw new IllegalArgumentException("The Writer must not be null");
82          }
83          if (str == null) {
84              return;
85          }
86          int sz;
87          sz = str.length();
88          for (int i = 0; i < sz; i++) {
89              char ch = str.charAt(i);
90  
91              // handle unicode
92              if (ch > 0xfff) {
93              	//某些情况下 velocity会对content中的中文进行一次转义为例如\u5DE5填充值时再对\转义为\\u5DE5
94              	//因此会出现问题,此处注释掉对中文的处理,中文字符原样输出
95                 // out.write("\\u" + hex(ch));
96              	out.write(ch);
97              } else if (ch > 0xff) {
98                  out.write("\\u0" + hex(ch));
99              } else if (ch > 0x7f) {
100                 out.write("\\u00" + hex(ch));
101             } else if (ch < 32) {
102                 switch (ch) {
103                     case '\b' :
104                         out.write('\\');
105                         out.write('b');
106                         break;
107                     case '\n' :
108                         out.write('\\');
109                         out.write('n');
110                         break;
111                     case '\t' :
112                         out.write('\\');
113                         out.write('t');
114                         break;
115                     case '\f' :
116                         out.write('\\');
117                         out.write('f');
118                         break;
119                     case '\r' :
120                         out.write('\\');
121                         out.write('r');
122                         break;
123                     default :
124                         if (ch > 0xf) {
125                             out.write("\\u00" + hex(ch));
126                         } else {
127                             out.write("\\u000" + hex(ch));
128                         }
129                         break;
130                 }
131             } else {
132                 switch (ch) {
133                     case '\'' :
134                         if (escapeSingleQuote) {
135                           out.write('\\');
136                         }
137                         out.write('\'');
138                         //out.write('‘');
139                         break;
140                     case '"' :
141                         out.write('\\');
142                         out.write('"');
143                         break;
144                     case '\\' :
145                         out.write('\\');
146                         out.write('\\');
147                         break;
148                         //有些情况下会在velocity值中加入html标签,例如<strong></strong>转义/会出现extjs decode错误
149                         //因此注释掉此段逻辑
150 //                    case '/' :
151 //                        if (escapeForwardSlash) {
152 //                            out.write('\\');
153 //                        }
154 //                        out.write('/');
155 //                        break;
156                     default :
157                         out.write(ch);
158                         break;
159                 }
160             }
161         }
162     }
163     
164     private static String hex(char ch) {
165         return Integer.toHexString(ch).toUpperCase(Locale.ENGLISH);
166     }
167     
168 
169 }