Adding unified way of pre-loading classes that works in HotSpot as well as Bck2Brwsr VM
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Tue, 23 Apr 2013 15:58:19 +0200
changeset 300ab8f16d9b75
parent 29 0a945188e4a0
child 31 7a86845b0850
Adding unified way of pre-loading classes that works in HotSpot as well as Bck2Brwsr VM
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/impl/PropertyBindingAccessor.java
json/src/test/java/org/apidesign/html/json/impl/EmployeeImpl.java
json/src/test/java/org/apidesign/html/json/impl/EmployerTest.java
     1.1 --- a/json/src/main/java/org/apidesign/html/json/impl/ContextAccessor.java	Tue Apr 23 14:17:06 2013 +0200
     1.2 +++ b/json/src/main/java/org/apidesign/html/json/impl/ContextAccessor.java	Tue Apr 23 15:58:19 2013 +0200
     1.3 @@ -34,7 +34,11 @@
     1.4      private static ContextAccessor DEFAULT;
     1.5      static {
     1.6          // run initializers
     1.7 -        Context.EMPTY.getClass();
     1.8 +        try {
     1.9 +            Context.EMPTY.getClass();
    1.10 +        } catch (NullPointerException ex) {
    1.11 +            // ignore
    1.12 +        }
    1.13      }
    1.14      
    1.15      protected ContextAccessor() {
     2.1 --- a/json/src/main/java/org/apidesign/html/json/impl/JSON.java	Tue Apr 23 14:17:06 2013 +0200
     2.2 +++ b/json/src/main/java/org/apidesign/html/json/impl/JSON.java	Tue Apr 23 15:58:19 2013 +0200
     2.3 @@ -22,7 +22,6 @@
     2.4  
     2.5  import java.util.HashMap;
     2.6  import java.util.Map;
     2.7 -import java.util.WeakHashMap;
     2.8  import net.java.html.json.Context;
     2.9  import org.apidesign.html.json.spi.JSONCall;
    2.10  import org.apidesign.html.json.spi.Transfer;
    2.11 @@ -80,6 +79,9 @@
    2.12          }
    2.13          return (Number)obj;
    2.14      }
    2.15 +    public static <M> M toModel(Class<M> aClass, Object data, Object object) {
    2.16 +        return aClass.cast(data);
    2.17 +    }
    2.18  
    2.19      
    2.20      public static void loadJSON(
    2.21 @@ -93,23 +95,40 @@
    2.22      
    2.23      private static final Map<Class,FromJSON<?>> froms;
    2.24      static {
    2.25 -        Map<Class,FromJSON<?>> m;
    2.26 -        try {
    2.27 -            m = new WeakHashMap<>();
    2.28 -        } catch (LinkageError ex) {
    2.29 -            m = new HashMap<>();
    2.30 -        }
    2.31 +        Map<Class,FromJSON<?>> m = new HashMap<>();
    2.32          froms = m;
    2.33      }
    2.34      public static void register(FromJSON<?> from) {
    2.35 -        froms.put(from.getClass(), from);
    2.36 +        froms.put(from.factoryFor(), from);
    2.37      }
    2.38      
    2.39      public static <T> T read(Context c, Class<T> modelClazz, Object data) {
    2.40 -        FromJSON<?> from = froms.get(modelClazz);
    2.41 -        if (from == null) {
    2.42 -            throw new NullPointerException();
    2.43 +        for (int i = 0; i < 2; i++) {
    2.44 +            FromJSON<?> from = froms.get(modelClazz);
    2.45 +            if (from == null) {
    2.46 +                initClass(modelClazz);
    2.47 +            } else {
    2.48 +                return modelClazz.cast(from.read(c, data));
    2.49 +            }
    2.50          }
    2.51 -        return modelClazz.cast(from.read(c, data));
    2.52 +        throw new NullPointerException();
    2.53 +    }
    2.54 +    static void initClass(Class<?> modelClazz) {
    2.55 +        try {
    2.56 +            // try to resolve the class
    2.57 +            ClassLoader l;
    2.58 +            try {
    2.59 +                l = modelClazz.getClassLoader();
    2.60 +            } catch (SecurityException ex) {
    2.61 +                l = null;
    2.62 +            }
    2.63 +            if (l != null) {
    2.64 +                Class.forName(modelClazz.getName(), true, l);
    2.65 +            }
    2.66 +            modelClazz.newInstance();
    2.67 +        } catch (ClassNotFoundException | InstantiationException |
    2.68 +            IllegalAccessException | SecurityException ex) {
    2.69 +            // ignore and try again
    2.70 +        }
    2.71      }
    2.72  }
     3.1 --- a/json/src/main/java/org/apidesign/html/json/impl/PropertyBindingAccessor.java	Tue Apr 23 14:17:06 2013 +0200
     3.2 +++ b/json/src/main/java/org/apidesign/html/json/impl/PropertyBindingAccessor.java	Tue Apr 23 15:58:19 2013 +0200
     3.3 @@ -37,14 +37,7 @@
     3.4      }
     3.5      
     3.6      static {
     3.7 -        try {
     3.8 -            // run initializers
     3.9 -            Class.forName(PropertyBinding.class.getName(), 
    3.10 -                true, PropertyBinding.class.getClassLoader());
    3.11 -        } catch (Exception ex) {
    3.12 -            // OK
    3.13 -            throw new IllegalStateException(ex);
    3.14 -        }
    3.15 +        JSON.initClass(PropertyBinding.class);
    3.16      }
    3.17  
    3.18      protected abstract <M> PropertyBinding newBinding(PBData<M> d);
     4.1 --- a/json/src/test/java/org/apidesign/html/json/impl/EmployeeImpl.java	Tue Apr 23 14:17:06 2013 +0200
     4.2 +++ b/json/src/test/java/org/apidesign/html/json/impl/EmployeeImpl.java	Tue Apr 23 15:58:19 2013 +0200
     4.3 @@ -32,7 +32,7 @@
     4.4   */
     4.5  @Model(className = "Employee", properties = {
     4.6      @Property(name = "person", type = Person.class),
     4.7 -    @Property(name = "employer", type = String.class)
     4.8 +    @Property(name = "employer", type = Employer.class)
     4.9  })
    4.10  public class EmployeeImpl {
    4.11      @OnReceive(url = "some/url")
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/json/src/test/java/org/apidesign/html/json/impl/EmployerTest.java	Tue Apr 23 15:58:19 2013 +0200
     5.3 @@ -0,0 +1,41 @@
     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.json.impl;
    5.25 +
    5.26 +import net.java.html.json.Context;
    5.27 +import net.java.html.json.Model;
    5.28 +import net.java.html.json.Property;
    5.29 +import org.testng.Assert;
    5.30 +import org.testng.annotations.Test;
    5.31 +
    5.32 +/**
    5.33 + *
    5.34 + * @author Jaroslav Tulach <jtulach@netbeans.org>
    5.35 + */
    5.36 +@Model(className = "Employer", properties = {
    5.37 +    @Property(name = "name", type = String.class)
    5.38 +})
    5.39 +public class EmployerTest {
    5.40 +    @Test public void preLoadsTheClass() {
    5.41 +        Employer em = JSON.read(Context.EMPTY, Employer.class, this);
    5.42 +        Assert.assertNotNull(em, "Class loaded");
    5.43 +    }
    5.44 +}