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 <[email protected]> Authored: Sat Sep 9 09:00:39 2017 +0200 Committer: Jaroslav Tulach <[email protected]> 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>
