/*
 * Created on 02-Feb-2006
 */
package uk.org.ponder.stringutil;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Map;
import java.util.StringTokenizer;

import uk.org.ponder.util.Logger;
import uk.org.ponder.util.UniversalRuntimeException;

/** Utilities for operating on URLs */

public class URLUtil {
  
  public static boolean isAbsolute(String url) {
    if (url.startsWith("javascript:") || url.startsWith("mailto:") || url.startsWith("file:")) 
        return true;
    int protpos = url.indexOf("://");
    if (protpos == -1) return false;
    for (int i = 0; i < protpos; ++ i) {
      if (!Character.isLetterOrDigit(url.charAt(i))) return false;
    }
    return true;
  }
  /** Append the supplied name/value pair to the end of the supplied URL, 
   * after URLencoding name and value.
   */
  
  public static String appendAttribute(String url, String name, String value) {
    CharWrap togo = new CharWrap(url);
    int qpos = url.indexOf('?');
    appendAttribute(togo, qpos == -1, name, value);
    return togo.toString();
  }

  /** Append the supplied name/value pair to the end of the supplied URL, 
   * after URLencoding name and value. The attribute will use the ? or &amp; 
   * character according to whether <code>isfirst</code> is true or false.
   */
  
  public static void appendAttribute(CharWrap togo, boolean isfirst, String name, String value) {
    togo.append(isfirst ? '?' : '&');
    togo.append(URLEncoder.encode(name));
    togo.append("=");
    togo.append(URLEncoder.encode(value));
  }
  
  /** Convert list of URL-form name/value pairs into a Map representation */
  // TODO: backport vector values code
  public static Map paramsToMap(String extraparams,
        Map target) {
      if (Logger.log.isDebugEnabled()) {
        Logger.log
          .debug("Action link requires extra parameters from " + extraparams);
      }
      StringTokenizer st = new StringTokenizer(extraparams, "&");
      while (st.hasMoreTokens()) {
        String token = st.nextToken();
        int eqpos = token.indexOf("=");
        String key = decodeURL(token.substring(0, eqpos));
        String value = decodeURL(token.substring(eqpos + 1));
        target.put(key, value);
      }
      return target;
    }

  public static String[] splitPathInfo(String pathinfo) {
    return pathinfo.split("/");
  }

  /** Decodes a URL assuming UTF-8, and wrapping any tedious exceptions */
  public static String decodeURL(String url) {
    try {
      return URLDecoder.decode(url, "UTF-8");
    }
    catch (UnsupportedEncodingException e) {
      throw UniversalRuntimeException.accumulate(e, "Error decoding URL " + 
          url + " using UTF-8");
    }
  }
  
  /** URL-encodes only the whitespace characters in a URL (necessary for some
   * faulty incomplete encodings).
   */
  
  public static String deSpace(String URL) {   
    CharWrap togo = new CharWrap(URL.length());
    for (int i = 0; i < URL.length(); ++ i) {
      char c = URL.charAt(i);
      if (Character.isWhitespace(c)) {
        URLEncoder.appendURLHex(c, togo);
      }
      else togo.append(c);
    }
    return togo.toString();
  }
  
}

@@ -191,16 +191,58 @@
 nizer;%0A%0A
+import uk.org.ponder.arrayutil.ArrayUtil;%0A
 import u
@@ -2382,40 +2382,488 @@
     
-return pathinfo.split(%22/%22);%0A  %7D%0A
+String%5B%5D togo = pathinfo.split(%22/%22);%0A    if (togo.length %3E 0 && togo%5B0%5D.equals(%22%22)) %7B%0A      togo = (String%5B%5D) ArrayUtil.subArray(togo, 1, togo.length);%0A    %7D%0A    return togo;%0A  %7D%0A  %0A  /** Convert a pathinfo array into an array of segments **/%0A  public static String toPathInfo(String%5B%5D paths) %7B%0A    CharWrap togo = new CharWrap(%22/%22);%0A    for (int i = 0; i %3C paths.length; ++ i) %7B%0A      togo.append(URLEncoder.encode(paths%5Bi%5D)).append(%22/%22);%0A    %7D%0A    return togo.toString();%0A  %7D%0A  
 %0A  /

Fix for Eng issue RSF-100 - unusual characters in pathinfo. RawURLState and all others now have pathinfo -> String[] ViewIDInferrer also refactored