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&lt;Bar&gt;"} 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}