Separating context into its own module and making it less exposed for users of the @Model annotation
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Tue, 28 May 2013 23:06:45 +0200
changeset 11633ef89a4a306
parent 104 c053a7d09c8c
parent 115 b236fc0949e0
child 117 605c51d32380
Separating context into its own module and making it less exposed for users of the @Model annotation
json/src/main/java/net/java/html/json/Context.java
json/src/main/java/org/apidesign/html/json/impl/ContextAccessor.java
json/src/main/java/org/apidesign/html/json/spi/ContextBuilder.java
json/src/main/java/org/apidesign/html/json/spi/ContextProvider.java
ko-bck2brwsr/src/main/java/org/apidesign/html/ko2brwsr/BrwsrCntxt.java
ko-bck2brwsr/src/main/java/org/apidesign/html/ko2brwsr/BrwsrCntxtPrvdr.java
     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