123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334 |
- /*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- /* $Id$ */
-
- package org.apache.fop.util;
-
- import java.awt.Rectangle;
- import java.awt.geom.Rectangle2D;
-
- import org.xml.sax.Attributes;
- import org.xml.sax.SAXException;
- import org.xml.sax.helpers.AttributesImpl;
-
- /**
- * A collection of utility method for XML handling.
- */
- public final class XMLUtil implements XMLConstants {
-
- private XMLUtil() {
- }
-
- /**
- * Returns an attribute value as a boolean value.
- * @param attributes the Attributes object
- * @param name the name of the attribute
- * @param defaultValue the default value if the attribute is not specified
- * @return the attribute value as a boolean
- */
- public static boolean getAttributeAsBoolean(Attributes attributes, String name,
- boolean defaultValue) {
- String s = attributes.getValue(name);
- if (s == null) {
- return defaultValue;
- } else {
- return Boolean.valueOf(s);
- }
- }
-
- /**
- * Returns an attribute value as a int value.
- * @param attributes the Attributes object
- * @param name the name of the attribute
- * @param defaultValue the default value if the attribute is not specified
- * @return the attribute value as an int
- */
- public static int getAttributeAsInt(Attributes attributes, String name,
- int defaultValue) {
- String s = attributes.getValue(name);
- if (s == null) {
- return defaultValue;
- } else {
- return Integer.parseInt(s);
- }
- }
-
- /**
- * Returns an attribute value as a int value.
- * @param attributes the Attributes object
- * @param name the name of the attribute
- * @return the attribute value as an int
- * @throws SAXException if the attribute is missing
- */
- public static int getAttributeAsInt(Attributes attributes, String name) throws SAXException {
- String s = attributes.getValue(name);
- if (s == null) {
- throw new SAXException("Attribute '" + name + "' is missing");
- } else {
- return Integer.parseInt(s);
- }
- }
-
- /**
- * Returns an attribute value as a Integer value.
- * @param attributes the Attributes object
- * @param name the name of the attribute
- * @return the attribute value as an Integer or null if the attribute is missing
- */
- public static Integer getAttributeAsInteger(Attributes attributes, String name) {
- String s = attributes.getValue(name);
- if (s == null) {
- return null;
- } else {
- return Integer.valueOf(s);
- }
- }
-
- /**
- * Returns an attribute value as a Rectangle2D value. The string value is expected as 4
- * double-precision numbers separated by whitespace.
- * @param attributes the Attributes object
- * @param name the name of the attribute
- * @return the attribute value as an Rectangle2D
- */
- public static Rectangle2D getAttributeAsRectangle2D(Attributes attributes, String name) {
- String s = attributes.getValue(name).trim();
- double[] values = ConversionUtils.toDoubleArray(s, "\\s");
- if (values.length != 4) {
- throw new IllegalArgumentException("Rectangle must consist of 4 double values!");
- }
- return new Rectangle2D.Double(values[0], values[1], values[2], values[3]);
- }
-
- /**
- * Returns an attribute value as a Rectangle value. The string value is expected as 4
- * integer numbers separated by whitespace.
- * @param attributes the Attributes object
- * @param name the name of the attribute
- * @return the attribute value as an Rectangle
- */
- public static Rectangle getAttributeAsRectangle(Attributes attributes, String name) {
- String s = attributes.getValue(name);
- if (s == null) {
- return null;
- }
- int[] values = ConversionUtils.toIntArray(s.trim(), "\\s");
- if (values.length != 4) {
- throw new IllegalArgumentException("Rectangle must consist of 4 int values!");
- }
- return new Rectangle(values[0], values[1], values[2], values[3]);
- }
-
- /**
- * Returns an attribute value as a integer array. The string value is expected as 4
- * integer numbers separated by whitespace.
- * @param attributes the Attributes object
- * @param name the name of the attribute
- * @return the attribute value as an int array
- */
- public static int[] getAttributeAsIntArray(Attributes attributes, String name) {
- String s = attributes.getValue(name);
- if (s == null) {
- return null;
- } else {
- return ConversionUtils.toIntArray(s.trim(), "\\s");
- }
- }
-
- /**
- * Adds an attribute to a given {@link AttributesImpl} instance.
- * @param atts the attributes collection
- * @param attribute the attribute to add
- * @param value the attribute's CDATA value
- */
- public static void addAttribute(AttributesImpl atts,
- org.apache.xmlgraphics.util.QName attribute, String value) {
- atts.addAttribute(attribute.getNamespaceURI(),
- attribute.getLocalName(), attribute.getQName(), XMLUtil.CDATA, value);
- }
-
- /**
- * Adds an attribute to a given {@link AttributesImpl} instance. The attribute will be
- * added in the default namespace.
- * @param atts the attributes collection
- * @param localName the local name of the attribute
- * @param value the attribute's CDATA value
- */
- public static void addAttribute(AttributesImpl atts, String localName, String value) {
- atts.addAttribute("", localName, localName, XMLUtil.CDATA, value);
- }
-
- /**
- * Encode a glyph position adjustments array as a string, where the string value
- * adheres to the following syntax:
- *
- * count ( 'Z' repeat | number )
- *
- * where each token is separated by whitespace, except that 'Z' followed by repeat
- * are considered to be a single token with no intervening whitespace, and where
- * 'Z' repeat encodes repeated zeroes.
- * @param dp the adjustments array
- * @param paCount the number of entries to encode from adjustments array
- * @return the encoded value
- */
- public static String encodePositionAdjustments(int[][] dp, int paCount) {
- assert dp != null;
- StringBuffer sb = new StringBuffer();
- int na = paCount;
- int nz = 0;
- sb.append(na);
- for (int i = 0; i < na; i++) {
- int[] pa = dp [ i ];
- if (pa != null) {
- for (int k = 0; k < 4; k++) {
- int a = pa [ k ];
- if (a != 0) {
- encodeNextAdjustment(sb, nz, a);
- nz = 0;
- } else {
- nz++;
- }
- }
- } else {
- nz += 4;
- }
- }
- encodeNextAdjustment(sb, nz, 0);
- return sb.toString();
- }
-
- /**
- * Encode a glyph position adjustments array as a string, where the string value
- * adheres to the following syntax:
- *
- * count ( 'Z' repeat | number )
- *
- * where each token is separated by whitespace, except that 'Z' followed by repeat
- * are considered to be a single token with no intervening whitespace.
- * @param dp the adjustments array
- * @return the encoded value
- */
- public static String encodePositionAdjustments(int[][] dp) {
- assert dp != null;
- return encodePositionAdjustments(dp, dp.length);
- }
-
- private static void encodeNextAdjustment(StringBuffer sb, int nz, int a) {
- encodeZeroes(sb, nz);
- encodeAdjustment(sb, a);
- }
-
- private static void encodeZeroes(StringBuffer sb, int nz) {
- if (nz > 0) {
- sb.append(' ');
- if (nz == 1) {
- sb.append('0');
- } else {
- sb.append('Z');
- sb.append(nz);
- }
- }
- }
-
- private static void encodeAdjustment(StringBuffer sb, int a) {
- if (a != 0) {
- sb.append(' ');
- sb.append(a);
- }
- }
-
- /**
- * Decode a string as a glyph position adjustments array, where the string
- * shall adhere to the syntax specified by {@link #encodePositionAdjustments}.
- * @param value the encoded value
- * @return the position adjustments array
- */
- public static int[][] decodePositionAdjustments(String value) {
- int[][] dp = null;
- if (value != null) {
- String[] sa = value.split("\\s");
- if (sa != null) {
- if (sa.length > 0) {
- int na = Integer.parseInt(sa[0]);
- dp = new int [ na ] [ 4 ];
- for (int i = 1, n = sa.length, k = 0; i < n; i++) {
- String s = sa [ i ];
- if (s.charAt(0) == 'Z') {
- int nz = Integer.parseInt(s.substring(1));
- k += nz;
- } else {
- dp [ k / 4 ] [ k % 4 ] = Integer.parseInt(s);
- k += 1;
- }
- }
- }
- }
- }
- return dp;
- }
-
- /**
- * Returns an attribute value as a glyph position adjustments array. The string value
- * is expected to be a non-empty sequence of either Z<repeat> or <number>, where the
- * former encodes a repeat count (of zeroes) and the latter encodes a integer number,
- * and where each item is separated by whitespace.
- * @param attributes the Attributes object
- * @param name the name of the attribute
- * @return the position adjustments array
- */
- public static int[][] getAttributeAsPositionAdjustments(Attributes attributes, String name) {
- String s = attributes.getValue(name);
- if (s == null) {
- return null;
- } else {
- return decodePositionAdjustments(s.trim());
- }
- }
-
- /**
- * Escape '<', '>' and '&' using NCRs.
- * @param unescaped string
- * @return escaped string
- */
- public static String escape(String unescaped) {
- int needsEscape = 0;
- for (int i = 0, n = unescaped.length(); i < n; ++i) {
- char c = unescaped.charAt(i);
- if ((c == '<') || (c == '>') || (c == '&')) {
- ++needsEscape;
- }
- }
- if (needsEscape > 0) {
- StringBuffer sb = new StringBuffer(unescaped.length() + 6 * needsEscape);
- for (int i = 0, n = unescaped.length(); i < n; ++i) {
- char c = unescaped.charAt(i);
- if ((c == '<') || (c == '>') || (c == '&')) {
- sb.append("&#x");
- sb.append(Integer.toString(c, 16));
- sb.append(';');
- } else {
- sb.append(c);
- }
- }
- return sb.toString();
- } else {
- return unescaped;
- }
- }
-
- }
|