001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      https://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018package org.apache.commons.text.translate;
019
020/**
021 * Translates code points to their Unicode escaped value suitable for Java source.
022 *
023 * @since 1.0
024 */
025public class JavaUnicodeEscaper extends UnicodeEscaper {
026
027    /**
028     * Constructs a {@code JavaUnicodeEscaper} above the specified value (exclusive).
029     *
030     * @param codePoint above which to escape.
031     * @return The newly created {@code UnicodeEscaper} instance.
032     */
033    public static JavaUnicodeEscaper above(final int codePoint) {
034        return outsideOf(0, codePoint);
035    }
036
037    /**
038     * Constructs a {@code JavaUnicodeEscaper} below the specified value (exclusive).
039     *
040     * @param codePoint below which to escape.
041     * @return The newly created {@code UnicodeEscaper} instance.
042     */
043    public static JavaUnicodeEscaper below(final int codePoint) {
044        return outsideOf(codePoint, Integer.MAX_VALUE);
045    }
046
047    /**
048     * Constructs a {@code JavaUnicodeEscaper} between the specified values (inclusive).
049     *
050     * @param codePointLow  above which to escape.
051     * @param codePointHigh below which to escape.
052     * @return The newly created {@code UnicodeEscaper} instance.
053     */
054    public static JavaUnicodeEscaper between(final int codePointLow, final int codePointHigh) {
055        return new JavaUnicodeEscaper(codePointLow, codePointHigh, true);
056    }
057
058    /**
059     * Constructs a {@code JavaUnicodeEscaper} outside of the specified values (exclusive).
060     *
061     * @param codePointLow  below which to escape.
062     * @param codePointHigh above which to escape.
063     * @return The newly created {@code UnicodeEscaper} instance.
064     */
065    public static JavaUnicodeEscaper outsideOf(final int codePointLow, final int codePointHigh) {
066        return new JavaUnicodeEscaper(codePointLow, codePointHigh, false);
067    }
068
069    /**
070     * Constructs a {@code JavaUnicodeEscaper} for the specified range. This is the underlying method for the other constructors/builders. The {@code below} and
071     * {@code above} boundaries are inclusive when {@code between} is {@code true} and exclusive when it is {@code false}.
072     *
073     * @param below   int value representing the lowest code point boundary.
074     * @param above   int value representing the highest code point boundary.
075     * @param between whether to escape between the boundaries or outside them.
076     */
077    public JavaUnicodeEscaper(final int below, final int above, final boolean between) {
078        super(below, above, between);
079    }
080
081    /**
082     * Converts the given code point to a hexadecimal string of the form {@code "\\uXXXX\\uXXXX"}.
083     *
084     * @param codePoint a Unicode code point.
085     * @return The hexadecimal string for the given code point.
086     */
087    @Override
088    protected String toUtf16Escape(final int codePoint) {
089        final char[] surrogatePair = Character.toChars(codePoint);
090        return "\\u" + hex(surrogatePair[0]) + "\\u" + hex(surrogatePair[1]);
091    }
092}