Java/GWT/Utility

Материал из Java эксперт
Версия от 06:35, 1 июня 2010; Admin (обсуждение | вклад) (1 версия)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

Array Utils for client side GWT

/*
 * Copyright 2006 Robert Hanson <iamroberthanson AT gmail.ru>
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *    http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.gwtwidgets.client.util;
import com.google.gwt.core.client.JavaScriptObject;
public class ArrayUtils
{

    public static JavaScriptObject toJsArray (int[] array)
    {
        JavaScriptObject result = createArray();
        for (int i = 0; i < array.length; i++) {
            pushArray(result, array[i]);
        }
        return result;
    };

    public static JavaScriptObject toJsArray (double[] array)
    {
        JavaScriptObject result = createArray();
        for (int i = 0; i < array.length; i++) {
            pushArray(result, array[i]);
        }
        return result;
    };
    
    public static JavaScriptObject toJsArray (Object[] array)
    {
        JavaScriptObject result = createArray();
        for (int i = 0; i < array.length; i++) {
            pushArray(result, array[i]);
        }
        return result;
    };
    
    
    private native static JavaScriptObject createArray () /*-{
        return new Array();
    }-*/;
    private native static void pushArray (JavaScriptObject array, int i) /*-{
        array.push(i);
    }-*/;
    private native static void pushArray (JavaScriptObject array, double d) /*-{
        array.push(d);
    }-*/;
    private native static void pushArray (JavaScriptObject array, Object o) /*-{
        array.push(o);
    }-*/;
}





A simple number formatting/ parsing class

/*
 * Copyright 2006 Robert Hanson <iamroberthanson AT gmail.ru>
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *    http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.gwtwidgets.client.util;
/**
 * <dl>
 * <dt><b>Title: </b><dd>Decimal Format</dd>
 * <p>
 * <dt><b>Description: </b><dd>This is a simple number formatting/ parsing class. Besides the simple number formatting
 * it also interprets shortcuts for thousand (k) million (m) and billion (b).<p/>
 * This Number Format class was adapted from the public domain javascript class found at 
 * http://www.mredkj.ru/javascript/nfdocs.html </dd>
 * <p>
 * </dl>
 * @author 
 * @version $Revision: 0.0 $
 */
public class NumberFormat
{
    public static final String COMMA = ",";
    public static final String PERIOD = ".";
    public static final char DASH = "-";
    public static final char LEFT_PAREN = "(";
    public static final char RIGHT_PAREN = ")";
    // k/m/b Shortcuts
    public static final String THOUSAND = "k";
    public static final String MILLION = "m";
    public static final String BILLION = "b";
    
    // currency position constants
    public static final int CUR_POS_LEFT_OUTSIDE = 0;
    public static final int CUR_POS_LEFT_INSIDE = 1;
    public static final int CUR_POS_RIGHT_INSIDE = 2;
    public static final int CUR_POS_RIGHT_OUTSIDE = 3;
    // negative format constants
    public static final int NEG_LEFT_DASH = 0;
    public static final int NEG_RIGHT_DASH = 1;
    public static final int NEG_PARENTHESIS = 2;
    // constant to signal that fixed precision is not to be used
    public static final int ARBITRARY_PRECISION = -1;
    private String inputDecimalSeparator = PERIOD; // decimal character used on the original string
    private boolean showGrouping = true;
    private String groupingSeparator = COMMA; // thousands grouping character
    private String decimalSeparator = PERIOD; // decimal point character
    private boolean showCurrencySymbol = false;
    private String currencySymbol = "$";
    private int currencySymbolPosition = CUR_POS_LEFT_OUTSIDE;
    private int negativeFormat = NEG_LEFT_DASH;
    private boolean isNegativeRed = false; // wrap the output in html that will display red?
    private int decimalPrecision = 0;
    private boolean useFixedPrecision = false;
    private boolean truncate = false; // truncate to decimalPrecision rather than rounding? 
    private boolean isPercentage = false; // should the result be displayed as a percentage?
    private NumberFormat()
    {
    }
    /**
     * returns the default instance of NumberFormat
     * @return
     */
    public static NumberFormat getInstance ()
    {
        NumberFormat nf = new NumberFormat();
        return nf;
    }
    /**
     * Returns a currency instance of number format
     * @return
     */
    public static NumberFormat getCurrencyInstance ()
    {
        return getCurrencyInstance("$", true);
    }
    /**
     * Returns a currency instance of number format that uses curSymbol as the currency symbol
     * @param curSymbol
     * @return
     */
    public static NumberFormat getCurrencyInstance (String curSymbol)
    {
        return getCurrencyInstance(curSymbol, true);
    }
    /**
     * Returns a currency instance of number format that uses curSymbol as the currency symbol 
     * and either commas or periods as the thousands separator.
     * @param curSymbol Currency Symbol
     * @param useCommas true, uses commas as the thousands separator, false uses periods
     * @return
     */
    public static NumberFormat getCurrencyInstance (String curSymbol, boolean useCommas)
    {
        NumberFormat nf = new NumberFormat();
        nf.isCurrency(true);
        nf.setCurrencySymbol(curSymbol);
        if (!useCommas) {
            nf.setDecimalSeparator(COMMA);
            nf.setGroupingSeparator(PERIOD);
        }
        nf.setFixedPrecision(2);
        return nf;
    }
    /**
     * Returns an instance that formats numbers as integers.
     * @return
     */
    public static NumberFormat getIntegerInstance ()
    {
        NumberFormat nf = new NumberFormat();
        nf.setShowGrouping(false);
        nf.setFixedPrecision(0);
        return nf;
    }
    public static NumberFormat getPercentInstance ()
    {
        NumberFormat nf = new NumberFormat();
        nf.isPercentage(true);
        nf.setFixedPrecision(2);
        nf.setShowGrouping(false);
        return nf;
    }
    public String format (String num)
    {
        return toFormatted(parse(num));
    }
    public double parse (String num)
    {
        return asNumber(num, inputDecimalSeparator);
    }
    /**
     * Static routine that attempts to create a double out of the
     * supplied text. This routine is a bit smarter than Double.parseDouble()
     * @param num
     * @return
     */
    public static double parseDouble (String num, String decimalChar)
    {
        return asNumber(num, decimalChar);
    }
    public static double parseDouble (String num)
    {
        return parseDouble(num, PERIOD);
    }
    public void setInputDecimalSeparator (String val)
    {
        inputDecimalSeparator = val == null ? PERIOD : val;
    }
    public void setNegativeFormat (int format)
    {
        negativeFormat = format;
    }
    public void setNegativeRed (boolean isRed)
    {
        isNegativeRed = isRed;
    }
    public void setShowGrouping (boolean show)
    {
        showGrouping = show;
    }
    public void setDecimalSeparator (String separator)
    {
        decimalSeparator = separator;
    }
    public void setGroupingSeparator (String separator)
    {
        groupingSeparator = separator;
    }
    public void isCurrency (boolean isC)
    {
        showCurrencySymbol = isC;
    }
    public void setCurrencySymbol (String symbol)
    {
        currencySymbol = symbol;
    }
    public void setCurrencyPosition (int cp)
    {
        currencySymbolPosition = cp;
    }
    public void isPercentage (boolean pct)
    {
        isPercentage = pct;
    }
    /**
     * Sets the number of fixed precision decimal places should be displayed.
     * To use arbitrary precision, setFixedPrecision(NumberFormat.ARBITRARY_PRECISION)
     * @param places 
     */
    public void setFixedPrecision (int places)
    {
        useFixedPrecision = places != ARBITRARY_PRECISION;
        this.decimalPrecision = places < 0 ? 0 : places;
    }
    /**
     * Causes the number to be truncated rather than rounded to its fixed precision.
     * @param trunc
     */
    public void setTruncate (boolean trunc)
    {
        truncate = trunc;
    }
    /**
     * 
     * @param preSep raw number as text
     * @param PERIOD incoming decimal point
     * @param decimalSeparator outgoing decimal point
     * @param groupingSeparator thousands separator
     * @return
     */
    private String addSeparators (String preSep)
    {
        String nStr = preSep;
        int dpos = nStr.indexOf(PERIOD);
        String nStrEnd = "";
        if (dpos != -1) {
            nStrEnd = decimalSeparator + nStr.substring(dpos + 1, nStr.length());
            nStr = nStr.substring(0, dpos);
        }
        int l = nStr.length();
        for (int i = l; i > 0; i--) {
            nStrEnd = nStr.charAt(i - 1) + nStrEnd;
            if (i != 1 && ((l - i + 1) % 3) == 0) nStrEnd = groupingSeparator + nStrEnd;
        }
        return nStrEnd;
    }
    protected String toFormatted(double num)
    {
        String nStr;
        if (isPercentage) num = num * 100;
        nStr = useFixedPrecision ? toFixed(Math.abs(getRounded(num)), decimalPrecision) : Double.toString(num);
        nStr = showGrouping ? addSeparators(nStr) : nStr.replaceAll("\\" + PERIOD, decimalSeparator);
        String c0 = "";
        String n0 = "";
        String c1 = "";
        String n1 = "";
        String n2 = "";
        String c2 = "";
        String n3 = "";
        String c3 = "";
        String negSignL = "" + ((negativeFormat == NEG_PARENTHESIS) ? LEFT_PAREN : DASH);
        String negSignR = "" + ((negativeFormat == NEG_PARENTHESIS) ? RIGHT_PAREN : DASH);
        
        if (currencySymbolPosition == CUR_POS_LEFT_OUTSIDE) {
            if (num < 0) {
                if (negativeFormat == NEG_LEFT_DASH || negativeFormat == NEG_PARENTHESIS)
                    n1 = negSignL;
                if (negativeFormat == NEG_RIGHT_DASH || negativeFormat == NEG_PARENTHESIS)
                    n2 = negSignR;
            }
            if (showCurrencySymbol) c0 = currencySymbol;
        }
        else if (currencySymbolPosition == CUR_POS_LEFT_INSIDE) {
            if (num < 0) {
                if (negativeFormat == NEG_LEFT_DASH || negativeFormat == NEG_PARENTHESIS)
                    n0 = negSignL;
                if (negativeFormat == NEG_RIGHT_DASH || negativeFormat == NEG_PARENTHESIS)
                    n3 = negSignR;
            }
            if (showCurrencySymbol) c1 = currencySymbol;
        }
        else if (currencySymbolPosition == CUR_POS_RIGHT_INSIDE) {
            if (num < 0) {
                if (negativeFormat == NEG_LEFT_DASH || negativeFormat == NEG_PARENTHESIS)
                    n0 = negSignL;
                if (negativeFormat == NEG_RIGHT_DASH || negativeFormat == NEG_PARENTHESIS)
                    n3 = negSignR;
            }
            if (showCurrencySymbol) c2 = currencySymbol;
        }
        else if (currencySymbolPosition == CUR_POS_RIGHT_OUTSIDE) {
            if (num < 0) {
                if (negativeFormat == NEG_LEFT_DASH || negativeFormat == NEG_PARENTHESIS)
                    n1 = negSignL;
                if (negativeFormat == NEG_RIGHT_DASH || negativeFormat == NEG_PARENTHESIS)
                    n2 = negSignR;
            }
            if (showCurrencySymbol) c3 = currencySymbol;
        }
        nStr = c0 + n0 + c1 + n1 + nStr + n2 + c2 + n3 + c3 + (isPercentage ? "%" : "");
        if (isNegativeRed && num < 0) {
            nStr = "<font color="red">" + nStr + "</font>";
        }
        return nStr;
   }
    /**
     * javascript only rounds to whole numbers, so we need to shift our decimal right, 
     * then round, then shift the decimal back left.
     * @param val
     * @return
     */
    private double getRounded (double val)
    {
        double exp = Math.pow(10, decimalPrecision);
        double rounded = val * exp;
        if (truncate)
            rounded = rounded >= 0 ? Math.floor(rounded) : Math.ceil(rounded);
        else
            rounded = Math.round(rounded);
        return rounded / exp;
    }
    private static native String toFixed(double val, int places) /*-{
        return val.toFixed(places);
    }-*/;
    private static double asNumber(String val, String inputDecimalValue)
    {
        String newVal = val;
        boolean isPercentage = false;
        // remove % if there is one
        if (newVal.indexOf("%") != -1) {
            newVal = newVal.replaceAll("\\%", "");
            isPercentage = true;
        }
        // convert abbreviations for thousand, million and billion
        newVal = newVal.toLowerCase().replaceAll(BILLION, "000000000");
        newVal = newVal.replaceAll(MILLION, "000000");
        newVal = newVal.replaceAll(THOUSAND, "000");
        // remove any characters that are not digit, decimal separator, +, -, (, ), e, or E      
        String re = "[^\\" + inputDecimalValue + "\\d\\-\\+\\(\\)eE]";
        newVal = newVal.replaceAll(re, "");
        // ensure that the first decimal separator is a . and remove the rest.
        int index = newVal.indexOf(inputDecimalValue);
        if (index != -1) {
            newVal = newVal.substring(0, index)
                    + PERIOD
                    + (newVal.substring(index + inputDecimalValue.length()).replaceAll("\\"
                            + inputDecimalValue, ""));
        }
        // convert right dash and paren negatives to left dash negative
        if (newVal.charAt(newVal.length() - 1) == DASH) {
            newVal = newVal.substring(0, newVal.length() - 1);
            newVal = DASH + newVal;
        }
        else if (newVal.charAt(0) == LEFT_PAREN
                && newVal.charAt(newVal.length() - 1) == RIGHT_PAREN) {
            newVal = newVal.substring(1, newVal.length() - 1);
            newVal = DASH + newVal;
        }
        Double parsed;
        try {
            parsed = new Double(newVal);
            if (parsed.isInfinite() || parsed.isNaN()) parsed = new Double(0);
        }
        catch (NumberFormatException e) {
            parsed = new Double(0);
        }
        return isPercentage ? parsed.doubleValue() / 100 : parsed.doubleValue();
    }
}





