You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commons-cvs@xml.apache.org by mr...@apache.org on 2008/11/09 04:53:13 UTC

svn commit: r712469 - /xml/commons/trunk/java/src/org/apache/xml/resolver/helpers/PublicId.java

Author: mrglavas
Date: Sat Nov  8 19:53:13 2008
New Revision: 712469

URL: http://svn.apache.org/viewvc?rev=712469&view=rev
Log:
Improving the performance of decodeURN(). It was creating many temporary objects
(new Strings and StringBuffers). Looks like it's about 4x faster when the input
does not contain any escape sequences. In reworking the code I also fixed a bug.
If the string to replace was an escape sequence only the '%' was getting replaced.
This was due to an assumption that the length of the string to replace was always 1.

Modified:
    xml/commons/trunk/java/src/org/apache/xml/resolver/helpers/PublicId.java

Modified: xml/commons/trunk/java/src/org/apache/xml/resolver/helpers/PublicId.java
URL: http://svn.apache.org/viewvc/xml/commons/trunk/java/src/org/apache/xml/resolver/helpers/PublicId.java?rev=712469&r1=712468&r2=712469&view=diff
==============================================================================
--- xml/commons/trunk/java/src/org/apache/xml/resolver/helpers/PublicId.java (original)
+++ xml/commons/trunk/java/src/org/apache/xml/resolver/helpers/PublicId.java Sat Nov  8 19:53:13 2008
@@ -31,7 +31,8 @@
  * @version 1.0
  */
 public abstract class PublicId {
-  protected PublicId() { }
+    
+  protected PublicId() {}
 
   /**
    * Normalize a public identifier.
@@ -55,18 +56,17 @@
    * @return The normalized identifier.
    */
   public static String normalize(String publicId) {
-    String normal = publicId.replace('\t', ' ');
-    normal = normal.replace('\r', ' ');
-    normal = normal.replace('\n', ' ');
-    normal = normal.trim();
-
-    int pos;
-
-    while ((pos = normal.indexOf("  ")) >= 0) {
-      normal = normal.substring(0, pos) + normal.substring(pos+1);
-    }
-
-    return normal;
+      String normal = publicId.replace('\t', ' ');
+      normal = normal.replace('\r', ' ');
+      normal = normal.replace('\n', ' ');
+      normal = normal.trim();
+
+      int pos;
+
+      while ((pos = normal.indexOf("  ")) >= 0) {
+          normal = normal.substring(0, pos) + normal.substring(pos+1);
+      }
+      return normal;
   }
 
   /**
@@ -80,21 +80,24 @@
    * @return The normalized identifier.
    */
   public static String encodeURN(String publicId) {
-    String urn = PublicId.normalize(publicId);
-
-    urn = PublicId.stringReplace(urn, "%", "%25");
-    urn = PublicId.stringReplace(urn, ";", "%3B");
-    urn = PublicId.stringReplace(urn, "'", "%27");
-    urn = PublicId.stringReplace(urn, "?", "%3F");
-    urn = PublicId.stringReplace(urn, "#", "%23");
-    urn = PublicId.stringReplace(urn, "+", "%2B");
-    urn = PublicId.stringReplace(urn, " ", "+");
-    urn = PublicId.stringReplace(urn, "::", ";");
-    urn = PublicId.stringReplace(urn, ":", "%3A");
-    urn = PublicId.stringReplace(urn, "//", ":");
-    urn = PublicId.stringReplace(urn, "/", "%2F");
+      String urn = PublicId.normalize(publicId);
 
-    return "urn:publicid:" + urn;
+      urn = PublicId.stringReplace(urn, "%", "%25");
+      urn = PublicId.stringReplace(urn, ";", "%3B");
+      urn = PublicId.stringReplace(urn, "'", "%27");
+      urn = PublicId.stringReplace(urn, "?", "%3F");
+      urn = PublicId.stringReplace(urn, "#", "%23");
+      urn = PublicId.stringReplace(urn, "+", "%2B");
+      urn = PublicId.stringReplace(urn, " ", "+");
+      urn = PublicId.stringReplace(urn, "::", ";");
+      urn = PublicId.stringReplace(urn, ":", "%3A");
+      urn = PublicId.stringReplace(urn, "//", ":");
+      urn = PublicId.stringReplace(urn, "/", "%2F");
+      
+      StringBuffer buffer = new StringBuffer(13 + urn.length());
+      buffer.append("urn:publicid:");
+      buffer.append(urn);
+      return buffer.toString();
   }
 
   /**
@@ -108,51 +111,62 @@
    * @return The normalized identifier.
    */
   public static String decodeURN(String urn) {
-    String publicId = "";
-
-    if (urn.startsWith("urn:publicid:")) {
-      publicId = urn.substring(13);
-    } else {
-      return urn;
-    }
-
-    publicId = PublicId.stringReplace(publicId, "%2F", "/");
-    publicId = PublicId.stringReplace(publicId, ":", "//");
-    publicId = PublicId.stringReplace(publicId, "%3A", ":");
-    publicId = PublicId.stringReplace(publicId, ";", "::");
-    publicId = PublicId.stringReplace(publicId, "+", " ");
-    publicId = PublicId.stringReplace(publicId, "%2B", "+");
-    publicId = PublicId.stringReplace(publicId, "%23", "#");
-    publicId = PublicId.stringReplace(publicId, "%3F", "?");
-    publicId = PublicId.stringReplace(publicId, "%27", "'");
-    publicId = PublicId.stringReplace(publicId, "%3B", ";");
-    publicId = PublicId.stringReplace(publicId, "%25", "%");
-
-    return publicId;
-    }
+      String publicId;
+      if (urn.startsWith("urn:publicid:")) {
+          publicId = urn.substring(13);
+      } 
+      else {
+          return urn;
+      }
+      
+      final boolean hasEscape = (publicId.indexOf('%') >= 0);
+      if (hasEscape) {
+          publicId = PublicId.stringReplace(publicId, "%2F", "/");
+      }
+      publicId = PublicId.stringReplace(publicId, ":", "//");
+      if (hasEscape) {
+          publicId = PublicId.stringReplace(publicId, "%3A", ":");
+      }
+      publicId = PublicId.stringReplace(publicId, ";", "::");
+      publicId = PublicId.stringReplace(publicId, "+", " ");
+      if (hasEscape) {
+          publicId = PublicId.stringReplace(publicId, "%2B", "+");
+          publicId = PublicId.stringReplace(publicId, "%23", "#");
+          publicId = PublicId.stringReplace(publicId, "%3F", "?");
+          publicId = PublicId.stringReplace(publicId, "%27", "'");
+          publicId = PublicId.stringReplace(publicId, "%3B", ";");
+          publicId = PublicId.stringReplace(publicId, "%25", "%");
+      }
+      
+      return publicId;
+  }
 
   /**
    * Replace one string with another.
-   *
    */
   private static String stringReplace(String str,
-				      String oldStr,
-				      String newStr) {
-
-    String result = "";
-    int pos = str.indexOf(oldStr);
-
-    //    System.out.println(str + ": " + oldStr + " => " + newStr);
-
-    while (pos >= 0) {
-      //      System.out.println(str + " (" + pos + ")");
-      result += str.substring(0, pos);
-      result += newStr;
-      str = str.substring(pos+1);
-
-      pos = str.indexOf(oldStr);
-    }
-
-    return result + str;
+          String oldStr,
+          String newStr) {
+      int pos = str.indexOf(oldStr);
+      if (pos >= 0) {
+          final StringBuffer buffer = new StringBuffer();
+          final int oldStrLength = oldStr.length();
+          int start = 0;
+          do {
+              for (int i = start; i < pos; ++i) {
+                  buffer.append(str.charAt(i));
+              }
+              buffer.append(newStr);
+              start = pos + oldStrLength;
+              pos = str.indexOf(oldStr, start);
+          } 
+          while (pos >= 0);
+          final int strLength = str.length();
+          for (int i = start; i < strLength; ++i) {
+              buffer.append(str.charAt(i));
+          }
+          return buffer.toString();
+      }
+      return str;
   }
 }