Separating context into its own module and making it less exposed for users of the @Model annotation
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/context/pom.xml Tue May 28 23:06:45 2013 +0200
1.3 @@ -0,0 +1,20 @@
1.4 +<?xml version="1.0"?>
1.5 +<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
1.6 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
1.7 + <modelVersion>4.0.0</modelVersion>
1.8 + <parent>
1.9 + <groupId>org.apidesign</groupId>
1.10 + <artifactId>html</artifactId>
1.11 + <version>0.4-SNAPSHOT</version>
1.12 + </parent>
1.13 + <groupId>org.apidesign.html</groupId>
1.14 + <artifactId>net.java.html</artifactId>
1.15 + <version>0.4-SNAPSHOT</version>
1.16 + <name>HTML Context</name>
1.17 + <url>http://maven.apache.org</url>
1.18 + <properties>
1.19 + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
1.20 + </properties>
1.21 + <dependencies>
1.22 + </dependencies>
1.23 +</project>
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/context/src/main/java/net/java/html/BrwsrCtx.java Tue May 28 23:06:45 2013 +0200
2.3 @@ -0,0 +1,93 @@
2.4 +/**
2.5 + * HTML via Java(tm) Language Bindings
2.6 + * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
2.7 + *
2.8 + * This program is free software: you can redistribute it and/or modify
2.9 + * it under the terms of the GNU General Public License as published by
2.10 + * the Free Software Foundation, version 2 of the License.
2.11 + *
2.12 + * This program is distributed in the hope that it will be useful,
2.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2.15 + * GNU General Public License for more details. apidesign.org
2.16 + * designates this particular file as subject to the
2.17 + * "Classpath" exception as provided by apidesign.org
2.18 + * in the License file that accompanied this code.
2.19 + *
2.20 + * You should have received a copy of the GNU General Public License
2.21 + * along with this program. Look for COPYING file in the top folder.
2.22 + * If not, see http://wiki.apidesign.org/wiki/GPLwithClassPathException
2.23 + */
2.24 +package net.java.html;
2.25 +
2.26 +import java.util.ServiceLoader;
2.27 +import org.apidesign.html.context.impl.CtxAccssr;
2.28 +import org.apidesign.html.context.impl.CtxImpl;
2.29 +import org.apidesign.html.context.spi.Contexts;
2.30 +
2.31 +/** Represents context where the {@link Model} and other objects
2.32 + * operate in. The context is usually a particular HTML page in a browser.
2.33 + * The context is also associated with the actual HTML rendering technology
2.34 + * in the HTML page - there is likely to be different context for
2.35 + * <a href="http://knockoutjs.com">knockout.js</a> and different one
2.36 + * for <a href="http://angularjs.org">angular</a>.
2.37 + *
2.38 + * @author Jaroslav Tulach <jtulach@netbeans.org>
2.39 + */
2.40 +public final class BrwsrCtx {
2.41 + private final CtxImpl impl;
2.42 + private BrwsrCtx(CtxImpl impl) {
2.43 + this.impl = impl;
2.44 + }
2.45 + static {
2.46 + new CtxAccssr() {
2.47 + @Override
2.48 + protected BrwsrCtx newContext(CtxImpl impl) {
2.49 + return new BrwsrCtx(impl);
2.50 + }
2.51 +
2.52 + @Override
2.53 + protected CtxImpl find(BrwsrCtx context) {
2.54 + return context.impl;
2.55 + }
2.56 + };
2.57 + }
2.58 + /** Dummy context without binding to any real browser or technology.
2.59 + * Useful for simple unit testing of behavior of various business logic
2.60 + * code.
2.61 + */
2.62 + public static final BrwsrCtx EMPTY = Contexts.newBuilder().build();
2.63 +
2.64 + /** Seeks for the default context that is associated with the requesting
2.65 + * class. If no suitable context is found, a warning message is
2.66 + * printed and {@link #EMPTY} context is returned.
2.67 + *
2.68 + * @param requestor the class that makes the request
2.69 + * @return appropriate context for the request
2.70 + */
2.71 + public static BrwsrCtx findDefault(Class<?> requestor) {
2.72 + org.apidesign.html.context.spi.Contexts.Builder cb = Contexts.newBuilder();
2.73 + boolean found = false;
2.74 + for (org.apidesign.html.context.spi.Contexts.Provider cp : ServiceLoader.load(org.apidesign.html.context.spi.Contexts.Provider.class)) {
2.75 + cp.fillContext(cb, requestor);
2.76 + found = true;
2.77 + }
2.78 + try {
2.79 + for (org.apidesign.html.context.spi.Contexts.Provider cp : ServiceLoader.load(org.apidesign.html.context.spi.Contexts.Provider.class, org.apidesign.html.context.spi.Contexts.Provider.class.getClassLoader())) {
2.80 + cp.fillContext(cb, requestor);
2.81 + found = true;
2.82 + }
2.83 + } catch (SecurityException ex) {
2.84 + if (!found) {
2.85 + throw ex;
2.86 + }
2.87 + // if we have some data from regular provides, go on
2.88 + }
2.89 + if (!found) {
2.90 + // XXX: print out a warning
2.91 + return EMPTY;
2.92 + }
2.93 + return cb.build();
2.94 + }
2.95 +
2.96 +}
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/context/src/main/java/org/apidesign/html/context/impl/CtxAccssr.java Tue May 28 23:06:45 2013 +0200
3.3 @@ -0,0 +1,52 @@
3.4 +/**
3.5 + * HTML via Java(tm) Language Bindings
3.6 + * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
3.7 + *
3.8 + * This program is free software: you can redistribute it and/or modify
3.9 + * it under the terms of the GNU General Public License as published by
3.10 + * the Free Software Foundation, version 2 of the License.
3.11 + *
3.12 + * This program is distributed in the hope that it will be useful,
3.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3.15 + * GNU General Public License for more details. apidesign.org
3.16 + * designates this particular file as subject to the
3.17 + * "Classpath" exception as provided by apidesign.org
3.18 + * in the License file that accompanied this code.
3.19 + *
3.20 + * You should have received a copy of the GNU General Public License
3.21 + * along with this program. Look for COPYING file in the top folder.
3.22 + * If not, see http://wiki.apidesign.org/wiki/GPLwithClassPathException
3.23 + */
3.24 +package org.apidesign.html.context.impl;
3.25 +
3.26 +import net.java.html.BrwsrCtx;
3.27 +
3.28 +/** Internal communication between API (e.g. {@link BrwsrCtx}), SPI
3.29 + * (e.g. {@link ContextBuilder}) and the implementation package.
3.30 + *
3.31 + * @author Jaroslav Tulach <jtulach@netbeans.org>
3.32 + */
3.33 +public abstract class CtxAccssr {
3.34 + private static CtxAccssr DEFAULT;
3.35 + static {
3.36 + // run initializers
3.37 + try {
3.38 + BrwsrCtx.EMPTY.getClass();
3.39 + } catch (NullPointerException ex) {
3.40 + // ignore
3.41 + }
3.42 + }
3.43 +
3.44 + protected CtxAccssr() {
3.45 + if (DEFAULT != null) throw new IllegalStateException();
3.46 + DEFAULT = this;
3.47 + }
3.48 +
3.49 + protected abstract BrwsrCtx newContext(CtxImpl impl);
3.50 + protected abstract CtxImpl find(BrwsrCtx context);
3.51 +
3.52 + static CtxAccssr getDefault() {
3.53 + return DEFAULT;
3.54 + }
3.55 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/context/src/main/java/org/apidesign/html/context/impl/CtxImpl.java Tue May 28 23:06:45 2013 +0200
4.3 @@ -0,0 +1,83 @@
4.4 +/**
4.5 + * HTML via Java(tm) Language Bindings
4.6 + * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
4.7 + *
4.8 + * This program is free software: you can redistribute it and/or modify
4.9 + * it under the terms of the GNU General Public License as published by
4.10 + * the Free Software Foundation, version 2 of the License.
4.11 + *
4.12 + * This program is distributed in the hope that it will be useful,
4.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
4.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4.15 + * GNU General Public License for more details. apidesign.org
4.16 + * designates this particular file as subject to the
4.17 + * "Classpath" exception as provided by apidesign.org
4.18 + * in the License file that accompanied this code.
4.19 + *
4.20 + * You should have received a copy of the GNU General Public License
4.21 + * along with this program. Look for COPYING file in the top folder.
4.22 + * If not, see http://wiki.apidesign.org/wiki/GPLwithClassPathException
4.23 + */
4.24 +package org.apidesign.html.context.impl;
4.25 +
4.26 +import java.util.ArrayList;
4.27 +import java.util.Collections;
4.28 +import java.util.List;
4.29 +import net.java.html.BrwsrCtx;
4.30 +
4.31 +/** Implementation detail. Holds list of technologies for particular
4.32 + * {@link BrwsrCtx}.
4.33 + *
4.34 + * @author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
4.35 + */
4.36 +public final class CtxImpl {
4.37 + private final List<Bind<?>> techs;
4.38 +
4.39 + public CtxImpl() {
4.40 + techs = new ArrayList<Bind<?>>();
4.41 + }
4.42 +
4.43 + private CtxImpl(List<Bind<?>> techs) {
4.44 + this.techs = techs;
4.45 + }
4.46 +
4.47 + public static <Tech> Tech find(BrwsrCtx context, Class<Tech> technology) {
4.48 + CtxImpl impl = CtxAccssr.getDefault().find(context);
4.49 + for (Bind<?> bind : impl.techs) {
4.50 + if (technology == bind.clazz) {
4.51 + return technology.cast(bind.impl);
4.52 + }
4.53 + }
4.54 + return null;
4.55 + }
4.56 +
4.57 + public BrwsrCtx build() {
4.58 + Collections.sort(techs);
4.59 + CtxImpl impl = new CtxImpl(Collections.unmodifiableList(techs));
4.60 + return CtxAccssr.getDefault().newContext(impl);
4.61 + }
4.62 +
4.63 + public <Tech> void register(Class<Tech> type, Tech impl, int priority) {
4.64 + techs.add(new Bind<Tech>(type, impl, priority));
4.65 + }
4.66 +
4.67 + private static final class Bind<Tech> implements Comparable<Bind<?>> {
4.68 + private final Class<Tech> clazz;
4.69 + private final Tech impl;
4.70 + private final int priority;
4.71 +
4.72 + public Bind(Class<Tech> clazz, Tech impl, int priority) {
4.73 + this.clazz = clazz;
4.74 + this.impl = impl;
4.75 + this.priority = priority;
4.76 + }
4.77 +
4.78 + @Override
4.79 + public int compareTo(Bind<?> o) {
4.80 + if (priority != o.priority) {
4.81 + return priority - o.priority;
4.82 + }
4.83 + return clazz.getName().compareTo(o.clazz.getName());
4.84 + }
4.85 + }
4.86 +}
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/context/src/main/java/org/apidesign/html/context/spi/Contexts.java Tue May 28 23:06:45 2013 +0200
5.3 @@ -0,0 +1,115 @@
5.4 +/**
5.5 + * HTML via Java(tm) Language Bindings
5.6 + * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
5.7 + *
5.8 + * This program is free software: you can redistribute it and/or modify
5.9 + * it under the terms of the GNU General Public License as published by
5.10 + * the Free Software Foundation, version 2 of the License.
5.11 + *
5.12 + * This program is distributed in the hope that it will be useful,
5.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
5.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5.15 + * GNU General Public License for more details. apidesign.org
5.16 + * designates this particular file as subject to the
5.17 + * "Classpath" exception as provided by apidesign.org
5.18 + * in the License file that accompanied this code.
5.19 + *
5.20 + * You should have received a copy of the GNU General Public License
5.21 + * along with this program. Look for COPYING file in the top folder.
5.22 + * If not, see http://wiki.apidesign.org/wiki/GPLwithClassPathException
5.23 + */
5.24 +package org.apidesign.html.context.spi;
5.25 +
5.26 +import net.java.html.BrwsrCtx;
5.27 +import org.apidesign.html.context.impl.CtxImpl;
5.28 +
5.29 +/**
5.30 + *
5.31 + * @author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
5.32 + */
5.33 +public final class Contexts {
5.34 + private Contexts() {
5.35 + }
5.36 +
5.37 + /** Creates new, empty builder for creation of {@link BrwsrCtx}. At the
5.38 + * end call the {@link #build()} method to generate the context.
5.39 + *
5.40 + * @return new instance of the builder
5.41 + */
5.42 + public static Builder newBuilder() {
5.43 + return new Builder();
5.44 + }
5.45 +
5.46 + /** Seeks for the specified technology in the provided context.
5.47 + *
5.48 + * @param <Tech> type of the technology
5.49 + * @param context the context to seek in
5.50 + * (previously filled with ({@link Builder#register(java.lang.Class, java.lang.Object, int)})
5.51 + * @param technology class that identifies the technology
5.52 + * @return
5.53 + */
5.54 + public static <Tech> Tech find(BrwsrCtx context, Class<Tech> technology) {
5.55 + return CtxImpl.find(context, technology);
5.56 + }
5.57 +
5.58 + /** Implementors of various HTML technologies should
5.59 + * register their implementation via {@link ServiceProvider} so
5.60 + * {@link ServiceProvider} can find them, when their JARs are included
5.61 + * on the classpath of the running application.
5.62 + *
5.63 + * @author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
5.64 + */
5.65 + public static interface Provider {
5.66 +
5.67 + /** Register into the context if suitable technology is
5.68 + * available for the requesting class.
5.69 + * The provider should check if its own technology is available in current
5.70 + * scope (e.g. proper JDK, proper browser, etc.). The provider
5.71 + * can also find the right context depending on requestor's classloader, etc.
5.72 + * <p>
5.73 + * Providers should use {@link Builder} to enrich appropriately
5.74 + * the context.
5.75 + *
5.76 + * @param context the context builder to fill with technologies
5.77 + * @param requestor the application class requesting access the the HTML page
5.78 + * @see BrwsrCtx#findDefault(java.lang.Class)
5.79 + */
5.80 + void fillContext(Builder context, Class<?> requestor);
5.81 + }
5.82 +
5.83 + /** Support for providers of new {@link BrwsrCtx}. Providers of different
5.84 + * technologies should be of particular interest in this class. End users
5.85 + * designing their application with existing technologies should rather
5.86 + * point their attention to {@link BrwsrCtx} and co.
5.87 + *
5.88 + * @author Jaroslav Tulach <jtulach@netbeans.org>
5.89 + */
5.90 + public static final class Builder {
5.91 + private CtxImpl impl = new CtxImpl();
5.92 +
5.93 + Builder() {
5.94 + }
5.95 +
5.96 + /** Registers new technology into the context. Each technology is
5.97 + * exactly identified by its implementation class and can be associated
5.98 + * with (positive) priority. In case of presence of multiple technologies
5.99 + * with the same class, the one with higher lower priority takes precedence.
5.100 + */
5.101 + public <Tech> Builder register(Class<Tech> type, Tech impl, int priority) {
5.102 + if (priority <= 0) {
5.103 + throw new IllegalStateException();
5.104 + }
5.105 + this.impl.register(type, impl, priority);
5.106 + return this;
5.107 + }
5.108 +
5.109 + /** Generates context based on values previously inserted into
5.110 + * this builder.
5.111 + *
5.112 + * @return new, immutable instance of {@link BrwsrCtx}
5.113 + */
5.114 + public BrwsrCtx build() {
5.115 + return impl.build();
5.116 + }
5.117 + }
5.118 +}
6.1 --- a/json-tck/src/main/java/net/java/html/json/tests/ConvertTypesTest.java Mon May 27 16:22:20 2013 +0200
6.2 +++ b/json-tck/src/main/java/net/java/html/json/tests/ConvertTypesTest.java Tue May 28 23:06:45 2013 +0200
6.3 @@ -25,7 +25,7 @@
6.4 import java.io.UnsupportedEncodingException;
6.5 import java.util.HashMap;
6.6 import java.util.Map;
6.7 -import net.java.html.json.Context;
6.8 +import net.java.html.BrwsrCtx;
6.9 import net.java.html.json.Models;
6.10 import org.apidesign.bck2brwsr.vmtest.BrwsrTest;
6.11 import org.apidesign.bck2brwsr.vmtest.VMTest;
6.12 @@ -71,7 +71,7 @@
6.13
6.14 @BrwsrTest
6.15 public void parseConvertToPeople() throws Exception {
6.16 - final Context c = Utils.newContext();
6.17 + final BrwsrCtx c = Utils.newContext();
6.18 final InputStream o = createIS(true);
6.19
6.20 Person p = Models.parse(c, Person.class, o);
6.21 @@ -94,7 +94,7 @@
6.22
6.23 @BrwsrTest
6.24 public void parseConvertToPeopleWithoutSex() throws Exception {
6.25 - final Context c = Utils.newContext();
6.26 + final BrwsrCtx c = Utils.newContext();
6.27 final InputStream o = createIS(false);
6.28 Person p = Models.parse(c, Person.class, o);
6.29
7.1 --- a/json-tck/src/main/java/net/java/html/json/tests/JSONTest.java Mon May 27 16:22:20 2013 +0200
7.2 +++ b/json-tck/src/main/java/net/java/html/json/tests/JSONTest.java Tue May 28 23:06:45 2013 +0200
7.3 @@ -21,7 +21,7 @@
7.4 package net.java.html.json.tests;
7.5
7.6 import java.io.ByteArrayInputStream;
7.7 -import net.java.html.json.Context;
7.8 +import net.java.html.BrwsrCtx;
7.9 import net.java.html.json.Model;
7.10 import net.java.html.json.Models;
7.11 import net.java.html.json.OnReceive;
7.12 @@ -46,7 +46,7 @@
7.13 private Integer orig;
7.14
7.15 @BrwsrTest public void toJSONInABrowser() throws Throwable {
7.16 - Person p = new Person(Utils.newContext());
7.17 + Person p = Models.bind(new Person(), Utils.newContext());
7.18 p.setSex(Sex.MALE);
7.19 p.setFirstName("Jarda");
7.20 p.setLastName("Tulach");
7.21 @@ -97,7 +97,7 @@
7.22 ))
7.23 @BrwsrTest public void loadAndParseJSON() throws InterruptedException {
7.24 if (js == null) {
7.25 - js = new JSONik(Utils.newContext());
7.26 + js = Models.bind(new JSONik(), Utils.newContext());
7.27 js.applyBindings();
7.28
7.29 js.fetch("person.json");
7.30 @@ -129,7 +129,7 @@
7.31 orig = scriptElements();
7.32 assert orig > 0 : "There should be some scripts on the page";
7.33
7.34 - js = new JSONik(Utils.newContext());
7.35 + js = Models.bind(new JSONik(), Utils.newContext());
7.36 js.applyBindings();
7.37
7.38 js.fetchViaJSONP("person.json");
7.39 @@ -166,10 +166,10 @@
7.40 orig = scriptElements();
7.41 assert orig > 0 : "There should be some scripts on the page";
7.42
7.43 - js = new JSONik(Utils.newContext());
7.44 + js = Models.bind(new JSONik(), Utils.newContext());
7.45 js.applyBindings();
7.46
7.47 - Person p = new Person(Context.EMPTY);
7.48 + Person p = Models.bind(new Person(), BrwsrCtx.EMPTY);
7.49 p.setFirstName("Jarda");
7.50 js.putPerson("person.json", p);
7.51 }
7.52 @@ -208,7 +208,7 @@
7.53 ))
7.54 @BrwsrTest public void loadAndParseJSONSentToArray() throws InterruptedException {
7.55 if (js == null) {
7.56 - js = new JSONik(Utils.newContext());
7.57 + js = Models.bind(new JSONik(), Utils.newContext());
7.58 js.applyBindings();
7.59
7.60 js.fetchArray("person.json");
7.61 @@ -230,7 +230,7 @@
7.62 ))
7.63 @BrwsrTest public void loadAndParseJSONArraySingle() throws InterruptedException {
7.64 if (js == null) {
7.65 - js = new JSONik(Utils.newContext());
7.66 + js = Models.bind(new JSONik(), Utils.newContext());
7.67 js.applyBindings();
7.68
7.69 js.fetch("person.json");
7.70 @@ -252,7 +252,7 @@
7.71 ))
7.72 @BrwsrTest public void loadAndParseArrayInPeople() throws InterruptedException {
7.73 if (js == null) {
7.74 - js = new JSONik(Utils.newContext());
7.75 + js = Models.bind(new JSONik(), Utils.newContext());
7.76 js.applyBindings();
7.77
7.78 js.fetchPeople("people.json");
7.79 @@ -278,7 +278,7 @@
7.80 ))
7.81 @BrwsrTest public void loadAndParseArrayOfIntegers() throws InterruptedException {
7.82 if (js == null) {
7.83 - js = new JSONik(Utils.newContext());
7.84 + js = Models.bind(new JSONik(), Utils.newContext());
7.85 js.applyBindings();
7.86
7.87 js.fetchPeopleAge("people.json");
7.88 @@ -305,7 +305,7 @@
7.89 ))
7.90 @BrwsrTest public void loadAndParseArrayOfEnums() throws InterruptedException {
7.91 if (js == null) {
7.92 - js = new JSONik(Utils.newContext());
7.93 + js = Models.bind(new JSONik(), Utils.newContext());
7.94 js.applyBindings();
7.95
7.96 js.fetchPeopleSex("people.json");
7.97 @@ -332,7 +332,7 @@
7.98 ))
7.99 @BrwsrTest public void loadAndParseJSONArray() throws InterruptedException {
7.100 if (js == null) {
7.101 - js = new JSONik(Utils.newContext());
7.102 + js = Models.bind(new JSONik(), Utils.newContext());
7.103 js.applyBindings();
7.104 js.fetchArray("person.json");
7.105 }
8.1 --- a/json-tck/src/main/java/net/java/html/json/tests/KnockoutTest.java Mon May 27 16:22:20 2013 +0200
8.2 +++ b/json-tck/src/main/java/net/java/html/json/tests/KnockoutTest.java Tue May 28 23:06:45 2013 +0200
8.3 @@ -24,6 +24,7 @@
8.4 import net.java.html.json.ComputedProperty;
8.5 import net.java.html.json.Function;
8.6 import net.java.html.json.Model;
8.7 +import net.java.html.json.Models;
8.8 import net.java.html.json.Property;
8.9 import org.apidesign.bck2brwsr.vmtest.BrwsrTest;
8.10 import org.apidesign.bck2brwsr.vmtest.HtmlFragment;
8.11 @@ -48,7 +49,7 @@
8.12 "<button id=\"hello\">Say Hello!</button>\n"
8.13 )
8.14 @BrwsrTest public void modifyValueAssertChangeInModel() throws Exception {
8.15 - KnockoutModel m = new KnockoutModel(Utils.newContext());
8.16 + KnockoutModel m = Models.bind(new KnockoutModel(), Utils.newContext());
8.17 m.setName("Kukuc");
8.18 m.applyBindings();
8.19
8.20 @@ -82,7 +83,7 @@
8.21 + "</ul>\n"
8.22 )
8.23 @BrwsrTest public void displayContentOfArray() throws Exception {
8.24 - KnockoutModel m = new KnockoutModel(Utils.newContext());
8.25 + KnockoutModel m = Models.bind(new KnockoutModel(), Utils.newContext());
8.26 m.getResults().add("Ahoj");
8.27 m.applyBindings();
8.28
8.29 @@ -104,7 +105,7 @@
8.30 "<input type='checkbox' id='b' data-bind='checked: enabled'></input>\n"
8.31 )
8.32 @BrwsrTest public void checkBoxToBooleanBinding() throws Exception {
8.33 - KnockoutModel m = new KnockoutModel(Utils.newContext());
8.34 + KnockoutModel m = Models.bind(new KnockoutModel(), Utils.newContext());
8.35 m.applyBindings();
8.36
8.37 assert !m.isEnabled() : "Is disabled";
8.38 @@ -122,7 +123,7 @@
8.39 + "</ul>\n"
8.40 )
8.41 @BrwsrTest public void displayContentOfDerivedArray() throws Exception {
8.42 - KnockoutModel m = new KnockoutModel(Utils.newContext());
8.43 + KnockoutModel m = Models.bind(new KnockoutModel(), Utils.newContext());
8.44 m.getResults().add("Ahoj");
8.45 m.applyBindings();
8.46
8.47 @@ -141,9 +142,9 @@
8.48 + "</ul>\n"
8.49 )
8.50 @BrwsrTest public void displayContentOfArrayOfPeople() throws Exception {
8.51 - KnockoutModel m = new KnockoutModel(Utils.newContext());
8.52 + KnockoutModel m = Models.bind(new KnockoutModel(), Utils.newContext());
8.53
8.54 - final Person first = new Person(Utils.newContext());
8.55 + final Person first = Models.bind(new Person(), Utils.newContext());
8.56 first.setFirstName("first");
8.57 m.getPeople().add(first);
8.58
8.59 @@ -152,7 +153,7 @@
8.60 int cnt = countChildren("ul");
8.61 assert cnt == 1 : "One child, but was " + cnt;
8.62
8.63 - final Person second = new Person(Utils.newContext());
8.64 + final Person second = Models.bind(new Person(), Utils.newContext());
8.65 second.setFirstName("second");
8.66 m.getPeople().add(second);
8.67
8.68 @@ -199,9 +200,9 @@
8.69 }
8.70
8.71 private void trasfertToFemale() throws Exception {
8.72 - KnockoutModel m = new KnockoutModel(Utils.newContext());
8.73 + KnockoutModel m = Models.bind(new KnockoutModel(), Utils.newContext());
8.74
8.75 - final Person first = new Person(Utils.newContext());
8.76 + final Person first = Models.bind(new Person(), Utils.newContext());
8.77 first.setFirstName("first");
8.78 first.setSex(Sex.MALE);
8.79 m.getPeople().add(first);
9.1 --- a/json-tck/src/main/java/net/java/html/json/tests/Utils.java Mon May 27 16:22:20 2013 +0200
9.2 +++ b/json-tck/src/main/java/net/java/html/json/tests/Utils.java Tue May 28 23:06:45 2013 +0200
9.3 @@ -22,7 +22,7 @@
9.4
9.5 import java.util.Map;
9.6 import java.util.ServiceLoader;
9.7 -import net.java.html.json.Context;
9.8 +import net.java.html.BrwsrCtx;
9.9 import org.apidesign.html.json.tck.KnockoutTCK;
9.10
9.11 /**
9.12 @@ -33,9 +33,9 @@
9.13 private Utils() {
9.14 }
9.15
9.16 - static Context newContext() {
9.17 + static BrwsrCtx newContext() {
9.18 for (KnockoutTCK tck : ServiceLoader.load(KnockoutTCK.class)) {
9.19 - Context c = tck.createContext();
9.20 + BrwsrCtx c = tck.createContext();
9.21 if (c != null) {
9.22 return c;
9.23 }
10.1 --- a/json-tck/src/main/java/org/apidesign/html/json/tck/KnockoutTCK.java Mon May 27 16:22:20 2013 +0200
10.2 +++ b/json-tck/src/main/java/org/apidesign/html/json/tck/KnockoutTCK.java Tue May 28 23:06:45 2013 +0200
10.3 @@ -21,13 +21,12 @@
10.4 package org.apidesign.html.json.tck;
10.5
10.6 import java.util.Map;
10.7 +import net.java.html.BrwsrCtx;
10.8 import net.java.html.json.tests.ConvertTypesTest;
10.9 import net.java.html.json.tests.KnockoutTest;
10.10 import net.java.html.json.tests.JSONTest;
10.11 -import net.java.html.json.Context;
10.12 import org.apidesign.bck2brwsr.vmtest.BrwsrTest;
10.13 import org.apidesign.bck2brwsr.vmtest.VMTest;
10.14 -import org.apidesign.html.json.spi.ContextBuilder;
10.15 import org.openide.util.lookup.ServiceProvider;
10.16
10.17 /** Entry point for providers of different HTML binding technologies (like
10.18 @@ -55,7 +54,7 @@
10.19 /** Implement to create new context for the test.
10.20 * Use {@link ContextBuilder} to implement context for your technology.
10.21 */
10.22 - public abstract Context createContext();
10.23 + public abstract BrwsrCtx createContext();
10.24
10.25 /** Create a JSON object as seen by the technology
10.26 * @param values mapping from names to values of properties
11.1 --- a/json/pom.xml Mon May 27 16:22:20 2013 +0200
11.2 +++ b/json/pom.xml Tue May 28 23:06:45 2013 +0200
11.3 @@ -51,5 +51,10 @@
11.4 <artifactId>org-openide-util-lookup</artifactId>
11.5 <scope>provided</scope>
11.6 </dependency>
11.7 + <dependency>
11.8 + <groupId>${project.groupId}</groupId>
11.9 + <artifactId>net.java.html</artifactId>
11.10 + <version>${project.version}</version>
11.11 + </dependency>
11.12 </dependencies>
11.13 </project>
12.1 --- a/json/src/main/java/net/java/html/json/Context.java Mon May 27 16:22:20 2013 +0200
12.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
12.3 @@ -1,96 +0,0 @@
12.4 -/**
12.5 - * HTML via Java(tm) Language Bindings
12.6 - * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
12.7 - *
12.8 - * This program is free software: you can redistribute it and/or modify
12.9 - * it under the terms of the GNU General Public License as published by
12.10 - * the Free Software Foundation, version 2 of the License.
12.11 - *
12.12 - * This program is distributed in the hope that it will be useful,
12.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
12.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12.15 - * GNU General Public License for more details. apidesign.org
12.16 - * designates this particular file as subject to the
12.17 - * "Classpath" exception as provided by apidesign.org
12.18 - * in the License file that accompanied this code.
12.19 - *
12.20 - * You should have received a copy of the GNU General Public License
12.21 - * along with this program. Look for COPYING file in the top folder.
12.22 - * If not, see http://wiki.apidesign.org/wiki/GPLwithClassPathException
12.23 - */
12.24 -package net.java.html.json;
12.25 -
12.26 -import java.util.ServiceLoader;
12.27 -import org.apidesign.html.json.impl.ContextAccessor;
12.28 -import org.apidesign.html.json.spi.ContextBuilder;
12.29 -import org.apidesign.html.json.spi.ContextProvider;
12.30 -import org.apidesign.html.json.spi.Technology;
12.31 -import org.apidesign.html.json.spi.Transfer;
12.32 -
12.33 -/** Represents context where the {@link Model} and other objects
12.34 - * operate in. The context is usually a particular HTML page in a browser.
12.35 - * The context is also associated with the actual HTML rendering technology
12.36 - * in the HTML page - there is likely to be different context for
12.37 - * <a href="http://knockoutjs.com">knockout.js</a> and different one
12.38 - * for <a href="http://angularjs.org">angular</a>.
12.39 - *
12.40 - * @author Jaroslav Tulach <jtulach@netbeans.org>
12.41 - */
12.42 -public final class Context {
12.43 - private final Technology<?> t;
12.44 - private final Transfer r;
12.45 -
12.46 - private Context(Technology<?> t, Transfer r) {
12.47 - t.getClass();
12.48 - r.getClass();
12.49 - this.t = t;
12.50 - this.r = r;
12.51 - }
12.52 - static {
12.53 - new ContextAccessor() {
12.54 - @Override
12.55 - protected Context newContext(Technology<?> t, Transfer r) {
12.56 - return new Context(t, r);
12.57 - }
12.58 -
12.59 - @Override
12.60 - protected Technology<?> technology(Context c) {
12.61 - return c.t;
12.62 - }
12.63 -
12.64 - @Override
12.65 - protected Transfer transfer(Context c) {
12.66 - return c.r;
12.67 - }
12.68 - };
12.69 - }
12.70 - /** Dummy context without binding to any real browser or technology.
12.71 - * Useful for simple unit testing of behavior of model classes.
12.72 - */
12.73 - public static final Context EMPTY = ContextBuilder.create().build();
12.74 -
12.75 - /** Seeks for the default context that is associated with the requesting
12.76 - * class. If no suitable context is found, a warning message is
12.77 - * printed and {@link #EMPTY} context is returned.
12.78 - *
12.79 - * @param requestor the class that makes the request
12.80 - * @return appropriate context for the request
12.81 - */
12.82 - public static Context findDefault(Class<?> requestor) {
12.83 - for (ContextProvider cp : ServiceLoader.load(ContextProvider.class)) {
12.84 - Context c = cp.findContext(requestor);
12.85 - if (c != null) {
12.86 - return c;
12.87 - }
12.88 - }
12.89 - for (ContextProvider cp : ServiceLoader.load(ContextProvider.class, ContextProvider.class.getClassLoader())) {
12.90 - Context c = cp.findContext(requestor);
12.91 - if (c != null) {
12.92 - return c;
12.93 - }
12.94 - }
12.95 - // XXX: print out a warning
12.96 - return Context.EMPTY;
12.97 - }
12.98 -
12.99 -}
13.1 --- a/json/src/main/java/net/java/html/json/Models.java Mon May 27 16:22:20 2013 +0200
13.2 +++ b/json/src/main/java/net/java/html/json/Models.java Tue May 28 23:06:45 2013 +0200
13.3 @@ -20,6 +20,7 @@
13.4 */
13.5 package net.java.html.json;
13.6
13.7 +import net.java.html.BrwsrCtx;
13.8 import java.io.IOException;
13.9 import java.io.InputStream;
13.10 import java.lang.reflect.Method;
13.11 @@ -46,6 +47,19 @@
13.12 return JSON.isModel(clazz);
13.13 }
13.14
13.15 + /** Binds given model to another context.
13.16 + *
13.17 + * @param <Model> class defined by {@link net.java.html.json.Model} annotation
13.18 + * @param model instance of a model defined by {@link net.java.html.json.Model} annotation
13.19 + * @param context context to which the model should be bound
13.20 + * @return new instance of model bound to new <code>context</code>
13.21 + * @throws IllegalArgumentException in case the instance is not generated by model interface
13.22 + * @since 0.4
13.23 + */
13.24 + public static <Model> Model bind(Model model, BrwsrCtx context) {
13.25 + return JSON.bindTo(model, context);
13.26 + }
13.27 +
13.28 /** Generic method to parse content of a model class from a stream.
13.29 *
13.30 * @param c context of the technology to use for reading
13.31 @@ -54,7 +68,7 @@
13.32 * @return new instance of the model class
13.33 * @since 0.2
13.34 */
13.35 - public static <M> M parse(Context c, Class<M> model, InputStream is) throws IOException {
13.36 + public static <M> M parse(BrwsrCtx c, Class<M> model, InputStream is) throws IOException {
13.37 return JSON.readStream(c, model, is);
13.38 }
13.39 }
14.1 --- a/json/src/main/java/org/apidesign/html/json/impl/Bindings.java Mon May 27 16:22:20 2013 +0200
14.2 +++ b/json/src/main/java/org/apidesign/html/json/impl/Bindings.java Tue May 28 23:06:45 2013 +0200
14.3 @@ -21,7 +21,7 @@
14.4 package org.apidesign.html.json.impl;
14.5
14.6 import org.apidesign.html.json.spi.PropertyBinding;
14.7 -import net.java.html.json.Context;
14.8 +import net.java.html.BrwsrCtx;
14.9 import org.apidesign.html.json.impl.PropertyBindingAccessor.FBData;
14.10 import org.apidesign.html.json.impl.PropertyBindingAccessor.PBData;
14.11 import org.apidesign.html.json.spi.FunctionBinding;
14.12 @@ -52,8 +52,8 @@
14.13 return fb;
14.14 }
14.15
14.16 - public static Bindings<?> apply(Context c, Object model) {
14.17 - Technology<?> bp = ContextAccessor.findTechnology(c);
14.18 + public static Bindings<?> apply(BrwsrCtx c, Object model) {
14.19 + Technology<?> bp = JSON.findTechnology(c);
14.20 return apply(bp, model);
14.21 }
14.22
15.1 --- a/json/src/main/java/org/apidesign/html/json/impl/ContextAccessor.java Mon May 27 16:22:20 2013 +0200
15.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
15.3 @@ -1,64 +0,0 @@
15.4 -/**
15.5 - * HTML via Java(tm) Language Bindings
15.6 - * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
15.7 - *
15.8 - * This program is free software: you can redistribute it and/or modify
15.9 - * it under the terms of the GNU General Public License as published by
15.10 - * the Free Software Foundation, version 2 of the License.
15.11 - *
15.12 - * This program is distributed in the hope that it will be useful,
15.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
15.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15.15 - * GNU General Public License for more details. apidesign.org
15.16 - * designates this particular file as subject to the
15.17 - * "Classpath" exception as provided by apidesign.org
15.18 - * in the License file that accompanied this code.
15.19 - *
15.20 - * You should have received a copy of the GNU General Public License
15.21 - * along with this program. Look for COPYING file in the top folder.
15.22 - * If not, see http://wiki.apidesign.org/wiki/GPLwithClassPathException
15.23 - */
15.24 -package org.apidesign.html.json.impl;
15.25 -
15.26 -import net.java.html.json.Context;
15.27 -import org.apidesign.html.json.spi.ContextBuilder;
15.28 -import org.apidesign.html.json.spi.Technology;
15.29 -import org.apidesign.html.json.spi.Transfer;
15.30 -
15.31 -/** Internal communication between API (e.g. {@link Context}), SPI
15.32 - * (e.g. {@link ContextBuilder}) and the implementation package.
15.33 - *
15.34 - * @author Jaroslav Tulach <jtulach@netbeans.org>
15.35 - */
15.36 -public abstract class ContextAccessor {
15.37 - private static ContextAccessor DEFAULT;
15.38 - static {
15.39 - // run initializers
15.40 - try {
15.41 - Context.EMPTY.getClass();
15.42 - } catch (NullPointerException ex) {
15.43 - // ignore
15.44 - }
15.45 - }
15.46 -
15.47 - protected ContextAccessor() {
15.48 - if (DEFAULT != null) throw new IllegalStateException();
15.49 - DEFAULT = this;
15.50 - }
15.51 -
15.52 - protected abstract Context newContext(Technology<?> t, Transfer r);
15.53 - protected abstract Technology<?> technology(Context c);
15.54 - protected abstract Transfer transfer(Context c);
15.55 -
15.56 -
15.57 - public static Context create(Technology<?> t, Transfer r) {
15.58 - return DEFAULT.newContext(t, r);
15.59 - }
15.60 -
15.61 - static Technology<?> findTechnology(Context c) {
15.62 - return DEFAULT.technology(c);
15.63 - }
15.64 - static Transfer findTransfer(Context c) {
15.65 - return DEFAULT.transfer(c);
15.66 - }
15.67 -}
16.1 --- a/json/src/main/java/org/apidesign/html/json/impl/FromJSON.java Mon May 27 16:22:20 2013 +0200
16.2 +++ b/json/src/main/java/org/apidesign/html/json/impl/FromJSON.java Tue May 28 23:06:45 2013 +0200
16.3 @@ -21,7 +21,7 @@
16.4
16.5 package org.apidesign.html.json.impl;
16.6
16.7 -import net.java.html.json.Context;
16.8 +import net.java.html.BrwsrCtx;
16.9
16.10 /**
16.11 *
16.12 @@ -29,5 +29,6 @@
16.13 */
16.14 public interface FromJSON<Data> {
16.15 public Class<Data> factoryFor();
16.16 - public Data read(Context c, Object d);
16.17 + public Data read(BrwsrCtx c, Object d);
16.18 + public Data cloneTo(Object d, BrwsrCtx c);
16.19 }
17.1 --- a/json/src/main/java/org/apidesign/html/json/impl/JSON.java Mon May 27 16:22:20 2013 +0200
17.2 +++ b/json/src/main/java/org/apidesign/html/json/impl/JSON.java Tue May 28 23:06:45 2013 +0200
17.3 @@ -20,13 +20,16 @@
17.4 */
17.5 package org.apidesign.html.json.impl;
17.6
17.7 +import org.apidesign.html.context.impl.CtxAccssr;
17.8 import java.io.IOException;
17.9 import java.io.InputStream;
17.10 import java.util.HashMap;
17.11 import java.util.Map;
17.12 -import net.java.html.json.Context;
17.13 -import static org.apidesign.html.json.impl.ContextAccessor.findTechnology;
17.14 +import net.java.html.BrwsrCtx;
17.15 +import org.apidesign.html.context.spi.Contexts;
17.16 +import org.apidesign.html.json.spi.FunctionBinding;
17.17 import org.apidesign.html.json.spi.JSONCall;
17.18 +import org.apidesign.html.json.spi.PropertyBinding;
17.19 import org.apidesign.html.json.spi.Technology;
17.20 import org.apidesign.html.json.spi.Transfer;
17.21
17.22 @@ -35,16 +38,25 @@
17.23 * @author Jaroslav Tulach <jtulach@netbeans.org>
17.24 */
17.25 public final class JSON {
17.26 -
17.27 private JSON() {
17.28 }
17.29
17.30 - public static void extract(Context c, Object value, String[] props, Object[] values) {
17.31 - Transfer t = ContextAccessor.findTransfer(c);
17.32 + static Technology<?> findTechnology(BrwsrCtx c) {
17.33 + Technology<?> t = Contexts.find(c, Technology.class);
17.34 + return t == null ? EmptyTech.EMPTY : t;
17.35 + }
17.36 +
17.37 + static Transfer findTransfer(BrwsrCtx c) {
17.38 + Transfer t = Contexts.find(c, Transfer.class);
17.39 + return t == null ? EmptyTech.EMPTY : t;
17.40 + }
17.41 +
17.42 + public static void extract(BrwsrCtx c, Object value, String[] props, Object[] values) {
17.43 + Transfer t = findTransfer(c);
17.44 t.extract(value, props, values);
17.45 }
17.46
17.47 - private static Object getProperty(Context c, Object obj, String prop) {
17.48 + private static Object getProperty(BrwsrCtx c, Object obj, String prop) {
17.49 if (prop == null) return obj;
17.50
17.51 String[] arr = { prop };
17.52 @@ -72,18 +84,18 @@
17.53 return value.toString();
17.54 }
17.55
17.56 - public static String toString(Context c, Object obj, String prop) {
17.57 + public static String toString(BrwsrCtx c, Object obj, String prop) {
17.58 obj = getProperty(c, obj, prop);
17.59 return obj instanceof String ? (String)obj : null;
17.60 }
17.61 - public static Number toNumber(Context c, Object obj, String prop) {
17.62 + public static Number toNumber(BrwsrCtx c, Object obj, String prop) {
17.63 obj = getProperty(c, obj, prop);
17.64 if (!(obj instanceof Number)) {
17.65 obj = Double.NaN;
17.66 }
17.67 return (Number)obj;
17.68 }
17.69 - public static <M> M toModel(Context c, Class<M> aClass, Object data, Object object) {
17.70 + public static <M> M toModel(BrwsrCtx c, Class<M> aClass, Object data, Object object) {
17.71 Technology<?> t = findTechnology(c);
17.72 Object o = t.toModel(aClass, data);
17.73 return aClass.cast(o);
17.74 @@ -91,19 +103,19 @@
17.75
17.76
17.77 public static void loadJSON(
17.78 - Context c, Runnable whenDone, Object[] result,
17.79 + BrwsrCtx c, Runnable whenDone, Object[] result,
17.80 String urlBefore, String urlAfter
17.81 ) {
17.82 loadJSON(c, whenDone, result, urlBefore, urlAfter, null, null);
17.83 }
17.84
17.85 public static void loadJSON(
17.86 - Context c, Runnable whenDone, Object[] result,
17.87 + BrwsrCtx c, Runnable whenDone, Object[] result,
17.88 String urlBefore, String urlAfter, String method,
17.89 Object data
17.90 ) {
17.91 JSONCall call = PropertyBindingAccessor.createCall(whenDone, result, urlBefore, urlAfter, method, data);
17.92 - Transfer t = ContextAccessor.findTransfer(c);
17.93 + Transfer t = findTransfer(c);
17.94 t.loadJSON(call);
17.95 }
17.96
17.97 @@ -117,23 +129,35 @@
17.98 }
17.99
17.100 public static boolean isModel(Class<?> clazz) {
17.101 + return findFrom(clazz) != null;
17.102 + }
17.103 +
17.104 + private static FromJSON<?> findFrom(Class<?> clazz) {
17.105 for (int i = 0; i < 2; i++) {
17.106 FromJSON<?> from = froms.get(clazz);
17.107 if (from == null) {
17.108 initClass(clazz);
17.109 } else {
17.110 - return true;
17.111 + return from;
17.112 }
17.113 }
17.114 - return false;
17.115 + return null;
17.116 }
17.117
17.118 - public static <T> T readStream(Context c, Class<T> modelClazz, InputStream data)
17.119 + public static <Model> Model bindTo(Model model, BrwsrCtx c) {
17.120 + FromJSON<?> from = findFrom(model.getClass());
17.121 + if (from == null) {
17.122 + throw new IllegalArgumentException();
17.123 + }
17.124 + return (Model) from.cloneTo(model, c);
17.125 + }
17.126 +
17.127 + public static <T> T readStream(BrwsrCtx c, Class<T> modelClazz, InputStream data)
17.128 throws IOException {
17.129 - Transfer tr = ContextAccessor.findTransfer(c);
17.130 + Transfer tr = findTransfer(c);
17.131 return read(c, modelClazz, tr.toJSON((InputStream)data));
17.132 }
17.133 - public static <T> T read(Context c, Class<T> modelClazz, Object data) {
17.134 + public static <T> T read(BrwsrCtx c, Class<T> modelClazz, Object data) {
17.135 if (modelClazz == String.class) {
17.136 return modelClazz.cast(data.toString());
17.137 }
17.138 @@ -164,4 +188,57 @@
17.139 // ignore and try again
17.140 }
17.141 }
17.142 +
17.143 + private static final class EmptyTech implements Technology<Object>, Transfer {
17.144 + private static final EmptyTech EMPTY = new EmptyTech();
17.145 +
17.146 + @Override
17.147 + public Object wrapModel(Object model) {
17.148 + return model;
17.149 + }
17.150 +
17.151 + @Override
17.152 + public void valueHasMutated(Object data, String propertyName) {
17.153 + }
17.154 +
17.155 + @Override
17.156 + public void bind(PropertyBinding b, Object model, Object data) {
17.157 + }
17.158 +
17.159 + @Override
17.160 + public void expose(FunctionBinding fb, Object model, Object d) {
17.161 + }
17.162 +
17.163 + @Override
17.164 + public void applyBindings(Object data) {
17.165 + }
17.166 +
17.167 + @Override
17.168 + public Object wrapArray(Object[] arr) {
17.169 + return arr;
17.170 + }
17.171 +
17.172 + @Override
17.173 + public void extract(Object obj, String[] props, Object[] values) {
17.174 + for (int i = 0; i < values.length; i++) {
17.175 + values[i] = null;
17.176 + }
17.177 + }
17.178 +
17.179 + @Override
17.180 + public void loadJSON(JSONCall call) {
17.181 + call.notifyError(new UnsupportedOperationException());
17.182 + }
17.183 +
17.184 + @Override
17.185 + public <M> M toModel(Class<M> modelClass, Object data) {
17.186 + return modelClass.cast(data);
17.187 + }
17.188 +
17.189 + @Override
17.190 + public Object toJSON(InputStream is) throws IOException {
17.191 + throw new IOException("Not supported");
17.192 + }
17.193 + }
17.194 +
17.195 }
18.1 --- a/json/src/main/java/org/apidesign/html/json/impl/JSONList.java Mon May 27 16:22:20 2013 +0200
18.2 +++ b/json/src/main/java/org/apidesign/html/json/impl/JSONList.java Tue May 28 23:06:45 2013 +0200
18.3 @@ -148,10 +148,10 @@
18.4 for (String dependant : deps) {
18.5 m.valueHasMutated(dependant);
18.6 }
18.7 - }
18.8 - Runnable r = onchange;
18.9 - if (r != null) {
18.10 - r.run();
18.11 + Runnable r = onchange;
18.12 + if (r != null) {
18.13 + r.run();
18.14 + }
18.15 }
18.16 }
18.17
19.1 --- a/json/src/main/java/org/apidesign/html/json/impl/ModelProcessor.java Mon May 27 16:22:20 2013 +0200
19.2 +++ b/json/src/main/java/org/apidesign/html/json/impl/ModelProcessor.java Tue May 28 23:06:45 2013 +0200
19.3 @@ -187,13 +187,16 @@
19.4 w.append("import net.java.html.json.*;\n");
19.5 w.append("public final class ").append(className).append(" implements Cloneable {\n");
19.6 w.append(" private boolean locked;\n");
19.7 - w.append(" private net.java.html.json.Context context;\n");
19.8 + w.append(" private net.java.html.BrwsrCtx context;\n");
19.9 w.append(" private org.apidesign.html.json.impl.Bindings ko;\n");
19.10 w.append(body.toString());
19.11 w.append(" private static Class<" + inPckName(e) + "> modelFor() { return null; }\n");
19.12 - w.append(" public ").append(className).append("(Context context) {\n");
19.13 + w.append(" private ").append(className).append("(net.java.html.BrwsrCtx context) {\n");
19.14 w.append(" this.context = context;\n");
19.15 w.append(" };\n");
19.16 + w.append(" public ").append(className).append("() {\n");
19.17 + w.append(" this(net.java.html.BrwsrCtx.findDefault(").append(className).append(".class));\n");
19.18 + w.append(" };\n");
19.19 w.append(" private org.apidesign.html.json.impl.Bindings intKnckt() {\n");
19.20 w.append(" if (ko != null) return ko;\n");
19.21 w.append(" ko = org.apidesign.html.json.impl.Bindings.apply(context, this);\n");
19.22 @@ -250,10 +253,11 @@
19.23 w.append(" throw new UnsupportedOperationException();\n");
19.24 w.append(" }\n");
19.25 w.append(" public Class<" + className + "> factoryFor() { return " + className + ".class; }\n");
19.26 - w.append(" public " + className + " read(Context c, Object json) { return new " + className + "(c, json); }\n");
19.27 + w.append(" public " + className + " read(net.java.html.BrwsrCtx c, Object json) { return new " + className + "(c, json); }\n");
19.28 + w.append(" public " + className + " cloneTo(Object o, net.java.html.BrwsrCtx c) { return ((" + className + ")o).clone(c); }\n");
19.29 w.append(" }\n");
19.30 w.append(" static { org.apidesign.html.json.impl.JSON.register(new P(0)); }\n");
19.31 - w.append(" private ").append(className).append("(Context c, Object json) {\n");
19.32 + w.append(" private ").append(className).append("(net.java.html.BrwsrCtx c, Object json) {\n");
19.33 w.append(" this.context = c;\n");
19.34 int values = 0;
19.35 for (int i = 0; i < propsGetSet.size(); i += 5) {
19.36 @@ -1022,7 +1026,10 @@
19.37 }
19.38 private void writeClone(String className, Prprt[] props, Writer w) throws IOException {
19.39 w.write(" public " + className + " clone() {\n");
19.40 - w.write(" " + className + " ret = new " + className + "(context);\n");
19.41 + w.write(" return clone(context);\n");
19.42 + w.write(" }\n");
19.43 + w.write(" private " + className + " clone(net.java.html.BrwsrCtx ctx) {\n");
19.44 + w.write(" " + className + " ret = new " + className + "(ctx);\n");
19.45 for (Prprt p : props) {
19.46 if (!p.array()) {
19.47 boolean isModel[] = { false };
19.48 @@ -1033,9 +1040,9 @@
19.49 w.write(" ret.prop_" + p.name() + " = prop_" + p.name() + ";\n");
19.50 continue;
19.51 }
19.52 - w.write(" ret.prop_" + p.name() + " = prop_" + p.name() + ".clone();\n");
19.53 + w.write(" ret.prop_" + p.name() + " = prop_" + p.name() + " == null ? null : prop_" + p.name() + ".clone();\n");
19.54 } else {
19.55 - w.write(" ret.prop_" + p.name() + " = prop_" + p.name() + ".clone();\n");
19.56 + w.write(" ret.prop_" + p.name() + ".addAll(prop_" + p.name() + ");\n");
19.57 }
19.58 }
19.59
20.1 --- a/json/src/main/java/org/apidesign/html/json/spi/ContextBuilder.java Mon May 27 16:22:20 2013 +0200
20.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
20.3 @@ -1,134 +0,0 @@
20.4 -/**
20.5 - * HTML via Java(tm) Language Bindings
20.6 - * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
20.7 - *
20.8 - * This program is free software: you can redistribute it and/or modify
20.9 - * it under the terms of the GNU General Public License as published by
20.10 - * the Free Software Foundation, version 2 of the License.
20.11 - *
20.12 - * This program is distributed in the hope that it will be useful,
20.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
20.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20.15 - * GNU General Public License for more details. apidesign.org
20.16 - * designates this particular file as subject to the
20.17 - * "Classpath" exception as provided by apidesign.org
20.18 - * in the License file that accompanied this code.
20.19 - *
20.20 - * You should have received a copy of the GNU General Public License
20.21 - * along with this program. Look for COPYING file in the top folder.
20.22 - * If not, see http://wiki.apidesign.org/wiki/GPLwithClassPathException
20.23 - */
20.24 -package org.apidesign.html.json.spi;
20.25 -
20.26 -import java.io.IOException;
20.27 -import java.io.InputStream;
20.28 -import net.java.html.json.Context;
20.29 -import org.apidesign.html.json.impl.ContextAccessor;
20.30 -
20.31 -/** Support for providers of new {@link Context}. Providers of different
20.32 - * technologies should be of particular interest in this class. End users
20.33 - * designing their application with existing technologies should rather
20.34 - * point their attention to {@link Context} and co.
20.35 - *
20.36 - * @author Jaroslav Tulach <jtulach@netbeans.org>
20.37 - */
20.38 -public final class ContextBuilder {
20.39 - private Technology<?> t;
20.40 - private Transfer r;
20.41 -
20.42 - private ContextBuilder() {
20.43 - EmptyTech et = new EmptyTech();
20.44 - t = et;
20.45 - r = et;
20.46 - }
20.47 -
20.48 - /** Creates new, empty builder for creation of {@link Context}. At the
20.49 - * end call the {@link #build()} method to generate the context.
20.50 - *
20.51 - * @return new instance of the builder
20.52 - */
20.53 - public static ContextBuilder create() {
20.54 - return new ContextBuilder();
20.55 - }
20.56 -
20.57 - /** Provides technology for the context.
20.58 - *
20.59 - * @param technology
20.60 - * @return this
20.61 - */
20.62 - public ContextBuilder withTechnology(Technology<?> technology) {
20.63 - this.t = technology;
20.64 - return this;
20.65 - }
20.66 -
20.67 - /** Provides transfer for the context.
20.68 - *
20.69 - * @param transfer
20.70 - * @return this
20.71 - */
20.72 - public ContextBuilder withTransfer(Transfer transfer) {
20.73 - this.r = transfer;
20.74 - return this;
20.75 - }
20.76 -
20.77 - /** Generates context based on values previously inserted into
20.78 - * this builder.
20.79 - *
20.80 - * @return new, immutable instance of {@link Context}
20.81 - */
20.82 - public Context build() {
20.83 - return ContextAccessor.create(t, r);
20.84 - }
20.85 -
20.86 - private static final class EmptyTech
20.87 - implements Technology<Object>, Transfer {
20.88 - @Override
20.89 - public Object wrapModel(Object model) {
20.90 - return model;
20.91 - }
20.92 -
20.93 - @Override
20.94 - public void valueHasMutated(Object data, String propertyName) {
20.95 - }
20.96 -
20.97 - @Override
20.98 - public void bind(PropertyBinding b, Object model, Object data) {
20.99 - }
20.100 -
20.101 - @Override
20.102 - public void expose(FunctionBinding fb, Object model, Object d) {
20.103 - }
20.104 -
20.105 - @Override
20.106 - public void applyBindings(Object data) {
20.107 - }
20.108 -
20.109 - @Override
20.110 - public Object wrapArray(Object[] arr) {
20.111 - return arr;
20.112 - }
20.113 -
20.114 - @Override
20.115 - public void extract(Object obj, String[] props, Object[] values) {
20.116 - for (int i = 0; i < values.length; i++) {
20.117 - values[i] = null;
20.118 - }
20.119 - }
20.120 -
20.121 - @Override
20.122 - public void loadJSON(JSONCall call) {
20.123 - call.notifyError(new UnsupportedOperationException());
20.124 - }
20.125 -
20.126 - @Override
20.127 - public <M> M toModel(Class<M> modelClass, Object data) {
20.128 - return modelClass.cast(data);
20.129 - }
20.130 -
20.131 - @Override
20.132 - public Object toJSON(InputStream is) throws IOException {
20.133 - throw new IOException("Not supported");
20.134 - }
20.135 - }
20.136 -
20.137 -}
21.1 --- a/json/src/main/java/org/apidesign/html/json/spi/ContextProvider.java Mon May 27 16:22:20 2013 +0200
21.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
21.3 @@ -1,46 +0,0 @@
21.4 -/**
21.5 - * HTML via Java(tm) Language Bindings
21.6 - * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
21.7 - *
21.8 - * This program is free software: you can redistribute it and/or modify
21.9 - * it under the terms of the GNU General Public License as published by
21.10 - * the Free Software Foundation, version 2 of the License.
21.11 - *
21.12 - * This program is distributed in the hope that it will be useful,
21.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
21.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21.15 - * GNU General Public License for more details. apidesign.org
21.16 - * designates this particular file as subject to the
21.17 - * "Classpath" exception as provided by apidesign.org
21.18 - * in the License file that accompanied this code.
21.19 - *
21.20 - * You should have received a copy of the GNU General Public License
21.21 - * along with this program. Look for COPYING file in the top folder.
21.22 - * If not, see http://wiki.apidesign.org/wiki/GPLwithClassPathException
21.23 - */
21.24 -package org.apidesign.html.json.spi;
21.25 -
21.26 -import net.java.html.json.Context;
21.27 -import org.openide.util.lookup.ServiceProvider;
21.28 -
21.29 -/** Implementors of various {@link Technology technologies} should
21.30 - * register their implementation via {@link ServiceProvider} so
21.31 - * {@link ServiceProvider} can find them, when their JARs are included
21.32 - * on the classpath of the running application.
21.33 - *
21.34 - * @author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
21.35 - */
21.36 -public interface ContextProvider {
21.37 - /** Identify the context suitable for provided requesting class.
21.38 - * The provider should check if its own technology is available in current
21.39 - * scope (e.g. proper JDK, proper browser, etc.). The provider
21.40 - * can also find the right context depending on requestor's classloader, etc.
21.41 - * <p>
21.42 - * Providers should use {@link ContextBuilder} to construct appropriately
21.43 - * configured context.
21.44 - *
21.45 - * @param requestor the application class requesting access the the HTML page
21.46 - * @return
21.47 - */
21.48 - Context findContext(Class<?> requestor);
21.49 -}
22.1 --- a/json/src/test/java/net/java/html/json/MapModelTest.java Mon May 27 16:22:20 2013 +0200
22.2 +++ b/json/src/test/java/net/java/html/json/MapModelTest.java Tue May 28 23:06:45 2013 +0200
22.3 @@ -20,13 +20,14 @@
22.4 */
22.5 package net.java.html.json;
22.6
22.7 +import net.java.html.BrwsrCtx;
22.8 import java.io.IOException;
22.9 import java.io.InputStream;
22.10 import java.lang.reflect.InvocationTargetException;
22.11 import java.util.HashMap;
22.12 import java.util.Map;
22.13 +import org.apidesign.html.context.spi.Contexts;
22.14 import org.apidesign.html.json.impl.WrapperObject;
22.15 -import org.apidesign.html.json.spi.ContextBuilder;
22.16 import org.apidesign.html.json.spi.FunctionBinding;
22.17 import org.apidesign.html.json.spi.JSONCall;
22.18 import org.apidesign.html.json.spi.PropertyBinding;
22.19 @@ -42,15 +43,16 @@
22.20 */
22.21 public class MapModelTest {
22.22 private MapTechnology t;
22.23 - private Context c;
22.24 + private BrwsrCtx c;
22.25
22.26 @BeforeMethod public void initTechnology() {
22.27 t = new MapTechnology();
22.28 - c = ContextBuilder.create().withTechnology(t).withTransfer(t).build();
22.29 + c = Contexts.newBuilder().register(Technology.class, t, 1).
22.30 + register(Transfer.class, t, 1).build();
22.31 }
22.32
22.33 @Test public void isThereABinding() throws Exception {
22.34 - Person p = new Person(c);
22.35 + Person p = Models.bind(new Person(), c);
22.36 p.setFirstName("Jarda");
22.37
22.38 Map m = (Map)WrapperObject.find(p);
22.39 @@ -70,7 +72,7 @@
22.40 }
22.41
22.42 @Test public void derivedProperty() throws Exception {
22.43 - Person p = new Person(c);
22.44 + Person p = Models.bind(new Person(), c);
22.45
22.46 Map m = (Map)WrapperObject.find(p);
22.47 Object v = m.get("fullName");
22.48 @@ -81,7 +83,7 @@
22.49 }
22.50
22.51 @Test public void changeSex() {
22.52 - Person p = new Person(c);
22.53 + Person p = Models.bind(new Person(), c);
22.54 p.setFirstName("Trans");
22.55 p.setSex(Sex.MALE);
22.56
22.57 @@ -99,7 +101,7 @@
22.58 }
22.59
22.60 @Test public void setSex() {
22.61 - Person p = new Person(c);
22.62 + Person p = Models.bind(new Person(), c);
22.63 p.setFirstName("Trans");
22.64
22.65 Map m = (Map)WrapperObject.find(p);
23.1 --- a/json/src/test/java/net/java/html/json/ModelTest.java Mon May 27 16:22:20 2013 +0200
23.2 +++ b/json/src/test/java/net/java/html/json/ModelTest.java Tue May 28 23:06:45 2013 +0200
23.3 @@ -20,12 +20,13 @@
23.4 */
23.5 package net.java.html.json;
23.6
23.7 +import net.java.html.BrwsrCtx;
23.8 import java.util.ArrayList;
23.9 import java.util.Collections;
23.10 import java.util.Iterator;
23.11 import java.util.List;
23.12 import java.util.ListIterator;
23.13 -import org.apidesign.html.json.spi.ContextBuilder;
23.14 +import org.apidesign.html.context.spi.Contexts;
23.15 import org.apidesign.html.json.spi.FunctionBinding;
23.16 import org.apidesign.html.json.spi.PropertyBinding;
23.17 import org.apidesign.html.json.spi.Technology;
23.18 @@ -54,7 +55,8 @@
23.19 @BeforeMethod
23.20 public void createModel() {
23.21 my = new MockTechnology();
23.22 - model = new Modelik(ContextBuilder.create().withTechnology(my).build());
23.23 + final BrwsrCtx c = Contexts.newBuilder().register(Technology.class, my, 1).build();
23.24 + model = Models.bind(new Modelik(), c);
23.25 }
23.26
23.27 @Test public void classGeneratedWithSetterGetter() {
23.28 @@ -166,7 +168,7 @@
23.29 static void loadPeople(Modelik thiz, People p) {
23.30 Modelik m = null;
23.31 m.applyBindings();
23.32 - m.loadPeople("http", "apidesign.org", "query", new Person(Context.EMPTY));
23.33 + m.loadPeople("http", "apidesign.org", "query", new Person());
23.34 }
23.35
23.36 @OnReceive(url = "{protocol}://{host}?callback={back}&query={query}", jsonp = "back")
24.1 --- a/json/src/test/java/net/java/html/json/TypesTest.java Mon May 27 16:22:20 2013 +0200
24.2 +++ b/json/src/test/java/net/java/html/json/TypesTest.java Tue May 28 23:06:45 2013 +0200
24.3 @@ -20,10 +20,13 @@
24.4 */
24.5 package net.java.html.json;
24.6
24.7 +import net.java.html.BrwsrCtx;
24.8 import java.util.Map;
24.9 import net.java.html.json.MapModelTest.One;
24.10 +import org.apidesign.html.context.spi.Contexts;
24.11 import org.apidesign.html.json.impl.WrapperObject;
24.12 -import org.apidesign.html.json.spi.ContextBuilder;
24.13 +import org.apidesign.html.json.spi.Technology;
24.14 +import org.apidesign.html.json.spi.Transfer;
24.15 import org.testng.annotations.BeforeMethod;
24.16 import org.testng.annotations.Test;
24.17 import static org.testng.Assert.*;
24.18 @@ -44,11 +47,12 @@
24.19 })
24.20 public class TypesTest {
24.21 private MapModelTest.MapTechnology t;
24.22 - private Context c;
24.23 + private BrwsrCtx c;
24.24
24.25 @BeforeMethod public void initTechnology() {
24.26 t = new MapModelTest.MapTechnology();
24.27 - c = ContextBuilder.create().withTechnology(t).withTransfer(t).build();
24.28 + c = Contexts.newBuilder().register(Technology.class, t, 1).
24.29 + register(Transfer.class, t, 1).build();
24.30 }
24.31 @Function static void readFromEvent(int intX,
24.32 /*
24.33 @@ -72,7 +76,7 @@
24.34 }
24.35
24.36 @Test public void canParseEventAttributes() {
24.37 - Types t = new Types(c);
24.38 + Types t = Models.bind(new Types(), c);
24.39 t.setIntX(33);
24.40 t.setDoubleX(180.5);
24.41 t.setStringX("Ahoj");
24.42 @@ -87,7 +91,7 @@
24.43
24.44 Object json = WrapperObject.find(t);
24.45
24.46 - Types copy = new Types(c);
24.47 + Types copy = Models.bind(new Types(), c);
24.48 Map copyMap = (Map) WrapperObject.find(copy);
24.49 One o = (One) copyMap.get("readFromEvent");
24.50 o.fb.call(null, json);
25.1 --- a/json/src/test/java/org/apidesign/html/json/impl/EmployerTest.java Mon May 27 16:22:20 2013 +0200
25.2 +++ b/json/src/test/java/org/apidesign/html/json/impl/EmployerTest.java Tue May 28 23:06:45 2013 +0200
25.3 @@ -20,7 +20,7 @@
25.4 */
25.5 package org.apidesign.html.json.impl;
25.6
25.7 -import net.java.html.json.Context;
25.8 +import net.java.html.BrwsrCtx;
25.9 import net.java.html.json.Model;
25.10 import net.java.html.json.Property;
25.11 import org.testng.Assert;
25.12 @@ -35,7 +35,7 @@
25.13 })
25.14 public class EmployerTest {
25.15 @Test public void preLoadsTheClass() {
25.16 - Employer em = JSON.read(Context.EMPTY, Employer.class, this);
25.17 + Employer em = JSON.read(BrwsrCtx.EMPTY, Employer.class, this);
25.18 Assert.assertNotNull(em, "Class loaded");
25.19 em.applyBindings();
25.20 }
26.1 --- a/json/src/test/java/org/apidesign/html/json/impl/JSONListTest.java Mon May 27 16:22:20 2013 +0200
26.2 +++ b/json/src/test/java/org/apidesign/html/json/impl/JSONListTest.java Tue May 28 23:06:45 2013 +0200
26.3 @@ -22,11 +22,12 @@
26.4
26.5 import java.util.HashMap;
26.6 import java.util.Map;
26.7 -import net.java.html.json.Context;
26.8 +import net.java.html.BrwsrCtx;
26.9 +import net.java.html.json.Models;
26.10 import net.java.html.json.People;
26.11 import net.java.html.json.Person;
26.12 import net.java.html.json.Sex;
26.13 -import org.apidesign.html.json.spi.ContextBuilder;
26.14 +import org.apidesign.html.context.spi.Contexts;
26.15 import org.apidesign.html.json.spi.FunctionBinding;
26.16 import org.apidesign.html.json.spi.PropertyBinding;
26.17 import org.apidesign.html.json.spi.Technology;
26.18 @@ -50,9 +51,9 @@
26.19 }
26.20
26.21 @Test public void testConvertorOnAnObject() {
26.22 - Context c = ContextBuilder.create().withTechnology(this).build();
26.23 + BrwsrCtx c = Contexts.newBuilder().register(Technology.class, this, 1).build();
26.24
26.25 - Person p = new Person(c);
26.26 + Person p = Models.bind(new Person(), c);
26.27 p.setFirstName("1");
26.28 p.setLastName("2");
26.29 p.setSex(Sex.MALE);
26.30 @@ -62,14 +63,14 @@
26.31 }
26.32
26.33 @Test public void testConvertorOnAnArray() {
26.34 - Context c = ContextBuilder.create().withTechnology(this).build();
26.35 + BrwsrCtx c = Contexts.newBuilder().register(Technology.class, this, 1).build();
26.36
26.37 - Person p = new Person(c);
26.38 + Person p = Models.bind(new Person(), c);
26.39 p.setFirstName("1");
26.40 p.setLastName("2");
26.41 p.setSex(Sex.MALE);
26.42
26.43 - People people = new People(c);
26.44 + People people = Models.bind(new People(), c);
26.45 people.getInfo().add(p);
26.46 assertEquals(people.getInfo().toString(), "[{\"firstName\":\"1\",\"lastName\":\"2\",\"sex\":\"MALE\"}]", "Converted to real JSON");
26.47
26.48 @@ -84,9 +85,9 @@
26.49 }
26.50
26.51 @Test public void testNicknames() {
26.52 - Context c = ContextBuilder.create().withTechnology(this).build();
26.53 + BrwsrCtx c = Contexts.newBuilder().register(Technology.class, this, 1).build();
26.54
26.55 - People people = new People(c);
26.56 + People people = Models.bind(new People(), c);
26.57 people.getNicknames().add("One");
26.58 people.getNicknames().add("Two");
26.59
26.60 @@ -103,14 +104,14 @@
26.61
26.62 @Test public void testConvertorOnAnArrayWithWrapper() {
26.63 this.replaceArray = true;
26.64 - Context c = ContextBuilder.create().withTechnology(this).build();
26.65 + BrwsrCtx c = Contexts.newBuilder().register(Technology.class, this, 1).build();
26.66
26.67 - Person p = new Person(c);
26.68 + Person p = Models.bind(new Person(), c);
26.69 p.setFirstName("1");
26.70 p.setLastName("2");
26.71 p.setSex(Sex.MALE);
26.72
26.73 - People people = new People(c);
26.74 + People people = Models.bind(new People(), c);
26.75 people.getInfo().add(p);
26.76
26.77 Object real = WrapperObject.find(people.getInfo());
26.78 @@ -119,9 +120,9 @@
26.79
26.80 @Test public void bindingsOnArray() {
26.81 this.replaceArray = true;
26.82 - Context c = ContextBuilder.create().withTechnology(this).build();
26.83 + BrwsrCtx c = Contexts.newBuilder().register(Technology.class, this, 1).build();
26.84
26.85 - People p = new People(c);
26.86 + People p = Models.bind(new People(), c);
26.87 p.getAge().add(30);
26.88
26.89 PropertyBinding pb = bindings.get("age");
27.1 --- a/ko-bck2brwsr/src/main/java/org/apidesign/html/ko2brwsr/BrwsrCntxt.java Mon May 27 16:22:20 2013 +0200
27.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
27.3 @@ -1,135 +0,0 @@
27.4 -/**
27.5 - * HTML via Java(tm) Language Bindings
27.6 - * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
27.7 - *
27.8 - * This program is free software: you can redistribute it and/or modify
27.9 - * it under the terms of the GNU General Public License as published by
27.10 - * the Free Software Foundation, version 2 of the License.
27.11 - *
27.12 - * This program is distributed in the hope that it will be useful,
27.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
27.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27.15 - * GNU General Public License for more details. apidesign.org
27.16 - * designates this particular file as subject to the
27.17 - * "Classpath" exception as provided by apidesign.org
27.18 - * in the License file that accompanied this code.
27.19 - *
27.20 - * You should have received a copy of the GNU General Public License
27.21 - * along with this program. Look for COPYING file in the top folder.
27.22 - * If not, see http://wiki.apidesign.org/wiki/GPLwithClassPathException
27.23 - */
27.24 -package org.apidesign.html.ko2brwsr;
27.25 -
27.26 -import java.io.ByteArrayOutputStream;
27.27 -import java.io.IOException;
27.28 -import java.io.InputStream;
27.29 -import java.io.InputStreamReader;
27.30 -import java.util.logging.Level;
27.31 -import java.util.logging.Logger;
27.32 -import net.java.html.json.Context;
27.33 -import org.apidesign.html.json.spi.ContextBuilder;
27.34 -import org.apidesign.html.json.spi.FunctionBinding;
27.35 -import org.apidesign.html.json.spi.JSONCall;
27.36 -import org.apidesign.html.json.spi.PropertyBinding;
27.37 -import org.apidesign.html.json.spi.Technology;
27.38 -import org.apidesign.html.json.spi.Transfer;
27.39 -
27.40 -/**
27.41 - *
27.42 - * @author Jaroslav Tulach <jtulach@netbeans.org>
27.43 - */
27.44 -final class BrwsrCntxt implements Technology<Object>, Transfer {
27.45 - private BrwsrCntxt() {}
27.46 -
27.47 - public static final Context DEFAULT;
27.48 - static {
27.49 - BrwsrCntxt c = new BrwsrCntxt();
27.50 - DEFAULT = ContextBuilder.create().withTechnology(c).withTransfer(c).build();
27.51 - }
27.52 -
27.53 - @Override
27.54 - public void extract(Object obj, String[] props, Object[] values) {
27.55 - ConvertTypes.extractJSON(obj, props, values);
27.56 - }
27.57 -
27.58 - @Override
27.59 - public void loadJSON(final JSONCall call) {
27.60 - class R implements Runnable {
27.61 - Object[] arr = { null };
27.62 - @Override
27.63 - public void run() {
27.64 - call.notifySuccess(arr[0]);
27.65 - }
27.66 - }
27.67 - R r = new R();
27.68 - if (call.isJSONP()) {
27.69 - String me = ConvertTypes.createJSONP(r.arr, r);
27.70 - ConvertTypes.loadJSONP(call.composeURL(me), me);
27.71 - } else {
27.72 - String data = null;
27.73 - if (call.isDoOutput()) {
27.74 - try {
27.75 - ByteArrayOutputStream bos = new ByteArrayOutputStream();
27.76 - call.writeData(bos);
27.77 - data = new String(bos.toByteArray(), "UTF-8");
27.78 - } catch (IOException ex) {
27.79 - call.notifyError(ex);
27.80 - }
27.81 - }
27.82 - ConvertTypes.loadJSON(call.composeURL(null), r.arr, r, call.getMethod(), data);
27.83 - }
27.84 - }
27.85 -
27.86 - @Override
27.87 - public Object wrapModel(Object model) {
27.88 - return model;
27.89 - }
27.90 -
27.91 - @Override
27.92 - public void bind(PropertyBinding b, Object model, Object data) {
27.93 - Knockout.bind(data, b, b.getPropertyName(),
27.94 - "getValue__Ljava_lang_Object_2",
27.95 - b.isReadOnly() ? null : "setValue__VLjava_lang_Object_2",
27.96 - false, false
27.97 - );
27.98 - }
27.99 -
27.100 - @Override
27.101 - public void valueHasMutated(Object data, String propertyName) {
27.102 - Knockout.valueHasMutated(data, propertyName);
27.103 - }
27.104 -
27.105 - @Override
27.106 - public void expose(FunctionBinding fb, Object model, Object d) {
27.107 - Knockout.expose(d, fb, fb.getFunctionName(), "call__VLjava_lang_Object_2Ljava_lang_Object_2");
27.108 - }
27.109 -
27.110 - @Override
27.111 - public void applyBindings(Object data) {
27.112 - Knockout.applyBindings(data);
27.113 - }
27.114 -
27.115 - @Override
27.116 - public Object wrapArray(Object[] arr) {
27.117 - return arr;
27.118 - }
27.119 -
27.120 - @Override
27.121 - public <M> M toModel(Class<M> modelClass, Object data) {
27.122 - return modelClass.cast(data);
27.123 - }
27.124 -
27.125 - @Override
27.126 - public Object toJSON(InputStream is) throws IOException {
27.127 - StringBuilder sb = new StringBuilder();
27.128 - InputStreamReader r = new InputStreamReader(is);
27.129 - for (;;) {
27.130 - int ch = r.read();
27.131 - if (ch == -1) {
27.132 - break;
27.133 - }
27.134 - sb.append((char)ch);
27.135 - }
27.136 - return ConvertTypes.parse(sb.toString());
27.137 - }
27.138 -}
28.1 --- a/ko-bck2brwsr/src/main/java/org/apidesign/html/ko2brwsr/BrwsrCntxtPrvdr.java Mon May 27 16:22:20 2013 +0200
28.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
28.3 @@ -1,49 +0,0 @@
28.4 -/**
28.5 - * HTML via Java(tm) Language Bindings
28.6 - * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
28.7 - *
28.8 - * This program is free software: you can redistribute it and/or modify
28.9 - * it under the terms of the GNU General Public License as published by
28.10 - * the Free Software Foundation, version 2 of the License.
28.11 - *
28.12 - * This program is distributed in the hope that it will be useful,
28.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
28.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28.15 - * GNU General Public License for more details. apidesign.org
28.16 - * designates this particular file as subject to the
28.17 - * "Classpath" exception as provided by apidesign.org
28.18 - * in the License file that accompanied this code.
28.19 - *
28.20 - * You should have received a copy of the GNU General Public License
28.21 - * along with this program. Look for COPYING file in the top folder.
28.22 - * If not, see http://wiki.apidesign.org/wiki/GPLwithClassPathException
28.23 - */
28.24 -package org.apidesign.html.ko2brwsr;
28.25 -
28.26 -import net.java.html.json.Context;
28.27 -import org.apidesign.bck2brwsr.core.JavaScriptBody;
28.28 -import org.apidesign.html.json.spi.ContextProvider;
28.29 -import org.openide.util.lookup.ServiceProvider;
28.30 -
28.31 -/** This is an implementation package - just
28.32 - * include its JAR on classpath and use official {@link Context} API
28.33 - * to access the functionality.
28.34 - * <p>
28.35 - * Provides binding between models and <a href="http://bck2brwsr.apidesign.org">
28.36 - * Bck2Brwsr</a> VM.
28.37 - * Registers {@link ContextProvider}, so {@link ServiceLoader} can find it.
28.38 - *
28.39 - * @author Jaroslav Tulach <jtulach@netbeans.org>
28.40 - */
28.41 -@ServiceProvider(service = ContextProvider.class)
28.42 -public final class BrwsrCntxtPrvdr implements ContextProvider {
28.43 - @Override
28.44 - public Context findContext(Class<?> requestor) {
28.45 - return bck2BrwsrVM() ? BrwsrCntxt.DEFAULT : null;
28.46 - }
28.47 -
28.48 - @JavaScriptBody(args = { }, body = "return true;")
28.49 - private static boolean bck2BrwsrVM() {
28.50 - return false;
28.51 - }
28.52 -}
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
29.2 +++ b/ko-bck2brwsr/src/main/java/org/apidesign/html/ko2brwsr/BrwsrCtxImpl.java Tue May 28 23:06:45 2013 +0200
29.3 @@ -0,0 +1,129 @@
29.4 +/**
29.5 + * HTML via Java(tm) Language Bindings
29.6 + * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
29.7 + *
29.8 + * This program is free software: you can redistribute it and/or modify
29.9 + * it under the terms of the GNU General Public License as published by
29.10 + * the Free Software Foundation, version 2 of the License.
29.11 + *
29.12 + * This program is distributed in the hope that it will be useful,
29.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
29.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29.15 + * GNU General Public License for more details. apidesign.org
29.16 + * designates this particular file as subject to the
29.17 + * "Classpath" exception as provided by apidesign.org
29.18 + * in the License file that accompanied this code.
29.19 + *
29.20 + * You should have received a copy of the GNU General Public License
29.21 + * along with this program. Look for COPYING file in the top folder.
29.22 + * If not, see http://wiki.apidesign.org/wiki/GPLwithClassPathException
29.23 + */
29.24 +package org.apidesign.html.ko2brwsr;
29.25 +
29.26 +import java.io.ByteArrayOutputStream;
29.27 +import java.io.IOException;
29.28 +import java.io.InputStream;
29.29 +import java.io.InputStreamReader;
29.30 +import net.java.html.BrwsrCtx;
29.31 +import org.apidesign.html.context.spi.Contexts;
29.32 +import org.apidesign.html.json.spi.FunctionBinding;
29.33 +import org.apidesign.html.json.spi.JSONCall;
29.34 +import org.apidesign.html.json.spi.PropertyBinding;
29.35 +import org.apidesign.html.json.spi.Technology;
29.36 +import org.apidesign.html.json.spi.Transfer;
29.37 +
29.38 +/**
29.39 + *
29.40 + * @author Jaroslav Tulach <jtulach@netbeans.org>
29.41 + */
29.42 +final class BrwsrCtxImpl implements Technology<Object>, Transfer {
29.43 + private BrwsrCtxImpl() {}
29.44 +
29.45 + public static final BrwsrCtxImpl DEFAULT = new BrwsrCtxImpl();
29.46 +
29.47 + @Override
29.48 + public void extract(Object obj, String[] props, Object[] values) {
29.49 + ConvertTypes.extractJSON(obj, props, values);
29.50 + }
29.51 +
29.52 + @Override
29.53 + public void loadJSON(final JSONCall call) {
29.54 + class R implements Runnable {
29.55 + Object[] arr = { null };
29.56 + @Override
29.57 + public void run() {
29.58 + call.notifySuccess(arr[0]);
29.59 + }
29.60 + }
29.61 + R r = new R();
29.62 + if (call.isJSONP()) {
29.63 + String me = ConvertTypes.createJSONP(r.arr, r);
29.64 + ConvertTypes.loadJSONP(call.composeURL(me), me);
29.65 + } else {
29.66 + String data = null;
29.67 + if (call.isDoOutput()) {
29.68 + try {
29.69 + ByteArrayOutputStream bos = new ByteArrayOutputStream();
29.70 + call.writeData(bos);
29.71 + data = new String(bos.toByteArray(), "UTF-8");
29.72 + } catch (IOException ex) {
29.73 + call.notifyError(ex);
29.74 + }
29.75 + }
29.76 + ConvertTypes.loadJSON(call.composeURL(null), r.arr, r, call.getMethod(), data);
29.77 + }
29.78 + }
29.79 +
29.80 + @Override
29.81 + public Object wrapModel(Object model) {
29.82 + return model;
29.83 + }
29.84 +
29.85 + @Override
29.86 + public void bind(PropertyBinding b, Object model, Object data) {
29.87 + Knockout.bind(data, b, b.getPropertyName(),
29.88 + "getValue__Ljava_lang_Object_2",
29.89 + b.isReadOnly() ? null : "setValue__VLjava_lang_Object_2",
29.90 + false, false
29.91 + );
29.92 + }
29.93 +
29.94 + @Override
29.95 + public void valueHasMutated(Object data, String propertyName) {
29.96 + Knockout.valueHasMutated(data, propertyName);
29.97 + }
29.98 +
29.99 + @Override
29.100 + public void expose(FunctionBinding fb, Object model, Object d) {
29.101 + Knockout.expose(d, fb, fb.getFunctionName(), "call__VLjava_lang_Object_2Ljava_lang_Object_2");
29.102 + }
29.103 +
29.104 + @Override
29.105 + public void applyBindings(Object data) {
29.106 + Knockout.applyBindings(data);
29.107 + }
29.108 +
29.109 + @Override
29.110 + public Object wrapArray(Object[] arr) {
29.111 + return arr;
29.112 + }
29.113 +
29.114 + @Override
29.115 + public <M> M toModel(Class<M> modelClass, Object data) {
29.116 + return modelClass.cast(data);
29.117 + }
29.118 +
29.119 + @Override
29.120 + public Object toJSON(InputStream is) throws IOException {
29.121 + StringBuilder sb = new StringBuilder();
29.122 + InputStreamReader r = new InputStreamReader(is);
29.123 + for (;;) {
29.124 + int ch = r.read();
29.125 + if (ch == -1) {
29.126 + break;
29.127 + }
29.128 + sb.append((char)ch);
29.129 + }
29.130 + return ConvertTypes.parse(sb.toString());
29.131 + }
29.132 +}
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
30.2 +++ b/ko-bck2brwsr/src/main/java/org/apidesign/html/ko2brwsr/BrwsrCtxPrvdr.java Tue May 28 23:06:45 2013 +0200
30.3 @@ -0,0 +1,54 @@
30.4 +/**
30.5 + * HTML via Java(tm) Language Bindings
30.6 + * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
30.7 + *
30.8 + * This program is free software: you can redistribute it and/or modify
30.9 + * it under the terms of the GNU General Public License as published by
30.10 + * the Free Software Foundation, version 2 of the License.
30.11 + *
30.12 + * This program is distributed in the hope that it will be useful,
30.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
30.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30.15 + * GNU General Public License for more details. apidesign.org
30.16 + * designates this particular file as subject to the
30.17 + * "Classpath" exception as provided by apidesign.org
30.18 + * in the License file that accompanied this code.
30.19 + *
30.20 + * You should have received a copy of the GNU General Public License
30.21 + * along with this program. Look for COPYING file in the top folder.
30.22 + * If not, see http://wiki.apidesign.org/wiki/GPLwithClassPathException
30.23 + */
30.24 +package org.apidesign.html.ko2brwsr;
30.25 +
30.26 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
30.27 +import org.apidesign.html.context.spi.Contexts;
30.28 +import org.apidesign.html.json.spi.Technology;
30.29 +import org.apidesign.html.json.spi.Transfer;
30.30 +import org.openide.util.lookup.ServiceProvider;
30.31 +
30.32 +/** This is an implementation package - just
30.33 + * include its JAR on classpath and use official {@link Context} API
30.34 + * to access the functionality.
30.35 + * <p>
30.36 + * Provides binding between models and <a href="http://bck2brwsr.apidesign.org">
30.37 + * Bck2Brwsr</a> VM.
30.38 + * Registers {@link ContextProvider}, so {@link ServiceLoader} can find it.
30.39 + *
30.40 + * @author Jaroslav Tulach <jtulach@netbeans.org>
30.41 + */
30.42 +@ServiceProvider(service = Contexts.Provider.class)
30.43 +public final class BrwsrCtxPrvdr implements Contexts.Provider {
30.44 +
30.45 + @Override
30.46 + public void fillContext(Contexts.Builder context, Class<?> requestor) {
30.47 + if (bck2BrwsrVM()) {
30.48 + context.register(Technology.class, BrwsrCtxImpl.DEFAULT, 50).
30.49 + register(Transfer.class, BrwsrCtxImpl.DEFAULT, 50);
30.50 + }
30.51 + }
30.52 +
30.53 + @JavaScriptBody(args = { }, body = "return true;")
30.54 + private static boolean bck2BrwsrVM() {
30.55 + return false;
30.56 + }
30.57 +}
31.1 --- a/ko-bck2brwsr/src/test/java/org/apidesign/html/ko2brwsr/Bck2BrwsrKnockoutTest.java Mon May 27 16:22:20 2013 +0200
31.2 +++ b/ko-bck2brwsr/src/test/java/org/apidesign/html/ko2brwsr/Bck2BrwsrKnockoutTest.java Tue May 28 23:06:45 2013 +0200
31.3 @@ -21,9 +21,12 @@
31.4 package org.apidesign.html.ko2brwsr;
31.5
31.6 import java.util.Map;
31.7 -import net.java.html.json.Context;
31.8 +import net.java.html.BrwsrCtx;
31.9 import org.apidesign.bck2brwsr.core.JavaScriptBody;
31.10 import org.apidesign.bck2brwsr.vmtest.VMTest;
31.11 +import org.apidesign.html.context.spi.Contexts;
31.12 +import org.apidesign.html.json.spi.Technology;
31.13 +import org.apidesign.html.json.spi.Transfer;
31.14 import org.apidesign.html.json.tck.KnockoutTCK;
31.15 import org.openide.util.lookup.ServiceProvider;
31.16 import org.testng.annotations.Factory;
31.17 @@ -42,8 +45,10 @@
31.18 }
31.19
31.20 @Override
31.21 - public Context createContext() {
31.22 - return BrwsrCntxt.DEFAULT;
31.23 + public BrwsrCtx createContext() {
31.24 + return Contexts.newBuilder().
31.25 + register(Transfer.class, BrwsrCtxImpl.DEFAULT, 9).
31.26 + register(Technology.class, BrwsrCtxImpl.DEFAULT, 9).build();
31.27 }
31.28
31.29
32.1 --- a/ko-fx/src/main/java/org/apidesign/html/kofx/FXContext.java Mon May 27 16:22:20 2013 +0200
32.2 +++ b/ko-fx/src/main/java/org/apidesign/html/kofx/FXContext.java Tue May 28 23:06:45 2013 +0200
32.3 @@ -24,10 +24,8 @@
32.4 import java.io.InputStream;
32.5 import java.util.ServiceLoader;
32.6 import java.util.logging.Logger;
32.7 -import net.java.html.json.Context;
32.8 import netscape.javascript.JSObject;
32.9 -import org.apidesign.html.json.spi.ContextBuilder;
32.10 -import org.apidesign.html.json.spi.ContextProvider;
32.11 +import org.apidesign.html.context.spi.Contexts;
32.12 import org.apidesign.html.json.spi.FunctionBinding;
32.13 import org.apidesign.html.json.spi.JSONCall;
32.14 import org.apidesign.html.json.spi.PropertyBinding;
32.15 @@ -43,18 +41,16 @@
32.16 *
32.17 * @author Jaroslav Tulach <jtulach@netbeans.org>
32.18 */
32.19 -@ServiceProvider(service = ContextProvider.class)
32.20 +@ServiceProvider(service = Contexts.Provider.class)
32.21 public final class FXContext
32.22 -implements Technology<JSObject>, Transfer, ContextProvider {
32.23 +implements Technology<JSObject>, Transfer, Contexts.Provider {
32.24 static final Logger LOG = Logger.getLogger(FXContext.class.getName());
32.25
32.26 @Override
32.27 - public Context findContext(Class<?> requestor) {
32.28 + public void fillContext(Contexts.Builder context, Class<?> requestor) {
32.29 if (Knockout.web() != null) {
32.30 - return ContextBuilder.create().withTechnology(this).
32.31 - withTransfer(this).build();
32.32 - } else {
32.33 - return null;
32.34 + context.register(Technology.class, this, 100);
32.35 + context.register(Transfer.class, this, 100);
32.36 }
32.37 }
32.38
33.1 --- a/ko-fx/src/main/java/org/apidesign/html/kofx/Knockout.java Mon May 27 16:22:20 2013 +0200
33.2 +++ b/ko-fx/src/main/java/org/apidesign/html/kofx/Knockout.java Tue May 28 23:06:45 2013 +0200
33.3 @@ -27,7 +27,6 @@
33.4 import java.util.logging.Level;
33.5 import java.util.logging.Logger;
33.6 import javafx.scene.web.WebEngine;
33.7 -import net.java.html.json.Context;
33.8 import net.java.html.json.Model;
33.9 import netscape.javascript.JSObject;
33.10 import org.apidesign.html.json.spi.FunctionBinding;
34.1 --- a/ko-fx/src/test/java/org/apidesign/html/kofx/KnockoutFXTest.java Mon May 27 16:22:20 2013 +0200
34.2 +++ b/ko-fx/src/test/java/org/apidesign/html/kofx/KnockoutFXTest.java Tue May 28 23:06:45 2013 +0200
34.3 @@ -21,10 +21,12 @@
34.4 package org.apidesign.html.kofx;
34.5
34.6 import java.util.Map;
34.7 -import net.java.html.json.Context;
34.8 +import net.java.html.BrwsrCtx;
34.9 import netscape.javascript.JSObject;
34.10 import org.apidesign.bck2brwsr.vmtest.VMTest;
34.11 -import org.apidesign.html.json.spi.ContextBuilder;
34.12 +import org.apidesign.html.context.spi.Contexts;
34.13 +import org.apidesign.html.json.spi.Technology;
34.14 +import org.apidesign.html.json.spi.Transfer;
34.15 import org.apidesign.html.json.tck.KnockoutTCK;
34.16 import org.json.JSONException;
34.17 import org.json.JSONObject;
34.18 @@ -45,10 +47,12 @@
34.19 }
34.20
34.21 @Override
34.22 - public Context createContext() {
34.23 + public BrwsrCtx createContext() {
34.24 FXContext fx = new FXContext();
34.25 - return ContextBuilder.create().
34.26 - withTechnology(fx).withTransfer(fx).build();
34.27 + return Contexts.newBuilder().
34.28 + register(Technology.class, fx, 10).
34.29 + register(Transfer.class, fx, 10).
34.30 + build();
34.31 }
34.32
34.33 @Override
35.1 --- a/pom.xml Mon May 27 16:22:20 2013 +0200
35.2 +++ b/pom.xml Tue May 28 23:06:45 2013 +0200
35.3 @@ -25,6 +25,7 @@
35.4 <module>ko-archetype-test</module>
35.5 <module>ko-bck2brwsr</module>
35.6 <module>ko-fx</module>
35.7 + <module>context</module>
35.8 </modules>
35.9 <licenses>
35.10 <license>
35.11 @@ -255,4 +256,4 @@
35.12 </dependency>
35.13 </dependencies>
35.14 </dependencyManagement>
35.15 -</project>
35.16 +</project>
35.17 \ No newline at end of file