GWT color class

/*
 * Copyright 2006 Robert Hanson <iamroberthanson AT gmail.ru>
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *    http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.gwtwidgets.client.style;
/**
 * This class is under consideration for removal,
 * if you have an opion please comment on http://gwtwidgets.blogspot.ru.
 */
public class Color
{
    public final static Color WHITE = new Color(255, 255, 255);
    public final static Color LIGHT_GRAY = new Color(192, 192, 192);
    public final static Color GRAY = new Color(128, 128, 128);
    public final static Color DARK_GRAY = new Color(64, 64, 64);
    public final static Color BLACK = new Color(0, 0, 0);
    public final static Color RED = new Color(255, 0, 0);
    public final static Color PINK = new Color(255, 175, 175);
    public final static Color ORANGE = new Color(255, 200, 0);
    public final static Color YELLOW = new Color(255, 255, 0);
    public final static Color GREEN = new Color(0, 255, 0);
    public final static Color MAGENTA = new Color(255, 0, 255);
    public final static Color CYAN = new Color(0, 255, 255);
    public final static Color BLUE = new Color(0, 0, 255);
    public static final Color NONE = new Color("");
    
    private int r, g, b;
    
    // only for special cases, like no color, or maybe named colors
    private String colorText = null;
    private Color (String colorText) {
        this.colorText = colorText;
    }
    public Color (int r, int g, int b)
    {
        this.r = r;
        this.g = g;
        this.b = b;
    }
    public int getRed ()
    {
        return r;
    }
    public int getGreen ()
    {
        return g;
    }
    public int getBlue ()
    {
        return b;
    }
    public String getHexValue ()
    {
        if (colorText != null) {
            return colorText;
        }
        return "#"
            + pad(Integer.toHexString(r))
            + pad(Integer.toHexString(g))
            + pad(Integer.toHexString(b));
    }
    private String pad (String in)
    {
        if (in.length() == 0) {
            return "00";
        }
        if (in.length() == 1) {
            return "0" + in;
        }
        return in;
    }
    public String toString ()
    {
        if (colorText != null) {
            return colorText;
        }
        return "red=" + r + ", green=" + g + ", blue=" + b;
    }
}





