You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@netbeans.apache.org by jt...@apache.org on 2017/09/09 07:00:57 UTC
incubator-netbeans-html4j git commit: Removing dependency on Java
collection classes implementations. Providing simpler replacements. Avoiding
usage of WeakReferences unless requested.
Repository: incubator-netbeans-html4j
Updated Branches:
refs/heads/master 7ddcc5f1a -> ee703cfd4
Removing dependency on Java collection classes implementations. Providing simpler replacements. Avoiding usage of WeakReferences unless requested.
Project: http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/commit/ee703cfd
Tree: http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/tree/ee703cfd
Diff: http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/diff/ee703cfd
Branch: refs/heads/master
Commit: ee703cfd4703009437267c98e5ef0e9dac99abef
Parents: 7ddcc5f
Author: Jaroslav Tulach <ja...@oracle.com>
Authored: Sat Sep 9 09:00:39 2017 +0200
Committer: Jaroslav Tulach <ja...@oracle.com>
Committed: Sat Sep 9 09:00:39 2017 +0200
----------------------------------------------------------------------
.../org/netbeans/html/boot/impl/FnContext.java | 3 +-
.../java/org/netbeans/html/boot/spi/Fn.java | 6 +-
.../src/main/java/net/java/html/BrwsrCtx.java | 3 -
.../org/netbeans/html/context/impl/CtxImpl.java | 50 +-
.../org/netbeans/html/context/spi/Contexts.java | 26 +-
.../java/html/js/tests/JavaScriptBodyTest.java | 4 +-
.../java/html/json/tests/ConvertTypesTest.java | 12 +-
.../java/net/java/html/json/tests/JSONTest.java | 37 +-
.../net/java/html/json/tests/KnockoutTest.java | 15 +-
.../net/java/html/json/tests/MinesTest.java | 68 +-
.../net/java/html/json/tests/PairModel.java | 4 +-
.../net/java/html/json/tests/SimpleMap.java | 266 ++++++++
.../java/net/java/html/json/tests/Utils.java | 26 +-
.../org/netbeans/html/json/tck/KnockoutTCK.java | 32 +-
.../main/java/net/java/html/json/Models.java | 13 +
.../org/netbeans/html/json/impl/Bindings.java | 10 -
.../java/org/netbeans/html/json/impl/JSON.java | 19 +-
.../org/netbeans/html/json/impl/JSONList.java | 14 +-
.../org/netbeans/html/json/impl/SimpleList.java | 658 +++++++++++++++++++
.../netbeans/html/json/spi/FunctionBinding.java | 7 +-
.../org/netbeans/html/json/spi/Observers.java | 29 +-
.../netbeans/html/json/spi/PropertyBinding.java | 16 +-
.../java/org/netbeans/html/json/spi/Proto.java | 4 +-
.../netbeans/html/json/impl/SimpleListTest.java | 123 ++++
.../main/java/org/netbeans/html/ko4j/KO4J.java | 2 -
.../java/org/netbeans/html/ko4j/KOTech.java | 7 +-
.../java/org/netbeans/html/ko4j/KOTransfer.java | 6 +-
.../java/org/netbeans/html/ko4j/Knockout.java | 20 +-
.../test/java/org/netbeans/html/ko4j/KOFx.java | 2 -
.../org/netbeans/html/ko4j/KnockoutFXTest.java | 8 +-
src/main/javadoc/overview.html | 5 +
31 files changed, 1333 insertions(+), 162 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/ee703cfd/boot/src/main/java/org/netbeans/html/boot/impl/FnContext.java
----------------------------------------------------------------------
diff --git a/boot/src/main/java/org/netbeans/html/boot/impl/FnContext.java b/boot/src/main/java/org/netbeans/html/boot/impl/FnContext.java
index ee7f077..74af344 100644
--- a/boot/src/main/java/org/netbeans/html/boot/impl/FnContext.java
+++ b/boot/src/main/java/org/netbeans/html/boot/impl/FnContext.java
@@ -36,7 +36,6 @@ import org.netbeans.html.boot.spi.Fn;
* @author Jaroslav Tulach
*/
public final class FnContext implements Closeable {
- private static final Logger LOG = Logger.getLogger(FnContext.class.getName());
private static final FnContext DUMMY;
static {
DUMMY = new FnContext(null, null);
@@ -84,7 +83,7 @@ public final class FnContext implements Closeable {
}
pw.println("Cannot initialize asm-5.0.jar!");
pw.flush();
- LOG.log(Level.SEVERE, w.toString(), t);
+ Logger.getLogger(FnContext.class.getName()).log(Level.SEVERE, w.toString(), t);
return null;
}
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/ee703cfd/boot/src/main/java/org/netbeans/html/boot/spi/Fn.java
----------------------------------------------------------------------
diff --git a/boot/src/main/java/org/netbeans/html/boot/spi/Fn.java b/boot/src/main/java/org/netbeans/html/boot/spi/Fn.java
index 57187a6..e70ad91 100644
--- a/boot/src/main/java/org/netbeans/html/boot/spi/Fn.java
+++ b/boot/src/main/java/org/netbeans/html/boot/spi/Fn.java
@@ -38,6 +38,7 @@ import org.netbeans.html.boot.impl.FnContext;
* @author Jaroslav Tulach
*/
public abstract class Fn {
+ private static Map<String, Set<Presenter>> LOADED;
private final Presenter presenter;
/**
@@ -126,8 +127,6 @@ public abstract class Fn {
return p.defineFn(code, names);
}
- private static final Map<String,Set<Presenter>> LOADED = new HashMap<String, Set<Presenter>>();
-
/** Wraps function to ensure that the script represented by <code>resource</code>
* gets loaded into the browser environment before the function <code>fn</code>
* is executed.
@@ -164,6 +163,9 @@ public abstract class Fn {
p = FnContext.currentPresenter(false);
}
if (p != null) {
+ if (LOADED == null) {
+ LOADED = new HashMap<String, Set<Presenter>>();
+ }
Set<Presenter> there = LOADED.get(resource);
if (there == null) {
there = new HashSet<Presenter>();
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/ee703cfd/context/src/main/java/net/java/html/BrwsrCtx.java
----------------------------------------------------------------------
diff --git a/context/src/main/java/net/java/html/BrwsrCtx.java b/context/src/main/java/net/java/html/BrwsrCtx.java
index 37ac048..50bcfa4 100644
--- a/context/src/main/java/net/java/html/BrwsrCtx.java
+++ b/context/src/main/java/net/java/html/BrwsrCtx.java
@@ -19,7 +19,6 @@
package net.java.html;
import java.util.concurrent.Executor;
-import java.util.logging.Logger;
import org.netbeans.html.context.impl.CtxAccssr;
import org.netbeans.html.context.impl.CtxImpl;
import org.netbeans.html.context.spi.Contexts;
@@ -41,7 +40,6 @@ import org.netbeans.html.context.spi.Contexts.Id;
* @author Jaroslav Tulach
*/
public final class BrwsrCtx implements Executor {
- private static final Logger LOG = Logger.getLogger(BrwsrCtx.class.getName());
private final CtxImpl impl;
private BrwsrCtx(CtxImpl impl) {
this.impl = impl;
@@ -88,7 +86,6 @@ public final class BrwsrCtx implements Executor {
org.netbeans.html.context.spi.Contexts.Builder cb = Contexts.newBuilder();
boolean found = Contexts.fillInByProviders(requestor, cb);
if (!found) {
- LOG.config("No browser context found. Returning empty technology!");
return EMPTY;
}
return cb.build();
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/ee703cfd/context/src/main/java/org/netbeans/html/context/impl/CtxImpl.java
----------------------------------------------------------------------
diff --git a/context/src/main/java/org/netbeans/html/context/impl/CtxImpl.java b/context/src/main/java/org/netbeans/html/context/impl/CtxImpl.java
index 093d9cc..2088e98 100644
--- a/context/src/main/java/org/netbeans/html/context/impl/CtxImpl.java
+++ b/context/src/main/java/org/netbeans/html/context/impl/CtxImpl.java
@@ -18,10 +18,6 @@
*/
package org.netbeans.html.context.impl;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
import net.java.html.BrwsrCtx;
import org.netbeans.html.context.spi.Contexts;
@@ -31,14 +27,14 @@ import org.netbeans.html.context.spi.Contexts;
* @author Jaroslav Tulach
*/
public final class CtxImpl {
- private final List<Bind<?>> techs;
+ private Bind<?>[] techs;
private final Object[] context;
public CtxImpl(Object[] context) {
- this(context, new ArrayList<Bind<?>>());
+ this(context, new Bind<?>[0]);
}
- private CtxImpl(Object[] context, List<Bind<?>> techs) {
+ private CtxImpl(Object[] context, Bind<?>[] techs) {
this.techs = techs;
this.context = context;
}
@@ -54,15 +50,14 @@ public final class CtxImpl {
}
public BrwsrCtx build() {
- Collections.sort(techs, new BindCompare());
- final List<Bind<?>> arr = Collections.unmodifiableList(techs);
- CtxImpl impl = new CtxImpl(context, arr);
+ new BindCompare().sort(techs);
+ CtxImpl impl = new CtxImpl(context, techs.clone());
BrwsrCtx ctx = CtxAccssr.getDefault().newContext(impl);
return ctx;
}
public <Tech> void register(Class<Tech> type, Tech impl, int priority) {
- techs.add(new Bind<Tech>(type, impl, priority));
+ techs = new BindCompare().add(techs, new Bind<Tech>(type, impl, priority));
}
private static final class Bind<Tech> {
@@ -82,8 +77,34 @@ public final class CtxImpl {
}
}
- private final class BindCompare implements Comparator<Bind<?>> {
- boolean isPrefered(Bind<?> b) {
+ private final class BindCompare {
+
+ void sort(Bind<?>[] techs) {
+ for (int i = 0; i < techs.length; i++) {
+ Bind<?> min = techs[i];
+ int minIndex = i;
+ for (int j = i + 1; j < techs.length; j++) {
+ if (compare(min, techs[j]) > 0) {
+ min = techs[j];
+ minIndex = j;
+ }
+ }
+ if (minIndex != i) {
+ techs[minIndex] = techs[i];
+ techs[i] = min;
+ }
+ }
+ }
+
+ private <Tech> Bind<?>[] add(Bind<?>[] techs, Bind<Tech> bind) {
+ Bind<?>[] newArr = new Bind<?>[techs.length + 1];
+ for (int i = 0; i < techs.length; i++) {
+ newArr[i] = techs[i];
+ }
+ newArr[techs.length] = bind;
+ return newArr;
+ }
+ private boolean isPrefered(Bind<?> b) {
final Class<?> implClazz = b.impl.getClass();
Contexts.Id id = implClazz.getAnnotation(Contexts.Id.class);
if (id == null) {
@@ -99,8 +120,7 @@ public final class CtxImpl {
return false;
}
- @Override
- public int compare(Bind<?> o1, Bind<?> o2) {
+ private int compare(Bind<?> o1, Bind<?> o2) {
boolean p1 = isPrefered(o1);
boolean p2 = isPrefered(o2);
if (p1 != p2) {
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/ee703cfd/context/src/main/java/org/netbeans/html/context/spi/Contexts.java
----------------------------------------------------------------------
diff --git a/context/src/main/java/org/netbeans/html/context/spi/Contexts.java b/context/src/main/java/org/netbeans/html/context/spi/Contexts.java
index e10e223..224be02 100644
--- a/context/src/main/java/org/netbeans/html/context/spi/Contexts.java
+++ b/context/src/main/java/org/netbeans/html/context/spi/Contexts.java
@@ -23,9 +23,7 @@ import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
-import java.util.HashSet;
import java.util.ServiceLoader;
-import java.util.Set;
import net.java.html.BrwsrCtx;
import org.netbeans.html.context.impl.CtxImpl;
@@ -91,7 +89,7 @@ public final class Contexts {
} catch (SecurityException ex) {
l = null;
}
- Set<Class<?>> classes = new HashSet<Class<?>>();
+ ClassSet classes = new ClassSet(null);
for (Provider cp : ServiceLoader.load(Provider.class, l)) {
if (!classes.add(cp.getClass())) {
continue;
@@ -123,6 +121,28 @@ public final class Contexts {
}
return found;
}
+
+ private static class ClassSet {
+ private final Class<?> clazz;
+ private ClassSet next;
+
+ public ClassSet(Class<?> clazz) {
+ this.clazz = clazz;
+ }
+
+
+ boolean add(Class<?> c) {
+ if (clazz == c) {
+ return false;
+ }
+ if (next == null) {
+ next = new ClassSet(c);
+ return true;
+ } else {
+ return next.add(c);
+ }
+ }
+ }
/** Identifies the technologies passed to {@link Builder context builder}
* by a name. Each implementation of a technology
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/ee703cfd/json-tck/src/main/java/net/java/html/js/tests/JavaScriptBodyTest.java
----------------------------------------------------------------------
diff --git a/json-tck/src/main/java/net/java/html/js/tests/JavaScriptBodyTest.java b/json-tck/src/main/java/net/java/html/js/tests/JavaScriptBodyTest.java
index 08ad1a5..e79d47b 100644
--- a/json-tck/src/main/java/net/java/html/js/tests/JavaScriptBodyTest.java
+++ b/json-tck/src/main/java/net/java/html/js/tests/JavaScriptBodyTest.java
@@ -19,8 +19,8 @@
package net.java.html.js.tests;
import java.io.StringReader;
-import java.util.Arrays;
import java.util.concurrent.Callable;
+import net.java.html.json.Models;
import org.netbeans.html.boot.spi.Fn;
import org.netbeans.html.json.tck.KOTest;
@@ -264,7 +264,7 @@ public class JavaScriptBodyTest {
Object b = Bodies.callbackAndPush(a, "Worl\nd!");
assertTrue(b instanceof Object[], "Returns an array: " + b);
Object[] arr = (Object[]) b;
- String str = Arrays.toString(arr);
+ String str = Models.asList(arr).toString();
assertEquals(arr.length, 2, "Size is two " + str);
assertEquals("He\nllo", arr[0], "Hello expected: " + arr[0]);
assertEquals("Worl\nd!", arr[1], "World! expected: " + arr[1]);
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/ee703cfd/json-tck/src/main/java/net/java/html/json/tests/ConvertTypesTest.java
----------------------------------------------------------------------
diff --git a/json-tck/src/main/java/net/java/html/json/tests/ConvertTypesTest.java b/json-tck/src/main/java/net/java/html/json/tests/ConvertTypesTest.java
index f39f8d0..af3e0e2 100644
--- a/json-tck/src/main/java/net/java/html/json/tests/ConvertTypesTest.java
+++ b/json-tck/src/main/java/net/java/html/json/tests/ConvertTypesTest.java
@@ -22,8 +22,6 @@ import java.io.ByteArrayInputStream;
import java.io.EOFException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.java.html.BrwsrCtx;
@@ -75,7 +73,7 @@ public final class ConvertTypesTest {
}
private static Object createJSON(boolean includeSex)
throws UnsupportedEncodingException {
- Map<String,Object> map = new HashMap<String,Object>();
+ Map<String,Object> map = SimpleMap.empty();
map.put("firstName", "son");
map.put("lastName", "dj");
if (includeSex) {
@@ -126,7 +124,7 @@ public final class ConvertTypesTest {
final BrwsrCtx c = newContext();
final InputStream o = createIS(null, true, true, -1, null);
- List<Person> arr = new ArrayList<Person>();
+ List<Person> arr = Models.asList();
Models.parse(c, Person.class, o, arr);
assertEquals(arr.size(), 1, "There is one item in " + arr);
@@ -163,7 +161,7 @@ public final class ConvertTypesTest {
sb.append(" \"lastName\" : null } ]\n");
final ByteArrayInputStream is = new ByteArrayInputStream(sb.toString().getBytes("UTF-8"));
- List<Person> arr = new ArrayList<Person>();
+ List<Person> arr = Models.asList();
Models.parse(c, Person.class, is, arr);
assertEquals(arr.size(), 2, "There are two items in " + arr);
@@ -237,7 +235,7 @@ public final class ConvertTypesTest {
final BrwsrCtx c = newContext();
final InputStream o = createIS(null, false, false, 5, null);
- List<Person> res = new ArrayList<Person>();
+ List<Person> res = Models.asList();
Models.parse(c, Person.class, o, res);
assertEquals(res.size(), 5, "Five elements found" + res);
@@ -262,7 +260,7 @@ public final class ConvertTypesTest {
final BrwsrCtx c = newContext();
final InputStream o = createIS("{ \"info\" : ", false, false, array, "}");
- List<People> res = new ArrayList<People>();
+ List<People> res = Models.asList();
Models.parse(c, People.class, o, res);
assertEquals(res.size(), 1, "One people" + res);
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/ee703cfd/json-tck/src/main/java/net/java/html/json/tests/JSONTest.java
----------------------------------------------------------------------
diff --git a/json-tck/src/main/java/net/java/html/json/tests/JSONTest.java b/json-tck/src/main/java/net/java/html/json/tests/JSONTest.java
index ed15526..19e989f 100644
--- a/json-tck/src/main/java/net/java/html/json/tests/JSONTest.java
+++ b/json-tck/src/main/java/net/java/html/json/tests/JSONTest.java
@@ -21,6 +21,8 @@ package net.java.html.json.tests;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
+import java.lang.reflect.Field;
+import java.nio.charset.Charset;
import net.java.html.BrwsrCtx;
import net.java.html.json.Model;
import net.java.html.json.ModelOperation;
@@ -48,6 +50,18 @@ public final class JSONTest {
private Integer orig;
private String url;
+ static {
+ try {
+ System.setProperty("file.encoding", "windows-1251");
+ Field f = Charset.class.getDeclaredField("defaultCharset");
+ f.setAccessible(true);
+ f.set(null, null);
+ assertEquals(Charset.defaultCharset().toString(), "windows-1251", "Encoding has been changed");
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+ }
+
@ModelOperation static void assignFetched(JSONik m, Person p) {
m.setFetched(p);
}
@@ -56,8 +70,8 @@ public final class JSONTest {
@KOTest public void toJSONInABrowser() throws Throwable {
Person p = Models.bind(new Person(), newContext());
p.setSex(Sex.MALE);
- p.setFirstName("Jarda");
- p.setLastName("Tulach");
+ p.setFirstName("Jára");
+ p.setLastName("Tulachů");
Object json;
try {
@@ -72,6 +86,20 @@ public final class JSONTest {
"Should be the same: " + p.getFirstName() + " != " + p2.getFirstName());
}
+ @KOTest public void fromJsonWithUTF8() throws Throwable {
+ final BrwsrCtx c = newContext();
+ Person p = Models.bind(new Person(), c);
+ p.setSex(Sex.MALE);
+ p.setFirstName("Jára");
+ p.setLastName("Tulachů");
+
+ byte[] arr = p.toString().getBytes("UTF-8");
+ Person p2 = Models.parse(c, Person.class, new ByteArrayInputStream(arr));
+
+ assertEquals(p2.getFirstName(), p.getFirstName(),
+ "Should be the same: " + p.getFirstName() + " != " + p2.getFirstName());
+ }
+
@KOTest public void toJSONWithEscapeCharactersInABrowser() throws Throwable {
Person p = Models.bind(new Person(), newContext());
p.setSex(Sex.MALE);
@@ -580,10 +608,7 @@ public final class JSONTest {
try {
prev = System.err;
System.setErr(new PrintStream(err));
- } catch (SecurityException e) {
- err = null;
- prev = null;
- } catch (LinkageError e) {
+ } catch (Throwable e) {
err = null;
prev = null;
}
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/ee703cfd/json-tck/src/main/java/net/java/html/json/tests/KnockoutTest.java
----------------------------------------------------------------------
diff --git a/json-tck/src/main/java/net/java/html/json/tests/KnockoutTest.java b/json-tck/src/main/java/net/java/html/json/tests/KnockoutTest.java
index d628907..e4cd463 100644
--- a/json-tck/src/main/java/net/java/html/json/tests/KnockoutTest.java
+++ b/json-tck/src/main/java/net/java/html/json/tests/KnockoutTest.java
@@ -18,10 +18,7 @@
*/
package net.java.html.json.tests;
-import java.util.Arrays;
import java.util.List;
-import java.util.Timer;
-import java.util.TimerTask;
import net.java.html.BrwsrCtx;
import net.java.html.json.ComputedProperty;
import net.java.html.json.Function;
@@ -62,7 +59,7 @@ public final class KnockoutTest {
for (int i = 0; i < arr.length; i++) {
arr[i] = results.get(i).length();
}
- return Arrays.asList(arr);
+ return Models.asList(arr);
}
@KOTest public void modifyValueAssertChangeInModelOnEnum() throws Throwable {
@@ -366,13 +363,12 @@ public final class KnockoutTest {
String v = getSetInput("input", null);
assertEquals("Kukuc", v, "Value is really kukuc: " + v);
- Timer t = new Timer("Set to Jardo");
- t.schedule(new TimerTask() {
+ Utils.scheduleLater(1, new Runnable() {
@Override
public void run() {
js.setName("Jardo");
}
- }, 1);
+ });
}
String v = getSetInput("input", null);
@@ -525,13 +521,12 @@ public final class KnockoutTest {
int cnt = Utils.countChildren(KnockoutTest.class, "ul");
assertEquals(cnt, 1, "One child, but was " + cnt);
- Timer t = new Timer("add to array");
- t.schedule(new TimerTask() {
+ Utils.scheduleLater(1, new Runnable() {
@Override
public void run() {
js.getResults().add("Hi");
}
- }, 1);
+ });
}
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/ee703cfd/json-tck/src/main/java/net/java/html/json/tests/MinesTest.java
----------------------------------------------------------------------
diff --git a/json-tck/src/main/java/net/java/html/json/tests/MinesTest.java b/json-tck/src/main/java/net/java/html/json/tests/MinesTest.java
index fcb8664..55c5ce3 100644
--- a/json-tck/src/main/java/net/java/html/json/tests/MinesTest.java
+++ b/json-tck/src/main/java/net/java/html/json/tests/MinesTest.java
@@ -18,9 +18,7 @@
*/
package net.java.html.json.tests;
-import java.util.ArrayList;
import java.util.List;
-import java.util.Random;
import net.java.html.BrwsrCtx;
import net.java.html.json.ComputedProperty;
import net.java.html.json.Function;
@@ -42,7 +40,7 @@ public final class MinesTest {
@KOTest public void paintTheGridOnClick() throws Throwable {
if (m == null) {
BrwsrCtx ctx = Utils.newContext(MinesTest.class);
- Object exp = Utils.exposeHTML(MinesTest.class,
+ Object exp = Utils.exposeHTML(MinesTest.class,
" <button id='init' data-bind='click: normalSize'></button>\n" +
" <table>\n" +
" <tbody id='table'>\n" +
@@ -72,21 +70,21 @@ public final class MinesTest {
throw new InterruptedException();
}
assertEquals(cnt, 10, "There is ten rows in the table now: " + cnt);
-
+
Utils.exposeHTML(MinesTest.class, "");
}
-
+
@KOTest public void countAround() throws Exception {
Mines mines = new Mines();
mines.init(5, 5, 0);
mines.getRows().get(0).getColumns().get(0).setMine(true);
mines.getRows().get(1).getColumns().get(0).setMine(true);
mines.getRows().get(0).getColumns().get(1).setMine(true);
-
+
int cnt = around(mines, 1, 1);
assertEquals(cnt, 3, "There are three mines around. Was: " + cnt);
}
-
+
private static void scheduleClick(String id, int delay) throws Exception {
String s = "var id = arguments[0]; var delay = arguments[1];"
+ "var e = window.document.getElementById(id);\n "
@@ -100,11 +98,11 @@ public final class MinesTest {
MinesTest.class,
s, id, delay);
}
-
+
enum GameState {
IN_PROGRESS, WON, LOST;
}
-
+
@Model(className = "Row", properties = {
@Property(name = "columns", type = Square.class, array = true)
})
@@ -121,21 +119,21 @@ public final class MinesTest {
switch (state) {
case EXPLOSION: return "✗";
case UNKNOWN: return " ";
- case DISCOVERED: return "✔";
+ case DISCOVERED: return "✔";
case N_0: return " ";
}
return "ɸ" + (state.ordinal() - 1);
}
-
+
@ComputedProperty static String style(SquareType state) {
return state == null ? null : state.toString();
}
}
-
+
enum SquareType {
N_0, N_1, N_2, N_3, N_4, N_5, N_6, N_7, N_8,
UNKNOWN, EXPLOSION, DISCOVERED;
-
+
final boolean isVisible() {
return name().startsWith("N_");
}
@@ -151,17 +149,26 @@ public final class MinesTest {
return values()[ordinal() + 1];
}
}
-
+
@ComputedProperty static boolean fieldShowing(GameState state) {
return state != null;
}
-
+
@Function static void normalSize(Mines m) {
m.init(10, 10, 10);
}
-
+
+ private static int randIndex;
+ private static int[] RANDOM = {
+ 4, 5, 8, 1, 3, 9, 2, 7, 7, 3, 8, 5, 4, 0,
+ 2, 7, 5, 3, 2, 9, 8, 8, 5, 3, 5, 8, 1, 5
+ };
+ private static int random() {
+ return RANDOM[randIndex++ % RANDOM.length];
+ }
+
@ModelOperation static void init(Mines model, int width, int height, int mines) {
- List<Row> rows = new ArrayList<Row>(height);
+ List<Row> rows = Models.asList();
for (int y = 0; y < height; y++) {
Square[] columns = new Square[width];
for (int x = 0; x < width; x++) {
@@ -169,11 +176,10 @@ public final class MinesTest {
}
rows.add(new Row(columns));
}
-
- Random r = new Random();
+
while (mines > 0) {
- int x = r.nextInt(width);
- int y = r.nextInt(height);
+ int x = random() % width;
+ int y = random() % height;
final Square s = rows.get(y).getColumns().get(x);
if (s.isMine()) {
continue;
@@ -186,10 +192,10 @@ public final class MinesTest {
model.getRows().clear();
model.getRows().addAll(rows);
}
-
+
@ModelOperation static void computeMines(Mines model) {
- List<Integer> xBombs = new ArrayList<Integer>();
- List<Integer> yBombs = new ArrayList<Integer>();
+ List<Integer> xBombs = Models.asList();
+ List<Integer> yBombs = Models.asList();
final List<Row> rows = model.getRows();
boolean emptyHidden = false;
SquareType[][] arr = new SquareType[rows.size()][];
@@ -214,7 +220,7 @@ public final class MinesTest {
for (int i = 0; i < xBombs.size(); i++) {
int x = xBombs.get(i);
int y = yBombs.get(i);
-
+
incrementAround(arr, x, y);
}
for (int y = 0; y < rows.size(); y++) {
@@ -227,13 +233,13 @@ public final class MinesTest {
}
}
}
-
+
if (!emptyHidden) {
model.setState(GameState.WON);
showAllBombs(model, SquareType.DISCOVERED);
}
}
-
+
private static void incrementAround(SquareType[][] arr, int x, int y) {
incrementAt(arr, x - 1, y - 1);
incrementAt(arr, x - 1, y);
@@ -242,11 +248,11 @@ public final class MinesTest {
incrementAt(arr, x + 1, y - 1);
incrementAt(arr, x + 1, y);
incrementAt(arr, x + 1, y + 1);
-
+
incrementAt(arr, x, y - 1);
incrementAt(arr, x, y + 1);
}
-
+
private static void incrementAt(SquareType[][] arr, int x, int y) {
if (y >= 0 && y < arr.length) {
SquareType[] r = arr[y];
@@ -258,7 +264,7 @@ public final class MinesTest {
}
}
}
-
+
static void showAllBombs(Mines model, SquareType state) {
for (Row row : model.getRows()) {
for (Square square : row.getColumns()) {
@@ -268,7 +274,7 @@ public final class MinesTest {
}
}
}
-
+
private static void expandKnown(Mines model, Square data) {
final List<Row> rows = model.getRows();
for (int y = 0; y < rows.size(); y++) {
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/ee703cfd/json-tck/src/main/java/net/java/html/json/tests/PairModel.java
----------------------------------------------------------------------
diff --git a/json-tck/src/main/java/net/java/html/json/tests/PairModel.java b/json-tck/src/main/java/net/java/html/json/tests/PairModel.java
index 35e0905..ef74c38 100644
--- a/json-tck/src/main/java/net/java/html/json/tests/PairModel.java
+++ b/json-tck/src/main/java/net/java/html/json/tests/PairModel.java
@@ -18,12 +18,12 @@
*/
package net.java.html.json.tests;
-import java.util.Arrays;
import java.util.List;
import net.java.html.BrwsrCtx;
import net.java.html.json.ComputedProperty;
import net.java.html.json.Function;
import net.java.html.json.Model;
+import net.java.html.json.Models;
import net.java.html.json.Property;
/**
@@ -40,7 +40,7 @@ class PairModel {
@ComputedProperty
static List<String> bothNames(String firstName, String lastName) {
- return Arrays.asList(firstName, lastName);
+ return Models.asList(firstName, lastName);
}
@ComputedProperty
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/ee703cfd/json-tck/src/main/java/net/java/html/json/tests/SimpleMap.java
----------------------------------------------------------------------
diff --git a/json-tck/src/main/java/net/java/html/json/tests/SimpleMap.java b/json-tck/src/main/java/net/java/html/json/tests/SimpleMap.java
new file mode 100644
index 0000000..7394bdd
--- /dev/null
+++ b/json-tck/src/main/java/net/java/html/json/tests/SimpleMap.java
@@ -0,0 +1,266 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 net.java.html.json.tests;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import net.java.html.json.Models;
+
+final class SimpleMap<K,V> implements Map<K,V> {
+ private final List<E<K,V>> entries;
+
+ private SimpleMap() {
+ this.entries = Models.asList();
+ }
+
+ public static <K,V> Map<K,V> empty() {
+ return new SimpleMap<K,V>();
+ }
+
+ @Override
+ public int size() {
+ return entries.size();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return entries.isEmpty();
+ }
+
+ private int indexOf(Object obj, int index) {
+ for (int i = 0; i < entries.size(); i++) {
+ E<K,V> arr = entries.get(i);
+ if (equals(index == 0 ? arr.key : arr.value, obj)) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ private static boolean equals(Object obj1, Object obj2) {
+ if (obj1 == null) {
+ return obj2 == null;
+ }
+ return obj1.equals(obj2);
+ }
+
+ @Override
+ public boolean containsKey(Object key) {
+ return indexOf(key, 0) != -1;
+ }
+
+ @Override
+ public boolean containsValue(Object value) {
+ return indexOf(value, 1) != -1;
+ }
+
+ @Override
+ public V get(Object key) {
+ int at = indexOf(key, 0);
+ return at == -1 ? null : entries.get(at).value;
+ }
+
+ @Override
+ public V put(K key, V value) {
+ int at = indexOf(key, 0);
+ if (at == -1) {
+ entries.add(new E<K,V>(key, value));
+ return null;
+ } else {
+ E<K,V> arr = entries.get(at);
+ return arr.setValue(value);
+ }
+ }
+
+ @Override
+ public V remove(Object key) {
+ int at = indexOf(key, 0);
+ if (at == -1) {
+ return null;
+ }
+ return entries.remove(at).value;
+ }
+
+ @Override
+ public void putAll(Map<? extends K, ? extends V> m) {
+ throw new UnsupportedOperationException("");
+ }
+
+ @Override
+ public void clear() {
+ entries.clear();
+ }
+
+ @Override
+ public Set<K> keySet() {
+ List<K> keys = Models.asList();
+ for (E<K, V> entry : entries) {
+ keys.add(entry.key);
+ }
+ return new ROSet<K>(keys);
+ }
+
+ @Override
+ public Collection<V> values() {
+ List<V> values = Models.asList();
+ for (E<K, V> entry : entries) {
+ values.add(entry.value);
+ }
+ return values;
+ }
+
+ @Override
+ public Set<Entry<K, V>> entrySet() {
+ return new ROSet<Entry<K, V>>(entries);
+ }
+
+ private static final class E<K,V> implements Entry<K,V> {
+ final K key;
+ V value;
+
+ E(K key, V v) {
+ this.key = key;
+ this.value = v;
+ }
+
+ @Override
+ public K getKey() {
+ return key;
+ }
+
+ @Override
+ public V getValue() {
+ return value;
+ }
+
+ @Override
+ public V setValue(V value) {
+ V prev = this.value;
+ this.value = value;
+ return prev;
+ }
+ }
+
+ private static final class ROSet<T> implements Set<T> {
+ private final Collection<? extends T> delegate;
+
+ ROSet(Collection<? extends T> delegate) {
+ this.delegate = delegate;
+ }
+
+ @Override
+ public int size() {
+ return delegate.size();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return delegate.isEmpty();
+ }
+
+ @Override
+ public boolean contains(Object o) {
+ return delegate.contains(o);
+ }
+
+ @Override
+ public Iterator<T> iterator() {
+ final Iterator<? extends T> it = delegate.iterator();
+ return new Iterator<T>() {
+ @Override
+ public boolean hasNext() {
+ return it.hasNext();
+ }
+
+ @Override
+ public T next() {
+ return it.next();
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+
+ @Override
+ public Object[] toArray() {
+ return delegate.toArray();
+ }
+
+ @Override
+ public <T> T[] toArray(T[] a) {
+ return delegate.toArray(a);
+ }
+
+ @Override
+ public boolean add(T e) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean remove(Object o) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean containsAll(Collection<?> c) {
+ return delegate.containsAll(c);
+ }
+
+ @Override
+ public boolean addAll(Collection<? extends T> c) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean removeAll(Collection<?> c) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean retainAll(Collection<?> c) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void clear() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return delegate.equals(o);
+ }
+
+ @Override
+ public int hashCode() {
+ return delegate.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return delegate.toString();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/ee703cfd/json-tck/src/main/java/net/java/html/json/tests/Utils.java
----------------------------------------------------------------------
diff --git a/json-tck/src/main/java/net/java/html/json/tests/Utils.java b/json-tck/src/main/java/net/java/html/json/tests/Utils.java
index dddb98a..486b507 100644
--- a/json-tck/src/main/java/net/java/html/json/tests/Utils.java
+++ b/json-tck/src/main/java/net/java/html/json/tests/Utils.java
@@ -18,10 +18,11 @@
*/
package net.java.html.json.tests;
-import java.net.URI;
-import java.util.Collections;
+import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;
+import java.util.Timer;
+import java.util.TimerTask;
import net.java.html.BrwsrCtx;
import org.netbeans.html.json.tck.KnockoutTCK;
@@ -48,6 +49,21 @@ public final class Utils {
return false;
}
+ static void scheduleLater(int delay, final Runnable r) {
+ for (KnockoutTCK tck : tcks(r.getClass())) {
+ if (tck.scheduleLater(delay, r)) {
+ return;
+ }
+ }
+ Timer t = new Timer("Running later");
+ t.schedule(new TimerTask() {
+ @Override
+ public void run() {
+ r.run();
+ }
+ }, delay);
+ }
+
private Utils() {
}
@@ -84,7 +100,9 @@ public final class Utils {
private static Iterable<KnockoutTCK> tcks(Class<?> clazz) {
if (instantiatedTCK != null) {
- return Collections.singleton(instantiatedTCK);
+ List<KnockoutTCK> l = (List<KnockoutTCK>)(Object)new People().getInfo();
+ l.add(instantiatedTCK);
+ return l;
}
return ServiceLoader.load(KnockoutTCK.class, cl(clazz));
}
@@ -135,7 +153,7 @@ public final class Utils {
static String prepareURL(
Class<?> clazz, String content, String mimeType, String... parameters) {
for (KnockoutTCK tck : tcks(clazz)) {
- URI o = tck.prepareURL(content, mimeType, parameters);
+ String o = tck.prepareWebResource(content, mimeType, parameters);
if (o != null) {
return o.toString();
}
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/ee703cfd/json-tck/src/main/java/org/netbeans/html/json/tck/KnockoutTCK.java
----------------------------------------------------------------------
diff --git a/json-tck/src/main/java/org/netbeans/html/json/tck/KnockoutTCK.java b/json-tck/src/main/java/org/netbeans/html/json/tck/KnockoutTCK.java
index b5e4424..c3c02e0 100644
--- a/json-tck/src/main/java/org/netbeans/html/json/tck/KnockoutTCK.java
+++ b/json-tck/src/main/java/org/netbeans/html/json/tck/KnockoutTCK.java
@@ -19,6 +19,7 @@
package org.netbeans.html.json.tck;
import java.net.URI;
+import java.net.URISyntaxException;
import java.util.Map;
import net.java.html.BrwsrCtx;
import net.java.html.json.tests.ConvertTypesTest;
@@ -85,9 +86,25 @@ public abstract class KnockoutTCK {
* <code>$1</code> to reference <code>parameters</code> by their position
* @param mimeType the type of the resource
* @param parameters names of parameters as reference by <code>content</code>
- * @return URI the test can connect to to obtain the (processed) content
+ * @return URL the test can connect to to obtain the (processed) content
+ * @since 1.5
*/
- public abstract URI prepareURL(String content, String mimeType, String[] parameters);
+ public String prepareWebResource(String content, String mimeType, String[] parameters) {
+ return prepareURL(content, mimeType, parameters).toString();
+ }
+
+ /**
+ * @deprecated provide {@link #prepareWebResource(java.lang.String, java.lang.String, java.lang.String[])}
+ * implementation instead since post 1.4 version of HTML/Java API.
+ */
+ @Deprecated
+ public URI prepareURL(String content, String mimeType, String[] parameters) {
+ try {
+ return new URI(prepareWebResource(content, mimeType, parameters));
+ } catch (URISyntaxException ex) {
+ throw new IllegalStateException();
+ }
+ }
/** Gives you list of classes included in the TCK. Their test methods
* are annotated by {@link KOTest} annotation. The methods are public
@@ -116,5 +133,16 @@ public abstract class KnockoutTCK {
return false;
}
+ /** Schedules the given runnable to run later.
+ *
+ * @param delay the delay in milliseconds
+ * @param r the runnable to run
+ * @return <code>true</code> if the runnable was really scheduled,
+ * <code>false</code> otherwise
+ * @since 1.5 version
+ */
+ public boolean scheduleLater(int delay, Runnable r) {
+ return false;
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/ee703cfd/json/src/main/java/net/java/html/json/Models.java
----------------------------------------------------------------------
diff --git a/json/src/main/java/net/java/html/json/Models.java b/json/src/main/java/net/java/html/json/Models.java
index 776ca78..ad76792 100644
--- a/json/src/main/java/net/java/html/json/Models.java
+++ b/json/src/main/java/net/java/html/json/Models.java
@@ -22,7 +22,9 @@ import net.java.html.BrwsrCtx;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
+import java.util.List;
import org.netbeans.html.json.impl.JSON;
+import org.netbeans.html.json.impl.SimpleList;
import org.netbeans.html.json.spi.Technology;
/** Information about and
@@ -164,4 +166,15 @@ public final class Models {
public static void applyBindings(Object model, String targetId) {
JSON.applyBindings(model, targetId);
}
+
+ /** Wrap provided values into mutable list.
+ *
+ * @param <T> type of the values and resulting list
+ * @param values the values, if any
+ * @return full features implementation of mutable and extendable list
+ * @since 1.5
+ */
+ public static <T> List<T> asList(T... values) {
+ return SimpleList.asList(values);
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/ee703cfd/json/src/main/java/org/netbeans/html/json/impl/Bindings.java
----------------------------------------------------------------------
diff --git a/json/src/main/java/org/netbeans/html/json/impl/Bindings.java b/json/src/main/java/org/netbeans/html/json/impl/Bindings.java
index 02c101a..fdd1b57 100644
--- a/json/src/main/java/org/netbeans/html/json/impl/Bindings.java
+++ b/json/src/main/java/org/netbeans/html/json/impl/Bindings.java
@@ -18,8 +18,6 @@
*/
package org.netbeans.html.json.impl;
-import java.util.logging.Level;
-import java.util.logging.Logger;
import net.java.html.BrwsrCtx;
import org.netbeans.html.json.spi.FunctionBinding;
import org.netbeans.html.json.spi.PropertyBinding;
@@ -31,8 +29,6 @@ import org.netbeans.html.json.spi.Technology;
* @author Jaroslav Tulach
*/
public final class Bindings<Data> {
- private static final Logger LOG = Logger.getLogger(Bindings.class.getName());
-
private Data data;
private final Technology<Data> bp;
@@ -94,12 +90,6 @@ public final class Bindings<Data> {
ai.applyBindings(id, data);
return;
}
- if (id != null) {
- LOG.log(Level.WARNING,
- "Technology {0} does not implement ApplyId extension. Can't apply to {1}. Applying globally.",
- new Object[]{bp, id}
- );
- }
bp.applyBindings(data);
}
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/ee703cfd/json/src/main/java/org/netbeans/html/json/impl/JSON.java
----------------------------------------------------------------------
diff --git a/json/src/main/java/org/netbeans/html/json/impl/JSON.java b/json/src/main/java/org/netbeans/html/json/impl/JSON.java
index 0d1bb1a..f9cc31b 100644
--- a/json/src/main/java/org/netbeans/html/json/impl/JSON.java
+++ b/json/src/main/java/org/netbeans/html/json/impl/JSON.java
@@ -22,8 +22,6 @@ import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
import net.java.html.BrwsrCtx;
import org.netbeans.html.context.spi.Contexts;
import org.netbeans.html.json.spi.FunctionBinding;
@@ -344,12 +342,17 @@ public final class JSON {
}
- private static final Map<Class,Proto.Type<?>> modelTypes;
- static {
- modelTypes = new HashMap<Class, Proto.Type<?>>();
+ private static final class ModelTypes extends ClassValue<Proto.Type[]> {
+ static final ModelTypes MODELS = new ModelTypes();
+
+ @Override
+ protected Proto.Type[] computeValue(Class<?> type) {
+ return new Proto.Type<?>[1];
+ }
}
+
public static void register(Class c, Proto.Type<?> type) {
- modelTypes.put(c, type);
+ ModelTypes.MODELS.get(c)[0]= type;
}
public static boolean isModel(Class<?> clazz) {
@@ -358,7 +361,7 @@ public final class JSON {
static Proto.Type<?> findType(Class<?> clazz) {
for (int i = 0; i < 2; i++) {
- Proto.Type<?> from = modelTypes.get(clazz);
+ Proto.Type<?> from = ModelTypes.MODELS.get(clazz)[0];
if (from == null) {
initClass(clazz);
} else {
@@ -407,7 +410,7 @@ public final class JSON {
return modelClazz.cast(data.toString());
}
for (int i = 0; i < 2; i++) {
- Proto.Type<?> from = modelTypes.get(modelClazz);
+ Proto.Type<?> from = ModelTypes.MODELS.get(modelClazz)[0];
if (from == null) {
initClass(modelClazz);
} else {
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/ee703cfd/json/src/main/java/org/netbeans/html/json/impl/JSONList.java
----------------------------------------------------------------------
diff --git a/json/src/main/java/org/netbeans/html/json/impl/JSONList.java b/json/src/main/java/org/netbeans/html/json/impl/JSONList.java
index 6988c81..4bbd80a 100644
--- a/json/src/main/java/org/netbeans/html/json/impl/JSONList.java
+++ b/json/src/main/java/org/netbeans/html/json/impl/JSONList.java
@@ -19,8 +19,6 @@
package org.netbeans.html.json.impl;
import java.lang.reflect.Array;
-import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
@@ -30,7 +28,7 @@ import org.netbeans.html.json.spi.Proto;
*
* @author Jaroslav Tulach
*/
-public final class JSONList<T> extends ArrayList<T> {
+public final class JSONList<T> extends SimpleList<T> {
private final Proto proto;
private final String name;
private final String[] deps;
@@ -119,11 +117,7 @@ public final class JSONList<T> extends ArrayList<T> {
}
public void sort(Comparator<? super T> c) {
- Object[] arr = this.toArray();
- Arrays.sort(arr, (Comparator<Object>) c);
- for (int i = 0; i < arr.length; i++) {
- super.set(i, (T) arr[i]);
- }
+ super.sort(c);
notifyChange();
}
@@ -159,8 +153,8 @@ public final class JSONList<T> extends ArrayList<T> {
}
@Override
- protected void removeRange(int fromIndex, int toIndex) {
- super.removeRange(fromIndex, toIndex);
+ void clearImpl(int from, int to) {
+ super.clearImpl(from, to);
notifyChange();
}
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/ee703cfd/json/src/main/java/org/netbeans/html/json/impl/SimpleList.java
----------------------------------------------------------------------
diff --git a/json/src/main/java/org/netbeans/html/json/impl/SimpleList.java b/json/src/main/java/org/netbeans/html/json/impl/SimpleList.java
new file mode 100644
index 0000000..0950c7e
--- /dev/null
+++ b/json/src/main/java/org/netbeans/html/json/impl/SimpleList.java
@@ -0,0 +1,658 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.netbeans.html.json.impl;
+
+import java.lang.reflect.Array;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+
+public class SimpleList<E> implements List<E> {
+ private Object[] arr;
+ private int size;
+
+ public SimpleList() {
+ }
+
+ private SimpleList(Object[] data) {
+ arr = data.clone();
+ size = data.length;
+ }
+
+ public static <T> List<T> asList(T... arr) {
+ return new SimpleList<T>(arr);
+ }
+
+ @Override
+ public int size() {
+ return size;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return size == 0;
+ }
+
+ @Override
+ public boolean contains(Object o) {
+ return containsImpl(o, 0, size);
+ }
+
+ final boolean containsImpl(Object o, int from, int to) {
+ for (int i = from; i < to; i++) {
+ if (equals(o, arr[i])) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public Iterator<E> iterator() {
+ return new LI(0, size);
+ }
+
+ @Override
+ public Object[] toArray() {
+ return toArrayImpl(0, size);
+ }
+
+ final Object[] toArrayImpl(int from, int to) {
+ Object[] ret = new Object[to - from];
+ for (int i = 0; i < ret.length; i++) {
+ ret[i] = arr[i + from];
+ }
+ return ret;
+ }
+
+ @Override
+ public <T> T[] toArray(T[] a) {
+ return toArrayImpl(a, 0, size);
+ }
+
+ final <T> T[] toArrayImpl(T[] a, int from, int to) {
+ if (a.length < to - from) {
+ a = newArr(a, to - from);
+ }
+ for (int i = 0; i < size; i++) {
+ a[i] = (T) arr[i + from];
+ }
+ return a;
+ }
+
+ @Override
+ public boolean add(E e) {
+ return addImpl(e);
+ }
+
+ private boolean addImpl(E e) {
+ ensureAccess(size + 1);
+ arr[size++] = e;
+ return true;
+ }
+
+ @Override
+ public boolean remove(Object o) {
+ return removeImpl(o, 0, size);
+ }
+
+ private boolean removeImpl(Object o, int from, int to) {
+ boolean found = false;
+ for (int i = from; i < to; i++) {
+ if (found) {
+ arr[i - 1] = arr[i];
+ } else {
+ if (equals(o, arr[i])) {
+ found = true;
+ }
+ }
+ }
+ if (found) {
+ arr[--size] = null;
+ }
+ return found;
+ }
+
+ @Override
+ public boolean containsAll(Collection<?> c) {
+ for (Object o : c) {
+ if (!contains(o)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public boolean addAll(Collection<? extends E> c) {
+ ensureAccess(size + c.size());
+ for (E o : c) {
+ addImpl(o);
+ }
+ return !c.isEmpty();
+ }
+
+ @Override
+ public boolean addAll(int index, Collection<? extends E> c) {
+ return addImpl(index, c);
+ }
+
+ private boolean addImpl(int index, Collection<? extends E> c) {
+ final int toAdd = c.size();
+ if (toAdd == 0) {
+ return false;
+ }
+ int nowSize = size;
+ ensureAccess(nowSize + toAdd);
+ for (int i = nowSize - 1; i >= index; i--) {
+ arr[i + toAdd] = arr[i];
+ }
+ for (Object o : c) {
+ arr[index++] = o;
+ }
+ size += toAdd;
+ return true;
+ }
+
+ @Override
+ public boolean removeAll(Collection<?> c) {
+ int prev = size;
+ for (Object o : c) {
+ remove(o);
+ }
+ return prev != size;
+ }
+
+ @Override
+ public boolean retainAll(Collection<?> c) {
+ return retainImpl(this, c);
+ }
+
+ public void sort(Comparator<? super E> c) {
+ sortImpl(c, 0, size);
+ }
+
+ final void sortImpl(Comparator<? super E> c, int from, int to) {
+ for (int i = from; i < to; i++) {
+ Object min = arr[i];
+ int minIndex = i;
+ for (int j = i + 1; j < to; j++) {
+ final int compare;
+ if (c == null) {
+ compare = ((Comparable<Object>)min).compareTo(arr[j]);
+ } else {
+ compare = c.compare((E)min, (E)arr[j]);
+ }
+ if (compare > 0) {
+ min = arr[j];
+ minIndex = j;
+ }
+ }
+ if (i != minIndex) {
+ arr[minIndex] = arr[i];
+ arr[i] = min;
+ }
+ }
+ }
+
+ @Override
+ public void clear() {
+ size = 0;
+ }
+
+ void clearImpl(int from, int to) {
+ for (int i = 0; i + from < size; i++) {
+ arr[from + i] = arr[to + i];
+ }
+ size += from;
+ size -= to;
+ }
+
+ @Override
+ public E get(int index) {
+ checkAccess(index);
+ return (E) arr[index];
+ }
+
+ private void checkAccess(int index) throws ArrayIndexOutOfBoundsException {
+ if (index < 0 || index >= size) {
+ throw new ArrayIndexOutOfBoundsException();
+ }
+ }
+
+ private void ensureAccess(int reqSize) {
+ if (reqSize < size) {
+ return;
+ }
+
+ int newSize = arr == null ? 0 : arr.length;
+ if (newSize < 4) {
+ newSize = 4;
+ }
+ while (newSize < reqSize) {
+ newSize *= 2;
+ }
+ Object[] newArr = new Object[newSize];
+ for (int i = 0; i < size; i++) {
+ newArr[i] = arr[i];
+ }
+
+ arr = newArr;
+ }
+
+ @Override
+ public E set(int index, E element) {
+ checkAccess(index);
+ E prev = (E) arr[index];
+ arr[index] = element;
+ return prev;
+ }
+
+ @Override
+ public void add(int index, E element) {
+ addImpl(index, asList(element));
+ }
+
+ @Override
+ public E remove(int index) {
+ checkAccess(index);
+ E prev = (E) arr[index];
+ for (int i = index + 1; i < size; i++) {
+ arr[i - 1] = arr[i];
+ }
+ arr[--size] = null;
+ return prev;
+ }
+
+ @Override
+ public int indexOf(Object o) {
+ return indexOfImpl(o, 0, size);
+ }
+
+ final int indexOfImpl(Object o, int from, int to) {
+ for (int i = from; i < to; i++) {
+ if (equals(o, arr[i])) {
+ return i - from;
+ }
+ }
+ return -1;
+ }
+
+ @Override
+ public int lastIndexOf(Object o) {
+ return lastIndexOfImpl(o, 0, size);
+ }
+
+ public int lastIndexOfImpl(Object o, int from, int to) {
+ for (int i = to - 1; i >= from; i--) {
+ if (equals(o, arr[i])) {
+ return i - from;
+ }
+ }
+ return -1;
+ }
+
+ @Override
+ public ListIterator<E> listIterator() {
+ return new LI(0, size);
+ }
+
+ @Override
+ public ListIterator<E> listIterator(int index) {
+ return new LI(index, 0, size);
+ }
+
+ @Override
+ public List<E> subList(int fromIndex, int toIndex) {
+ return new Sub(fromIndex, toIndex);
+ }
+
+ private static boolean equals(Object o1, Object o2) {
+ if (o1 == null) {
+ return o2 == null;
+ } else {
+ return o1.equals(o2);
+ }
+ }
+
+ private static <T> T[] newArr(T[] a, int size) {
+ return (T[]) Array.newInstance(a.getClass().getComponentType(), size);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return equalsList(this, obj);
+ }
+
+ @Override
+ public int hashCode() {
+ return hashList(this);
+ }
+
+ @Override
+ public String toString() {
+ return toStringList(this);
+ }
+
+ boolean retainImpl(Collection<?> thiz, Collection<?> c) {
+ boolean changed = false;
+ Iterator<?> it = thiz.iterator();
+ while (it.hasNext()) {
+ Object obj = it.next();
+ if (!c.contains(obj)) {
+ it.remove();
+ changed = true;
+ }
+ }
+ return changed;
+ }
+
+ static boolean equalsList(List<?> thiz, Object obj) {
+ if (obj == thiz) return true;
+ if (obj instanceof List) {
+ List<?> list = (List<?>) obj;
+ if (thiz.size() != list.size()) {
+ return false;
+ }
+ for (int i = 0; i < thiz.size(); i++) {
+ if (!equals(thiz.get(i), list.get(i))) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ static int hashList(List<?> thiz) {
+ int hashCode = 1;
+ for (Object e : thiz) {
+ hashCode = 31 * hashCode + (e == null ? 0 : e.hashCode());
+ }
+ return hashCode;
+ }
+
+ static String toStringList(List<?> thiz) {
+ StringBuilder sb = new StringBuilder();
+ sb.append('[');
+ String sep = "";
+ for (Object e : thiz) {
+ sb.append(sep);
+ sb.append(e);
+ sep = ", ";
+ }
+ sb.append(']');
+ return sb.toString();
+ }
+
+
+ private final class Sub implements List<E> {
+ private final int from;
+ private int to;
+
+ Sub(int from, int to) {
+ this.from = from;
+ this.to = to;
+ }
+
+ @Override
+ public int size() {
+ return to - from;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return to <= from;
+ }
+
+ @Override
+ public boolean contains(Object o) {
+ return containsImpl(o, from, to);
+ }
+
+ @Override
+ public Object[] toArray() {
+ return toArrayImpl(from, to);
+ }
+
+ @Override
+ public <T> T[] toArray(T[] a) {
+ return toArrayImpl(a, from, to);
+ }
+
+ @Override
+ public boolean add(E e) {
+ SimpleList.this.add(to++, e);
+ return true;
+ }
+
+ @Override
+ public boolean remove(Object o) {
+ if (removeImpl(o, from, to)) {
+ to--;
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean containsAll(Collection<?> c) {
+ for (Object o : c) {
+ if (!contains(o)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public boolean addAll(Collection<? extends E> c) {
+ SimpleList.this.addAll(to, c);
+ to += c.size();
+ return true;
+ }
+
+ @Override
+ public boolean addAll(int index, Collection<? extends E> c) {
+ SimpleList.this.addAll(from + index, c);
+ to += c.size();
+ return true;
+ }
+
+ @Override
+ public boolean removeAll(Collection<?> c) {
+ int prev = size();
+ for (Object o : c) {
+ remove(o);
+ }
+ return prev != size();
+ }
+
+ @Override
+ public boolean retainAll(Collection<?> c) {
+ return retainImpl(this, c);
+ }
+
+ public void sort(Comparator<? super E> c) {
+ sortImpl(c, from, to);
+ }
+
+ @Override
+ public void clear() {
+ clearImpl(from, to);
+ to = from;
+ }
+
+ @Override
+ public E get(int index) {
+ return SimpleList.this.get(from + index);
+ }
+
+ @Override
+ public E set(int index, E element) {
+ return SimpleList.this.set(from + index, element);
+ }
+
+ @Override
+ public void add(int index, E element) {
+ SimpleList.this.add(index + from, element);
+ to++;
+ }
+
+ @Override
+ public E remove(int index) {
+ E ret = SimpleList.this.remove(index + from);
+ to--;
+ return ret;
+ }
+
+ @Override
+ public int indexOf(Object o) {
+ return indexOfImpl(o, from, to);
+ }
+
+ @Override
+ public int lastIndexOf(Object o) {
+ return lastIndexOfImpl(o, from, to);
+ }
+
+ @Override
+ public Iterator<E> iterator() {
+ return listIterator(0);
+ }
+
+ @Override
+ public ListIterator<E> listIterator() {
+ return listIterator(0);
+ }
+
+ @Override
+ public ListIterator<E> listIterator(int index) {
+ return new LI(from + index, from, to) {
+ @Override
+ public void remove() {
+ super.remove();
+ to--;
+ }
+ };
+ }
+
+ @Override
+ public List<E> subList(int fromIndex, int toIndex) {
+ return new Sub(from + fromIndex, from + toIndex);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return equalsList(this, obj);
+ }
+
+ @Override
+ public int hashCode() {
+ return hashList(this);
+ }
+
+ @Override
+ public String toString() {
+ return toStringList(this);
+ }
+ }
+
+ private class LI implements ListIterator<E> {
+ private int prev = -1;
+ private int at;
+ private final int min;
+ private final int max;
+ private int add;
+
+ LI(int at, int min, int max) {
+ this.at = at;
+ this.min = min;
+ this.max = max;
+ }
+
+ LI(int min, int max) {
+ this(min, min, max);
+ }
+
+ @Override
+ public boolean hasNext() {
+ return at < max + add;
+ }
+
+ @Override
+ public E next() {
+ if (at == max + add) {
+ throw new NoSuchElementException();
+ }
+ prev = at;
+ return (E) arr[at++];
+ }
+
+ @Override
+ public boolean hasPrevious() {
+ return at > min;
+ }
+
+ @Override
+ public E previous() {
+ if (at == min) {
+ throw new NoSuchElementException();
+ }
+ prev = --at;
+ return (E) arr[prev];
+ }
+
+ @Override
+ public int nextIndex() {
+ return at - min;
+ }
+
+ @Override
+ public int previousIndex() {
+ return at - 1 - min;
+ }
+
+ @Override
+ public void remove() {
+ if (prev == -1) {
+ throw new IllegalStateException();
+ }
+ SimpleList.this.remove(prev);
+ at = prev;
+ prev = -1;
+ add--;
+ }
+
+ @Override
+ public void set(E e) {
+ SimpleList.this.set(min + prev, e);
+ }
+
+ @Override
+ public void add(E e) {
+ SimpleList.this.add(min + at, e);
+ add++;
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/ee703cfd/json/src/main/java/org/netbeans/html/json/spi/FunctionBinding.java
----------------------------------------------------------------------
diff --git a/json/src/main/java/org/netbeans/html/json/spi/FunctionBinding.java b/json/src/main/java/org/netbeans/html/json/spi/FunctionBinding.java
index 41bce74..bd7d486 100644
--- a/json/src/main/java/org/netbeans/html/json/spi/FunctionBinding.java
+++ b/json/src/main/java/org/netbeans/html/json/spi/FunctionBinding.java
@@ -23,6 +23,7 @@ import java.lang.ref.WeakReference;
import net.java.html.BrwsrCtx;
import net.java.html.json.Function;
import net.java.html.json.Model;
+import static org.netbeans.html.json.spi.PropertyBinding.weakSupported;
/** Describes a function provided by the {@link Model} and
* annotated by {@link Function} annotation.
@@ -113,7 +114,11 @@ public abstract class FunctionBinding {
@Override
public FunctionBinding weak() {
- return new Weak(model, name, index, access);
+ if (weakSupported) {
+ return new Weak(model, name, index, access);
+ } else {
+ return this;
+ }
}
}
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/ee703cfd/json/src/main/java/org/netbeans/html/json/spi/Observers.java
----------------------------------------------------------------------
diff --git a/json/src/main/java/org/netbeans/html/json/spi/Observers.java b/json/src/main/java/org/netbeans/html/json/spi/Observers.java
index 59c225e..0728f1a 100644
--- a/json/src/main/java/org/netbeans/html/json/spi/Observers.java
+++ b/json/src/main/java/org/netbeans/html/json/spi/Observers.java
@@ -18,21 +18,18 @@
*/
package org.netbeans.html.json.spi;
-import java.util.ArrayList;
-import java.util.HashMap;
import java.util.Iterator;
-import java.util.LinkedList;
import java.util.List;
-import java.util.Map;
+import org.netbeans.html.json.impl.SimpleList;
/**
*
* @author Jaroslav Tulach
*/
final class Observers {
- private static final LinkedList<Watcher> GLOBAL = new LinkedList<Watcher>();
- private final List<Watcher> watchers = new ArrayList<Watcher>();
- private final List<Ref> observers = new ArrayList<Ref>();
+ private static final List<Watcher> GLOBAL = SimpleList.asList();
+ private final List<Watcher> watchers = SimpleList.asList();
+ private final List<Ref> observers = SimpleList.asList();
Observers() {
assert Thread.holdsLock(GLOBAL);
@@ -42,7 +39,7 @@ final class Observers {
synchronized (GLOBAL) {
verifyUnlocked(p);
final Watcher nw = new Watcher(p, name);
- GLOBAL.push(nw);
+ GLOBAL.add(nw);
return Usages.register(name, nw, usages);
}
}
@@ -118,7 +115,7 @@ final class Observers {
return ref.proto == null ? null : ref;
}
}
-
+
private Watcher find(String prop) {
if (prop == null) {
return null;
@@ -148,7 +145,7 @@ final class Observers {
}
static final void valueHasMutated(Proto p, String propName) {
- List<Watcher> mutated = new LinkedList<Watcher>();
+ List<Watcher> mutated = SimpleList.asList();
synchronized (GLOBAL) {
Observers mine = p.observers(false);
if (mine == null) {
@@ -219,7 +216,8 @@ final class Observers {
}
static final class Usages {
- private final Map<String,Watcher> watchers = new HashMap<String, Watcher>();
+ private final List<String> names = SimpleList.asList();
+ private final List<Watcher> watchers = SimpleList.asList();
private Usages() {
}
@@ -229,9 +227,14 @@ final class Observers {
if (usages == null) {
usages = new Usages();
}
- Observers.Watcher prev = usages.watchers.put(propName, w);
- if (prev != null) {
+ int index = usages.names.indexOf(propName);
+ if (index == -1) {
+ usages.names.add(propName);
+ usages.watchers.add(w);
+ } else {
+ Watcher prev = usages.watchers.get(index);
prev.destroy();
+ usages.watchers.set(index, w);
}
}
return usages;
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/ee703cfd/json/src/main/java/org/netbeans/html/json/spi/PropertyBinding.java
----------------------------------------------------------------------
diff --git a/json/src/main/java/org/netbeans/html/json/spi/PropertyBinding.java b/json/src/main/java/org/netbeans/html/json/spi/PropertyBinding.java
index b151b49..ef83ffd 100644
--- a/json/src/main/java/org/netbeans/html/json/spi/PropertyBinding.java
+++ b/json/src/main/java/org/netbeans/html/json/spi/PropertyBinding.java
@@ -36,6 +36,8 @@ public abstract class PropertyBinding {
PropertyBinding() {
}
+ static final boolean weakSupported;
+
static {
new PropertyBindingAccessor() {
@Override
@@ -74,6 +76,14 @@ public abstract class PropertyBinding {
return new Impl(model, bindings, name, index, access, propertyType);
}
};
+ boolean weakOK;
+ try {
+ Class<?> weakRefClass = Class.forName("java.lang.ref.WeakReference"); // NOI18N
+ weakOK = weakRefClass != null;
+ } catch (ClassNotFoundException ex) {
+ weakOK = false;
+ }
+ weakSupported = weakOK;
}
/** Name of the property this binding represents.
@@ -188,7 +198,11 @@ public abstract class PropertyBinding {
@Override
public PropertyBinding weak() {
- return new Weak(model, bindings, name, index, access, propertyType);
+ if (weakSupported) {
+ return new Weak(model, bindings, name, index, access, propertyType);
+ } else {
+ return this;
+ }
}
}
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/ee703cfd/json/src/main/java/org/netbeans/html/json/spi/Proto.java
----------------------------------------------------------------------
diff --git a/json/src/main/java/org/netbeans/html/json/spi/Proto.java b/json/src/main/java/org/netbeans/html/json/spi/Proto.java
index 626a6cb..6f9065f 100644
--- a/json/src/main/java/org/netbeans/html/json/spi/Proto.java
+++ b/json/src/main/java/org/netbeans/html/json/spi/Proto.java
@@ -18,12 +18,12 @@
*/
package org.netbeans.html.json.spi;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import net.java.html.BrwsrCtx;
import net.java.html.json.ComputedProperty;
import net.java.html.json.Model;
+import net.java.html.json.Models;
import net.java.html.json.Property;
import org.netbeans.html.json.impl.Bindings;
import org.netbeans.html.json.impl.JSON;
@@ -878,7 +878,7 @@ public final class Proto {
* @since 1.0
*/
public final <T> void replaceValue(Collection<? super T> arr, Class<T> type, Object value) {
- List<T> tmp = new ArrayList<T>();
+ List<T> tmp = Models.asList();
if (value instanceof Object[]) {
for (Object e : (Object[]) value) {
tmp.add(extractValue(type, e));
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/ee703cfd/json/src/test/java/org/netbeans/html/json/impl/SimpleListTest.java
----------------------------------------------------------------------
diff --git a/json/src/test/java/org/netbeans/html/json/impl/SimpleListTest.java b/json/src/test/java/org/netbeans/html/json/impl/SimpleListTest.java
new file mode 100644
index 0000000..58eee5a
--- /dev/null
+++ b/json/src/test/java/org/netbeans/html/json/impl/SimpleListTest.java
@@ -0,0 +1,123 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.netbeans.html.json.impl;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.ListIterator;
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class SimpleListTest {
+
+ public SimpleListTest() {
+ }
+
+ @DataProvider(name = "lists")
+ public static Object[][] bothLists() {
+ return new Object[][] {
+ new Object[] { new ArrayList<Object>() },
+ new Object[] { SimpleList.asList() },
+ };
+ }
+
+ @Test(dataProvider = "lists")
+ public void testListIterator(List<String> list) {
+ list.add("Hi");
+ list.add("Ahoj");
+ list.add("Ciao");
+
+ Collections.sort(list);
+
+ ListIterator<String> it = list.listIterator(3);
+ assertEquals(it.previous(), "Hi");
+ assertEquals(it.previous(), "Ciao");
+ it.remove();
+ assertEquals(it.next(), "Hi");
+ assertEquals(it.previous(), "Hi");
+ assertEquals(it.previous(), "Ahoj");
+ assertEquals(list.size(), 2);
+ }
+
+ @Test(dataProvider = "lists")
+ public void toStringHashTest(List<Number> list) {
+ list.add(3);
+ list.add(3.3f);
+ list.add(4L);
+ list.add(4.4);
+ assertEquals(list.toString(), "[3, 3.3, 4, 4.4]");
+ assertEquals(list.hashCode(), 1374332816);
+ }
+
+ @Test(dataProvider = "lists")
+ public void toStringHashSubListTest(List<Number> list) {
+ list.add(3);
+ list.add(3.3f);
+ list.add(4L);
+ list.add(4.4);
+
+ list = list.subList(0, 4);
+
+ assertEquals(list.toString(), "[3, 3.3, 4, 4.4]");
+ assertEquals(list.hashCode(), 1374332816);
+ }
+
+ @Test(dataProvider = "lists")
+ public void subListEqualsTest(List<Number> list) {
+ list.add(3);
+ list.add(3.3f);
+ list.add(4L);
+ list.add(4.4);
+
+ assertEquals(list, list.subList(0, 4));
+ }
+
+ @Test(dataProvider = "lists")
+ public void retainAll(List<Number> list) {
+ list.add(3);
+ list.add(3.3f);
+ list.add(4L);
+ list.add(4.4);
+
+ list.retainAll(Collections.singleton(4L));
+
+ assertEquals(list.size(), 1);
+ assertEquals(list.get(0), 4L);
+ }
+
+ @Test(dataProvider = "lists")
+ public void retainAllOnSubList(List<Number> list) {
+ list.add(3);
+ list.add(3.3f);
+ list.add(4L);
+ list.add(4.4);
+
+ List<Number> subList = list.subList(1, 4);
+
+ subList.retainAll(Collections.singleton(4L));
+
+ assertEquals(subList.size(), 1);
+ assertEquals(subList.get(0), 4L);
+
+ assertEquals(list.size(), 2);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/ee703cfd/ko4j/src/main/java/org/netbeans/html/ko4j/KO4J.java
----------------------------------------------------------------------
diff --git a/ko4j/src/main/java/org/netbeans/html/ko4j/KO4J.java b/ko4j/src/main/java/org/netbeans/html/ko4j/KO4J.java
index 4f304af..eb8afa4 100644
--- a/ko4j/src/main/java/org/netbeans/html/ko4j/KO4J.java
+++ b/ko4j/src/main/java/org/netbeans/html/ko4j/KO4J.java
@@ -18,7 +18,6 @@
*/
package org.netbeans.html.ko4j;
-import java.util.logging.Logger;
import net.java.html.json.Model;
import net.java.html.json.OnReceive;
import org.netbeans.html.boot.spi.Fn;
@@ -54,7 +53,6 @@ import org.openide.util.lookup.ServiceProvider;
*/
@ServiceProvider(service = Provider.class)
public final class KO4J implements Provider {
- static final Logger LOG = Logger.getLogger(KOSockets.class.getName());
private KOTech ko4j;
private KOTransfer trans;
private KOSockets socks;
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/ee703cfd/ko4j/src/main/java/org/netbeans/html/ko4j/KOTech.java
----------------------------------------------------------------------
diff --git a/ko4j/src/main/java/org/netbeans/html/ko4j/KOTech.java b/ko4j/src/main/java/org/netbeans/html/ko4j/KOTech.java
index dd1ba6d..c94e5ae 100644
--- a/ko4j/src/main/java/org/netbeans/html/ko4j/KOTech.java
+++ b/ko4j/src/main/java/org/netbeans/html/ko4j/KOTech.java
@@ -18,11 +18,12 @@
*/
package org.netbeans.html.ko4j;
+import java.util.List;
+import net.java.html.json.Models;
import org.netbeans.html.context.spi.Contexts;
import org.netbeans.html.json.spi.FunctionBinding;
import org.netbeans.html.json.spi.PropertyBinding;
import org.netbeans.html.json.spi.Technology;
-import static org.netbeans.html.ko4j.KO4J.LOG;
/** This is an implementation package - just
* include its JAR on classpath and use official {@link Context} API
@@ -132,9 +133,12 @@ implements Technology.BatchCopy<Object>, Technology.ValueMutated<Object>, Techno
Object ko = Knockout.applyBindings(id, data);
if (ko instanceof Knockout) {
((Knockout)ko).hold();
+ applied.add((Knockout) ko);
}
}
+ private static final List<Knockout> applied = Models.asList();
+
@Override
public Object wrapArray(Object[] arr) {
return arr;
@@ -142,7 +146,6 @@ implements Technology.BatchCopy<Object>, Technology.ValueMutated<Object>, Techno
@Override
public void runSafe(final Runnable r) {
- LOG.warning("Technology.runSafe has been deprecated. Use BrwsrCtx.execute!");
r.run();
}
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/ee703cfd/ko4j/src/main/java/org/netbeans/html/ko4j/KOTransfer.java
----------------------------------------------------------------------
diff --git a/ko4j/src/main/java/org/netbeans/html/ko4j/KOTransfer.java b/ko4j/src/main/java/org/netbeans/html/ko4j/KOTransfer.java
index 6da4858..e980f98 100644
--- a/ko4j/src/main/java/org/netbeans/html/ko4j/KOTransfer.java
+++ b/ko4j/src/main/java/org/netbeans/html/ko4j/KOTransfer.java
@@ -22,8 +22,8 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
-import java.util.ArrayList;
import java.util.List;
+import net.java.html.json.Models;
import org.netbeans.html.context.spi.Contexts;
import org.netbeans.html.json.spi.JSONCall;
import org.netbeans.html.json.spi.Transfer;
@@ -65,7 +65,7 @@ implements Transfer {
call.notifyError(ex);
}
}
- List<String> headerPairs = new ArrayList<String>();
+ List<String> headerPairs = Models.asList();
String h = call.getHeaders();
if (h != null) {
int pos = 0;
@@ -94,7 +94,7 @@ implements Transfer {
@Override
public Object toJSON(InputStream is) throws IOException {
StringBuilder sb = new StringBuilder();
- InputStreamReader r = new InputStreamReader(is);
+ InputStreamReader r = new InputStreamReader(is, "UTF-8");
for (;;) {
int ch = r.read();
if (ch == -1) {
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/ee703cfd/ko4j/src/main/java/org/netbeans/html/ko4j/Knockout.java
----------------------------------------------------------------------
diff --git a/ko4j/src/main/java/org/netbeans/html/ko4j/Knockout.java b/ko4j/src/main/java/org/netbeans/html/ko4j/Knockout.java
index f175ee0..df5b03a 100644
--- a/ko4j/src/main/java/org/netbeans/html/ko4j/Knockout.java
+++ b/ko4j/src/main/java/org/netbeans/html/ko4j/Knockout.java
@@ -18,11 +18,6 @@
*/
package org.netbeans.html.ko4j;
-import java.lang.ref.ReferenceQueue;
-import java.lang.ref.WeakReference;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
import net.java.html.js.JavaScriptBody;
import net.java.html.js.JavaScriptResource;
import net.java.html.json.Model;
@@ -39,9 +34,7 @@ import org.netbeans.html.json.spi.PropertyBinding;
* @author Jaroslav Tulach
*/
@JavaScriptResource("knockout-3.4.0.js")
-final class Knockout extends WeakReference<Object> {
- private static final ReferenceQueue<Object> QUEUE = new ReferenceQueue();
- private static final Set<Knockout> active = Collections.synchronizedSet(new HashSet<Knockout>());
+final class Knockout {
@JavaScriptBody(args = {"object", "property"}, body =
"var ret;\n" +
@@ -60,7 +53,7 @@ final class Knockout extends WeakReference<Object> {
private Object strong;
public Knockout(Object model, Object js, PropertyBinding[] props, FunctionBinding[] funcs) {
- super(model, QUEUE);
+ this.strong = model;
this.js = js;
this.props = new PropertyBinding[props.length];
for (int i = 0; i < props.length; i++) {
@@ -70,16 +63,14 @@ final class Knockout extends WeakReference<Object> {
for (int i = 0; i < funcs.length; i++) {
this.funcs[i] = funcs[i].weak();
}
- active.add(this);
}
static void cleanUp() {
for (;;) {
- Knockout ko = (Knockout)QUEUE.poll();
+ Knockout ko = null;
if (ko == null) {
return;
}
- active.remove(ko);
clean(ko.js);
ko.js = null;
ko.props = null;
@@ -88,7 +79,10 @@ final class Knockout extends WeakReference<Object> {
}
final void hold() {
- strong = get();
+ }
+
+ final Object get() {
+ return strong;
}
final Object getValue(int index) {
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/ee703cfd/ko4j/src/test/java/org/netbeans/html/ko4j/KOFx.java
----------------------------------------------------------------------
diff --git a/ko4j/src/test/java/org/netbeans/html/ko4j/KOFx.java b/ko4j/src/test/java/org/netbeans/html/ko4j/KOFx.java
index ba47648..1e34b1c 100644
--- a/ko4j/src/test/java/org/netbeans/html/ko4j/KOFx.java
+++ b/ko4j/src/test/java/org/netbeans/html/ko4j/KOFx.java
@@ -22,8 +22,6 @@ import java.io.Closeable;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-import java.util.logging.Level;
-import java.util.logging.Logger;
import javafx.application.Platform;
import org.netbeans.html.boot.spi.Fn;
import org.testng.ITest;
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/ee703cfd/ko4j/src/test/java/org/netbeans/html/ko4j/KnockoutFXTest.java
----------------------------------------------------------------------
diff --git a/ko4j/src/test/java/org/netbeans/html/ko4j/KnockoutFXTest.java b/ko4j/src/test/java/org/netbeans/html/ko4j/KnockoutFXTest.java
index 389086e..4306983 100644
--- a/ko4j/src/test/java/org/netbeans/html/ko4j/KnockoutFXTest.java
+++ b/ko4j/src/test/java/org/netbeans/html/ko4j/KnockoutFXTest.java
@@ -24,7 +24,6 @@ import java.io.InputStreamReader;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.net.URI;
-import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
@@ -174,7 +173,7 @@ public final class KnockoutFXTest extends KnockoutTCK {
private static native String findBaseURL();
@Override
- public URI prepareURL(String content, String mimeType, String[] parameters) {
+ public String prepareWebResource(String content, String mimeType, String[] parameters) {
try {
final URL baseURL = new URL(findBaseURL());
StringBuilder sb = new StringBuilder();
@@ -189,12 +188,9 @@ public final class KnockoutFXTest extends KnockoutTCK {
URL query = new URL(baseURL, sb.toString());
URLConnection c = query.openConnection();
BufferedReader br = new BufferedReader(new InputStreamReader(c.getInputStream()));
- URI connectTo = new URI(br.readLine());
- return connectTo;
+ return br.readLine();
} catch (IOException ex) {
throw new IllegalStateException(ex);
- } catch (URISyntaxException ex) {
- throw new IllegalStateException(ex);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/ee703cfd/src/main/javadoc/overview.html
----------------------------------------------------------------------
diff --git a/src/main/javadoc/overview.html b/src/main/javadoc/overview.html
index 408e0cb..5a898b6 100644
--- a/src/main/javadoc/overview.html
+++ b/src/main/javadoc/overview.html
@@ -57,6 +57,11 @@
multiple observers</a> on a single model object.
Better <a target="_blank" href="https://netbeans.org/bugzilla/show_bug.cgi?id=270553">
GC behavior</a> specified in TCK and used in Knockout for Java implementation.
+ Removing dependency on Java collection classes implementations.
+ Adding {@link net.java.html.json.Models#asList} factory method to
+ create simple list implementation.
+ Simplifying {@link org.netbeans.html.json.tck.KnockoutTCK} to avoid
+ usage of {@link java.net.URI}, etc.
<h3>New features in version 1.4</h3>