1.1 --- a/rt/emul/mini/src/main/java/java/lang/String.java Fri Apr 25 08:14:12 2014 +0200
1.2 +++ b/rt/emul/mini/src/main/java/java/lang/String.java Wed Apr 30 15:04:10 2014 +0200
1.3 @@ -26,7 +26,10 @@
1.4 package java.lang;
1.5
1.6 import java.io.UnsupportedEncodingException;
1.7 +import java.lang.reflect.InvocationTargetException;
1.8 +import java.lang.reflect.Method;
1.9 import java.util.Comparator;
1.10 +import java.util.Locale;
1.11 import org.apidesign.bck2brwsr.core.ExtraJavaScript;
1.12 import org.apidesign.bck2brwsr.core.JavaScriptBody;
1.13 import org.apidesign.bck2brwsr.core.JavaScriptOnly;
1.14 @@ -2097,13 +2100,31 @@
1.15 * @since 1.4
1.16 * @spec JSR-51
1.17 */
1.18 + public boolean matches(String regex) {
1.19 + try {
1.20 + return matchesViaJS(regex);
1.21 + } catch (Throwable t) {
1.22 + // fallback to classical behavior
1.23 + try {
1.24 + Method m = Class.forName("java.util.regex.Pattern").getMethod("matches", String.class, CharSequence.class);
1.25 + return (Boolean)m.invoke(null, regex, this);
1.26 + } catch (InvocationTargetException ex) {
1.27 + if (ex.getTargetException() instanceof RuntimeException) {
1.28 + throw (RuntimeException)ex.getTargetException();
1.29 + }
1.30 + } catch (Throwable another) {
1.31 + // will report the old one
1.32 + }
1.33 + throw new RuntimeException(t);
1.34 + }
1.35 + }
1.36 @JavaScriptBody(args = { "regex" }, body =
1.37 "var self = this.toString();\n"
1.38 + "var re = new RegExp(regex.toString());\n"
1.39 + "var r = re.exec(self);\n"
1.40 + "return r != null && r.length > 0 && self.length == r[0].length;"
1.41 )
1.42 - public boolean matches(String regex) {
1.43 + private boolean matchesViaJS(String regex) {
1.44 throw new UnsupportedOperationException();
1.45 }
1.46
1.47 @@ -2159,6 +2180,14 @@
1.48 * @since 1.4
1.49 * @spec JSR-51
1.50 */
1.51 + @JavaScriptBody(args = { "regex", "newText" }, body =
1.52 + "var self = this.toString();\n"
1.53 + + "var re = new RegExp(regex.toString());\n"
1.54 + + "var r = re.exec(self);\n"
1.55 + + "if (r === null || r.length === 0) return this;\n"
1.56 + + "var from = self.indexOf(r[0]);\n"
1.57 + + "return this.substring(0, from) + newText + this.substring(from + r[0].length);\n"
1.58 + )
1.59 public String replaceFirst(String regex, String replacement) {
1.60 throw new UnsupportedOperationException();
1.61 }
1.62 @@ -2203,7 +2232,14 @@
1.63 * @spec JSR-51
1.64 */
1.65 public String replaceAll(String regex, String replacement) {
1.66 - throw new UnsupportedOperationException();
1.67 + String p = this;
1.68 + for (;;) {
1.69 + String n = p.replaceFirst(regex, replacement);
1.70 + if (n == p) {
1.71 + return n;
1.72 + }
1.73 + p = n;
1.74 + }
1.75 }
1.76
1.77 /**
1.78 @@ -2224,12 +2260,14 @@
1.79 "var s = this.toString();\n"
1.80 + "target = target.toString();\n"
1.81 + "replacement = replacement.toString();\n"
1.82 + + "var pos = 0;\n"
1.83 + "for (;;) {\n"
1.84 - + " var ret = s.replace(target, replacement);\n"
1.85 - + " if (ret === s) {\n"
1.86 - + " return ret;\n"
1.87 + + " var indx = s.indexOf(target, pos);\n"
1.88 + + " if (indx === -1) {\n"
1.89 + + " return s;\n"
1.90 + " }\n"
1.91 - + " s = ret;\n"
1.92 + + " pos = indx + replacement.length;\n"
1.93 + + " s = s.substring(0, indx) + replacement + s.substring(indx + target.length);\n"
1.94 + "}"
1.95 )
1.96 public native String replace(CharSequence target, CharSequence replacement);
1.97 @@ -2315,8 +2353,35 @@
1.98 * @spec JSR-51
1.99 */
1.100 public String[] split(String regex, int limit) {
1.101 - throw new UnsupportedOperationException("Needs regexp");
1.102 + if (limit <= 0) {
1.103 + Object[] arr = splitImpl(this, regex, Integer.MAX_VALUE);
1.104 + int to = arr.length;
1.105 + if (limit == 0 && to > 0) {
1.106 + while (to > 0 && ((String)arr[--to]).isEmpty()) {
1.107 + }
1.108 + to++;
1.109 + }
1.110 + String[] ret = new String[to];
1.111 + System.arraycopy(arr, 0, ret, 0, to);
1.112 + return ret;
1.113 + } else {
1.114 + Object[] arr = splitImpl(this, regex, limit);
1.115 + String[] ret = new String[arr.length];
1.116 + int pos = 0;
1.117 + for (int i = 0; i < arr.length; i++) {
1.118 + final String s = (String)arr[i];
1.119 + ret[i] = s;
1.120 + pos = indexOf(s, pos) + s.length();
1.121 + }
1.122 + ret[arr.length - 1] += substring(pos);
1.123 + return ret;
1.124 + }
1.125 }
1.126 +
1.127 + @JavaScriptBody(args = { "str", "regex", "limit"}, body =
1.128 + "return str.split(new RegExp(regex), limit);"
1.129 + )
1.130 + private static native Object[] splitImpl(String str, String regex, int limit);
1.131
1.132 /**
1.133 * Splits this string around matches of the given <a
1.134 @@ -2412,7 +2477,9 @@
1.135 * @see java.lang.String#toUpperCase(Locale)
1.136 * @since 1.1
1.137 */
1.138 -// public String toLowerCase(Locale locale) {
1.139 + public String toLowerCase(java.util.Locale locale) {
1.140 + return toLowerCase();
1.141 + }
1.142 // if (locale == null) {
1.143 // throw new NullPointerException();
1.144 // }
1.145 @@ -2527,7 +2594,7 @@
1.146 */
1.147 @JavaScriptBody(args = {}, body = "return this.toLowerCase();")
1.148 public String toLowerCase() {
1.149 - throw new UnsupportedOperationException("Should be supported but without connection to locale");
1.150 + return null;
1.151 }
1.152
1.153 /**
1.154 @@ -2578,8 +2645,10 @@
1.155 * @see java.lang.String#toLowerCase(Locale)
1.156 * @since 1.1
1.157 */
1.158 + public String toUpperCase(Locale locale) {
1.159 + return toUpperCase();
1.160 + }
1.161 /* not for javascript
1.162 - public String toUpperCase(Locale locale) {
1.163 if (locale == null) {
1.164 throw new NullPointerException();
1.165 }
1.166 @@ -2693,7 +2762,7 @@
1.167 */
1.168 @JavaScriptBody(args = {}, body = "return this.toUpperCase();")
1.169 public String toUpperCase() {
1.170 - throw new UnsupportedOperationException();
1.171 + return null;
1.172 }
1.173
1.174 /**
1.175 @@ -2804,7 +2873,7 @@
1.176 * @since 1.5
1.177 */
1.178 public static String format(String format, Object ... args) {
1.179 - throw new UnsupportedOperationException();
1.180 + return format((Locale)null, format, args);
1.181 }
1.182
1.183 /**
1.184 @@ -2847,9 +2916,15 @@
1.185 * @see java.util.Formatter
1.186 * @since 1.5
1.187 */
1.188 -// public static String format(Locale l, String format, Object ... args) {
1.189 -// return new Formatter(l).format(format, args).toString();
1.190 -// }
1.191 + public static String format(Locale l, String format, Object ... args) {
1.192 + String p = format;
1.193 + for (int i = 0; i < args.length; i++) {
1.194 + String v = args[i] == null ? "null" : args[i].toString();
1.195 + p = p.replaceFirst("%s", v);
1.196 + }
1.197 + return p;
1.198 + // return new Formatter(l).format(format, args).toString();
1.199 + }
1.200
1.201 /**
1.202 * Returns the string representation of the <code>Object</code> argument.
1.203 @@ -3034,6 +3109,14 @@
1.204 * @return a string that has the same contents as this string, but is
1.205 * guaranteed to be from a pool of unique strings.
1.206 */
1.207 + @JavaScriptBody(args = {}, body =
1.208 + "var s = this.toString().toString();\n" +
1.209 + "var i = String.intern || (String.intern = {})\n" +
1.210 + "if (!i[s]) {\n" +
1.211 + " i[s] = s;\n" +
1.212 + "}\n" +
1.213 + "return i[s];"
1.214 + )
1.215 public native String intern();
1.216
1.217