Test to verify basic introspection behavior beans
authorJaroslav Tulach <jtulach@netbeans.org>
Sun, 03 Aug 2014 17:38:24 +0200
branchbeans
changeset 7958c3e0f4aee77
parent 794 bbece6a5a52f
child 796 77922b8f0e36
Test to verify basic introspection behavior
json-beans/pom.xml
json-beans/src/main/java/net/java/html/beans/JSONBeans.java
json-beans/src/test/java/net/java/html/beans/MapModelTest.java
json-beans/src/test/java/net/java/html/beans/Person.java
json-beans/src/test/java/net/java/html/beans/Sex.java
json/src/main/java/org/apidesign/html/json/spi/Proto.java
     1.1 --- a/json-beans/pom.xml	Sun Aug 03 16:34:51 2014 +0200
     1.2 +++ b/json-beans/pom.xml	Sun Aug 03 17:38:24 2014 +0200
     1.3 @@ -15,5 +15,10 @@
     1.4              <artifactId>net.java.html.json</artifactId>
     1.5              <version>${project.version}</version>
     1.6          </dependency>
     1.7 +        <dependency>
     1.8 +            <groupId>org.testng</groupId>
     1.9 +            <artifactId>testng</artifactId>
    1.10 +            <scope>test</scope>
    1.11 +        </dependency>
    1.12      </dependencies>
    1.13  </project>
    1.14 \ No newline at end of file
     2.1 --- a/json-beans/src/main/java/net/java/html/beans/JSONBeans.java	Sun Aug 03 16:34:51 2014 +0200
     2.2 +++ b/json-beans/src/main/java/net/java/html/beans/JSONBeans.java	Sun Aug 03 17:38:24 2014 +0200
     2.3 @@ -1,7 +1,52 @@
     2.4 +/**
     2.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     2.6 + *
     2.7 + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
     2.8 + *
     2.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
    2.10 + * Other names may be trademarks of their respective owners.
    2.11 + *
    2.12 + * The contents of this file are subject to the terms of either the GNU
    2.13 + * General Public License Version 2 only ("GPL") or the Common
    2.14 + * Development and Distribution License("CDDL") (collectively, the
    2.15 + * "License"). You may not use this file except in compliance with the
    2.16 + * License. You can obtain a copy of the License at
    2.17 + * http://www.netbeans.org/cddl-gplv2.html
    2.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    2.19 + * specific language governing permissions and limitations under the
    2.20 + * License.  When distributing the software, include this License Header
    2.21 + * Notice in each file and include the License file at
    2.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
    2.23 + * particular file as subject to the "Classpath" exception as provided
    2.24 + * by Oracle in the GPL Version 2 section of the License file that
    2.25 + * accompanied this code. If applicable, add the following below the
    2.26 + * License Header, with the fields enclosed by brackets [] replaced by
    2.27 + * your own identifying information:
    2.28 + * "Portions Copyrighted [year] [name of copyright owner]"
    2.29 + *
    2.30 + * Contributor(s):
    2.31 + *
    2.32 + * The Original Software is NetBeans. The Initial Developer of the Original
    2.33 + * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
    2.34 + *
    2.35 + * If you wish your version of this file to be governed by only the CDDL
    2.36 + * or only the GPL Version 2, indicate your decision by adding
    2.37 + * "[Contributor] elects to include this software in this distribution
    2.38 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
    2.39 + * single choice of license, a recipient has the option to distribute
    2.40 + * your version of this file under either the CDDL, the GPL Version 2 or
    2.41 + * to extend the choice of license to its licensees as provided above.
    2.42 + * However, if you add GPL Version 2 code and therefore, elected the GPL
    2.43 + * Version 2 license, then the option applies only if the new code is
    2.44 + * made subject to such option by the copyright holder.
    2.45 + */
    2.46  
    2.47  package net.java.html.beans;
    2.48  
    2.49 -/**
    2.50 +import net.java.html.BrwsrCtx;
    2.51 +import org.apidesign.html.json.spi.Proto;
    2.52 +
    2.53 +/** Plain old JavaBean objects and {@link Model JSON models} finally together.
    2.54   *
    2.55   * @author Jaroslav Tulach
    2.56   */
    2.57 @@ -9,4 +54,48 @@
    2.58      private JSONBeans() {
    2.59      }
    2.60      
    2.61 +    public static void register(Class<?> javaBeanClass) {
    2.62 +        Html4JavaType html4JavaType = new Html4JavaType(javaBeanClass, 3, 3);
    2.63 +    }
    2.64 +    
    2.65 +    private static final class Html4JavaType extends Proto.Type {
    2.66 +        Html4JavaType(Class<?> javaBeanClass, int props, int fncs) {
    2.67 +            super(javaBeanClass, javaBeanClass, props, fncs);
    2.68 +        }
    2.69 +
    2.70 +        @Override
    2.71 +        protected void setValue(Object model, int index, Object value) {
    2.72 +            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    2.73 +        }
    2.74 +
    2.75 +        @Override
    2.76 +        protected Object getValue(Object model, int index) {
    2.77 +            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    2.78 +        }
    2.79 +
    2.80 +        @Override
    2.81 +        protected void call(Object model, int index, Object data, Object event) throws Exception {
    2.82 +            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    2.83 +        }
    2.84 +
    2.85 +        @Override
    2.86 +        protected Object cloneTo(Object model, BrwsrCtx ctx) {
    2.87 +            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    2.88 +        }
    2.89 +
    2.90 +        @Override
    2.91 +        protected Object read(BrwsrCtx c, Object json) {
    2.92 +            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    2.93 +        }
    2.94 +
    2.95 +        @Override
    2.96 +        protected void onChange(Object model, int index) {
    2.97 +            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    2.98 +        }
    2.99 +
   2.100 +        @Override
   2.101 +        protected Proto protoFor(Object object) {
   2.102 +            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
   2.103 +        }
   2.104 +    }
   2.105  }
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/json-beans/src/test/java/net/java/html/beans/MapModelTest.java	Sun Aug 03 17:38:24 2014 +0200
     3.3 @@ -0,0 +1,292 @@
     3.4 +/**
     3.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3.6 + *
     3.7 + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
     3.8 + *
     3.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
    3.10 + * Other names may be trademarks of their respective owners.
    3.11 + *
    3.12 + * The contents of this file are subject to the terms of either the GNU
    3.13 + * General Public License Version 2 only ("GPL") or the Common
    3.14 + * Development and Distribution License("CDDL") (collectively, the
    3.15 + * "License"). You may not use this file except in compliance with the
    3.16 + * License. You can obtain a copy of the License at
    3.17 + * http://www.netbeans.org/cddl-gplv2.html
    3.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    3.19 + * specific language governing permissions and limitations under the
    3.20 + * License.  When distributing the software, include this License Header
    3.21 + * Notice in each file and include the License file at
    3.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
    3.23 + * particular file as subject to the "Classpath" exception as provided
    3.24 + * by Oracle in the GPL Version 2 section of the License file that
    3.25 + * accompanied this code. If applicable, add the following below the
    3.26 + * License Header, with the fields enclosed by brackets [] replaced by
    3.27 + * your own identifying information:
    3.28 + * "Portions Copyrighted [year] [name of copyright owner]"
    3.29 + *
    3.30 + * Contributor(s):
    3.31 + *
    3.32 + * The Original Software is NetBeans. The Initial Developer of the Original
    3.33 + * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
    3.34 + *
    3.35 + * If you wish your version of this file to be governed by only the CDDL
    3.36 + * or only the GPL Version 2, indicate your decision by adding
    3.37 + * "[Contributor] elects to include this software in this distribution
    3.38 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
    3.39 + * single choice of license, a recipient has the option to distribute
    3.40 + * your version of this file under either the CDDL, the GPL Version 2 or
    3.41 + * to extend the choice of license to its licensees as provided above.
    3.42 + * However, if you add GPL Version 2 code and therefore, elected the GPL
    3.43 + * Version 2 license, then the option applies only if the new code is
    3.44 + * made subject to such option by the copyright holder.
    3.45 + */
    3.46 +package net.java.html.beans;
    3.47 +
    3.48 +import java.io.IOException;
    3.49 +import java.io.InputStream;
    3.50 +import java.lang.reflect.InvocationTargetException;
    3.51 +import java.util.HashMap;
    3.52 +import java.util.Map;
    3.53 +import net.java.html.BrwsrCtx;
    3.54 +import net.java.html.json.Models;
    3.55 +import org.apidesign.html.context.spi.Contexts;
    3.56 +import org.apidesign.html.json.spi.FunctionBinding;
    3.57 +import org.apidesign.html.json.spi.JSONCall;
    3.58 +import org.apidesign.html.json.spi.PropertyBinding;
    3.59 +import org.apidesign.html.json.spi.Technology;
    3.60 +import org.apidesign.html.json.spi.Transfer;
    3.61 +import static org.testng.Assert.*;
    3.62 +import org.testng.annotations.BeforeClass;
    3.63 +import org.testng.annotations.BeforeMethod;
    3.64 +import org.testng.annotations.Test;
    3.65 +
    3.66 +/**
    3.67 + *
    3.68 + * @author Jaroslav Tulach
    3.69 + */
    3.70 +public class MapModelTest {
    3.71 +    private MapTechnology t;
    3.72 +    private BrwsrCtx c;
    3.73 +    
    3.74 +    @BeforeClass public static void registerBeanAsModel() {
    3.75 +        JSONBeans.register(Person.class);
    3.76 +    }
    3.77 +
    3.78 +    @BeforeMethod public void initTechnology() {
    3.79 +        t = new MapTechnology();
    3.80 +        c = Contexts.newBuilder().register(Technology.class, t, 1).
    3.81 +            register(Transfer.class, t, 1).build();
    3.82 +    }
    3.83 +    
    3.84 +    @Test public void isThereABinding() throws Exception {
    3.85 +        Person p = Models.bind(new Person(), c);
    3.86 +        Models.applyBindings(p);
    3.87 +        p.setFirstName("Jarda");
    3.88 +        
    3.89 +        Map m = (Map)Models.toRaw(p);
    3.90 +        Object v = m.get("firstName");
    3.91 +        assertNotNull(v, "Value should be in the map");
    3.92 +        assertEquals(v.getClass(), One.class, "It is instance of One");
    3.93 +        One o = (One)v;
    3.94 +        assertEquals(o.changes, 1, "One change so far");
    3.95 +        assertFalse(o.pb.isReadOnly(), "Mutable property");
    3.96 +        
    3.97 +        assertEquals(o.get(), "Jarda", "Value should be in the map");
    3.98 +        
    3.99 +        o.set("Karle");
   3.100 +        
   3.101 +        assertEquals(p.getFirstName(), "Karle", "Model value updated");
   3.102 +        assertEquals(o.changes, 2, "Snd change");
   3.103 +    }
   3.104 +    
   3.105 +    
   3.106 +    @Test public void dontNotifySameProperty() throws Exception {
   3.107 +        Person p = Models.bind(new Person(), c);
   3.108 +        p.setFirstName("Jirka");
   3.109 +        
   3.110 +        Map m = (Map)Models.toRaw(p);
   3.111 +        Object v = m.get("firstName");
   3.112 +        assertNotNull(v, "Value should be in the map");
   3.113 +        assertEquals(v.getClass(), One.class, "It is instance of One");
   3.114 +        One o = (One)v;
   3.115 +        assertEquals(o.changes, 0, "No change so far the only one change happened before we connected");
   3.116 +        
   3.117 +        p.setFirstName(new String("Jirka"));
   3.118 +        assertEquals(o.changes, 0, "No change so far, the value is the same");
   3.119 +        
   3.120 +        p.setFirstName("Jarda");
   3.121 +        assertFalse(o.pb.isReadOnly(), "Mutable property");
   3.122 +        
   3.123 +        assertEquals(o.get(), "Jarda", "Value should be in the map");
   3.124 +        
   3.125 +        o.set("Karle");
   3.126 +        
   3.127 +        assertEquals(p.getFirstName(), "Karle", "Model value updated");
   3.128 +        assertEquals(o.changes, 2, "Snd change");
   3.129 +    }
   3.130 +    
   3.131 +    @Test public void canSetEnumAsString() throws Exception {
   3.132 +        Person p = Models.bind(new Person(), c);
   3.133 +        p.setFirstName("Jirka");
   3.134 +        p.setSex(Sex.MALE);
   3.135 +        
   3.136 +        Map m = (Map)Models.toRaw(p);
   3.137 +        Object v = m.get("sex");
   3.138 +        assertNotNull(v, "Value should be in the map");
   3.139 +        assertEquals(v.getClass(), One.class, "It is instance of One");
   3.140 +        One o = (One)v;
   3.141 +        
   3.142 +        o.set("FEMALE");
   3.143 +
   3.144 +        assertEquals(p.getSex(), Sex.FEMALE, "Changed to female");
   3.145 +    }
   3.146 +    
   3.147 +    @Test public void derivedProperty() throws Exception {
   3.148 +        Person p = Models.bind(new Person(), c);
   3.149 +        
   3.150 +        Map m = (Map)Models.toRaw(p);
   3.151 +        Object v = m.get("fullName");
   3.152 +        assertNotNull(v, "Value should be in the map");
   3.153 +        assertEquals(v.getClass(), One.class, "It is instance of One");
   3.154 +        One o = (One)v;
   3.155 +        assertTrue(o.pb.isReadOnly(), "Mutable property");
   3.156 +    }
   3.157 +    
   3.158 +    @Test public void changeSex() {
   3.159 +        Person p = Models.bind(new Person(), c);
   3.160 +        p.setFirstName("Trans");
   3.161 +        p.setSex(Sex.MALE);
   3.162 +        
   3.163 +        Map m = (Map)Models.toRaw(p);
   3.164 +        Object o = m.get("changeSex");
   3.165 +        assertNotNull(o, "Function registered in the model");
   3.166 +        assertEquals(o.getClass(), One.class);
   3.167 +        
   3.168 +        One one = (One)o;
   3.169 +        assertNotNull(one.fb, "Function binding specified");
   3.170 +        
   3.171 +        one.fb.call(null, null);
   3.172 +        
   3.173 +        assertEquals(p.getSex(), Sex.FEMALE, "Changed");
   3.174 +    }
   3.175 +    
   3.176 +    @Test public void setSex() {
   3.177 +        Person p = Models.bind(new Person(), c);
   3.178 +        p.setFirstName("Trans");
   3.179 +        
   3.180 +        Map m = (Map)Models.toRaw(p);
   3.181 +        Object o = m.get("changeSex");
   3.182 +        assertNotNull(o, "Function registered in the model");
   3.183 +        assertEquals(o.getClass(), One.class);
   3.184 +        
   3.185 +        One one = (One)o;
   3.186 +        assertNotNull(one.fb, "Function binding specified");
   3.187 +        
   3.188 +        one.fb.call("FEMALE", new Object());
   3.189 +        
   3.190 +        assertEquals(p.getSex(), Sex.FEMALE, "Changed");
   3.191 +    }
   3.192 +
   3.193 +    static final class One {
   3.194 +        int changes;
   3.195 +        final PropertyBinding pb;
   3.196 +        final FunctionBinding fb;
   3.197 +    
   3.198 +        One(Object m, PropertyBinding pb) throws NoSuchMethodException {
   3.199 +            this.pb = pb;
   3.200 +            this.fb = null;
   3.201 +        }
   3.202 +        One(Object m, FunctionBinding fb) throws NoSuchMethodException {
   3.203 +            this.pb = null;
   3.204 +            this.fb = fb;
   3.205 +        }
   3.206 +        
   3.207 +        Object get() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
   3.208 +            return pb.getValue();
   3.209 +        }
   3.210 +        
   3.211 +        void set(Object v) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
   3.212 +            pb.setValue(v);
   3.213 +        }
   3.214 +    }
   3.215 +    
   3.216 +    static final class MapTechnology 
   3.217 +    implements Technology<Map<String,One>>, Transfer {
   3.218 +
   3.219 +        @Override
   3.220 +        public Map<String, One> wrapModel(Object model) {
   3.221 +            return new HashMap<String, One>();
   3.222 +        }
   3.223 +
   3.224 +        @Override
   3.225 +        public void valueHasMutated(Map<String, One> data, String propertyName) {
   3.226 +            One p = data.get(propertyName);
   3.227 +            if (p != null) {
   3.228 +                p.changes++;
   3.229 +            }
   3.230 +        }
   3.231 +
   3.232 +        @Override
   3.233 +        public void bind(PropertyBinding b, Object model, Map<String, One> data) {
   3.234 +            try {
   3.235 +                One o = new One(model, b);
   3.236 +                data.put(b.getPropertyName(), o);
   3.237 +            } catch (NoSuchMethodException ex) {
   3.238 +                throw new IllegalStateException(ex);
   3.239 +            }
   3.240 +        }
   3.241 +
   3.242 +        @Override
   3.243 +        public void expose(FunctionBinding fb, Object model, Map<String, One> data) {
   3.244 +            try {
   3.245 +                data.put(fb.getFunctionName(), new One(model, fb));
   3.246 +            } catch (NoSuchMethodException ex) {
   3.247 +                throw new IllegalStateException(ex);
   3.248 +            }
   3.249 +        }
   3.250 +
   3.251 +        @Override
   3.252 +        public void applyBindings(Map<String, One> data) {
   3.253 +        }
   3.254 +
   3.255 +        @Override
   3.256 +        public Object wrapArray(Object[] arr) {
   3.257 +            return arr;
   3.258 +        }
   3.259 +
   3.260 +        @Override
   3.261 +        public void extract(Object obj, String[] props, Object[] values) {
   3.262 +            Map<?,?> map = obj instanceof Map ? (Map<?,?>)obj : null;
   3.263 +            for (int i = 0; i < Math.min(props.length, values.length); i++) {
   3.264 +                if (map == null) {
   3.265 +                    values[i] = null;
   3.266 +                } else {
   3.267 +                    values[i] = map.get(props[i]);
   3.268 +                    if (values[i] instanceof One) {
   3.269 +                        values[i] = ((One)values[i]).pb.getValue();
   3.270 +                    }
   3.271 +                }
   3.272 +            }
   3.273 +        }
   3.274 +
   3.275 +        @Override
   3.276 +        public void loadJSON(JSONCall call) {
   3.277 +            call.notifyError(new UnsupportedOperationException());
   3.278 +        }
   3.279 +
   3.280 +        @Override
   3.281 +        public <M> M toModel(Class<M> modelClass, Object data) {
   3.282 +            return modelClass.cast(data);
   3.283 +        }
   3.284 +
   3.285 +        @Override
   3.286 +        public Object toJSON(InputStream is) throws IOException {
   3.287 +            throw new IOException();
   3.288 +        }
   3.289 +
   3.290 +        @Override
   3.291 +        public void runSafe(Runnable r) {
   3.292 +            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
   3.293 +        }
   3.294 +    }
   3.295 +}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/json-beans/src/test/java/net/java/html/beans/Person.java	Sun Aug 03 17:38:24 2014 +0200
     4.3 @@ -0,0 +1,118 @@
     4.4 +/**
     4.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     4.6 + *
     4.7 + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
     4.8 + *
     4.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
    4.10 + * Other names may be trademarks of their respective owners.
    4.11 + *
    4.12 + * The contents of this file are subject to the terms of either the GNU
    4.13 + * General Public License Version 2 only ("GPL") or the Common
    4.14 + * Development and Distribution License("CDDL") (collectively, the
    4.15 + * "License"). You may not use this file except in compliance with the
    4.16 + * License. You can obtain a copy of the License at
    4.17 + * http://www.netbeans.org/cddl-gplv2.html
    4.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    4.19 + * specific language governing permissions and limitations under the
    4.20 + * License.  When distributing the software, include this License Header
    4.21 + * Notice in each file and include the License file at
    4.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
    4.23 + * particular file as subject to the "Classpath" exception as provided
    4.24 + * by Oracle in the GPL Version 2 section of the License file that
    4.25 + * accompanied this code. If applicable, add the following below the
    4.26 + * License Header, with the fields enclosed by brackets [] replaced by
    4.27 + * your own identifying information:
    4.28 + * "Portions Copyrighted [year] [name of copyright owner]"
    4.29 + *
    4.30 + * Contributor(s):
    4.31 + *
    4.32 + * The Original Software is NetBeans. The Initial Developer of the Original
    4.33 + * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
    4.34 + *
    4.35 + * If you wish your version of this file to be governed by only the CDDL
    4.36 + * or only the GPL Version 2, indicate your decision by adding
    4.37 + * "[Contributor] elects to include this software in this distribution
    4.38 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
    4.39 + * single choice of license, a recipient has the option to distribute
    4.40 + * your version of this file under either the CDDL, the GPL Version 2 or
    4.41 + * to extend the choice of license to its licensees as provided above.
    4.42 + * However, if you add GPL Version 2 code and therefore, elected the GPL
    4.43 + * Version 2 license, then the option applies only if the new code is
    4.44 + * made subject to such option by the copyright holder.
    4.45 + */
    4.46 +
    4.47 +package net.java.html.beans;
    4.48 +
    4.49 +import java.beans.PropertyChangeListener;
    4.50 +import java.beans.PropertyChangeSupport;
    4.51 +
    4.52 +/**
    4.53 + *
    4.54 + * @author Jaroslav Tulach
    4.55 + */
    4.56 +public final class Person {
    4.57 +    private String firstName;
    4.58 +    private String lastName;
    4.59 +    private Sex sex;
    4.60 +
    4.61 +    public static final String PROP_FIRSTNAME = "firstName";
    4.62 +    public static final String PROP_LASTNAME = "lastName";
    4.63 +    public static final String PROP_FULLNAME = "fullName";
    4.64 +    public static final String PROP_SEX = "sex";
    4.65 +
    4.66 +    public Person() {
    4.67 +    }
    4.68 +
    4.69 +    public Person(String firstName, String lastName, Sex sex) {
    4.70 +        this.firstName = firstName;
    4.71 +        this.lastName = lastName;
    4.72 +        this.sex = sex;
    4.73 +    }
    4.74 +
    4.75 +    public Sex getSex() {
    4.76 +        return sex;
    4.77 +    }
    4.78 +
    4.79 +    public void setSex(Sex sex) {
    4.80 +        Sex oldSex = this.sex;
    4.81 +        this.sex = sex;
    4.82 +        propertyChangeSupport.firePropertyChange(PROP_SEX, oldSex, sex);
    4.83 +    }
    4.84 +
    4.85 +    public String getFirstName() {
    4.86 +        return firstName;
    4.87 +    }
    4.88 +
    4.89 +    public void setFirstName(String firstName) {
    4.90 +        String oldFirstName = this.firstName;
    4.91 +        this.firstName = firstName;
    4.92 +        propertyChangeSupport.firePropertyChange(PROP_FIRSTNAME, oldFirstName, firstName);
    4.93 +        propertyChangeSupport.firePropertyChange(PROP_FULLNAME, null, null);
    4.94 +    }
    4.95 +
    4.96 +    public String getLastName() {
    4.97 +        return lastName;
    4.98 +    }
    4.99 +    
   4.100 +    public String getFullName() {
   4.101 +        return firstName + " " + lastName;
   4.102 +    }
   4.103 +
   4.104 +    public void setLastName(String lastName) {
   4.105 +        String oldLastName = this.lastName;
   4.106 +        this.lastName = lastName;
   4.107 +        propertyChangeSupport.firePropertyChange(PROP_LASTNAME, oldLastName, lastName);
   4.108 +        propertyChangeSupport.firePropertyChange(PROP_FULLNAME, null, null);
   4.109 +    }
   4.110 +
   4.111 +    private transient final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
   4.112 +
   4.113 +    public void addPropertyChangeListener(PropertyChangeListener listener) {
   4.114 +        propertyChangeSupport.addPropertyChangeListener(listener);
   4.115 +    }
   4.116 +
   4.117 +    public void removePropertyChangeListener(PropertyChangeListener listener) {
   4.118 +        propertyChangeSupport.removePropertyChangeListener(listener);
   4.119 +    }
   4.120 +    
   4.121 +}
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/json-beans/src/test/java/net/java/html/beans/Sex.java	Sun Aug 03 17:38:24 2014 +0200
     5.3 @@ -0,0 +1,51 @@
     5.4 +/**
     5.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     5.6 + *
     5.7 + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
     5.8 + *
     5.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
    5.10 + * Other names may be trademarks of their respective owners.
    5.11 + *
    5.12 + * The contents of this file are subject to the terms of either the GNU
    5.13 + * General Public License Version 2 only ("GPL") or the Common
    5.14 + * Development and Distribution License("CDDL") (collectively, the
    5.15 + * "License"). You may not use this file except in compliance with the
    5.16 + * License. You can obtain a copy of the License at
    5.17 + * http://www.netbeans.org/cddl-gplv2.html
    5.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    5.19 + * specific language governing permissions and limitations under the
    5.20 + * License.  When distributing the software, include this License Header
    5.21 + * Notice in each file and include the License file at
    5.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
    5.23 + * particular file as subject to the "Classpath" exception as provided
    5.24 + * by Oracle in the GPL Version 2 section of the License file that
    5.25 + * accompanied this code. If applicable, add the following below the
    5.26 + * License Header, with the fields enclosed by brackets [] replaced by
    5.27 + * your own identifying information:
    5.28 + * "Portions Copyrighted [year] [name of copyright owner]"
    5.29 + *
    5.30 + * Contributor(s):
    5.31 + *
    5.32 + * The Original Software is NetBeans. The Initial Developer of the Original
    5.33 + * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
    5.34 + *
    5.35 + * If you wish your version of this file to be governed by only the CDDL
    5.36 + * or only the GPL Version 2, indicate your decision by adding
    5.37 + * "[Contributor] elects to include this software in this distribution
    5.38 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
    5.39 + * single choice of license, a recipient has the option to distribute
    5.40 + * your version of this file under either the CDDL, the GPL Version 2 or
    5.41 + * to extend the choice of license to its licensees as provided above.
    5.42 + * However, if you add GPL Version 2 code and therefore, elected the GPL
    5.43 + * Version 2 license, then the option applies only if the new code is
    5.44 + * made subject to such option by the copyright holder.
    5.45 + */
    5.46 +package net.java.html.beans;
    5.47 +
    5.48 +/**
    5.49 + *
    5.50 + * @author Jaroslav Tulach
    5.51 + */
    5.52 +public enum Sex {
    5.53 +    MALE, FEMALE;
    5.54 +}
     6.1 --- a/json/src/main/java/org/apidesign/html/json/spi/Proto.java	Sun Aug 03 16:34:51 2014 +0200
     6.2 +++ b/json/src/main/java/org/apidesign/html/json/spi/Proto.java	Sun Aug 03 17:38:24 2014 +0200
     6.3 @@ -507,7 +507,7 @@
     6.4          ) {
     6.5              assert getClass().getName().endsWith("$Html4JavaType");
     6.6              try {
     6.7 -                assert getClass().getDeclaringClass() == clazz;
     6.8 +                assert clazz == modelFor || getClass().getDeclaringClass() == clazz;
     6.9              } catch (SecurityException ex) {
    6.10                  // OK, no check
    6.11              }