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 2019/05/04 11:05:12 UTC
[netbeans-html4j] 05/07: Documenting use of Fn.ref
This is an automated email from the ASF dual-hosted git repository.
jtulach pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/netbeans-html4j.git
commit 9f5b51df2e8db2e66f31085365b5d5b43d7ede83
Author: Jaroslav Tulach <ja...@apidesign.org>
AuthorDate: Sat May 4 10:40:56 2019 +0200
Documenting use of Fn.ref
---
.../netbeans/html/boot/fx/AbstractFXPresenter.java | 12 ++--
.../html/boot/fx/AbstractFXPresenterTest.java | 12 ++--
.../java/org/netbeans/html/boot/impl/FnUtils.java | 4 +-
.../html/boot/impl/JavaScriptProcesor.java | 10 +--
.../netbeans/html/boot/spi/FallbackIdentity.java | 4 +-
.../main/java/org/netbeans/html/boot/spi/Fn.java | 77 ++++++++++++++++++----
.../html/boot/spi/FallbackIdentityTest.java | 19 +++---
.../java/org/netbeans/html/ko4j/CacheObjs.java | 4 +-
.../main/java/org/netbeans/html/ko4j/Knockout.java | 2 +-
.../main/java/org/netbeans/html/ko4j/MapObjs.java | 18 ++---
10 files changed, 107 insertions(+), 55 deletions(-)
diff --git a/boot-fx/src/main/java/org/netbeans/html/boot/fx/AbstractFXPresenter.java b/boot-fx/src/main/java/org/netbeans/html/boot/fx/AbstractFXPresenter.java
index 26e1329..0e1737a 100644
--- a/boot-fx/src/main/java/org/netbeans/html/boot/fx/AbstractFXPresenter.java
+++ b/boot-fx/src/main/java/org/netbeans/html/boot/fx/AbstractFXPresenter.java
@@ -50,7 +50,7 @@ import org.netbeans.html.boot.spi.Fn;
* @author Jaroslav Tulach
*/
public abstract class AbstractFXPresenter implements Fn.Presenter,
-Fn.KeepAlive, Fn.ToJavaScript, Fn.FromJavaScript, Executor, Cloneable, Fn.Identity {
+Fn.KeepAlive, Fn.ToJavaScript, Fn.FromJavaScript, Executor, Cloneable, Fn.Ref<AbstractFXPresenter> {
static final Logger LOG = Logger.getLogger(FXPresenter.class.getName());
protected static int cnt;
protected Runnable onLoad;
@@ -605,7 +605,7 @@ Fn.KeepAlive, Fn.ToJavaScript, Fn.FromJavaScript, Executor, Cloneable, Fn.Identi
}
@Override
- public synchronized Fn.Identity id() {
+ public synchronized Fn.Ref<AbstractFXPresenter> reference() {
if (id == null) {
id = new Id(this);
}
@@ -613,22 +613,22 @@ Fn.KeepAlive, Fn.ToJavaScript, Fn.FromJavaScript, Executor, Cloneable, Fn.Identi
}
@Override
- public Fn.Presenter presenter() {
+ public AbstractFXPresenter presenter() {
return this;
}
- private static final class Id extends WeakReference<AbstractFXPresenter> implements Fn.Identity {
+ private static final class Id extends WeakReference<AbstractFXPresenter> implements Fn.Ref<AbstractFXPresenter> {
Id(AbstractFXPresenter referent) {
super(referent);
}
@Override
- public Fn.Identity id() {
+ public Fn.Ref<AbstractFXPresenter> reference() {
return this;
}
@Override
- public Fn.Presenter presenter() {
+ public AbstractFXPresenter presenter() {
return get();
}
}
diff --git a/boot-fx/src/test/java/org/netbeans/html/boot/fx/AbstractFXPresenterTest.java b/boot-fx/src/test/java/org/netbeans/html/boot/fx/AbstractFXPresenterTest.java
index 7176dbf..1c3a1cc 100644
--- a/boot-fx/src/test/java/org/netbeans/html/boot/fx/AbstractFXPresenterTest.java
+++ b/boot-fx/src/test/java/org/netbeans/html/boot/fx/AbstractFXPresenterTest.java
@@ -53,14 +53,16 @@ public class AbstractFXPresenterTest {
}
};
- Fn.Identity id1 = Fn.id(p1);
- Fn.Identity id12 = Fn.id(p1);
+ Fn.Ref<?> id1 = Fn.ref(p1);
+ Fn.Ref<?> id12 = Fn.ref(p1);
assertSame(id1, id12);
assertEquals(id1, id12);
+ assertSame(p1, id1.presenter());
- Fn.Identity id2 = Fn.id(p2);
- Fn.Identity id22 = Fn.id(p2);
+ Fn.Ref<?> id2 = Fn.ref(p2);
+ Fn.Ref<?> id22 = Fn.ref(p2);
+ assertSame(p2, id2.presenter());
assertSame(id2, id22);
assertEquals(id2, id22);
@@ -72,6 +74,6 @@ public class AbstractFXPresenterTest {
NbTestCase.assertGC("Presenter can disappear", ref1);
AbstractFXPresenter p2Clone = p2.clone();
- Assert.assertNotEquals(p2.id(), p2Clone.id());
+ Assert.assertNotEquals(p2.reference(), p2Clone.reference());
}
}
diff --git a/boot/src/main/java/org/netbeans/html/boot/impl/FnUtils.java b/boot/src/main/java/org/netbeans/html/boot/impl/FnUtils.java
index 02e753f..ed390dd 100644
--- a/boot/src/main/java/org/netbeans/html/boot/impl/FnUtils.java
+++ b/boot/src/main/java/org/netbeans/html/boot/impl/FnUtils.java
@@ -651,8 +651,8 @@ public final class FnUtils {
if (name.equals(Fn.Presenter.class.getName())) {
return Fn.Presenter.class;
}
- if (name.equals(Fn.Identity.class.getName())) {
- return Fn.Identity.class;
+ if (name.equals(Fn.Ref.class.getName())) {
+ return Fn.Ref.class;
}
if (name.equals(Fn.ToJavaScript.class.getName())) {
return Fn.ToJavaScript.class;
diff --git a/boot/src/main/java/org/netbeans/html/boot/impl/JavaScriptProcesor.java b/boot/src/main/java/org/netbeans/html/boot/impl/JavaScriptProcesor.java
index 5e421ae..9344809 100644
--- a/boot/src/main/java/org/netbeans/html/boot/impl/JavaScriptProcesor.java
+++ b/boot/src/main/java/org/netbeans/html/boot/impl/JavaScriptProcesor.java
@@ -400,18 +400,18 @@ public final class JavaScriptProcesor extends AbstractProcessor {
source.append("package ").append(pkgName).append(";\n");
source.append("public final class $JsCallbacks$ {\n");
source.append(" static final $JsCallbacks$ VM = new $JsCallbacks$(null);\n");
- source.append(" private final org.netbeans.html.boot.spi.Fn.Identity id;\n");
+ source.append(" private final org.netbeans.html.boot.spi.Fn.Ref<?> ref;\n");
source.append(" private $JsCallbacks$ next;\n");
source.append(" private $JsCallbacks$(org.netbeans.html.boot.spi.Fn.Presenter p) {\n");
- source.append(" this.id = org.netbeans.html.boot.spi.Fn.id(p);\n");
+ source.append(" this.ref = org.netbeans.html.boot.spi.Fn.ref(p);\n");
source.append(" }\n");
source.append(" synchronized final $JsCallbacks$ current() {\n");
source.append(" org.netbeans.html.boot.spi.Fn.Presenter now = org.netbeans.html.boot.spi.Fn.activePresenter();\n");
source.append(" $JsCallbacks$ thiz = this;\n");
source.append(" $JsCallbacks$ prev = null;\n");
source.append(" for (;;) {\n");
- source.append(" if (thiz.id != null) {\n");
- source.append(" org.netbeans.html.boot.spi.Fn.Presenter thizPresenter = thiz.id.presenter();\n");
+ source.append(" if (thiz.ref != null) {\n");
+ source.append(" org.netbeans.html.boot.spi.Fn.Presenter thizPresenter = thiz.ref.presenter();\n");
source.append(" if (thizPresenter == null) {\n");
source.append(" if (prev != null) {\n");
source.append(" prev.next = thiz.next;\n");
@@ -497,7 +497,7 @@ public final class JavaScriptProcesor extends AbstractProcessor {
sep = ", ";
}
source.append(") throws Throwable {\n");
- source.append(" org.netbeans.html.boot.spi.Fn.Presenter p = id.presenter(); \n");
+ source.append(" org.netbeans.html.boot.spi.Fn.Presenter p = ref.presenter(); \n");
source.append(convert);
if (useTryResources()) {
source.append(" try (java.io.Closeable a = org.netbeans.html.boot.spi.Fn.activate(p)) { \n");
diff --git a/boot/src/main/java/org/netbeans/html/boot/spi/FallbackIdentity.java b/boot/src/main/java/org/netbeans/html/boot/spi/FallbackIdentity.java
index a1d0cfc..087842c 100644
--- a/boot/src/main/java/org/netbeans/html/boot/spi/FallbackIdentity.java
+++ b/boot/src/main/java/org/netbeans/html/boot/spi/FallbackIdentity.java
@@ -20,7 +20,7 @@ package org.netbeans.html.boot.spi;
import java.lang.ref.WeakReference;
-final class FallbackIdentity extends WeakReference<Fn.Presenter> implements Fn.Identity {
+final class FallbackIdentity extends WeakReference<Fn.Presenter> implements Fn.Ref {
private final int hashCode;
FallbackIdentity(Fn.Presenter p) {
@@ -29,7 +29,7 @@ final class FallbackIdentity extends WeakReference<Fn.Presenter> implements Fn.I
}
@Override
- public Fn.Identity id() {
+ public Fn.Ref reference() {
return this;
}
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 f98abde..1a613ea 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
@@ -23,6 +23,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
+import java.lang.ref.WeakReference;
import java.net.URL;
import java.util.HashMap;
import java.util.HashSet;
@@ -38,7 +39,7 @@ import org.netbeans.html.boot.impl.FnContext;
* @author Jaroslav Tulach
*/
public abstract class Fn {
- private final Identity presenter;
+ private final Ref presenter;
/**
* @deprecated Ineffective as of 0.6.
@@ -56,7 +57,7 @@ public abstract class Fn {
* @since 0.6
*/
protected Fn(Presenter presenter) {
- this.presenter = id(presenter);
+ this.presenter = ref(presenter);
}
/** True, if currently active presenter is the same as presenter this
@@ -177,12 +178,25 @@ public abstract class Fn {
return FnContext.activate(p);
}
- public static Identity id(final Presenter p) {
+ /** Obtains a (usually {@linkplain WeakReference weak}) reference to
+ * the presenter. Such reference is suitable for embedding in various long
+ * living structures with a life-cycle that may outspan the one of presenter.
+ *
+ * @param p the presenter
+ * @return reference to the presenter, {@code null} only if {@code p} is {@code null}
+ * @since 1.6.1
+ * @see Ref
+ */
+ public static Ref<?> ref(final Presenter p) {
if (p == null) {
return null;
}
- if (p instanceof Identity) {
- return ((Identity) p).id();
+ if (p instanceof Ref<?>) {
+ Ref<?> r = ((Ref<?>) p).reference();
+ if (r == null) {
+ throw new NullPointerException();
+ }
+ return r;
}
return new FallbackIdentity(p);
}
@@ -332,17 +346,52 @@ public abstract class Fn {
public Fn defineFn(String code, String[] names, boolean[] keepAlive);
}
- public interface Identity {
- public Identity id();
- public Presenter presenter();
+ /**
+ * Reference to a {@link Presenter}.Each implementation of a {@link Presenter}
+ * may choose a way to reference itself (usually in a {@linkplain WeakReference weak way})
+ * effectively. Various code that needs to hold a reference to a presenter
+ * is then encouraged to obtain such reference via {@link Fn#ref(org.netbeans.html.boot.spi.Fn.Presenter)}
+ * call and hold on to it. Holding a reference to an instance of {@link Presenter}
+ * is discouraged as it may lead to memory leaks.
+ * <p>
+ * Presenters willing to to represent a reference to itself effectively shall
+ * also implement the {@link Ref} interface and return reasonable reference
+ * from the {@link #reference()} method.
+ *
+ * @param <P> the type of the presenter
+ * @see Fn#ref(org.netbeans.html.boot.spi.Fn.Presenter)
+ * @since 1.6.1
+ */
+ public interface Ref<P extends Presenter> {
+ /** Creates a reference to a presenter.
+ * Rather than calling this method directly, call {@link Fn#ref(org.netbeans.html.boot.spi.Fn.Presenter)}.
+ * @return a (weak) reference to the associated presenter
+ */
+ public Ref<P> reference();
+
+ /** The associated presenter.
+ *
+ * @return the presenter or {@code null}, if it has been GCed meanwhile
+ */
+ public P presenter();
+
+ /** Reference must properly implement {@link #hashCode} and {@link #equals}.
+ *
+ * @return proper hashcode
+ */
@Override
public int hashCode();
+
+ /** Reference must properly implement {@link #hashCode} and {@link #equals}.
+ *
+ * @return proper equals result
+ */
@Override
public boolean equals(Object obj);
}
private static class Preload extends Fn {
- private static Map<String, Set<Identity>> LOADED;
+ private static Map<String, Set<Ref>> LOADED;
private final Fn fn;
private final String resource;
private final Class<?> caller;
@@ -367,18 +416,18 @@ public abstract class Fn {
}
private void loadResource() throws Exception {
- Identity id = super.presenter;
+ Ref id = super.presenter;
if (id == null) {
- id = id(FnContext.currentPresenter(false));
+ id = ref(FnContext.currentPresenter(false));
}
Fn.Presenter realPresenter = id == null ? null : id.presenter();
if (realPresenter != null) {
if (LOADED == null) {
- LOADED = new HashMap<String, Set<Identity>>();
+ LOADED = new HashMap<String, Set<Ref>>();
}
- Set<Identity> there = LOADED.get(resource);
+ Set<Ref> there = LOADED.get(resource);
if (there == null) {
- there = new HashSet<Identity>();
+ there = new HashSet<Ref>();
LOADED.put(resource, there);
}
if (there.add(id)) {
diff --git a/boot/src/test/java/org/netbeans/html/boot/spi/FallbackIdentityTest.java b/boot/src/test/java/org/netbeans/html/boot/spi/FallbackIdentityTest.java
index 760531f..6a57522 100644
--- a/boot/src/test/java/org/netbeans/html/boot/spi/FallbackIdentityTest.java
+++ b/boot/src/test/java/org/netbeans/html/boot/spi/FallbackIdentityTest.java
@@ -24,10 +24,6 @@ import java.lang.ref.WeakReference;
import java.net.URL;
import org.netbeans.junit.NbTestCase;
import static org.testng.Assert.*;
-import org.testng.annotations.AfterClass;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
public class FallbackIdentityTest {
@@ -52,8 +48,8 @@ public class FallbackIdentityTest {
}
};
- Fn.Identity id1 = Fn.id(p);
- Fn.Identity id2 = Fn.id(p);
+ Fn.Ref<?> id1 = Fn.ref(p);
+ Fn.Ref<?> id2 = Fn.ref(p);
assertNotSame(id1, id2);
assertEquals(id1, id2);
@@ -66,7 +62,7 @@ public class FallbackIdentityTest {
@Test
public void testPresenterCanProvideItsOwnIdentity() {
- class IdPresenter implements Fn.Presenter, Fn.Identity {
+ class IdPresenter implements Fn.Presenter, Fn.Ref {
@Override
public Fn defineFn(String code, String... names) {
return null;
@@ -81,7 +77,7 @@ public class FallbackIdentityTest {
}
@Override
- public Fn.Identity id() {
+ public Fn.Ref reference() {
return this;
}
@@ -92,6 +88,11 @@ public class FallbackIdentityTest {
}
IdPresenter p = new IdPresenter();
- assertSame(p, Fn.id(p));
+ assertSame(p, Fn.ref(p));
+ }
+
+ @Test
+ public void nullYieldsNullReference() {
+ assertNull(Fn.ref(null));
}
}
diff --git a/ko4j/src/main/java/org/netbeans/html/ko4j/CacheObjs.java b/ko4j/src/main/java/org/netbeans/html/ko4j/CacheObjs.java
index 8b969ff..e1aea1a 100644
--- a/ko4j/src/main/java/org/netbeans/html/ko4j/CacheObjs.java
+++ b/ko4j/src/main/java/org/netbeans/html/ko4j/CacheObjs.java
@@ -25,14 +25,14 @@ final class CacheObjs {
/* both @GuardedBy CacheObjs.class */
private static final CacheObjs[] list = new CacheObjs[16];
private static int listAt = 0;
- private final Fn.Identity ref;
+ private final Fn.Ref<?> ref;
/* both @GuardedBy presenter single threaded access */
private Object[] jsObjects;
private int jsIndex;
private CacheObjs(Fn.Presenter p) {
- this.ref = Fn.id(p);
+ this.ref = Fn.ref(p);
}
Fn.Presenter get() {
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 883d27b..1e826d8 100644
--- a/ko4j/src/main/java/org/netbeans/html/ko4j/Knockout.java
+++ b/ko4j/src/main/java/org/netbeans/html/ko4j/Knockout.java
@@ -155,7 +155,7 @@ final class Knockout {
if (obj == null) {
return null;
} else {
- return ((Fn.Identity) obj).presenter();
+ return ((Fn.Ref) obj).presenter();
}
}
}
diff --git a/ko4j/src/main/java/org/netbeans/html/ko4j/MapObjs.java b/ko4j/src/main/java/org/netbeans/html/ko4j/MapObjs.java
index c2b996e..56a56bc 100644
--- a/ko4j/src/main/java/org/netbeans/html/ko4j/MapObjs.java
+++ b/ko4j/src/main/java/org/netbeans/html/ko4j/MapObjs.java
@@ -24,7 +24,7 @@ import net.java.html.json.Models;
import org.netbeans.html.boot.spi.Fn;
final class MapObjs {
- private static Fn.Identity onlyPresenter;
+ private static Fn.Ref onlyPresenter;
private static boolean usePresenter;
static {
@@ -38,11 +38,11 @@ final class MapObjs {
private final List<Object> all;
- private MapObjs(Fn.Identity id1, Object js) {
+ private MapObjs(Fn.Ref id1, Object js) {
this.all = Models.asList(id1, js);
}
- private MapObjs(Fn.Identity id1, Object js1, Fn.Identity id2, Object js2) {
+ private MapObjs(Fn.Ref id1, Object js1, Fn.Ref id2, Object js2) {
this.all = Models.asList(id1, js1, id2, js2);
}
@@ -62,9 +62,9 @@ final class MapObjs {
}
}
if (now == null) {
- return new MapObjs(Fn.id(key), js);
+ return new MapObjs(Fn.ref(key), js);
} else {
- return new MapObjs(onlyPresenter, now, Fn.id(key), js);
+ return new MapObjs(onlyPresenter, now, Fn.ref(key), js);
}
}
}
@@ -101,15 +101,15 @@ final class MapObjs {
return this;
}
}
- all.add(Fn.id(key));
+ all.add(Fn.ref(key));
all.add(js);
return this;
}
boolean isSameKey(int index, Fn.Presenter key) {
Object at = all.get(index);
- if (at instanceof Fn.Identity) {
- at = ((Fn.Identity)at).presenter();
+ if (at instanceof Fn.Ref) {
+ at = ((Fn.Ref)at).presenter();
}
return at == key;
}
@@ -138,6 +138,6 @@ final class MapObjs {
}
private static void setOnlyPresenter(Fn.Presenter p) {
- onlyPresenter = Fn.id(p);
+ onlyPresenter = Fn.ref(p);
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@netbeans.apache.org
For additional commands, e-mail: commits-help@netbeans.apache.org
For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists