Introducing second SPI interface - Transfer
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Tue, 23 Apr 2013 08:43:11 +0200
changeset 2354e266fb5c67
parent 22 990ceaedfbe0
child 24 ae78a6f9d1d2
Introducing second SPI interface - Transfer
json/src/main/java/net/java/html/json/Context.java
json/src/main/java/org/apidesign/html/json/impl/Bindings.java
json/src/main/java/org/apidesign/html/json/impl/ContextAccessor.java
json/src/main/java/org/apidesign/html/json/impl/JSON.java
json/src/main/java/org/apidesign/html/json/spi/ContextBuilder.java
json/src/main/java/org/apidesign/html/json/spi/Technology.java
json/src/main/java/org/apidesign/html/json/spi/Transfer.java
json/src/test/java/net/java/html/json/MapModelTest.java
json/src/test/java/net/java/html/json/ModelTest.java
json/src/test/java/net/java/html/json/TypesTest.java
json/src/test/java/org/apidesign/html/json/impl/JSONListTest.java
     1.1 --- a/json/src/main/java/net/java/html/json/Context.java	Mon Apr 22 23:18:55 2013 +0200
     1.2 +++ b/json/src/main/java/net/java/html/json/Context.java	Tue Apr 23 08:43:11 2013 +0200
     1.3 @@ -21,9 +21,11 @@
     1.4  package net.java.html.json;
     1.5  
     1.6  import org.apidesign.html.json.impl.ContextAccessor;
     1.7 +import org.apidesign.html.json.spi.ContextBuilder;
     1.8  import org.apidesign.html.json.spi.FunctionBinding;
     1.9  import org.apidesign.html.json.spi.PropertyBinding;
    1.10  import org.apidesign.html.json.spi.Technology;
    1.11 +import org.apidesign.html.json.spi.Transfer;
    1.12  
    1.13  /** Represents context where the {@link Model} and other objects
    1.14   * operate in. The context is usually a particular HTML page in a browser.
    1.15 @@ -36,61 +38,34 @@
    1.16   */
    1.17  public final class Context {
    1.18      private final Technology<?> t;
    1.19 +    private final Transfer r;
    1.20      
    1.21 -    private Context(Technology<?> t) {
    1.22 +    private Context(Technology<?> t, Transfer r) {
    1.23          t.getClass();
    1.24 +        r.getClass();
    1.25          this.t = t;
    1.26 +        this.r = r;
    1.27      }
    1.28      static {
    1.29          new ContextAccessor() {
    1.30              @Override
    1.31 -            protected Context newContext(Technology<?> t) {
    1.32 -                return new Context(t);
    1.33 +            protected Context newContext(Technology<?> t, Transfer r) {
    1.34 +                return new Context(t, r);
    1.35 +            }
    1.36 +            
    1.37 +            @Override
    1.38 +            protected Technology<?> technology(Context c) {
    1.39 +                return c.t;
    1.40              }
    1.41  
    1.42              @Override
    1.43 -            protected Technology<?> technology(Context c) {
    1.44 -                return c.t;
    1.45 +            protected Transfer transfer(Context c) {
    1.46 +                return c.r;
    1.47              }
    1.48          };
    1.49      }
    1.50      /** Dummy context without binding to any real browser or technology. 
    1.51       * Useful for simple unit testing of behavior of model classes.
    1.52       */
    1.53 -    public static final Context EMPTY = new Context(new EmptyTech());
    1.54 -    
    1.55 -    private static final class EmptyTech implements Technology<Object> {
    1.56 -        @Override
    1.57 -        public Object wrapModel(Object model) {
    1.58 -            return model;
    1.59 -        }
    1.60 -
    1.61 -        @Override
    1.62 -        public void valueHasMutated(Object data, String propertyName) {
    1.63 -        }
    1.64 -
    1.65 -        @Override
    1.66 -        public void bind(PropertyBinding b, Object model, Object data) {
    1.67 -        }
    1.68 -
    1.69 -        @Override
    1.70 -        public void expose(FunctionBinding fb, Object model, Object d) {
    1.71 -        }
    1.72 -
    1.73 -        @Override
    1.74 -        public void applyBindings(Object data) {
    1.75 -        }
    1.76 -
    1.77 -        @Override
    1.78 -        public Object wrapArray(Object[] arr) {
    1.79 -            return arr;
    1.80 -        }
    1.81 -
    1.82 -        @Override
    1.83 -        public void extract(Object obj, String[] props, Object[] values) {
    1.84 -            for (int i = 0; i < values.length; i++) {
    1.85 -                values[i] = null;
    1.86 -            }
    1.87 -        }
    1.88 -    }
    1.89 +    public static final Context EMPTY = ContextBuilder.create().build();
    1.90  }
     2.1 --- a/json/src/main/java/org/apidesign/html/json/impl/Bindings.java	Mon Apr 22 23:18:55 2013 +0200
     2.2 +++ b/json/src/main/java/org/apidesign/html/json/impl/Bindings.java	Tue Apr 23 08:43:11 2013 +0200
     2.3 @@ -20,8 +20,6 @@
     2.4   */
     2.5  package org.apidesign.html.json.impl;
     2.6  
     2.7 -import java.util.Arrays;
     2.8 -import java.util.List;
     2.9  import org.apidesign.html.json.spi.PropertyBinding;
    2.10  import net.java.html.json.Context;
    2.11  import org.apidesign.html.json.impl.PropertyBindingAccessor.FBData;
     3.1 --- a/json/src/main/java/org/apidesign/html/json/impl/ContextAccessor.java	Mon Apr 22 23:18:55 2013 +0200
     3.2 +++ b/json/src/main/java/org/apidesign/html/json/impl/ContextAccessor.java	Tue Apr 23 08:43:11 2013 +0200
     3.3 @@ -23,6 +23,7 @@
     3.4  import net.java.html.json.Context;
     3.5  import org.apidesign.html.json.spi.ContextBuilder;
     3.6  import org.apidesign.html.json.spi.Technology;
     3.7 +import org.apidesign.html.json.spi.Transfer;
     3.8  
     3.9  /** Internal communication between API (e.g. {@link Context}), SPI
    3.10   * (e.g. {@link ContextBuilder}) and the implementation package.
    3.11 @@ -41,15 +42,19 @@
    3.12          DEFAULT = this;
    3.13      }
    3.14      
    3.15 -    protected abstract Context newContext(Technology<?> t);
    3.16 +    protected abstract Context newContext(Technology<?> t, Transfer r);
    3.17      protected abstract Technology<?> technology(Context c);
    3.18 +    protected abstract Transfer transfer(Context c);
    3.19      
    3.20      
    3.21 -    public static Context create(Technology<?> t) {
    3.22 -        return DEFAULT.newContext(t);
    3.23 +    public static Context create(Technology<?> t, Transfer r) {
    3.24 +        return DEFAULT.newContext(t, r);
    3.25      }
    3.26      
    3.27      static Technology<?> findTechnology(Context c) {
    3.28          return DEFAULT.technology(c);
    3.29      }
    3.30 +    static Transfer findTransfer(Context c) {
    3.31 +        return DEFAULT.transfer(c);
    3.32 +    }
    3.33  }
     4.1 --- a/json/src/main/java/org/apidesign/html/json/impl/JSON.java	Mon Apr 22 23:18:55 2013 +0200
     4.2 +++ b/json/src/main/java/org/apidesign/html/json/impl/JSON.java	Tue Apr 23 08:43:11 2013 +0200
     4.3 @@ -22,6 +22,7 @@
     4.4  
     4.5  import net.java.html.json.Context;
     4.6  import org.apidesign.html.json.spi.Technology;
     4.7 +import org.apidesign.html.json.spi.Transfer;
     4.8  
     4.9  /**
    4.10   *
    4.11 @@ -33,7 +34,7 @@
    4.12      }
    4.13  
    4.14      public static void extract(Context c, Object value, String[] props, Object[] values) {
    4.15 -        Technology<?> t = ContextAccessor.findTechnology(c);
    4.16 +        Transfer t = ContextAccessor.findTransfer(c);
    4.17          t.extract(value, props, values);
    4.18      }
    4.19      
     5.1 --- a/json/src/main/java/org/apidesign/html/json/spi/ContextBuilder.java	Mon Apr 22 23:18:55 2013 +0200
     5.2 +++ b/json/src/main/java/org/apidesign/html/json/spi/ContextBuilder.java	Tue Apr 23 08:43:11 2013 +0200
     5.3 @@ -32,8 +32,12 @@
     5.4   */
     5.5  public final class ContextBuilder {
     5.6      private Technology<?> t;
     5.7 +    private Transfer r;
     5.8      
     5.9      private ContextBuilder() {
    5.10 +        EmptyTech et = new EmptyTech();
    5.11 +        t = et;
    5.12 +        r = et;
    5.13      }
    5.14      
    5.15      /** Creates new, empty builder for creation of {@link Context}. At the
    5.16 @@ -45,7 +49,8 @@
    5.17          return new ContextBuilder();
    5.18      }
    5.19      
    5.20 -    /** Provides technology for the context
    5.21 +    /** Provides technology for the context.
    5.22 +     * 
    5.23       * @param technology
    5.24       * @return this
    5.25       */
    5.26 @@ -53,6 +58,16 @@
    5.27          this.t = technology;
    5.28          return this;
    5.29      }
    5.30 +
    5.31 +    /** Provides transfer for the context.
    5.32 +     * 
    5.33 +     * @param transfer
    5.34 +     * @return this
    5.35 +     */
    5.36 +    public ContextBuilder withTransfer(Transfer transfer) {
    5.37 +        this.r = transfer;
    5.38 +        return this;
    5.39 +    }
    5.40      
    5.41      /** Generates context based on values previously inserted into
    5.42       * this builder.
    5.43 @@ -60,6 +75,43 @@
    5.44       * @return new, immutable instance of {@link Context}
    5.45       */
    5.46      public Context build() {
    5.47 -        return ContextAccessor.create(t);
    5.48 +        return ContextAccessor.create(t, r);
    5.49      }
    5.50 +    
    5.51 +    private static final class EmptyTech
    5.52 +    implements Technology<Object>, Transfer {
    5.53 +        @Override
    5.54 +        public Object wrapModel(Object model) {
    5.55 +            return model;
    5.56 +        }
    5.57 +
    5.58 +        @Override
    5.59 +        public void valueHasMutated(Object data, String propertyName) {
    5.60 +        }
    5.61 +
    5.62 +        @Override
    5.63 +        public void bind(PropertyBinding b, Object model, Object data) {
    5.64 +        }
    5.65 +
    5.66 +        @Override
    5.67 +        public void expose(FunctionBinding fb, Object model, Object d) {
    5.68 +        }
    5.69 +
    5.70 +        @Override
    5.71 +        public void applyBindings(Object data) {
    5.72 +        }
    5.73 +
    5.74 +        @Override
    5.75 +        public Object wrapArray(Object[] arr) {
    5.76 +            return arr;
    5.77 +        }
    5.78 +
    5.79 +        @Override
    5.80 +        public void extract(Object obj, String[] props, Object[] values) {
    5.81 +            for (int i = 0; i < values.length; i++) {
    5.82 +                values[i] = null;
    5.83 +            }
    5.84 +        }
    5.85 +    }
    5.86 +    
    5.87  }
     6.1 --- a/json/src/main/java/org/apidesign/html/json/spi/Technology.java	Mon Apr 22 23:18:55 2013 +0200
     6.2 +++ b/json/src/main/java/org/apidesign/html/json/spi/Technology.java	Tue Apr 23 08:43:11 2013 +0200
     6.3 @@ -61,23 +61,13 @@
     6.4       * @param data the data to apply
     6.5       */
     6.6      public void applyBindings(Data data);
     6.7 -
     6.8 -    /** Some technologies may require wrapping a Java array into a special
     6.9 +    
    6.10 +    /**
    6.11 +     * Some technologies may require wrapping a Java array into a special
    6.12       * object. In such case they may return it from this method.
    6.13 -     * 
    6.14 +     *
    6.15       * @param arr original array
    6.16       * @return wrapped array
    6.17       */
    6.18      public Object wrapArray(Object[] arr);
    6.19 -
    6.20 -    /** Called to inspect properties of an object (usually a JSON or JavaScript
    6.21 -     * wrapper. 
    6.22 -     * 
    6.23 -     * @param obj the object to inspect
    6.24 -     * @param props the names of properties to check on the object <code>obj</code>
    6.25 -     * @param values array of the same length as <code>props</code> should be filled
    6.26 -     *   by values of properties on the <code>obj</code>. If a property is not
    6.27 -     *   defined, a <code>null</code> value should be stored in the array
    6.28 -     */
    6.29 -    public void extract(Object obj, String[] props, Object[] values);
    6.30  }
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/json/src/main/java/org/apidesign/html/json/spi/Transfer.java	Tue Apr 23 08:43:11 2013 +0200
     7.3 @@ -0,0 +1,43 @@
     7.4 +/**
     7.5 + * HTML via Java(tm) Language Bindings
     7.6 + * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     7.7 + *
     7.8 + * This program is free software: you can redistribute it and/or modify
     7.9 + * it under the terms of the GNU General Public License as published by
    7.10 + * the Free Software Foundation, version 2 of the License.
    7.11 + *
    7.12 + * This program is distributed in the hope that it will be useful,
    7.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    7.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    7.15 + * GNU General Public License for more details. apidesign.org
    7.16 + * designates this particular file as subject to the
    7.17 + * "Classpath" exception as provided by apidesign.org
    7.18 + * in the License file that accompanied this code.
    7.19 + *
    7.20 + * You should have received a copy of the GNU General Public License
    7.21 + * along with this program. Look for COPYING file in the top folder.
    7.22 + * If not, see http://wiki.apidesign.org/wiki/GPLwithClassPathException
    7.23 + */
    7.24 +
    7.25 +package org.apidesign.html.json.spi;
    7.26 +
    7.27 +/** A {@link ContextBuilder service provider interface} responsible for 
    7.28 + * conversion of JSON objects to Java ones and vice-versa.
    7.29 + *
    7.30 + * @author Jaroslav Tulach <jtulach@netbeans.org>
    7.31 + */
    7.32 +public interface Transfer {
    7.33 +    /**
    7.34 +     * Called to inspect properties of an object (usually a JSON or JavaScript
    7.35 +     * wrapper).
    7.36 +     *
    7.37 +     * @param obj the object to inspect
    7.38 +     * @param props the names of properties to check on the object
    7.39 +     * <code>obj</code>
    7.40 +     * @param values array of the same length as <code>props</code> should be
    7.41 +     * filled by values of properties on the <code>obj</code>. If a property is
    7.42 +     * not defined, a <code>null</code> value should be stored in the array
    7.43 +     */
    7.44 +    public void extract(Object obj, String[] props, Object[] values);
    7.45 +    
    7.46 +}
     8.1 --- a/json/src/test/java/net/java/html/json/MapModelTest.java	Mon Apr 22 23:18:55 2013 +0200
     8.2 +++ b/json/src/test/java/net/java/html/json/MapModelTest.java	Tue Apr 23 08:43:11 2013 +0200
     8.3 @@ -28,6 +28,7 @@
     8.4  import org.apidesign.html.json.spi.FunctionBinding;
     8.5  import org.apidesign.html.json.spi.PropertyBinding;
     8.6  import org.apidesign.html.json.spi.Technology;
     8.7 +import org.apidesign.html.json.spi.Transfer;
     8.8  import org.testng.annotations.BeforeMethod;
     8.9  import org.testng.annotations.Test;
    8.10  import static org.testng.Assert.*;
    8.11 @@ -42,7 +43,7 @@
    8.12  
    8.13      @BeforeMethod public void initTechnology() {
    8.14          t = new MapTechnology();
    8.15 -        c = ContextBuilder.create().withTechnology(t).build();
    8.16 +        c = ContextBuilder.create().withTechnology(t).withTransfer(t).build();
    8.17      }
    8.18      
    8.19      @Test public void isThereABinding() throws Exception {
    8.20 @@ -134,7 +135,8 @@
    8.21          }
    8.22      }
    8.23      
    8.24 -    static final class MapTechnology implements Technology<Map<String,One>> {
    8.25 +    static final class MapTechnology 
    8.26 +    implements Technology<Map<String,One>>, Transfer {
    8.27  
    8.28          @Override
    8.29          public Map<String, One> wrapModel(Object model) {
     9.1 --- a/json/src/test/java/net/java/html/json/ModelTest.java	Mon Apr 22 23:18:55 2013 +0200
     9.2 +++ b/json/src/test/java/net/java/html/json/ModelTest.java	Tue Apr 23 08:43:11 2013 +0200
     9.3 @@ -261,9 +261,5 @@
     9.4          public Object wrapArray(Object[] arr) {
     9.5              return arr;
     9.6          }
     9.7 -
     9.8 -        @Override
     9.9 -        public void extract(Object obj, String[] props, Object[] values) {
    9.10 -        }
    9.11      }
    9.12  }
    10.1 --- a/json/src/test/java/net/java/html/json/TypesTest.java	Mon Apr 22 23:18:55 2013 +0200
    10.2 +++ b/json/src/test/java/net/java/html/json/TypesTest.java	Tue Apr 23 08:43:11 2013 +0200
    10.3 @@ -48,7 +48,7 @@
    10.4  
    10.5      @BeforeMethod public void initTechnology() {
    10.6          t = new MapModelTest.MapTechnology();
    10.7 -        c = ContextBuilder.create().withTechnology(t).build();
    10.8 +        c = ContextBuilder.create().withTechnology(t).withTransfer(t).build();
    10.9      }
   10.10      @Function static void readFromEvent(int intX, 
   10.11          /*
    11.1 --- a/json/src/test/java/org/apidesign/html/json/impl/JSONListTest.java	Mon Apr 22 23:18:55 2013 +0200
    11.2 +++ b/json/src/test/java/org/apidesign/html/json/impl/JSONListTest.java	Tue Apr 23 08:43:11 2013 +0200
    11.3 @@ -157,8 +157,4 @@
    11.4          return replaceArray ? this : arr;
    11.5      }
    11.6  
    11.7 -    @Override
    11.8 -    public void extract(Object obj, String[] props, Object[] values) {
    11.9 -    }
   11.10 -    
   11.11  }