NumericEntityEscaper.java

  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. package org.apache.commons.text.translate;

  18. import java.io.IOException;
  19. import java.io.Writer;

  20. import org.apache.commons.lang3.Range;

  21. /**
  22.  * Translates code points to their XML numeric entity escaped value.
  23.  *
  24.  * @since 1.0
  25.  */
  26. public class NumericEntityEscaper extends CodePointTranslator {

  27.     /**
  28.      * Constructs a {@code NumericEntityEscaper} above the specified value (exclusive).
  29.      *
  30.      * @param codePoint above which to escape
  31.      * @return The newly created {@code NumericEntityEscaper} instance
  32.      */
  33.     public static NumericEntityEscaper above(final int codePoint) {
  34.         return outsideOf(0, codePoint);
  35.     }

  36.     /**
  37.      * Constructs a {@code NumericEntityEscaper} below the specified value (exclusive).
  38.      *
  39.      * @param codePoint below which to escape
  40.      * @return The newly created {@code NumericEntityEscaper} instance
  41.      */
  42.     public static NumericEntityEscaper below(final int codePoint) {
  43.         return outsideOf(codePoint, Integer.MAX_VALUE);
  44.     }

  45.     /**
  46.      * Constructs a {@code NumericEntityEscaper} between the specified values (inclusive).
  47.      *
  48.      * @param codePointLow above which to escape
  49.      * @param codePointHigh below which to escape
  50.      * @return The newly created {@code NumericEntityEscaper} instance
  51.      */
  52.     public static NumericEntityEscaper between(final int codePointLow, final int codePointHigh) {
  53.         return new NumericEntityEscaper(codePointLow, codePointHigh, true);
  54.     }

  55.     /**
  56.      * Constructs a {@code NumericEntityEscaper} outside of the specified values (exclusive).
  57.      *
  58.      * @param codePointLow below which to escape
  59.      * @param codePointHigh above which to escape
  60.      * @return The newly created {@code NumericEntityEscaper} instance
  61.      */
  62.     public static NumericEntityEscaper outsideOf(final int codePointLow, final int codePointHigh) {
  63.         return new NumericEntityEscaper(codePointLow, codePointHigh, false);
  64.     }

  65.     /** Whether to escape between the boundaries or outside them. */
  66.     private final boolean between;

  67.     /** Range from lowest code point to highest code point. */
  68.     private final Range<Integer> range;

  69.     /**
  70.      * Constructs a {@code NumericEntityEscaper} for all characters.
  71.      */
  72.     public NumericEntityEscaper() {
  73.         this(0, Integer.MAX_VALUE, true);
  74.     }

  75.     /**
  76.      * Constructs a {@code NumericEntityEscaper} for the specified range. This is
  77.      * the underlying method for the other constructors/builders. The {@code below}
  78.      * and {@code above} boundaries are inclusive when {@code between} is
  79.      * {@code true} and exclusive when it is {@code false}.
  80.      *
  81.      * @param below int value representing the lowest code point boundary
  82.      * @param above int value representing the highest code point boundary
  83.      * @param between whether to escape between the boundaries or outside them
  84.      */
  85.     private NumericEntityEscaper(final int below, final int above, final boolean between) {
  86.         this.range = Range.of(below, above);
  87.         this.between = between;
  88.     }

  89.     /**
  90.      * {@inheritDoc}
  91.      */
  92.     @Override
  93.     public boolean translate(final int codePoint, final Writer writer) throws IOException {
  94.         if (this.between != this.range.contains(codePoint)) {
  95.             return false;
  96.         }
  97.         writer.write("&#");
  98.         writer.write(Integer.toString(codePoint, 10));
  99.         writer.write(';');
  100.         return true;
  101.     }
  102. }