GWT window utility

/*
 * Copyright 2006 Robert Hanson <iamroberthanson AT gmail.ru>
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *    http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.gwtwidgets.client.util;
public class WindowUtils
{
    public static Location getLocation ()
    {
        Location result = new Location();
        result.setHash(getHash());
        result.setHost(getHost());
        result.setHostName(getHostName());
        result.setHref(getHref());
        result.setPath(getPath());
        result.setPort(getPort());
        result.setProtocol(getProtocol());
        result.setQueryString(getQueryString());
        return result;
    }
    private static native String getQueryString () /*-{
        return $wnd.location.search;
    }-*/;
    private static native String getProtocol () /*-{
        return $wnd.location.protocol;
    }-*/;
    private static native String getPort () /*-{
        return $wnd.location.port;
    }-*/;
    private static native String getPath () /*-{
        return $wnd.location.pathname;
    }-*/;
    private static native String getHref () /*-{
        return $wnd.location.href;
    }-*/;
    private static native String getHostName () /*-{
        return $wnd.location.hostname;
    }-*/;
    private static native String getHost () /*-{
        return $wnd.location.host;
    }-*/;
    private static native String getHash () /*-{
        return $wnd.location.hash;
    }-*/;
    
}
/////////////////////////////////
/*
 * Copyright 2006 Robert Hanson <iamroberthanson AT gmail.ru>
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *    http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.gwtwidgets.client.util;
import java.util.HashMap;
import java.util.Map;
public class Location
{
    private String hash;
    private String host;
    private String hostName;
    private String href;
    private String path;
    private String port;
    private String protocol;
    private String queryString;
    private HashMap paramMap;

    public String getHash ()
    {
        return hash;
    }
    public String getHost ()
    {
        return host;
    }
    public String getHostName ()
    {
        return hostName;
    }
    public String getHref ()
    {
        return href;
    }
    public String getPath ()
    {
        return path;
    }
    public String getPort ()
    {
        return port;
    }
    public String getProtocol ()
    {
        return protocol;
    }
    public String getQueryString ()
    {
        return queryString;
    }
    protected void setHash (String hash)
    {
        this.hash = hash;
    }
    protected void setHost (String host)
    {
        this.host = host;
    }
    protected void setHostName (String hostName)
    {
        this.hostName = hostName;
    }
    protected void setHref (String href)
    {
        this.href = href;
    }
    protected void setPath (String path)
    {
        this.path = path;
    }
    protected void setPort (String port)
    {
        this.port = port;
    }
    protected void setProtocol (String protocol)
    {
        this.protocol = protocol;
    }
    protected void setQueryString (String queryString)
    {
        this.queryString = queryString;
        paramMap = new HashMap();
        
        if (queryString != null && queryString.length() > 1) {
            String qs = queryString.substring(1);
            String[] kvPairs = qs.split("&");
            for (int i = 0; i < kvPairs.length; i++) {
                String[] kv = kvPairs[i].split("=");
                if (kv.length > 1) {
                    paramMap.put(kv[0], unescape(kv[1]));
                }
                else {
                    paramMap.put(kv[0], "");
                }
            }
        }
    }
    
    private native String unescape (String val) /*-{
        return unescape(val);
    }-*/;
    public String getParameter (String name)
    {
        return (String) paramMap.get(name);
    }
    public Map getParameterMap ()
    {
        return paramMap;
    }
}





