1 /*
   2  * reserved comment block
   3  * DO NOT REMOVE OR ALTER!
   4  */
   5 // PublicId.java - Information about public identifiers
   6 
   7 /*
   8  * Copyright 2001-2004 The Apache Software Foundation or its licensors,
   9  * as applicable.
  10  *
  11  * Licensed under the Apache License, Version 2.0 (the "License");
  12  * you may not use this file except in compliance with the License.
  13  * You may obtain a copy of the License at
  14  *
  15  *      http://www.apache.org/licenses/LICENSE-2.0
  16  *
  17  * Unless required by applicable law or agreed to in writing, software
  18  * distributed under the License is distributed on an "AS IS" BASIS,
  19  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  20  * See the License for the specific language governing permissions and
  21  * limitations under the License.
  22  */
  23 
  24 package com.sun.org.apache.xml.internal.resolver.helpers;
  25 
  26 /**
  27  * Static methods for dealing with public identifiers.
  28  *
  29  * <p>This class defines a set of static methods that can be called
  30  * to handle public identifiers.</p>
  31  *
  32  * @author Norman Walsh
  33  * <a href="mailto:Norman.Walsh@Sun.COM">Norman.Walsh@Sun.COM</a>
  34  *
  35  */
  36 public abstract class PublicId {
  37   protected PublicId() { }
  38 
  39   /**
  40    * Normalize a public identifier.
  41    *
  42    * <p>Public identifiers must be normalized according to the following
  43    * rules before comparisons between them can be made:</p>
  44    *
  45    * <ul>
  46    * <li>Whitespace characters are normalized to spaces (e.g., line feeds,
  47    * tabs, etc. become spaces).</li>
  48    * <li>Leading and trailing whitespace is removed.</li>
  49    * <li>Multiple internal whitespaces are normalized to a single
  50    * space.</li>
  51    * </ul>
  52    *
  53    * <p>This method is declared static so that other classes
  54    * can use it directly.</p>
  55    *
  56    * @param publicId The unnormalized public identifier.
  57    *
  58    * @return The normalized identifier.
  59    */
  60   public static String normalize(String publicId) {
  61     String normal = publicId.replace('\t', ' ');
  62     normal = normal.replace('\r', ' ');
  63     normal = normal.replace('\n', ' ');
  64     normal = normal.trim();
  65 
  66     int pos;
  67 
  68     while ((pos = normal.indexOf("  ")) >= 0) {
  69       normal = normal.substring(0, pos) + normal.substring(pos+1);
  70     }
  71 
  72     return normal;
  73   }
  74 
  75   /**
  76    * Encode a public identifier as a "publicid" URN.
  77    *
  78    * <p>This method is declared static so that other classes
  79    * can use it directly.</p>
  80    *
  81    * @param publicId The unnormalized public identifier.
  82    *
  83    * @return The normalized identifier.
  84    */
  85   public static String encodeURN(String publicId) {
  86     String urn = PublicId.normalize(publicId);
  87 
  88     urn = PublicId.stringReplace(urn, "%", "%25");
  89     urn = PublicId.stringReplace(urn, ";", "%3B");
  90     urn = PublicId.stringReplace(urn, "'", "%27");
  91     urn = PublicId.stringReplace(urn, "?", "%3F");
  92     urn = PublicId.stringReplace(urn, "#", "%23");
  93     urn = PublicId.stringReplace(urn, "+", "%2B");
  94     urn = PublicId.stringReplace(urn, " ", "+");
  95     urn = PublicId.stringReplace(urn, "::", ";");
  96     urn = PublicId.stringReplace(urn, ":", "%3A");
  97     urn = PublicId.stringReplace(urn, "//", ":");
  98     urn = PublicId.stringReplace(urn, "/", "%2F");
  99 
 100     return "urn:publicid:" + urn;
 101   }
 102 
 103   /**
 104    * Decode a "publicid" URN into a public identifier.
 105    *
 106    * <p>This method is declared static so that other classes
 107    * can use it directly.</p>
 108    *
 109    * @param urn The urn:publicid: URN
 110    *
 111    * @return The normalized identifier.
 112    */
 113   public static String decodeURN(String urn) {
 114     String publicId = "";
 115 
 116     if (urn.startsWith("urn:publicid:")) {
 117       publicId = urn.substring(13);
 118     } else {
 119       return urn;
 120     }
 121 
 122     publicId = PublicId.stringReplace(publicId, "%2F", "/");
 123     publicId = PublicId.stringReplace(publicId, ":", "//");
 124     publicId = PublicId.stringReplace(publicId, "%3A", ":");
 125     publicId = PublicId.stringReplace(publicId, ";", "::");
 126     publicId = PublicId.stringReplace(publicId, "+", " ");
 127     publicId = PublicId.stringReplace(publicId, "%2B", "+");
 128     publicId = PublicId.stringReplace(publicId, "%23", "#");
 129     publicId = PublicId.stringReplace(publicId, "%3F", "?");
 130     publicId = PublicId.stringReplace(publicId, "%27", "'");
 131     publicId = PublicId.stringReplace(publicId, "%3B", ";");
 132     publicId = PublicId.stringReplace(publicId, "%25", "%");
 133 
 134     return publicId;
 135     }
 136 
 137   /**
 138    * Replace one string with another.
 139    *
 140    */
 141   private static String stringReplace(String str,
 142                                       String oldStr,
 143                                       String newStr) {
 144 
 145     String result = "";
 146     int pos = str.indexOf(oldStr);
 147 
 148     //    System.out.println(str + ": " + oldStr + " => " + newStr);
 149 
 150     while (pos >= 0) {
 151       //      System.out.println(str + " (" + pos + ")");
 152       result += str.substring(0, pos);
 153       result += newStr;
 154       str = str.substring(pos+1);
 155 
 156       pos = str.indexOf(oldStr);
 157     }
 158 
 159     return result + str;
 160   }
 161 }