/*
 * 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: URISpecification.java 1806679 2017-08-30 08:43:06Z cbowditch $ */

package org.apache.fop.datatypes;

import java.io.UnsupportedEncodingException;


This class contains method to deal with the <uri-specification> datatype from XSL-FO.
/** * This class contains method to deal with the &lt;uri-specification&gt; datatype from XSL-FO. */
public final class URISpecification { private URISpecification() { }
Get the URL string from a wrapped URL.
Params:
  • href – the input wrapped URL
Returns:the raw URL
/** * Get the URL string from a wrapped URL. * * @param href the input wrapped URL * @return the raw URL */
public static String getURL(String href) { /* * According to section 5.11 a <uri-specification> is: * "url(" + URI + ")" * according to 7.28.7 a <uri-specification> is: * URI * So handle both. */ href = href.trim(); if (href.startsWith("url(") && (href.indexOf(")") != -1)) { href = href.substring(4, href.lastIndexOf(")")).trim(); if (href.startsWith("'") && href.endsWith("'")) { href = href.substring(1, href.length() - 1); } else if (href.startsWith("\"") && href.endsWith("\"")) { href = href.substring(1, href.length() - 1); } } else { // warn } return href; } private static final String PUNCT = ",;:$&+="; private static final String RESERVED = PUNCT + "?/[]@"; /* not used private static boolean isValidURIChar(char ch) { return true; } */ private static boolean isDigit(char ch) { return (ch >= '0' && ch <= '9'); } private static boolean isAlpha(char ch) { return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'); } private static boolean isHexDigit(char ch) { return (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f'); } private static boolean isReserved(char ch) { if (RESERVED.indexOf(ch) >= 0) { return true; } else if ('#' == ch) { //# is not a reserved character but is used for the fragment return true; } return false; } private static boolean isUnreserved(char ch) { if (isDigit(ch) || isAlpha(ch)) { return true; } else if ("_-!.~\'()*".indexOf(ch) >= 0) { //remaining unreserved characters return true; } return false; } private static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; private static void appendEscape(StringBuffer sb, byte b) { sb.append('%').append(HEX_DIGITS[(b >> 4) & 0x0f]).append(HEX_DIGITS[(b >> 0) & 0x0f]); }
Escapes any illegal URI character in a given URI, for example, it escapes a space to "%20". Note: This method does not "parse" the URI and therefore does not treat the individual components (user-info, path, query etc.) individually.
Params:
  • uri – the URI to inspect
Returns:the escaped URI
/** * Escapes any illegal URI character in a given URI, for example, it escapes a space to "%20". * Note: This method does not "parse" the URI and therefore does not treat the individual * components (user-info, path, query etc.) individually. * @param uri the URI to inspect * @return the escaped URI */
public static String escapeURI(String uri) { uri = getURL(uri); StringBuffer sb = new StringBuffer(); for (int i = 0, c = uri.length(); i < c; i++) { char ch = uri.charAt(i); if (ch == '%') { if (i < c - 3 && isHexDigit(uri.charAt(i + 1)) && isHexDigit(uri.charAt(i + 2))) { sb.append(ch); continue; } } if (isReserved(ch) || isUnreserved(ch)) { //Note: this may not be accurate for some very special cases. sb.append(ch); } else { try { byte[] utf8 = Character.toString(ch).getBytes("UTF-8"); for (byte anUtf8 : utf8) { appendEscape(sb, anUtf8); } } catch (UnsupportedEncodingException e) { throw new Error("Incompatible JVM. UTF-8 not supported."); } } } return sb.toString(); } }