Implement java.util.regex.Pattern with Javascript RegExp object

/*
 * Copyright 2006 Robert Hanson <iamroberthanson AT gmail.ru>
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *    http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.gwtwidgets.client.util.regex;
import java.util.ArrayList;
import java.util.List;
import com.google.gwt.core.client.JavaScriptObject;
/**
 * <p>
 * Implementation of the {@link java.util.regex.Pattern} class with a
 * wrapper aroung the Javascript  object.
 * As most of the methods delegate to the JavaScript RegExp object, certain differences in the 
 * declaration and behaviour of regular expressions must be expected.
 * </p>
 * <p>
 * Please note that neither the {@link java.util.regex.Pattern#compile(String)} method nor
 * {@link Matcher} instances are supported. For the later, consider using {@link Pattern#match(String)}.
 * </p>
 * 
 * @author George Georgovassilis
 *
 */
public class Pattern {
  /**
   * Declares that regular expressions should be matched across line borders.
   */
  public final static int MULTILINE = 1;
  /**
   * Declares that characters are matched reglardless of case.
   */
  public final static int CASE_INSENSITIVE = 2;
  private JavaScriptObject regExp;
  private static JavaScriptObject createExpression(String pattern, int flags) {
    String sFlags = "";
    if ((flags & MULTILINE) != 0)
      sFlags += "m";
    if ((flags & CASE_INSENSITIVE) != 0)
      sFlags += "i";
    return _createExpression(pattern, sFlags);
  }
  private static native JavaScriptObject _createExpression(String pattern,
      String flags)/*-{
   return new RegExp(pattern, flags);
   }-*/;
  private native void _match(String text, List matches)/*-{
   var regExp = this.@org.gwtwidgets.client.util.regex.Pattern::regExp;
   var result = text.match(regExp);
   if (result == null) return;
   for (var i=0;i<result.length;i++)
   matches.@java.util.ArrayList::add(Ljava/lang/Object;)(result[i]);
   }-*/;
  /**
   * Determines wether the specified regular expression is validated by the 
   * provided input.
   * @param regex Regular expression
   * @param input String to validate
   * @return <code>true</code> if matched.
   */
  public static boolean matches(String regex, String input) {
    return new Pattern(regex).matches(input);
  }
  /**
   * Escape a provided string so that it will be interpreted as a literal
   * in regular expressions.
   * The current implementation does escape each character even if not neccessary,
   * generating verbose literals.
   * @param input
   * @return
   */
  public static String quote(String input) {
    String output = "";
    for (int i = 0; i < input.length(); i++) {
      output += "\\" + input.charAt(i);
    }
    return output;
  }
  /**
   * Class constructor
   * @param pattern Regular expression
   */
  public Pattern(String pattern) {
    this(pattern, 0);
  }
  /**
   * Class constructor
   * @param pattern Regular expression
   * @param flags 
   */
  public Pattern(String pattern, int flags) {
    regExp = createExpression(pattern, flags);
  }
  /**
   * This method is borrowed from the JavaScript RegExp object.
   * It parses a string and returns as an array any assignments to parenthesis groups
   * in the pattern"s regular expression
   * @param text
   * @return Array of strings following java"s Pattern convention for groups:
   * Group 0 is the entire input string and the remaining groups are the matched parenthesis.
   * In case nothing was matched an empty array is returned.
   */
  public String[] match(String text) {
    List matches = new ArrayList();
    _match(text, matches);
    String arr[] = new String[matches.size()];
    for (int i = 0; i < matches.size(); i++)
      arr[i] = matches.get(i).toString();
    return arr;
  }
  /**
   * Determines wether a provided text matches the regular expression
   * @param text
   * @return
   */
  public native boolean matches(String text)/*-{
   var regExp = this.@org.gwtwidgets.client.util.regex.Pattern::regExp;
   return regExp.test(text);
   }-*/;
  /**
   * Returns the regular expression for this pattern
   * @return
   */
  public native String pattern()/*-{
   var regExp = this.@org.gwtwidgets.client.util.regex.Pattern::regExp;
   return regExp.source;
   }-*/;
  private native void _split(String input, List results)/*-{
   var regExp = this.@org.gwtwidgets.client.util.regex.Pattern::regExp;
   var parts = input.split(regExp);
   for (var i=0;i<parts.length;i++)
   results.@java.util.ArrayList::add(Ljava/lang/Object;)(parts[i]  );
   }-*/;
  
