3253-omnibus save
[jalview.git] / src / jalview / util / StringUtils.java
index 2cbbfbf..a05dc95 100644 (file)
@@ -20,6 +20,8 @@
  */
 package jalview.util;
 
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.regex.Pattern;
@@ -29,8 +31,16 @@ public class StringUtils
   private static final Pattern DELIMITERS_PATTERN = Pattern
           .compile(".*='[^']*(?!')");
 
+  private static final char PERCENT = '%';
+
   private static final boolean DEBUG = false;
 
+  /*
+   * URL encoded characters, indexed by char value
+   * e.g. urlEncodings['='] = urlEncodings[61] = "%3D"
+   */
+  private static String[] urlEncodings = new String[255];
+
   /**
    * Returns a new character array, after inserting characters into the given
    * character array.
@@ -446,8 +456,66 @@ public class StringUtils
   }
 
   /**
-   * Answers true if the string is not empty and consists only of digits, or
-   * characters 'a'-'f' or 'A'-'F', else false
+   * Answers the input string with any occurrences of the 'encodeable' characters
+   * replaced by their URL encoding
+   * 
+   * @param s
+   * @param encodable
+   * @return
+   */
+  public static String urlEncode(String s, String encodable)
+  {
+    if (s == null || s.isEmpty())
+    {
+      return s;
+    }
+
+    /*
+     * do % encoding first, as otherwise it may double-encode!
+     */
+    if (encodable.indexOf(PERCENT) != -1)
+    {
+      s = urlEncode(s, PERCENT);
+    }
+
+    for (char c : encodable.toCharArray())
+    {
+      if (c != PERCENT)
+      {
+        s = urlEncode(s, c);
+      }
+    }
+    return s;
+  }
+
+  /**
+   * Answers the input string with any occurrences of {@code c} replaced with
+   * their url encoding. Answers the input string if it is unchanged.
+   * 
+   * @param s
+   * @param c
+   * @return
+   */
+  static String urlEncode(String s, char c)
+  {
+    String decoded = String.valueOf(c);
+    if (s.indexOf(decoded) != -1)
+    {
+      String encoded = getUrlEncoding(c);
+      if (!encoded.equals(decoded))
+      {
+        s = s.replace(decoded, encoded);
+      }
+    }
+    return s;
+  }
+
+  /**
+   * Answers the input string with any occurrences of the specified (unencoded)
+   * characters replaced by their URL decoding.
+   * <p>
+   * Example: {@code urlDecode("a%3Db%3Bc", "-;=,")} should answer
+   * {@code "a=b;c"}.
    * 
    * @param s
    * @return
@@ -470,4 +538,64 @@ public class StringUtils
     }
     return true;
   }
+  /**
+   * Answers the input string with any occurrences of the specified (unencoded)
+   * characters replaced by their URL decoding.
+   * <p>
+   * Example: {@code urlDecode("a%3Db%3Bc", "-;=,")} should answer
+   * {@code "a=b;c"}.
+   * 
+   * @param s
+   * @param encodable
+   * @return
+   */
+  public static String urlDecode(String s, String encodable)
+  {
+    if (s == null || s.isEmpty())
+    {
+      return s;
+    }
+
+    for (char c : encodable.toCharArray())
+    {
+      String encoded = getUrlEncoding(c);
+      if (s.indexOf(encoded) != -1)
+      {
+        String decoded = String.valueOf(c);
+        s = s.replace(encoded, decoded);
+      }
+    }
+    return s;
+  }
+
+  /**
+  * Does a lazy lookup of the url encoding of the given character, saving the
+  * value for repeat lookups
+  * 
+  * @param c
+  * @return
+  */
+ private static String getUrlEncoding(char c)
+ {
+   if (c < 0 || c >= urlEncodings.length)
+   {
+     return String.valueOf(c);
+   }
+
+   String enc = urlEncodings[c];
+   if (enc == null)
+   {
+     try
+     {
+       enc = urlEncodings[c] = URLEncoder.encode(String.valueOf(c),
+               "UTF-8");
+     } catch (UnsupportedEncodingException e)
+     {
+       enc = urlEncodings[c] = String.valueOf(c);
+     }
+   }
+   return enc;
+ }
+
+  
 }