jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/resolver/helpers/PublicId.java
changeset 45606 9f69dd961bf3
parent 45605 8d019eee3515
parent 45598 5e0712d61fbc
child 45607 a1fb7c733328
equal deleted inserted replaced
45605:8d019eee3515 45606:9f69dd961bf3
     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 
       
    18 package com.sun.org.apache.xml.internal.resolver.helpers;
       
    19 
       
    20 /**
       
    21  * Static methods for dealing with public identifiers.
       
    22  *
       
    23  * <p>This class defines a set of static methods that can be called
       
    24  * to handle public identifiers.</p>
       
    25  *
       
    26  * @author Norman Walsh
       
    27  * <a href="mailto:Norman.Walsh@Sun.COM">Norman.Walsh@Sun.COM</a>
       
    28  *
       
    29  */
       
    30 public abstract class PublicId {
       
    31 
       
    32   protected PublicId() {}
       
    33 
       
    34   /**
       
    35    * Normalize a public identifier.
       
    36    *
       
    37    * <p>Public identifiers must be normalized according to the following
       
    38    * rules before comparisons between them can be made:</p>
       
    39    *
       
    40    * <ul>
       
    41    * <li>Whitespace characters are normalized to spaces (e.g., line feeds,
       
    42    * tabs, etc. become spaces).</li>
       
    43    * <li>Leading and trailing whitespace is removed.</li>
       
    44    * <li>Multiple internal whitespaces are normalized to a single
       
    45    * space.</li>
       
    46    * </ul>
       
    47    *
       
    48    * <p>This method is declared static so that other classes
       
    49    * can use it directly.</p>
       
    50    *
       
    51    * @param publicId The unnormalized public identifier.
       
    52    *
       
    53    * @return The normalized identifier.
       
    54    */
       
    55   public static String normalize(String publicId) {
       
    56       String normal = publicId.replace('\t', ' ');
       
    57       normal = normal.replace('\r', ' ');
       
    58       normal = normal.replace('\n', ' ');
       
    59       normal = normal.trim();
       
    60 
       
    61       int pos;
       
    62 
       
    63       while ((pos = normal.indexOf("  ")) >= 0) {
       
    64           normal = normal.substring(0, pos) + normal.substring(pos+1);
       
    65       }
       
    66       return normal;
       
    67   }
       
    68 
       
    69   /**
       
    70    * Encode a public identifier as a "publicid" URN.
       
    71    *
       
    72    * <p>This method is declared static so that other classes
       
    73    * can use it directly.</p>
       
    74    *
       
    75    * @param publicId The unnormalized public identifier.
       
    76    *
       
    77    * @return The normalized identifier.
       
    78    */
       
    79   public static String encodeURN(String publicId) {
       
    80       String urn = PublicId.normalize(publicId);
       
    81 
       
    82       urn = PublicId.stringReplace(urn, "%", "%25");
       
    83       urn = PublicId.stringReplace(urn, ";", "%3B");
       
    84       urn = PublicId.stringReplace(urn, "'", "%27");
       
    85       urn = PublicId.stringReplace(urn, "?", "%3F");
       
    86       urn = PublicId.stringReplace(urn, "#", "%23");
       
    87       urn = PublicId.stringReplace(urn, "+", "%2B");
       
    88       urn = PublicId.stringReplace(urn, " ", "+");
       
    89       urn = PublicId.stringReplace(urn, "::", ";");
       
    90       urn = PublicId.stringReplace(urn, ":", "%3A");
       
    91       urn = PublicId.stringReplace(urn, "//", ":");
       
    92       urn = PublicId.stringReplace(urn, "/", "%2F");
       
    93 
       
    94       StringBuilder buffer = new StringBuilder(13 + urn.length());
       
    95       buffer.append("urn:publicid:");
       
    96       buffer.append(urn);
       
    97       return buffer.toString();
       
    98   }
       
    99 
       
   100   /**
       
   101    * Decode a "publicid" URN into a public identifier.
       
   102    *
       
   103    * <p>This method is declared static so that other classes
       
   104    * can use it directly.</p>
       
   105    *
       
   106    * @param urn The urn:publicid: URN
       
   107    *
       
   108    * @return The normalized identifier.
       
   109    */
       
   110   public static String decodeURN(String urn) {
       
   111       String publicId;
       
   112       if (urn.startsWith("urn:publicid:")) {
       
   113           publicId = urn.substring(13);
       
   114       }
       
   115       else {
       
   116           return urn;
       
   117       }
       
   118 
       
   119       final boolean hasEscape = (publicId.indexOf('%') >= 0);
       
   120       if (hasEscape) {
       
   121           publicId = PublicId.stringReplace(publicId, "%2F", "/");
       
   122       }
       
   123       publicId = PublicId.stringReplace(publicId, ":", "//");
       
   124       if (hasEscape) {
       
   125           publicId = PublicId.stringReplace(publicId, "%3A", ":");
       
   126       }
       
   127       publicId = PublicId.stringReplace(publicId, ";", "::");
       
   128       publicId = PublicId.stringReplace(publicId, "+", " ");
       
   129       if (hasEscape) {
       
   130           publicId = PublicId.stringReplace(publicId, "%2B", "+");
       
   131           publicId = PublicId.stringReplace(publicId, "%23", "#");
       
   132           publicId = PublicId.stringReplace(publicId, "%3F", "?");
       
   133           publicId = PublicId.stringReplace(publicId, "%27", "'");
       
   134           publicId = PublicId.stringReplace(publicId, "%3B", ";");
       
   135           publicId = PublicId.stringReplace(publicId, "%25", "%");
       
   136       }
       
   137 
       
   138       return publicId;
       
   139   }
       
   140 
       
   141   /**
       
   142    * Replace one string with another.
       
   143    */
       
   144   private static String stringReplace(String str,
       
   145           String oldStr,
       
   146           String newStr) {
       
   147       int pos = str.indexOf(oldStr);
       
   148       if (pos >= 0) {
       
   149           final StringBuilder buffer = new StringBuilder();
       
   150           final int oldStrLength = oldStr.length();
       
   151           int start = 0;
       
   152           do {
       
   153               for (int i = start; i < pos; ++i) {
       
   154                   buffer.append(str.charAt(i));
       
   155               }
       
   156               buffer.append(newStr);
       
   157               start = pos + oldStrLength;
       
   158               pos = str.indexOf(oldStr, start);
       
   159           }
       
   160           while (pos >= 0);
       
   161           final int strLength = str.length();
       
   162           for (int i = start; i < strLength; ++i) {
       
   163               buffer.append(str.charAt(i));
       
   164           }
       
   165           return buffer.toString();
       
   166       }
       
   167       return str;
       
   168   }
       
   169 }