A way to parse an input stream and create a JSON object
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Fri, 03 May 2013 10:27:06 +0200
changeset 60939453361b2d
parent 59 7fae5a91c9c7
child 61 4b63ae70ea42
A way to parse an input stream and create a JSON object
json-tck/src/main/java/net/java/html/json/tests/ConvertTypesTest.java
json/src/main/java/net/java/html/json/Models.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/Transfer.java
json/src/test/java/net/java/html/json/MapModelTest.java
ko-bck2brwsr/src/main/java/org/apidesign/html/ko2brwsr/BrwsrCntxt.java
ko-bck2brwsr/src/main/java/org/apidesign/html/ko2brwsr/ConvertTypes.java
ko-fx/src/main/java/org/apidesign/html/kofx/FXContext.java
ko-fx/src/main/java/org/apidesign/html/kofx/LoadJSON.java
     1.1 --- a/json-tck/src/main/java/net/java/html/json/tests/ConvertTypesTest.java	Fri May 03 09:26:03 2013 +0200
     1.2 +++ b/json-tck/src/main/java/net/java/html/json/tests/ConvertTypesTest.java	Fri May 03 10:27:06 2013 +0200
     1.3 @@ -20,8 +20,13 @@
     1.4   */
     1.5  package net.java.html.json.tests;
     1.6  
     1.7 +import java.io.ByteArrayInputStream;
     1.8 +import java.io.InputStream;
     1.9 +import java.io.UnsupportedEncodingException;
    1.10  import java.util.HashMap;
    1.11  import java.util.Map;
    1.12 +import net.java.html.json.Context;
    1.13 +import net.java.html.json.Models;
    1.14  import org.apidesign.bck2brwsr.vmtest.BrwsrTest;
    1.15  import org.apidesign.bck2brwsr.vmtest.VMTest;
    1.16  import org.apidesign.html.json.impl.JSON;
    1.17 @@ -31,7 +36,19 @@
    1.18   * @author Jaroslav Tulach <jtulach@netbeans.org>
    1.19   */
    1.20  public final class ConvertTypesTest {
    1.21 -    private static Object createJSON(boolean includeSex) {
    1.22 +    private static InputStream createIS(boolean includeSex) 
    1.23 +    throws UnsupportedEncodingException {
    1.24 +        StringBuilder sb = new StringBuilder();
    1.25 +        sb.append("{ \"firstName\" : \"son\",\n");
    1.26 +        sb.append("  \"lastName\" : \"dj\" \n");
    1.27 +        if (includeSex) {
    1.28 +            sb.append(",  \"sex\" : \"MALE\" ");
    1.29 +        }
    1.30 +        sb.append("}\n");
    1.31 +        return new ByteArrayInputStream(sb.toString().getBytes("UTF-8"));
    1.32 +    }
    1.33 +    private static Object createJSON(boolean includeSex) 
    1.34 +    throws UnsupportedEncodingException {
    1.35          Map<String,Object> map = new HashMap<>();
    1.36          map.put("firstName", "son");
    1.37          map.put("lastName", "dj");
    1.38 @@ -53,6 +70,18 @@
    1.39      }
    1.40  
    1.41      @BrwsrTest
    1.42 +    public void parseConvertToPeople() throws Exception {
    1.43 +        final Context c = Utils.newContext();
    1.44 +        final InputStream o = createIS(true);
    1.45 +        
    1.46 +        Person p = Models.parse(c, Person.class, o);
    1.47 +        
    1.48 +        assert "son".equals(p.getFirstName()) : "First name: " + p.getFirstName();
    1.49 +        assert "dj".equals(p.getLastName()) : "Last name: " + p.getLastName();
    1.50 +        assert Sex.MALE.equals(p.getSex()) : "Sex: " + p.getSex();
    1.51 +    }
    1.52 +
    1.53 +    @BrwsrTest
    1.54      public void testConvertToPeopleWithoutSex() throws Exception {
    1.55          final Object o = createJSON(false);
    1.56          
    1.57 @@ -63,6 +92,17 @@
    1.58          assert p.getSex() == null : "No sex: " + p.getSex();
    1.59      }
    1.60      
    1.61 +    @BrwsrTest
    1.62 +    public void parseConvertToPeopleWithoutSex() throws Exception {
    1.63 +        final Context c = Utils.newContext();
    1.64 +        final InputStream o = createIS(false);
    1.65 +        Person p = Models.parse(c, Person.class, o);
    1.66 +        
    1.67 +        assert "son".equals(p.getFirstName()) : "First name: " + p.getFirstName();
    1.68 +        assert "dj".equals(p.getLastName()) : "Last name: " + p.getLastName();
    1.69 +        assert p.getSex() == null : "No sex: " + p.getSex();
    1.70 +    }
    1.71 +    
    1.72      static Object[] create() {
    1.73          return VMTest.create(ConvertTypesTest.class);
    1.74      }
     2.1 --- a/json/src/main/java/net/java/html/json/Models.java	Fri May 03 09:26:03 2013 +0200
     2.2 +++ b/json/src/main/java/net/java/html/json/Models.java	Fri May 03 10:27:06 2013 +0200
     2.3 @@ -20,6 +20,8 @@
     2.4   */
     2.5  package net.java.html.json;
     2.6  
     2.7 +import java.io.IOException;
     2.8 +import java.io.InputStream;
     2.9  import java.lang.reflect.Method;
    2.10  import org.apidesign.html.json.impl.JSON;
    2.11  
    2.12 @@ -36,11 +38,23 @@
    2.13      /** Finds out whether given class is a model class - e.g. has been
    2.14       * generated by {@link Model @Model} annotation.
    2.15       * 
    2.16 -     * @param clazz the class 
    2.17 -     * @return 
    2.18 +     * @param clazz the class to test
    2.19 +     * @return true, if <code>clazz</code> was generated by {@link Model} annotation
    2.20       * @since 0.2
    2.21       */
    2.22      public static boolean isModel(Class<?> clazz) {
    2.23          return JSON.isModel(clazz);
    2.24      }
    2.25 +    
    2.26 +    /** Generic method to parse content of a model class from a stream.
    2.27 +     * 
    2.28 +     * @param c context of the technology to use for reading 
    2.29 +     * @param model the model class generated by {@link Model} annotation
    2.30 +     * @param is input stream with data
    2.31 +     * @return new instance of the model class
    2.32 +     * @since 0.2
    2.33 +     */
    2.34 +    public static <M> M parse(Context c, Class<M> model, InputStream is) throws IOException {
    2.35 +        return JSON.readStream(c, model, is);
    2.36 +    }
    2.37  }
     3.1 --- a/json/src/main/java/org/apidesign/html/json/impl/JSON.java	Fri May 03 09:26:03 2013 +0200
     3.2 +++ b/json/src/main/java/org/apidesign/html/json/impl/JSON.java	Fri May 03 10:27:06 2013 +0200
     3.3 @@ -20,6 +20,8 @@
     3.4   */
     3.5  package org.apidesign.html.json.impl;
     3.6  
     3.7 +import java.io.IOException;
     3.8 +import java.io.InputStream;
     3.9  import java.util.HashMap;
    3.10  import java.util.Map;
    3.11  import net.java.html.json.Context;
    3.12 @@ -118,6 +120,11 @@
    3.13          return false;
    3.14      }
    3.15      
    3.16 +    public static <T> T readStream(Context c, Class<T> modelClazz, InputStream data) 
    3.17 +    throws IOException {
    3.18 +        Transfer tr = ContextAccessor.findTransfer(c);
    3.19 +        return read(c, modelClazz, tr.toJSON((InputStream)data));
    3.20 +    }
    3.21      public static <T> T read(Context c, Class<T> modelClazz, Object data) {
    3.22          for (int i = 0; i < 2; i++) {
    3.23              FromJSON<?> from = froms.get(modelClazz);
     4.1 --- a/json/src/main/java/org/apidesign/html/json/spi/ContextBuilder.java	Fri May 03 09:26:03 2013 +0200
     4.2 +++ b/json/src/main/java/org/apidesign/html/json/spi/ContextBuilder.java	Fri May 03 10:27:06 2013 +0200
     4.3 @@ -20,6 +20,8 @@
     4.4   */
     4.5  package org.apidesign.html.json.spi;
     4.6  
     4.7 +import java.io.IOException;
     4.8 +import java.io.InputStream;
     4.9  import net.java.html.json.Context;
    4.10  import org.apidesign.html.json.impl.ContextAccessor;
    4.11  
    4.12 @@ -122,6 +124,11 @@
    4.13          public <M> M toModel(Class<M> modelClass, Object data) {
    4.14              return modelClass.cast(data);
    4.15          }
    4.16 +
    4.17 +        @Override
    4.18 +        public Object toJSON(InputStream is) throws IOException {
    4.19 +            throw new IOException("Not supported");
    4.20 +        }
    4.21      }
    4.22      
    4.23  }
     5.1 --- a/json/src/main/java/org/apidesign/html/json/spi/Transfer.java	Fri May 03 09:26:03 2013 +0200
     5.2 +++ b/json/src/main/java/org/apidesign/html/json/spi/Transfer.java	Fri May 03 10:27:06 2013 +0200
     5.3 @@ -21,6 +21,9 @@
     5.4  
     5.5  package org.apidesign.html.json.spi;
     5.6  
     5.7 +import java.io.IOException;
     5.8 +import java.io.InputStream;
     5.9 +
    5.10  /** A {@link ContextBuilder service provider interface} responsible for 
    5.11   * conversion of JSON objects to Java ones and vice-versa.
    5.12   *
    5.13 @@ -40,6 +43,17 @@
    5.14       */
    5.15      public void extract(Object obj, String[] props, Object[] values);
    5.16      
    5.17 +    /** Reads content of a stream and creates its JSON representation.
    5.18 +     * The returned object is implementation dependant. It however needs
    5.19 +     * to be acceptable as first argument of {@link #extract(java.lang.Object, java.lang.String[], java.lang.Object[]) extract}
    5.20 +     * method.
    5.21 +     * 
    5.22 +     * @param is input stream to read data from
    5.23 +     * @return an object representing the JSON data
    5.24 +     * @throws IOException if something goes wrong
    5.25 +     */
    5.26 +    public Object toJSON(InputStream is) throws IOException;
    5.27 +    
    5.28      /** Starts the JSON or JSONP query. 
    5.29       * 
    5.30       * @param call description of the call to make
     6.1 --- a/json/src/test/java/net/java/html/json/MapModelTest.java	Fri May 03 09:26:03 2013 +0200
     6.2 +++ b/json/src/test/java/net/java/html/json/MapModelTest.java	Fri May 03 10:27:06 2013 +0200
     6.3 @@ -20,6 +20,8 @@
     6.4   */
     6.5  package net.java.html.json;
     6.6  
     6.7 +import java.io.IOException;
     6.8 +import java.io.InputStream;
     6.9  import java.lang.reflect.InvocationTargetException;
    6.10  import java.util.HashMap;
    6.11  import java.util.Map;
    6.12 @@ -204,5 +206,10 @@
    6.13          public <M> M toModel(Class<M> modelClass, Object data) {
    6.14              return modelClass.cast(data);
    6.15          }
    6.16 +
    6.17 +        @Override
    6.18 +        public Object toJSON(InputStream is) throws IOException {
    6.19 +            throw new IOException();
    6.20 +        }
    6.21      }
    6.22  }
     7.1 --- a/ko-bck2brwsr/src/main/java/org/apidesign/html/ko2brwsr/BrwsrCntxt.java	Fri May 03 09:26:03 2013 +0200
     7.2 +++ b/ko-bck2brwsr/src/main/java/org/apidesign/html/ko2brwsr/BrwsrCntxt.java	Fri May 03 10:27:06 2013 +0200
     7.3 @@ -20,6 +20,9 @@
     7.4   */
     7.5  package org.apidesign.html.ko2brwsr;
     7.6  
     7.7 +import java.io.IOException;
     7.8 +import java.io.InputStream;
     7.9 +import java.io.InputStreamReader;
    7.10  import net.java.html.json.Context;
    7.11  import org.apidesign.html.json.spi.ContextBuilder;
    7.12  import org.apidesign.html.json.spi.FunctionBinding;
    7.13 @@ -102,4 +105,18 @@
    7.14      public <M> M toModel(Class<M> modelClass, Object data) {
    7.15          return modelClass.cast(data);
    7.16      }
    7.17 +
    7.18 +    @Override
    7.19 +    public Object toJSON(InputStream is) throws IOException {
    7.20 +        StringBuilder sb = new StringBuilder();
    7.21 +        InputStreamReader r = new InputStreamReader(is);
    7.22 +        for (;;) {
    7.23 +            int ch = r.read();
    7.24 +            if (ch == -1) {
    7.25 +                break;
    7.26 +            }
    7.27 +            sb.append((char)ch);
    7.28 +        }
    7.29 +        return ConvertTypes.parse(sb.toString());
    7.30 +    }
    7.31  }
     8.1 --- a/ko-bck2brwsr/src/main/java/org/apidesign/html/ko2brwsr/ConvertTypes.java	Fri May 03 09:26:03 2013 +0200
     8.2 +++ b/ko-bck2brwsr/src/main/java/org/apidesign/html/ko2brwsr/ConvertTypes.java	Fri May 03 10:27:06 2013 +0200
     8.3 @@ -107,6 +107,11 @@
     8.4          return true;
     8.5      }
     8.6      
     8.7 +    @JavaScriptBody(args = { "s" }, body = "return eval('(' + s + ')');")
     8.8 +    static Object parse(String s) {
     8.9 +        return s;
    8.10 +    }
    8.11 +    
    8.12      @JavaScriptBody(args = { "url", "arr", "callback" }, body = ""
    8.13          + "var request = new XMLHttpRequest();\n"
    8.14          + "request.open('GET', url, true);\n"
     9.1 --- a/ko-fx/src/main/java/org/apidesign/html/kofx/FXContext.java	Fri May 03 09:26:03 2013 +0200
     9.2 +++ b/ko-fx/src/main/java/org/apidesign/html/kofx/FXContext.java	Fri May 03 10:27:06 2013 +0200
     9.3 @@ -20,6 +20,8 @@
     9.4   */
     9.5  package org.apidesign.html.kofx;
     9.6  
     9.7 +import java.io.IOException;
     9.8 +import java.io.InputStream;
     9.9  import java.util.ServiceLoader;
    9.10  import java.util.logging.Logger;
    9.11  import net.java.html.json.Context;
    9.12 @@ -105,4 +107,9 @@
    9.13          }
    9.14          return modelClass.cast(data);
    9.15      }
    9.16 +
    9.17 +    @Override
    9.18 +    public Object toJSON(InputStream is) throws IOException {
    9.19 +        return LoadJSON.parse(is);
    9.20 +    }
    9.21  }
    10.1 --- a/ko-fx/src/main/java/org/apidesign/html/kofx/LoadJSON.java	Fri May 03 09:26:03 2013 +0200
    10.2 +++ b/ko-fx/src/main/java/org/apidesign/html/kofx/LoadJSON.java	Fri May 03 10:27:06 2013 +0200
    10.3 @@ -21,6 +21,7 @@
    10.4  package org.apidesign.html.kofx;
    10.5  
    10.6  import java.io.IOException;
    10.7 +import java.io.InputStream;
    10.8  import java.io.InputStreamReader;
    10.9  import java.io.PushbackInputStream;
   10.10  import java.io.Reader;
   10.11 @@ -39,6 +40,7 @@
   10.12  import org.json.JSONException;
   10.13  import org.json.JSONObject;
   10.14  import org.json.JSONTokener;
   10.15 +import org.openide.util.Exceptions;
   10.16  
   10.17  /** This is an implementation package - just
   10.18   * include its JAR on classpath and use official {@link Context} API
   10.19 @@ -167,6 +169,16 @@
   10.20          }
   10.21      }
   10.22      
   10.23 +    public static Object parse(InputStream is) throws IOException {
   10.24 +        try {
   10.25 +            InputStreamReader r = new InputStreamReader(is, "UTF-8");
   10.26 +            JSONTokener t = new JSONTokener(r);
   10.27 +            return new JSONObject(t);
   10.28 +        } catch (JSONException ex) {
   10.29 +            throw new IOException(ex);
   10.30 +        }
   10.31 +    }
   10.32 +    
   10.33      private static String findBaseURL() {
   10.34          WebEngine eng = (WebEngine) System.getProperties().get("webEngine");
   10.35          return (String) eng.executeScript(