  /**
   * Split an input string by the pattern"s regular expression
   * @param input
   * @return Array of strings
   */
  public String[] split(String input){
    List results = new ArrayList(); 
    _split(input, results);
    String[] parts = new String[results.size()];
    for (int i=0;i<results.size();i++)
      parts[i] = (String)results.get(i);
    return parts;
  }
}





Use reflection to generate the async interface from the Service interface as per GWT standard

package org.drools.brms.gwtutil;
/*
 * Copyright 2005 JBoss Inc
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import java.lang.reflect.Method;
import org.drools.brms.client.rpc.RepositoryService;
/**
 * This utility uses reflection to generate the async interface from the 
 * Service interface as per GWT standard.
 * 
 * @author Michael Neale
 */
public class AsyncInterfaceGenerator {
    public static void main(String[] args) throws Exception {
        Class cls = RepositoryService.class;
        String line = "";
        Method[] methods = cls.getMethods();
        for ( int i = 0; i < methods.length; i++ ) {
            Method meth = methods[i];
            if (meth.getDeclaringClass() == cls) {
                line += "public void " + meth.getName() + "(";
                Class params[] = meth.getParameterTypes();
                for ( int j = 0; j < params.length; j++ ) {
                    String type = params[j].getName();
                    if (type.equals( "[Ljava.lang.String;" )) {
                        type = "String[]";
                    }
                    line += type;
                    line += " p" + j;
                    if (j < params.length -1) {
                        line += ", ";
                    }
                }
                if (line.endsWith( "(" )) {
                    line += "AsyncCallback cb";
                } else {
                    line += ", AsyncCallback cb";
                }
                line += ");\n";
            }
        }
        System.out.println("/** Generated by AsyncInterfaceGenerator hackery */");
        System.out.println(line);
    }
}