18b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira/* 28b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * Copyright (C) 2008 Google Inc. 38b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * 48b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * Licensed under the Apache License, Version 2.0 (the "License"); 58b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * you may not use this file except in compliance with the License. 68b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * You may obtain a copy of the License at 78b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * 88b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * http://www.apache.org/licenses/LICENSE-2.0 98b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * 108b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * Unless required by applicable law or agreed to in writing, software 118b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * distributed under the License is distributed on an "AS IS" BASIS, 128b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * See the License for the specific language governing permissions and 148b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * limitations under the License. 158b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira */ 1630e2c24b056542f3b1b438aeb798305d1226d0c8Andy Huangpackage com.android.mail.lib.base; 178b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira 188b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira/** 198b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * An object that converts literal text into a format safe for inclusion in a particular context 208b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * (such as an XML document). Typically (but not always), the inverse process of "unescaping" the 218b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * text is performed automatically by the relevant parser. 228b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * 238b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * <p>For example, an XML escaper would convert the literal string {@code "Foo<Bar>"} into {@code 248b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * "Foo<Bar>"} to prevent {@code "<Bar>"} from being confused with an XML tag. When the 258b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * resulting XML document is parsed, the parser API will return this text as the original literal 268b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * string {@code "Foo<Bar>"}. 278b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * 288b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * <p>An {@code Escaper} instance is required to be stateless, and safe when used concurrently by 298b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * multiple threads. 308b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * 318b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * <p>The two primary implementations of this interface are {@link CharEscaper} and {@link 328b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * UnicodeEscaper}. They are heavily optimized for performance and greatly simplify the task of 338b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * implementing new escapers. It is strongly recommended that when implementing a new escaper you 348b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * extend one of these classes. If you find that you are unable to achieve the desired behavior 358b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * using either of these classes, please contact the Java libraries team for advice. 368b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * 378b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * <p>Several popular escapers are defined as constants in the class {@link CharEscapers}. To create 388b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * your own escapers, use {@link CharEscaperBuilder}, or extend {@link CharEscaper} or {@code 398b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * UnicodeEscaper}. 408b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * 418b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * @author dbeaumont@google.com (David Beaumont) 428b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira */ 438b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereirapublic abstract class Escaper { 448b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira /** 458b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * Returns the escaped form of a given literal string. 468b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * 478b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * <p>Note that this method may treat input characters differently depending on the specific 488b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * escaper implementation. 498b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * 508b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * <ul> 518b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * <li>{@link UnicodeEscaper} handles <a href="http://en.wikipedia.org/wiki/UTF-16">UTF-16</a> 528b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * correctly, including surrogate character pairs. If the input is badly formed the escaper 538b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * should throw {@link IllegalArgumentException}. 548b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * <li>{@link CharEscaper} handles Java characters independently and does not verify the input 558b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * for well formed characters. A CharEscaper should not be used in situations where input is 568b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * not guaranteed to be restricted to the Basic Multilingual Plane (BMP). 578b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * </ul> 588b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * 598b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * @param string the literal string to be escaped 608b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * @return the escaped form of {@code string} 618b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * @throws NullPointerException if {@code string} is null 628b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * @throws IllegalArgumentException if {@code string} contains badly formed UTF-16 or cannot be 638b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * escaped for any other reason 648b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira */ 658b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira public abstract String escape(String string); 668b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira 678b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira /** 688b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * Returns an {@code Appendable} instance which automatically escapes all text appended to it 698b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * before passing the resulting text to an underlying {@code Appendable}. 708b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * 718b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * <p>Note that the Appendable returned by this method may treat input characters differently 728b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * depending on the specific escaper implementation. 738b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * 748b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * <ul> 758b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * <li>{@link UnicodeEscaper} handles <a href="http://en.wikipedia.org/wiki/UTF-16">UTF-16</a> 768b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * correctly, including surrogate character pairs. If the input is badly formed the escaper 778b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * should throw {@link IllegalArgumentException}. 788b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * <li>{@link CharEscaper} handles Java characters independently and does not verify the input 798b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * for well formed characters. A CharEscaper should not be used in situations where input is 808b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * not guaranteed to be restricted to the Basic Multilingual Plane (BMP). 818b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * </ul> 828b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * 838b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * <p>In all implementations the escaped Appendable should throw {@code NullPointerException} if 848b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * given a {@code null} {@link CharSequence}. 858b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * 868b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * @param out the underlying {@code Appendable} to append escaped output to 878b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * @return an {@code Appendable} which passes text to {@code out} after escaping it 888b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira */ 898b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira public abstract Appendable escape(Appendable out); 908b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira 918b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira private final Function<String, String> asFunction = 928b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira new Function<String, String>() { 938b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira public String apply(String from) { 948b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira return escape(from); 958b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira } 968b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira }; 978b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira 988b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira /** 998b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira * Returns a {@link Function} that invokes {@link #escape(String)} on this escaper. 1008b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira */ 1018b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira public Function<String, String> asFunction() { 1028b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira return asFunction; 1038b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira } 1048b99ba451db6973978e60f91da2199686a9c85e7Mindy Pereira}