Migrating the dataprovider test cases from Creator code base results_sorting_root
authorwjprakash@netbeans.org
Tue, 13 Nov 2007 01:00:31 +0000
changeset 1848c1070f258f40
parent 1847 b2791a0816b7
child 1849 adbade4d7cbc
Migrating the dataprovider test cases from Creator code base
visualweb.dataprovider/test/unit/src/org/netbeans/modules/visualweb/dataprovider/AbstractDataProviderTest.java
visualweb.dataprovider/test/unit/src/org/netbeans/modules/visualweb/dataprovider/BasicTableDataFilterTest.java
visualweb.dataprovider/test/unit/src/org/netbeans/modules/visualweb/dataprovider/BasicTableDataSorterTest.java
visualweb.dataprovider/test/unit/src/org/netbeans/modules/visualweb/dataprovider/NbTestCase.java
visualweb.dataprovider/test/unit/src/org/netbeans/modules/visualweb/dataprovider/ObjectArrayDataProviderTest.java
visualweb.dataprovider/test/unit/src/org/netbeans/modules/visualweb/dataprovider/ObjectDataProviderTest.java
visualweb.dataprovider/test/unit/src/org/netbeans/modules/visualweb/dataprovider/ObjectListDataProviderTest.java
visualweb.dataprovider/test/unit/src/org/netbeans/modules/visualweb/dataprovider/TestBean.java
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/visualweb.dataprovider/test/unit/src/org/netbeans/modules/visualweb/dataprovider/AbstractDataProviderTest.java	Tue Nov 13 01:00:31 2007 +0000
     1.3 @@ -0,0 +1,107 @@
     1.4 +/*
     1.5 +* {START_JAVA_COPYRIGHT_NOTICE
     1.6 +* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
     1.7 +* Use is subject to license terms.
     1.8 +* END_COPYRIGHT_NOTICE}
     1.9 +*/
    1.10 +
    1.11 +package org.netbeans.modules.visualweb.dataprovider;
    1.12 +
    1.13 +import java.math.BigDecimal;
    1.14 +import java.math.BigInteger;
    1.15 +import java.util.ArrayList;
    1.16 +import java.util.Date;
    1.17 +import java.util.HashMap;
    1.18 +import java.util.List;
    1.19 +import java.util.Map;
    1.20 +import org.netbeans.junit.NbTestCase;
    1.21 +
    1.22 +
    1.23 +public class AbstractDataProviderTest extends NbTestCase {
    1.24 +    ArrayList dataTypes = new ArrayList();
    1.25 +    
    1.26 +    public AbstractDataProviderTest(String name) {
    1.27 +        super(name);
    1.28 +    }
    1.29 +
    1.30 +    @Override
    1.31 +    protected void setUp() throws Exception {
    1.32 +        super.setUp();
    1.33 +        dataTypes.add(Void.TYPE);
    1.34 +        dataTypes.add(Object[].class);
    1.35 +        dataTypes.add(String[].class);
    1.36 +        dataTypes.add(ArrayList.class);
    1.37 +        dataTypes.add(List.class);
    1.38 +        dataTypes.add(HashMap.class);
    1.39 +        dataTypes.add(Map.class);
    1.40 +        dataTypes.add(Boolean.TYPE);
    1.41 +        dataTypes.add(Character.TYPE);
    1.42 +        dataTypes.add(Byte.TYPE);
    1.43 +        dataTypes.add(Short.TYPE);
    1.44 +        dataTypes.add(Integer.TYPE);
    1.45 +        dataTypes.add(Long.TYPE);
    1.46 +        dataTypes.add(Float.TYPE);
    1.47 +        dataTypes.add(Double.TYPE);
    1.48 +        dataTypes.add(Boolean.class);
    1.49 +        dataTypes.add(Date.class);
    1.50 +        dataTypes.add(BigDecimal.class);
    1.51 +        dataTypes.add(BigInteger.class);
    1.52 +        dataTypes.add(Character.class);
    1.53 +        dataTypes.add(Byte.class);
    1.54 +        dataTypes.add(Short.class);
    1.55 +        dataTypes.add(Integer.class);
    1.56 +        dataTypes.add(Long.class);
    1.57 +        dataTypes.add(Float.class);
    1.58 +        dataTypes.add(Double.class);
    1.59 +        dataTypes.add(String.class);
    1.60 +        dataTypes.add(TestBean.class);
    1.61 +        dataTypes.add(AbstractDataProviderTest.class);
    1.62 +        dataTypes.add(IllegalArgumentException.class);
    1.63 +    }
    1.64 +
    1.65 +    @Override
    1.66 +    protected void tearDown() throws Exception {
    1.67 +        super.tearDown();
    1.68 +    }
    1.69 +
    1.70 +    public void testFakeDataTypes() {
    1.71 +//        for (int i = 0; i < dataTypes.size(); i++) {
    1.72 +//            Class c = (Class)dataTypes.get(i);
    1.73 +//            System.out.println(c.getName() + " --> " +
    1.74 +//                AbstractDataProvider.getFakeData(c, String.class));
    1.75 +//        }
    1.76 +    }
    1.77 +
    1.78 +    public void testFakeTestBean() {
    1.79 +//        Object o = AbstractDataProvider.getFakeData(TestBean.class);
    1.80 +//        System.out.println(o);
    1.81 +//        try {
    1.82 +//            BeanInfo bi = Introspector.getBeanInfo(o.getClass());
    1.83 +//            PropertyDescriptor[] props = bi.getPropertyDescriptors();
    1.84 +//            for (int i = 0; i < props.length; i++) {
    1.85 +//                if (props[i].getReadMethod() != null) {
    1.86 +//                    System.out.print(props[i].getName() + " [" +
    1.87 +//                        props[i].getPropertyType() + "] --> ");
    1.88 +//                    Object data = props[i].getReadMethod().invoke(o, null);
    1.89 +//                    if (data != null && data.getClass().isArray()) {
    1.90 +//                        System.out.println(data);
    1.91 +//                        for (int a = 0; a < Array.getLength(data); a++) {
    1.92 +//                            System.out.println("  " + Array.get(data, a));
    1.93 +//                        }
    1.94 +//                    } else if (data instanceof Object[]) {
    1.95 +//                        System.out.println(data);
    1.96 +//                        Object[] adata = (Object[])data;
    1.97 +//                        for (int a = 0; a < adata.length; a++) {
    1.98 +//                            System.out.println("  " + adata[a]);
    1.99 +//                        }
   1.100 +//                    }
   1.101 +//                    else {
   1.102 +//                        System.out.println(data);
   1.103 +//                    }
   1.104 +//                }
   1.105 +//            }
   1.106 +//        } catch (Exception x) {
   1.107 +//            x.printStackTrace();
   1.108 +//        }
   1.109 +    }
   1.110 +}
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/visualweb.dataprovider/test/unit/src/org/netbeans/modules/visualweb/dataprovider/BasicTableDataFilterTest.java	Tue Nov 13 01:00:31 2007 +0000
     2.3 @@ -0,0 +1,143 @@
     2.4 +/*
     2.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     2.6 + * 
     2.7 + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
     2.8 + * 
     2.9 + * The contents of this file are subject to the terms of either the GNU
    2.10 + * General Public License Version 2 only ("GPL") or the Common
    2.11 + * Development and Distribution License("CDDL") (collectively, the
    2.12 + * "License"). You may not use this file except in compliance with the
    2.13 + * License. You can obtain a copy of the License at
    2.14 + * http://www.netbeans.org/cddl-gplv2.html
    2.15 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    2.16 + * specific language governing permissions and limitations under the
    2.17 + * License.  When distributing the software, include this License Header
    2.18 + * Notice in each file and include the License file at
    2.19 + * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
    2.20 + * particular file as subject to the "Classpath" exception as provided
    2.21 + * by Sun in the GPL Version 2 section of the License file that
    2.22 + * accompanied this code. If applicable, add the following below the
    2.23 + * License Header, with the fields enclosed by brackets [] replaced by
    2.24 + * your own identifying information:
    2.25 + * "Portions Copyrighted [year] [name of copyright owner]"
    2.26 + * 
    2.27 + * If you wish your version of this file to be governed by only the CDDL
    2.28 + * or only the GPL Version 2, indicate your decision by adding
    2.29 + * "[Contributor] elects to include this software in this distribution
    2.30 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
    2.31 + * single choice of license, a recipient has the option to distribute
    2.32 + * your version of this file under either the CDDL, the GPL Version 2 or
    2.33 + * to extend the choice of license to its licensees as provided above.
    2.34 + * However, if you add GPL Version 2 code and therefore, elected the GPL
    2.35 + * Version 2 license, then the option applies only if the new code is
    2.36 + * made subject to such option by the copyright holder.
    2.37 + * 
    2.38 + * Contributor(s):
    2.39 + * 
    2.40 + * Portions Copyrighted 2007 Sun Microsystems, Inc.
    2.41 + */
    2.42 +package org.netbeans.modules.visualweb.dataprovider;
    2.43 +
    2.44 +import junit.framework.*;
    2.45 +import com.sun.data.provider.FilterCriteria;
    2.46 +import com.sun.data.provider.RowKey;
    2.47 +import com.sun.data.provider.impl.BasicTableDataFilter;
    2.48 +import com.sun.data.provider.impl.CompareFilterCriteria;
    2.49 +import com.sun.data.provider.impl.ObjectListDataProvider;
    2.50 +import com.sun.data.provider.impl.RegexFilterCriteria;
    2.51 +import org.netbeans.junit.NbTestCase;
    2.52 +
    2.53 +public class BasicTableDataFilterTest extends NbTestCase {
    2.54 +
    2.55 +    private ObjectListDataProvider tdp = null;
    2.56 +    private BasicTableDataFilter tdf = null;
    2.57 +
    2.58 +    public BasicTableDataFilterTest(String testName) {
    2.59 +        super(testName);
    2.60 +    }
    2.61 +
    2.62 +    @Override
    2.63 +    protected void setUp() throws Exception {
    2.64 +        super.setUp();
    2.65 +        tdp = new ObjectListDataProvider();
    2.66 +        tdf = new BasicTableDataFilter();
    2.67 +        for (int x = 0; x < 10; x++) {
    2.68 +            for (int i = 0; i < 20; i++) {
    2.69 +                TestBean tb = new TestBean("TestBean" + i);
    2.70 +                tb.setStringProperty(("TestBean:" + i) + tb.hashCode());
    2.71 +                tb.setLongProperty(System.currentTimeMillis());
    2.72 +                tb.setDoubleProperty(Math.random());
    2.73 +                tb.setIntProperty((int) Math.round(tb.getDoubleProperty() * 1000));
    2.74 +                tdp.addObject(tb);
    2.75 +            }
    2.76 +        }
    2.77 +    }
    2.78 +
    2.79 +    @Override
    2.80 +    protected void tearDown() throws Exception {
    2.81 +        tdf = null;
    2.82 +        tdp = null;
    2.83 +        super.tearDown();
    2.84 +    }
    2.85 +
    2.86 +    public void testFilter() {
    2.87 +        CompareFilterCriteria cfc1 = new CompareFilterCriteria(tdp.getFieldKey("intProperty"), new Integer(100));
    2.88 +        cfc1.setMatchLessThan(false);
    2.89 +        cfc1.setMatchEqualTo(true);
    2.90 +        cfc1.setMatchGreaterThan(true);
    2.91 +        cfc1.setInclude(true);
    2.92 +
    2.93 +        CompareFilterCriteria cfc2 = new CompareFilterCriteria(tdp.getFieldKey("intProperty"), new Integer(200));
    2.94 +        cfc2.setMatchLessThan(true);
    2.95 +        cfc2.setMatchEqualTo(true);
    2.96 +        cfc2.setMatchGreaterThan(false);
    2.97 +        cfc2.setInclude(true);
    2.98 +
    2.99 +        CompareFilterCriteria cfc3 = new CompareFilterCriteria(tdp.getFieldKey("intProperty"), new Integer(150));
   2.100 +        cfc3.setMatchLessThan(false);
   2.101 +        cfc3.setMatchEqualTo(true);
   2.102 +        cfc3.setMatchGreaterThan(false);
   2.103 +        cfc3.setInclude(false);
   2.104 +
   2.105 +        RegexFilterCriteria rfc1 = new RegexFilterCriteria(tdp.getFieldKey("id"), ".9");
   2.106 +        rfc1.setInclude(false);
   2.107 +
   2.108 +        tdf.setFilterCriteria(new FilterCriteria[]{
   2.109 +            //            rfc1,
   2.110 +            cfc1,
   2.111 +            cfc2,
   2.112 +            cfc3,
   2.113 +        });
   2.114 +
   2.115 +        tdf.setMatchAllCriteria(true);
   2.116 +//        idf.setMatchAllCriteria(false);
   2.117 +
   2.118 +        FilterCriteria[] ca = tdf.getFilterCriteria();
   2.119 +//        System.out.println("Filter Criteria (Match " + (tdf.isMatchAllCriteria() ? "ALL):" : "ANY):"));
   2.120 +//        for (int i = 0; i < ca.length; i++) {
   2.121 +//            System.out.println("  " + ca[i].getDisplayName());
   2.122 +//        }
   2.123 +
   2.124 +        RowKey[] rks = tdp.getRowKeys(tdp.getRowCount(), null);
   2.125 +//        System.out.println("ORIGINAL DATA: (" + rks.length + " rows)");
   2.126 +//        for (int i = 0; i < 5; i++) {
   2.127 +//        for (int i = 0; i < rks.length; i++) {
   2.128 +//            System.out.println("> row[" + i + "] " +
   2.129 +//                "id=\"" + tdp.getValue(tdp.getFieldKey("id"), rks[i]) + "\" " +
   2.130 +//                "int=" + tdp.getValue(tdp.getFieldKey("intProperty"), rks[i]) + " " +
   2.131 +//                "long=" + tdp.getValue(tdp.getFieldKey("longProperty"), rks[i]) + " " +
   2.132 +//                "double=" + tdp.getValue(tdp.getFieldKey("doubleProperty"), rks[i]) + " " +
   2.133 +//                "string=\"" + tdp.getValue(tdp.getFieldKey("stringProperty"), rks[i]) + "\"");
   2.134 +//        }
   2.135 +        RowKey[] fks = tdf.filter(tdp, rks);
   2.136 +//        System.out.println("FILTERED DATA: (" + fks.length + " rows)");
   2.137 +//        for (int i = 0; i < fks.length; i++) {
   2.138 +//            System.out.println("> row[" + i + "] " +
   2.139 +//                "id=\"" + tdp.getValue(tdp.getFieldKey("id"), fks[i]) + "\" " +
   2.140 +//                "int=" + tdp.getValue(tdp.getFieldKey("intProperty"), fks[i]) + " " +
   2.141 +//                "long=" + tdp.getValue(tdp.getFieldKey("longProperty"), fks[i]) + " " +
   2.142 +//                "double=" + tdp.getValue(tdp.getFieldKey("doubleProperty"), fks[i]) + " " +
   2.143 +//                "string=\"" + tdp.getValue(tdp.getFieldKey("stringProperty"), fks[i]) + "\"");
   2.144 +//        }
   2.145 +    }
   2.146 +}
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/visualweb.dataprovider/test/unit/src/org/netbeans/modules/visualweb/dataprovider/BasicTableDataSorterTest.java	Tue Nov 13 01:00:31 2007 +0000
     3.3 @@ -0,0 +1,74 @@
     3.4 +/*
     3.5 + * {START_JAVA_COPYRIGHT_NOTICE
     3.6 + * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
     3.7 + * Use is subject to license terms.
     3.8 + * END_COPYRIGHT_NOTICE}
     3.9 + */
    3.10 +package org.netbeans.modules.visualweb.dataprovider;
    3.11 +
    3.12 +import com.sun.data.provider.RowKey;
    3.13 +import com.sun.data.provider.SortCriteria;
    3.14 +import com.sun.data.provider.impl.BasicTableDataSorter;
    3.15 +import com.sun.data.provider.impl.FieldIdSortCriteria;
    3.16 +import com.sun.data.provider.impl.ObjectListDataProvider;
    3.17 +import org.netbeans.junit.NbTestCase;
    3.18 +
    3.19 +public class BasicTableDataSorterTest extends NbTestCase {
    3.20 +
    3.21 +    private BasicTableDataSorter tds = null;
    3.22 +    private ObjectListDataProvider tdp = null;
    3.23 +
    3.24 +    public BasicTableDataSorterTest(String testName) {
    3.25 +        super(testName);
    3.26 +    }
    3.27 +
    3.28 +    @Override
    3.29 +    protected void setUp() throws Exception {
    3.30 +        super.setUp();
    3.31 +        /**@todo verify the constructors*/
    3.32 +        tds = new BasicTableDataSorter();
    3.33 +        tdp = new ObjectListDataProvider();
    3.34 +        for (int x = 0; x < 10; x++) {
    3.35 +            for (int i = 0; i < 20; i++) {
    3.36 +                TestBean tb = new TestBean("TestBean" + i);
    3.37 +                tb.setStringProperty(("TestBean:" + i) + tb.hashCode());
    3.38 +                tb.setLongProperty(System.currentTimeMillis());
    3.39 +                tb.setDoubleProperty(Math.random());
    3.40 +                tb.setIntProperty((int) Math.round(tb.getDoubleProperty() * 1000));
    3.41 +                tdp.addObject(tb);
    3.42 +            }
    3.43 +        }
    3.44 +    }
    3.45 +
    3.46 +    @Override
    3.47 +    protected void tearDown() throws Exception {
    3.48 +        tds = null;
    3.49 +        tdp = null;
    3.50 +        super.tearDown();
    3.51 +    }
    3.52 +
    3.53 +    public void testSort() {
    3.54 +        tds.setSortCriteria(new SortCriteria[]{
    3.55 +            //            new FieldIdSortCriteria("stringProperty", true),
    3.56 +            new FieldIdSortCriteria("id", true),
    3.57 +            new FieldIdSortCriteria("intProperty", false),
    3.58 +//            new FieldIdSortCriteria("longProperty", true),
    3.59 +//            new FieldIdSortCriteria("doubleProperty", true),
    3.60 +        });
    3.61 +        SortCriteria[] sca = tds.getSortCriteria();
    3.62 +//        System.out.println("Sort Criteria:");
    3.63 +//        for (int i = 0; i < sca.length; i++) {
    3.64 +//            System.out.println("  [" + sca[i].getDisplayName() + "] " + (sca[i].isAscending() ? "ASC" : "DESC"));
    3.65 +//        }
    3.66 +        RowKey[] rows = tdp.getRowKeys(tdp.getRowCount(), null);
    3.67 +        RowKey[] sort = tds.sort(tdp, rows);
    3.68 +//        for (int i = 0; i < sort.length; i++) {
    3.69 +//            System.out.println("sorted[" + i + "] row[" + sort[i] + "] id=\"" +
    3.70 +//                tdp.getValue(tdp.getFieldKey("id"),             sort[i]) + "\" int=" +
    3.71 +//                tdp.getValue(tdp.getFieldKey("intProperty"),    sort[i]) + " long=" +
    3.72 +//                tdp.getValue(tdp.getFieldKey("longProperty"),   sort[i]) + " double=" +
    3.73 +//                tdp.getValue(tdp.getFieldKey("doubleProperty"), sort[i]) + " string=\"" +
    3.74 +//                tdp.getValue(tdp.getFieldKey("stringProperty"), sort[i]) + "\"");
    3.75 +//        }
    3.76 +    }
    3.77 +}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/visualweb.dataprovider/test/unit/src/org/netbeans/modules/visualweb/dataprovider/NbTestCase.java	Tue Nov 13 01:00:31 2007 +0000
     4.3 @@ -0,0 +1,48 @@
     4.4 +/*
     4.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     4.6 + * 
     4.7 + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
     4.8 + * 
     4.9 + * The contents of this file are subject to the terms of either the GNU
    4.10 + * General Public License Version 2 only ("GPL") or the Common
    4.11 + * Development and Distribution License("CDDL") (collectively, the
    4.12 + * "License"). You may not use this file except in compliance with the
    4.13 + * License. You can obtain a copy of the License at
    4.14 + * http://www.netbeans.org/cddl-gplv2.html
    4.15 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    4.16 + * specific language governing permissions and limitations under the
    4.17 + * License.  When distributing the software, include this License Header
    4.18 + * Notice in each file and include the License file at
    4.19 + * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
    4.20 + * particular file as subject to the "Classpath" exception as provided
    4.21 + * by Sun in the GPL Version 2 section of the License file that
    4.22 + * accompanied this code. If applicable, add the following below the
    4.23 + * License Header, with the fields enclosed by brackets [] replaced by
    4.24 + * your own identifying information:
    4.25 + * "Portions Copyrighted [year] [name of copyright owner]"
    4.26 + * 
    4.27 + * If you wish your version of this file to be governed by only the CDDL
    4.28 + * or only the GPL Version 2, indicate your decision by adding
    4.29 + * "[Contributor] elects to include this software in this distribution
    4.30 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
    4.31 + * single choice of license, a recipient has the option to distribute
    4.32 + * your version of this file under either the CDDL, the GPL Version 2 or
    4.33 + * to extend the choice of license to its licensees as provided above.
    4.34 + * However, if you add GPL Version 2 code and therefore, elected the GPL
    4.35 + * Version 2 license, then the option applies only if the new code is
    4.36 + * made subject to such option by the copyright holder.
    4.37 + * 
    4.38 + * Contributor(s):
    4.39 + * 
    4.40 + * Portions Copyrighted 2007 Sun Microsystems, Inc.
    4.41 + */
    4.42 +
    4.43 +package org.netbeans.modules.visualweb.dataprovider;
    4.44 +
    4.45 +/**
    4.46 + *
    4.47 + * @author winstonp
    4.48 + */
    4.49 +class NbTestCase {
    4.50 +
    4.51 +}
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/visualweb.dataprovider/test/unit/src/org/netbeans/modules/visualweb/dataprovider/ObjectArrayDataProviderTest.java	Tue Nov 13 01:00:31 2007 +0000
     5.3 @@ -0,0 +1,650 @@
     5.4 +package org.netbeans.modules.visualweb.dataprovider;
     5.5 +
     5.6 +/*
     5.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     5.8 + * 
     5.9 + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
    5.10 + * 
    5.11 + * The contents of this file are subject to the terms of either the GNU
    5.12 + * General Public License Version 2 only ("GPL") or the Common
    5.13 + * Development and Distribution License("CDDL") (collectively, the
    5.14 + * "License"). You may not use this file except in compliance with the
    5.15 + * License. You can obtain a copy of the License at
    5.16 + * http://www.netbeans.org/cddl-gplv2.html
    5.17 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    5.18 + * specific language governing permissions and limitations under the
    5.19 + * License.  When distributing the software, include this License Header
    5.20 + * Notice in each file and include the License file at
    5.21 + * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
    5.22 + * particular file as subject to the "Classpath" exception as provided
    5.23 + * by Sun in the GPL Version 2 section of the License file that
    5.24 + * accompanied this code. If applicable, add the following below the
    5.25 + * License Header, with the fields enclosed by brackets [] replaced by
    5.26 + * your own identifying information:
    5.27 + * "Portions Copyrighted [year] [name of copyright owner]"
    5.28 + * 
    5.29 + * If you wish your version of this file to be governed by only the CDDL
    5.30 + * or only the GPL Version 2, indicate your decision by adding
    5.31 + * "[Contributor] elects to include this software in this distribution
    5.32 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
    5.33 + * single choice of license, a recipient has the option to distribute
    5.34 + * your version of this file under either the CDDL, the GPL Version 2 or
    5.35 + * to extend the choice of license to its licensees as provided above.
    5.36 + * However, if you add GPL Version 2 code and therefore, elected the GPL
    5.37 + * Version 2 license, then the option applies only if the new code is
    5.38 + * made subject to such option by the copyright holder.
    5.39 + * 
    5.40 + * Contributor(s):
    5.41 + * 
    5.42 + * Portions Copyrighted 2007 Sun Microsystems, Inc.
    5.43 + */
    5.44 +import com.sun.data.provider.DataListener;
    5.45 +import com.sun.data.provider.DataProvider;
    5.46 +import com.sun.data.provider.FieldKey;
    5.47 +import com.sun.data.provider.RowKey;
    5.48 +import com.sun.data.provider.TableCursorListener;
    5.49 +import com.sun.data.provider.TableCursorVetoException;
    5.50 +import com.sun.data.provider.TableDataListener;
    5.51 +import com.sun.data.provider.TableDataProvider;
    5.52 +import com.sun.data.provider.impl.IndexRowKey;
    5.53 +import com.sun.data.provider.impl.ObjectArrayDataProvider;
    5.54 +import java.io.ByteArrayInputStream;
    5.55 +import java.io.ByteArrayOutputStream;
    5.56 +import java.io.ObjectInputStream;
    5.57 +import java.io.ObjectOutputStream;
    5.58 +import java.util.List;
    5.59 +import java.util.Map;
    5.60 +import org.netbeans.junit.NbTestCase;
    5.61 +
    5.62 +/**
    5.63 + *
    5.64 + * @author winstonp
    5.65 + */
    5.66 +public class ObjectArrayDataProviderTest extends NbTestCase {
    5.67 +
    5.68 +    public ObjectArrayDataProviderTest(String testName) {
    5.69 +        super(testName);
    5.70 +
    5.71 +    }
    5.72 +
    5.73 +    @Override
    5.74 +    protected void setUp() throws Exception {
    5.75 +        super.setUp();
    5.76 +        beans = new TestBean[5];
    5.77 +        for (int i = 0; i < beans.length; i++) {
    5.78 +            beans[i] = new TestBean("test" + i);
    5.79 +        }
    5.80 +        dp = new ObjectArrayDataProvider(beans, true);
    5.81 +
    5.82 +    }
    5.83 +
    5.84 +    @Override
    5.85 +    protected void tearDown() throws Exception {
    5.86 +        super.tearDown();
    5.87 +        dp = null;
    5.88 +        beans = null;
    5.89 +        listener = null;
    5.90 +        tdcListener = null;
    5.91 +        tdpListener = null;
    5.92 +    }
    5.93 +    // ------------------------------------------------------ Instance Variables
    5.94 +    /**
    5.95 +     * <p>The beans being wrapped by the {@link DataProvider} under test.
    5.96 +     */
    5.97 +    private TestBean beans[] = null;
    5.98 +    /**
    5.99 +     * <p>The {@link DataProvider} instance under test.
   5.100 +     */
   5.101 +    private ObjectArrayDataProvider dp = null;
   5.102 +    /**
   5.103 +     * <p>Event listener for event testing.</p>
   5.104 +     */
   5.105 +    private Listener listener = null;
   5.106 +    /**
   5.107 +     * <p>Event listener for event testing.</p>
   5.108 +     */
   5.109 +    private MyCursorListener tdcListener = null;
   5.110 +    /**
   5.111 +     * <p>Event listener for event testing.</p>
   5.112 +     */
   5.113 +    private MyDataListener tdpListener = null;
   5.114 +    // -------------------------------------------------------- Static Variables
   5.115 +    // Dummy variables just to provide access to type information
   5.116 +    private static int intArray[] = new int[0];
   5.117 +    private static TestBean nestedArray[] = new TestBean[0];
   5.118 +    /**
   5.119 +     * <p>Descriptors for the set of fieldKeys we expect to be known.</p>
   5.120 +     */
   5.121 +    private static Descriptor[] fieldKeys = {
   5.122 +        // Specific fieldKeys of this class
   5.123 +        new Descriptor("public1", String.class, false, "This is public1"),
   5.124 +        new Descriptor("public2", Integer.class, false, new Integer(8888)),
   5.125 +    };
   5.126 +    /**
   5.127 +     * <p>Descriptors for the set of properties we expect to be known.</p>
   5.128 +     */
   5.129 +    private static Descriptor[] properties = {
   5.130 +        // Specific properties of this class
   5.131 +        new Descriptor("booleanProperty", Boolean.class, false, Boolean.TRUE),
   5.132 +        new Descriptor("byteProperty", Byte.class, false, new Byte((byte) 123)),
   5.133 +        new Descriptor("doubleProperty", Double.class, false, new Double(654.321)),
   5.134 +        new Descriptor("floatProperty", Float.class, false, new Float((float) 123.45)),
   5.135 +        new Descriptor("id", String.class, false, null),
   5.136 +        new Descriptor("intArray", intArray.getClass(), false, null),
   5.137 +        new Descriptor("intList", List.class, false, null),
   5.138 +        new Descriptor("intProperty", Integer.class, false, new Integer(1234)),
   5.139 +        new Descriptor("longProperty", Long.class, false, new Long(54321)),
   5.140 +        new Descriptor("nestedArray", nestedArray.getClass(), false, null),
   5.141 +        new Descriptor("nestedList", List.class, false, null),
   5.142 +        new Descriptor("nestedMap", Map.class, false, null),
   5.143 +        new Descriptor("nestedProperty", TestBean.class, false, null),
   5.144 +        new Descriptor("readOnly", String.class, true, null),
   5.145 +        new Descriptor("shortProperty", Short.class, false, new Short((short) 321)),
   5.146 +        new Descriptor("stringProperty", String.class, false, "This is a String"),
   5.147 +        new Descriptor("nullString", String.class, true, null),
   5.148 +        // Inherited from java.lang.Object
   5.149 +        new Descriptor("class", Class.class, true, null),
   5.150 +    };
   5.151 +    /**
   5.152 +     * <p>Descriptors for updates that should be applied and tested.</p>
   5.153 +     */
   5.154 +    private static Update[] updates = {
   5.155 +        // Updates to read-write properties
   5.156 +        new Update("booleanProperty", Boolean.FALSE),
   5.157 +        new Update("byteProperty", new Byte((byte) 213)),
   5.158 +        new Update("doubleProperty", new Double(123.456)),
   5.159 +        new Update("floatProperty", new Float((float) 111.22)),
   5.160 +        new Update("intProperty", new Integer(23432)),
   5.161 +        new Update("longProperty", new Long((long) 55555)),
   5.162 +        new Update("shortProperty", new Short((short) 123)),
   5.163 +        new Update("stringProperty", "Updated string value"),
   5.164 +        // Public fieldKeys are read-write as well
   5.165 +        new Update("public1", "revised String1 value"),
   5.166 +        new Update("public2", new Integer(55555)),
   5.167 +    };
   5.168 +
   5.169 +    
   5.170 +
   5.171 +
   5.172 +    // ------------------------------------------------- Individual Test Methods
   5.173 +    /**
   5.174 +     * <p>Check convenience methods on abstract base class that
   5.175 +     * should still show through the concrete implementation.</p>
   5.176 +     */
   5.177 +    public void testBaseClassMethods() {
   5.178 +
   5.179 +        // Operate on FieldKey or field identifier
   5.180 +        for (int i = 0; i < properties.length; i++) {
   5.181 +            String fieldId = properties[i].name;
   5.182 +            FieldKey fieldKey = dp.getFieldKey(fieldId);
   5.183 +            assertEquals("type(" + fieldId + ")",
   5.184 +                    dp.getType(fieldKey),
   5.185 +                    dp.getType(fieldId));
   5.186 +            assertEquals("value(" + fieldId + ")",
   5.187 +                    dp.getValue(fieldKey),
   5.188 +                    dp.getValue(fieldId));
   5.189 +            assertEquals("readOnly(" + fieldId + ")",
   5.190 +                    dp.isReadOnly(fieldKey),
   5.191 +                    dp.isReadOnly(fieldId));
   5.192 +        }
   5.193 +
   5.194 +    }
   5.195 +
   5.196 +    /**
   5.197 +     * <p>Check for event propogation for basic DataProvider events.</p>
   5.198 +     */
   5.199 +    public void testEventsBasic() {
   5.200 +
   5.201 +        assertNotNull(dp.getFieldKey("intProperty"));
   5.202 +        assertNotNull(dp.getFieldKey("public1"));
   5.203 +
   5.204 +        // Register a new listener and verify that it worked
   5.205 +        listener = new Listener();
   5.206 +        dp.addDataListener(listener);
   5.207 +        DataListener listeners[] = dp.getDataListeners();
   5.208 +        assertEquals(1, listeners.length);
   5.209 +        assertTrue(listener == listeners[0]);
   5.210 +
   5.211 +        // Make sure we log the update events correctly
   5.212 +        dp.setValue(dp.getFieldKey("intProperty"), new Integer(23432));
   5.213 +        dp.setValue(dp.getFieldKey("public1"), "new public1");
   5.214 +        assertEquals("intProperty/1234/23432//public1/This is public1/new public1//",
   5.215 +                listener.getLog());
   5.216 +
   5.217 +        // Deregister the old listener and verify that it worked
   5.218 +        dp.removeDataListener(listener);
   5.219 +        listeners = dp.getDataListeners();
   5.220 +        assertEquals(0, listeners.length);
   5.221 +
   5.222 +    }
   5.223 +
   5.224 +    /**
   5.225 +     * <p>Check for event propogation for cursor changes.</p>
   5.226 +     */
   5.227 +    public void testEventsCursor() throws Exception {
   5.228 +
   5.229 +        // Register a new listener and verify that it worked
   5.230 +        tdcListener = new MyCursorListener();
   5.231 +        dp.addTableCursorListener(tdcListener);
   5.232 +        TableCursorListener listeners[] = dp.getTableCursorListeners();
   5.233 +        assertEquals(1, listeners.length);
   5.234 +        assertTrue(tdcListener == listeners[0]);
   5.235 +
   5.236 +        // Make sure we log cursor change events correctly
   5.237 +        assertEquals(new IndexRowKey(0), dp.getCursorRow());
   5.238 +        dp.setCursorRow(new IndexRowKey(2));
   5.239 +        assertEquals(new IndexRowKey(2), dp.getCursorRow());
   5.240 +        dp.setCursorRow(new IndexRowKey(1));
   5.241 +        assertEquals(new IndexRowKey(1), dp.getCursorRow());
   5.242 +        assertEquals("cursorChanging/RowKey[0]/RowKey[2]//cursorChanged/RowKey[0]/RowKey[2]//" +
   5.243 +                "cursorChanging/RowKey[2]/RowKey[1]//cursorChanged/RowKey[2]/RowKey[1]//",
   5.244 +                tdcListener.getLog());
   5.245 +
   5.246 +        // Make sure we can deal with vetos as well
   5.247 +        tdcListener.clear();
   5.248 +        tdcListener.setVeto(true);
   5.249 +        try {
   5.250 +            dp.setCursorRow(new IndexRowKey(3));
   5.251 +            fail("Should have thrown TableCursorVetoException");
   5.252 +        } catch (TableCursorVetoException e) {
   5.253 +            ; // Expected result
   5.254 +        }
   5.255 +        assertEquals(new IndexRowKey(1), dp.getCursorRow());
   5.256 +        assertEquals("cursorChanging/RowKey[1]/RowKey[3]//cursorVetoed/RowKey[1]/RowKey[3]//",
   5.257 +                tdcListener.getLog());
   5.258 +
   5.259 +        // Deregister the old listener and verify that it worked
   5.260 +        dp.removeTableCursorListener(tdcListener);
   5.261 +        listeners = dp.getTableCursorListeners();
   5.262 +        assertEquals(0, listeners.length);
   5.263 +
   5.264 +    }
   5.265 +
   5.266 +    /**
   5.267 +     * <p>Check for event propogation on random data changes.</p>
   5.268 +     */
   5.269 +    public void testEventsData() {
   5.270 +
   5.271 +        // Register a new listener and verify that it worked
   5.272 +        tdpListener = new MyDataListener();
   5.273 +        dp.addTableDataListener(tdpListener);
   5.274 +        TableDataListener listeners[] = dp.getTableDataListeners();
   5.275 +        assertEquals(1, listeners.length);
   5.276 +        assertTrue(tdpListener == listeners[0]);
   5.277 +
   5.278 +        dp.cursorFirst();
   5.279 +        // Make sure we log the update events correctly
   5.280 +        dp.setValue(dp.getFieldKey("intProperty"),
   5.281 +                new Integer(23432)); // Change, so event expected
   5.282 +        Object value = dp.getValue(dp.getFieldKey("stringProperty"));
   5.283 +        dp.setValue(dp.getFieldKey("stringProperty"), value); // No change, so no event expected
   5.284 +
   5.285 +
   5.286 +        assertEquals("FieldKey[intProperty]/RowKey[0]/1234/23432//" + // Row-specific event
   5.287 +                "FieldKey[intProperty]/1234/23432//", // Row-independent event
   5.288 +                tdpListener.getLog());
   5.289 +
   5.290 +        // We should get a provider change event too
   5.291 +        tdpListener.clear();
   5.292 +        dp.setArray(dp.getArray());
   5.293 +        assertEquals("providerChanged//", tdpListener.getLog());
   5.294 +
   5.295 +        // Deregister the old listener and verify that it worked
   5.296 +        dp.removeTableDataListener(tdpListener);
   5.297 +        listeners = dp.getTableDataListeners();
   5.298 +        assertEquals(0, listeners.length);
   5.299 +
   5.300 +    }
   5.301 +
   5.302 +    /**
   5.303 +     * <p>Check some things that should <strong>not</strong> work.</p>
   5.304 +     */
   5.305 +    public void testNegative() {
   5.306 +
   5.307 +        // Access to unknown fieldKey/property
   5.308 +        try {
   5.309 +            dp.getFieldKey("unknown id value");
   5.310 +            fail("Should have thrown IllegalArgumentException");
   5.311 +        } catch (IllegalArgumentException e) {
   5.312 +            ; // Expected result
   5.313 +        }
   5.314 +
   5.315 +        // Attempt to update a read only value
   5.316 +        try {
   5.317 +            dp.setValue(dp.getFieldKey("readOnly"), "xyz");
   5.318 +            fail("Should have thrown IllegalStateException");
   5.319 +        } catch (IllegalStateException e) {
   5.320 +            ; // Expected result
   5.321 +        }
   5.322 +
   5.323 +        // Attempt to set value with an incorrect data type
   5.324 +        try {
   5.325 +            dp.setValue(dp.getFieldKey("intProperty"), "string value");
   5.326 +            fail("Should have thrown IllegalArgumentException");
   5.327 +        } catch (IllegalArgumentException e) {
   5.328 +            ; // Expected result
   5.329 +        }
   5.330 +
   5.331 +    }
   5.332 +
   5.333 +    /**
   5.334 +     * <p>Ensure that access to public fields can be turned off.</p>
   5.335 +     */
   5.336 +    public void testNoFields() {
   5.337 +
   5.338 +        dp = new ObjectArrayDataProvider(beans, false);
   5.339 +        try {
   5.340 +            dp.getFieldKey("public1");
   5.341 +            fail("Should have thrown IllegalArgumentException");
   5.342 +        } catch (IllegalArgumentException e) {
   5.343 +            ; // Expected result
   5.344 +        }
   5.345 +        try {
   5.346 +            dp.getFieldKey("public2");
   5.347 +            fail("Should have thrown IllegalArgumentException");
   5.348 +        } catch (IllegalArgumentException e) {
   5.349 +            ; // Expected result
   5.350 +        }
   5.351 +
   5.352 +        // Check the available properties for expected characteristics
   5.353 +        checkProperties();
   5.354 +        checkExtras();
   5.355 +
   5.356 +    }
   5.357 +
   5.358 +    /**
   5.359 +     * <p>Test a pristine instance.</p>
   5.360 +     */
   5.361 +    public void testPristine() throws Exception {
   5.362 +
   5.363 +        assertTrue(dp.isIncludeFields());
   5.364 +        assertEquals(beans.length, dp.getRowCount());
   5.365 +
   5.366 +        // Check the available fieldKeys and properties for expected characteristics
   5.367 +        for (int i = 0; i < beans.length; i++) {
   5.368 +            dp.setCursorRow(dp.getRowKey("" + i));
   5.369 +            assertEquals("test" + i, dp.getValue(dp.getFieldKey("id")));
   5.370 +            checkFields();
   5.371 +            checkProperties();
   5.372 +            checkExtras();
   5.373 +        }
   5.374 +
   5.375 +        // Check random access on the id property
   5.376 +        for (int i = 0; i < beans.length; i++) {
   5.377 +            assertEquals("test" + i, dp.getValue(dp.getFieldKey("id"), dp.getRowKey("" + i)));
   5.378 +        }
   5.379 +
   5.380 +    }
   5.381 +
   5.382 +    /**
   5.383 +     * <p>Test serializability of this data provider.</p>
   5.384 +     */
   5.385 +    public void testSerializable() throws Exception {
   5.386 +
   5.387 +        ByteArrayOutputStream baos = new ByteArrayOutputStream();
   5.388 +        ObjectOutputStream oos = new ObjectOutputStream(baos);
   5.389 +        oos.writeObject(dp);
   5.390 +        oos.close();
   5.391 +        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
   5.392 +        ObjectInputStream ois = new ObjectInputStream(bais);
   5.393 +        dp = (ObjectArrayDataProvider) ois.readObject();
   5.394 +        ois.close();
   5.395 +
   5.396 +        testPristine();
   5.397 +
   5.398 +    }
   5.399 +
   5.400 +    /**
   5.401 +     * <p>Test updates to updateable fieldKeys and properties.</p>
   5.402 +     */
   5.403 +    public void testUpdates() {
   5.404 +
   5.405 +        // Do the easy cases
   5.406 +        checkUpdates();
   5.407 +
   5.408 +    }
   5.409 +
   5.410 +
   5.411 +    // --------------------------------------------------------- Support Methods
   5.412 +    /**
   5.413 +     * <p>Ensure that the array returned by <code>getFieldKeys()</code>
   5.414 +     * does not include any keys that should not be there.</p>
   5.415 +     */
   5.416 +    private void checkExtras() {
   5.417 +
   5.418 +        FieldKey keys[] = dp.getFieldKeys();
   5.419 +        assertNotNull(keys);
   5.420 +        for (int i = 0; i < keys.length; i++) {
   5.421 +            String name = keys[i].getFieldId();
   5.422 +            boolean found = false;
   5.423 +            for (int j = 0; j < properties.length; j++) {
   5.424 +                if (name.equals(properties[j].name)) {
   5.425 +                    found = true;
   5.426 +                    break;
   5.427 +                }
   5.428 +            }
   5.429 +            if (!found && dp.isIncludeFields()) {
   5.430 +                for (int j = 0; j < fieldKeys.length; j++) {
   5.431 +                    if (name.equals(fieldKeys[j].name)) {
   5.432 +                        found = true;
   5.433 +                        break;
   5.434 +                    }
   5.435 +                }
   5.436 +            }
   5.437 +            assertTrue("Id '" + name + "' is valid", found);
   5.438 +        }
   5.439 +
   5.440 +    }
   5.441 +
   5.442 +    /**
   5.443 +     * <p>Ensure that all the expected fieldKeys are present and have
   5.444 +     * the specified default values (where possible).</p>
   5.445 +     */
   5.446 +    private void checkFields() {
   5.447 +
   5.448 +        FieldKey dk = null;
   5.449 +        String name = null;
   5.450 +        for (int i = 0; i < fieldKeys.length; i++) {
   5.451 +            name = fieldKeys[i].name;
   5.452 +            dk = dp.getFieldKey(name);
   5.453 +            assertNotNull("FieldKey for '" + name + "'", dk);
   5.454 +            assertTrue("Type for '" + name + "'",
   5.455 +                    isAssignableFrom(dp.getType(dk), fieldKeys[i].type));
   5.456 +            assertEquals("ReadOnly for '" + name + "'",
   5.457 +                    fieldKeys[i].canSetValue, dp.isReadOnly(dk));
   5.458 +            if (fieldKeys[i].defaultValue != null) {
   5.459 +                assertEquals("Value for '" + name + "'",
   5.460 +                        fieldKeys[i].defaultValue, dp.getValue(dk));
   5.461 +            }
   5.462 +        }
   5.463 +
   5.464 +    }
   5.465 +
   5.466 +    /**
   5.467 +     * <p>Ensure that all the expected properties are present and have
   5.468 +     * the specified default values (where possible).</p>
   5.469 +     */
   5.470 +    private void checkProperties() {
   5.471 +
   5.472 +        FieldKey dk = null;
   5.473 +        String name = null;
   5.474 +        for (int i = 0; i < properties.length; i++) {
   5.475 +            name = properties[i].name;
   5.476 +            dk = dp.getFieldKey(name);
   5.477 +            assertNotNull("FieldKey for '" + name + "'", dk);
   5.478 +            assertTrue("Type for '" + name + "'",
   5.479 +                    isAssignableFrom(dp.getType(dk), properties[i].type));
   5.480 +            assertEquals("ReadOnly for '" + name + "'",
   5.481 +                    properties[i].canSetValue, dp.isReadOnly(dk));
   5.482 +            if (properties[i].defaultValue != null) {
   5.483 +                assertEquals("Value for '" + name + "'",
   5.484 +                        properties[i].defaultValue, dp.getValue(dk));
   5.485 +            }
   5.486 +        }
   5.487 +
   5.488 +    }
   5.489 +
   5.490 +    private boolean isAssignableFrom(Class to, Class from) {
   5.491 +        if (to.isPrimitive()) {
   5.492 +            if (to == Boolean.TYPE) {
   5.493 +                to = Boolean.class;
   5.494 +            } else if (to == Character.TYPE) {
   5.495 +                to = Character.class;
   5.496 +            } else if (to == Byte.TYPE) {
   5.497 +                to = Byte.class;
   5.498 +            } else if (to == Short.TYPE) {
   5.499 +                to = Short.class;
   5.500 +            } else if (to == Integer.TYPE) {
   5.501 +                to = Integer.class;
   5.502 +            } else if (to == Long.TYPE) {
   5.503 +                to = Long.class;
   5.504 +            } else if (to == Float.TYPE) {
   5.505 +                to = Float.class;
   5.506 +            } else if (to == Double.TYPE) {
   5.507 +                to = Double.class;
   5.508 +            }
   5.509 +        }
   5.510 +        return to.isAssignableFrom(from);
   5.511 +    }
   5.512 +
   5.513 +    /**
   5.514 +     * <p>Ensure that we can update all the simple fieldKeys and properties
   5.515 +     * that should be updatable by default.</p>
   5.516 +     */
   5.517 +    private void checkUpdates() {
   5.518 +
   5.519 +        FieldKey dk = null;
   5.520 +        String name = null;
   5.521 +        for (int i = 0; i < updates.length; i++) {
   5.522 +            name = updates[i].name;
   5.523 +            try {
   5.524 +                dp.setValue(dp.getFieldKey(name), updates[i].value);
   5.525 +            } catch (Exception e) {
   5.526 +                fail("Cannot set value for '" + name + "':" + e);
   5.527 +            }
   5.528 +            assertEquals("Updated value for '" + name + "'",
   5.529 +                    updates[i].value, dp.getValue(dp.getFieldKey(name)));
   5.530 +        }
   5.531 +
   5.532 +    }
   5.533 +
   5.534 +    // Private class to describe the expected properties
   5.535 +    static class Descriptor {
   5.536 +
   5.537 +        public Descriptor(String name, Class type, boolean canSetValue, Object defaultValue) {
   5.538 +            this.name = name;
   5.539 +            this.type = type;
   5.540 +            this.canSetValue = canSetValue;
   5.541 +            this.defaultValue = defaultValue;
   5.542 +        }
   5.543 +        public String name;
   5.544 +        public Class type;
   5.545 +        public boolean canSetValue;
   5.546 +        public Object defaultValue;
   5.547 +    }
   5.548 +
   5.549 +    // Private class to represent an event listener
   5.550 +    static class Listener
   5.551 +            implements DataListener {
   5.552 +
   5.553 +        String log = "";
   5.554 +
   5.555 +        public String getLog() {
   5.556 +            return this.log;
   5.557 +        }
   5.558 +
   5.559 +        public void clear() {
   5.560 +            this.log = "";
   5.561 +        }
   5.562 +
   5.563 +        public void valueChanged(DataProvider dp, FieldKey dk, Object oldValue,
   5.564 +                Object newValue) {
   5.565 +            log += dk.getFieldId() + "/" + oldValue + "/" + newValue + "//";
   5.566 +        }
   5.567 +
   5.568 +        public void providerChanged(DataProvider dp) {
   5.569 +            log += "providerChanged//";
   5.570 +        }
   5.571 +    }
   5.572 +
   5.573 +    // Private class to represent a TableDataProvider cursor listener
   5.574 +    static class MyCursorListener implements TableCursorListener {
   5.575 +
   5.576 +        boolean veto = false;
   5.577 +        String log = "";
   5.578 +
   5.579 +        public String getLog() {
   5.580 +            return this.log;
   5.581 +        }
   5.582 +
   5.583 +        public void clear() {
   5.584 +            this.log = "";
   5.585 +        }
   5.586 +
   5.587 +        public void cursorChanged(TableDataProvider dp, RowKey oldRow, RowKey newRow) {
   5.588 +            log += "cursorChanged/" + oldRow + "/" + newRow + "//";
   5.589 +        }
   5.590 +
   5.591 +        public void cursorChanging(TableDataProvider dp, RowKey oldRow, RowKey newRow)
   5.592 +                throws TableCursorVetoException {
   5.593 +            log += "cursorChanging/" + oldRow + "/" + newRow + "//";
   5.594 +            if (veto) {
   5.595 +                log += "cursorVetoed/" + oldRow + "/" + newRow + "//";
   5.596 +                throw new TableCursorVetoException("No way, Jose");
   5.597 +            }
   5.598 +        }
   5.599 +
   5.600 +        public boolean isVeto() {
   5.601 +            return this.veto;
   5.602 +        }
   5.603 +
   5.604 +        public void setVeto(boolean veto) {
   5.605 +            this.veto = veto;
   5.606 +        }
   5.607 +    }
   5.608 +
   5.609 +    // Private class to represent a TableDataProvider event listener
   5.610 +    class MyDataListener implements TableDataListener {
   5.611 +
   5.612 +        String log = "";
   5.613 +
   5.614 +        public String getLog() {
   5.615 +            return this.log;
   5.616 +        }
   5.617 +
   5.618 +        public void clear() {
   5.619 +            this.log = "";
   5.620 +        }
   5.621 +
   5.622 +        public void valueChanged(DataProvider dp, FieldKey fk, Object oldValue, Object newValue) {
   5.623 +            log += fk + "/" + oldValue + "/" + newValue + "//";
   5.624 +        }
   5.625 +
   5.626 +        public void providerChanged(DataProvider dp) {
   5.627 +            log += "providerChanged//";
   5.628 +        }
   5.629 +
   5.630 +        public void rowAdded(TableDataProvider dp, RowKey rk) {
   5.631 +            log += "rowAdded/" + rk + "//";
   5.632 +        }
   5.633 +
   5.634 +        public void rowRemoved(TableDataProvider dp, RowKey rk) {
   5.635 +            log += "rowRemoved/" + rk + "//";
   5.636 +        }
   5.637 +
   5.638 +        public void valueChanged(TableDataProvider dp, FieldKey fk, RowKey rk, Object oldValue, Object newValue) {
   5.639 +            log += fk + "/" + rk + "/" + oldValue + "/" + newValue + "//";
   5.640 +        }
   5.641 +    }
   5.642 +
   5.643 +    // Private class to describe updates to be performed and checked
   5.644 +    static class Update {
   5.645 +
   5.646 +        public Update(String name, Object value) {
   5.647 +            this.name = name;
   5.648 +            this.value = value;
   5.649 +        }
   5.650 +        public String name;
   5.651 +        public Object value;
   5.652 +    }
   5.653 +}
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/visualweb.dataprovider/test/unit/src/org/netbeans/modules/visualweb/dataprovider/ObjectDataProviderTest.java	Tue Nov 13 01:00:31 2007 +0000
     6.3 @@ -0,0 +1,516 @@
     6.4 +/*
     6.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     6.6 + * 
     6.7 + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
     6.8 + * 
     6.9 + * The contents of this file are subject to the terms of either the GNU
    6.10 + * General Public License Version 2 only ("GPL") or the Common
    6.11 + * Development and Distribution License("CDDL") (collectively, the
    6.12 + * "License"). You may not use this file except in compliance with the
    6.13 + * License. You can obtain a copy of the License at
    6.14 + * http://www.netbeans.org/cddl-gplv2.html
    6.15 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    6.16 + * specific language governing permissions and limitations under the
    6.17 + * License.  When distributing the software, include this License Header
    6.18 + * Notice in each file and include the License file at
    6.19 + * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
    6.20 + * particular file as subject to the "Classpath" exception as provided
    6.21 + * by Sun in the GPL Version 2 section of the License file that
    6.22 + * accompanied this code. If applicable, add the following below the
    6.23 + * License Header, with the fields enclosed by brackets [] replaced by
    6.24 + * your own identifying information:
    6.25 + * "Portions Copyrighted [year] [name of copyright owner]"
    6.26 + * 
    6.27 + * If you wish your version of this file to be governed by only the CDDL
    6.28 + * or only the GPL Version 2, indicate your decision by adding
    6.29 + * "[Contributor] elects to include this software in this distribution
    6.30 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
    6.31 + * single choice of license, a recipient has the option to distribute
    6.32 + * your version of this file under either the CDDL, the GPL Version 2 or
    6.33 + * to extend the choice of license to its licensees as provided above.
    6.34 + * However, if you add GPL Version 2 code and therefore, elected the GPL
    6.35 + * Version 2 license, then the option applies only if the new code is
    6.36 + * made subject to such option by the copyright holder.
    6.37 + * 
    6.38 + * Contributor(s):
    6.39 + * 
    6.40 + * Portions Copyrighted 2007 Sun Microsystems, Inc.
    6.41 + */
    6.42 +
    6.43 +package org.netbeans.modules.visualweb.dataprovider;
    6.44 +
    6.45 +import com.sun.data.provider.FieldKey;
    6.46 +import com.sun.data.provider.DataProvider;
    6.47 +import com.sun.data.provider.DataListener;
    6.48 +import com.sun.data.provider.impl.ObjectDataProvider;
    6.49 +import java.io.ByteArrayInputStream;
    6.50 +import java.io.ByteArrayOutputStream;
    6.51 +import java.io.ObjectInputStream;
    6.52 +import java.io.ObjectOutputStream;
    6.53 +import java.util.List;
    6.54 +import java.util.Map;
    6.55 +import org.netbeans.junit.NbTestCase;
    6.56 +
    6.57 +/**
    6.58 + * <p>Unit tests for {@link ObjectDataProvider}.</p>
    6.59 + */
    6.60 +public class ObjectDataProviderTest extends NbTestCase {
    6.61 +
    6.62 +
    6.63 +    // ------------------------------------------------------ Instance Variables
    6.64 +
    6.65 +
    6.66 +    /**
    6.67 +     * <p>The bean being wrapped by the {@link DataProvider} under test.
    6.68 +     */
    6.69 +    private TestBean bean = null;
    6.70 +
    6.71 +
    6.72 +    /**
    6.73 +     * <p>The {@link DataProvider} instance under test.
    6.74 +     */
    6.75 +    private ObjectDataProvider dp = null;
    6.76 +
    6.77 +
    6.78 +    /**
    6.79 +     * <p>Event listener for event testing.</p>
    6.80 +     */
    6.81 +    private Listener listener = null;
    6.82 +
    6.83 +
    6.84 +    // -------------------------------------------------------- Static Variables
    6.85 +
    6.86 +
    6.87 +    // Dummy variables just to provide access to type information
    6.88 +    private static int intArray[] = new int[0];
    6.89 +    private static TestBean nestedArray[] = new TestBean[0];
    6.90 +
    6.91 +
    6.92 +    /**
    6.93 +     * <p>Descriptors for the set of fieldKeys we expect to be known.</p>
    6.94 +     */
    6.95 +    private static Descriptor[] fieldKeys = {
    6.96 +        // Specific fieldKeys of this class
    6.97 +        new Descriptor("public1", String.class, false, "This is public1"),
    6.98 +        new Descriptor("public2", Integer.class, false, new Integer(8888)),
    6.99 +    };
   6.100 +
   6.101 +
   6.102 +    /**
   6.103 +     * <p>Descriptors for the set of properties we expect to be known.</p>
   6.104 +     */
   6.105 +    private static Descriptor[] properties = {
   6.106 +        // Specific properties of this class
   6.107 +        new Descriptor("booleanProperty", Boolean.class, false, Boolean.TRUE),
   6.108 +        new Descriptor("byteProperty", Byte.class, false, new Byte((byte) 123)),
   6.109 +        new Descriptor("doubleProperty", Double.class, false, new Double(654.321)),
   6.110 +        new Descriptor("floatProperty", Float.class, false, new Float((float) 123.45)),
   6.111 +        new Descriptor("id", String.class, false, null),
   6.112 +        new Descriptor("intArray", intArray.getClass(), false, null),
   6.113 +        new Descriptor("intList", List.class, false, null),
   6.114 +        new Descriptor("intProperty", Integer.class, false, new Integer(1234)),
   6.115 +        new Descriptor("longProperty", Long.class, false, new Long(54321)),
   6.116 +        new Descriptor("nestedArray", nestedArray.getClass(), false, null),
   6.117 +        new Descriptor("nestedList", List.class, false, null),
   6.118 +        new Descriptor("nestedMap", Map.class, false, null),
   6.119 +        new Descriptor("nestedProperty", TestBean.class, false, null),
   6.120 +        new Descriptor("readOnly", String.class, true, null),
   6.121 +        new Descriptor("shortProperty", Short.class, false, new Short((short) 321)),
   6.122 +        new Descriptor("stringProperty", String.class, false, "This is a String"),
   6.123 +        new Descriptor("nullString", String.class, true, null),
   6.124 +        // Inherited from java.lang.Object
   6.125 +        new Descriptor("class", Class.class, true, null),
   6.126 +    };
   6.127 +
   6.128 +
   6.129 +    /**
   6.130 +     * <p>Descriptors for updates that should be applied and tested.</p>
   6.131 +     */
   6.132 +    private static Update[] updates = {
   6.133 +        // Updates to read-write properties
   6.134 +        new Update("booleanProperty", Boolean.FALSE),
   6.135 +        new Update("byteProperty", new Byte((byte) 213)),
   6.136 +        new Update("doubleProperty", new Double(123.456)),
   6.137 +        new Update("floatProperty", new Float((float) 111.22)),
   6.138 +        new Update("intProperty", new Integer(23432)),
   6.139 +        new Update("longProperty", new Long((long) 55555)),
   6.140 +        new Update("shortProperty", new Short((short) 123)),
   6.141 +        new Update("stringProperty", "Updated string value"),
   6.142 +        // Public fieldKeys are read-write as well
   6.143 +        new Update("public1", "revised String1 value"),
   6.144 +        new Update("public2", new Integer(55555)),
   6.145 +    };
   6.146 +
   6.147 +
   6.148 +
   6.149 +    // ------------------------------------------------------------ Constructors
   6.150 +
   6.151 +
   6.152 +    /**
   6.153 +     * <p>Construct a new test case instance.</p>
   6.154 +     */
   6.155 +    public ObjectDataProviderTest(String name) {
   6.156 +        super(name);
   6.157 +    }
   6.158 +
   6.159 +
   6.160 +    // ---------------------------------------------------- Overall Test Methods
   6.161 +
   6.162 +
   6.163 +    /**
   6.164 +     * <p>Set up the instance to be tested.</p>
   6.165 +     */
   6.166 +    @Override
   6.167 +    public void setUp() {
   6.168 +        bean = new TestBean("test");
   6.169 +        dp = new ObjectDataProvider(bean, true);
   6.170 +    }
   6.171 +
   6.172 +    /**
   6.173 +     * <p>Tear down the instance from the previous test.</p>
   6.174 +     */
   6.175 +    @Override
   6.176 +    public void tearDown() {
   6.177 +        dp = null;
   6.178 +        bean = null;
   6.179 +    }
   6.180 +
   6.181 +
   6.182 +    // ------------------------------------------------- Individual Test Methods
   6.183 +
   6.184 +
   6.185 +    /**
   6.186 +     * <p>Check convenience methods on abstract base class that
   6.187 +     * should still show through the concrete implementation.</p>
   6.188 +     */
   6.189 +    public void testBaseClassMethods() {
   6.190 +
   6.191 +        // Operate on FieldKey or field identifier
   6.192 +        for (int i = 0; i < properties.length; i++) {
   6.193 +            String fieldId = properties[i].name;
   6.194 +            FieldKey fieldKey = dp.getFieldKey(fieldId);
   6.195 +            assertEquals("type(" + fieldId + ")",
   6.196 +                         dp.getType(fieldKey),
   6.197 +                         dp.getType(fieldId));
   6.198 +            assertEquals("value(" + fieldId + ")",
   6.199 +                         dp.getValue(fieldKey),
   6.200 +                         dp.getValue(fieldId));
   6.201 +            assertEquals("readOnly(" + fieldId + ")",
   6.202 +                         dp.isReadOnly(fieldKey),
   6.203 +                         dp.isReadOnly(fieldId));
   6.204 +        }
   6.205 +
   6.206 +    }
   6.207 +
   6.208 +
   6.209 +    /**
   6.210 +     * <p>Check for event propogation.</p>
   6.211 +     */
   6.212 +    public void testEvents() {
   6.213 +
   6.214 +        assertNotNull(dp.getFieldKey("intProperty"));
   6.215 +        assertNotNull(dp.getFieldKey("public1"));
   6.216 +
   6.217 +        // Register a new listener and verify that it worked
   6.218 +        listener = new Listener();
   6.219 +        dp.addDataListener(listener);
   6.220 +        DataListener listeners[] = dp.getDataListeners();
   6.221 +        assertEquals(1, listeners.length);
   6.222 +        assertTrue(listener == listeners[0]);
   6.223 +
   6.224 +        // Make sure we log the update events correctly
   6.225 +        dp.setValue(dp.getFieldKey("intProperty"), new Integer(23432));
   6.226 +        dp.setValue(dp.getFieldKey("public1"), "new public1");
   6.227 +        assertEquals
   6.228 +          ("intProperty/1234/23432//public1/This is public1/new public1//",
   6.229 +           listener.getLog());
   6.230 +
   6.231 +        // Deregister the old listener and verify that it worked
   6.232 +        dp.removeDataListener(listener);
   6.233 +        listeners = dp.getDataListeners();
   6.234 +        assertEquals(0, listeners.length);
   6.235 +
   6.236 +    }
   6.237 +
   6.238 +
   6.239 +
   6.240 +    /**
   6.241 +     * <p>Check some things that should <strong>not</strong> work.</p>
   6.242 +     */
   6.243 +    public void testNegative() {
   6.244 +
   6.245 +        // Access to unknown fieldKey/property
   6.246 +        try {
   6.247 +            dp.getFieldKey("unknown id value");
   6.248 +            fail("Should have thrown IllegalArgumentException");
   6.249 +        } catch (IllegalArgumentException e) {
   6.250 +            ; // Expected result
   6.251 +        }
   6.252 +
   6.253 +        // Attempt to update a read only value
   6.254 +        try {
   6.255 +            dp.setValue(dp.getFieldKey("readOnly"), "xyz");
   6.256 +            fail("Should have thrown IllegalStateException");
   6.257 +        } catch (IllegalStateException e) {
   6.258 +            ; // Expected result
   6.259 +        }
   6.260 +
   6.261 +        // Attempt to set value with an incorrect data type
   6.262 +        try {
   6.263 +            dp.setValue(dp.getFieldKey("intProperty"), "string value");
   6.264 +            fail("Should have thrown IllegalArgumentException");
   6.265 +        } catch (IllegalArgumentException e) {
   6.266 +            ; // Expected result
   6.267 +        }
   6.268 +
   6.269 +    }
   6.270 +
   6.271 +
   6.272 +
   6.273 +    /**
   6.274 +     * <p>Ensure that access to public fields can be turned off.</p>
   6.275 +     */
   6.276 +    public void testNoFields() {
   6.277 +
   6.278 +        dp = new ObjectDataProvider(bean, false);
   6.279 +        try {
   6.280 +            dp.getFieldKey("public1");
   6.281 +            fail("Should have thrown IllegalArgumentException");
   6.282 +        } catch (IllegalArgumentException e) {
   6.283 +            ; // Expected result
   6.284 +        }
   6.285 +        try {
   6.286 +            dp.getFieldKey("public2");
   6.287 +            fail("Should have thrown IllegalArgumentException");
   6.288 +        } catch (IllegalArgumentException e) {
   6.289 +            ; // Expected result
   6.290 +        }
   6.291 +
   6.292 +        // Check the available properties for expected characteristics
   6.293 +        checkProperties();
   6.294 +        checkExtras();
   6.295 +
   6.296 +    }
   6.297 +
   6.298 +
   6.299 +    /**
   6.300 +     * <p>Test a pristine instance.</p>
   6.301 +     */
   6.302 +    public void testPristine() {
   6.303 +
   6.304 +        assertEquals("test", ((TestBean) dp.getObject()).getId());
   6.305 +
   6.306 +        // Check the available fieldKeys and properties for expected characteristics
   6.307 +        checkFields();
   6.308 +        checkProperties();
   6.309 +        checkExtras();
   6.310 +
   6.311 +    }
   6.312 +
   6.313 +
   6.314 +    /**
   6.315 +     * <p>Test updates to updateable fieldKeys and properties.</p>
   6.316 +     */
   6.317 +    public void testUpdates() {
   6.318 +
   6.319 +        // Do the easy cases
   6.320 +        checkUpdates();
   6.321 +
   6.322 +    }
   6.323 +
   6.324 +
   6.325 +    /**
   6.326 +     * <p>Test serializability of this data provider.</p>
   6.327 +     */
   6.328 +    public void testSerializable() throws Exception {
   6.329 +
   6.330 +        ByteArrayOutputStream baos = new ByteArrayOutputStream();
   6.331 +        ObjectOutputStream oos = new ObjectOutputStream(baos);
   6.332 +        oos.writeObject(dp);
   6.333 +        oos.close();
   6.334 +        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
   6.335 +        ObjectInputStream ois = new ObjectInputStream(bais);
   6.336 +        dp = (ObjectDataProvider) ois.readObject();
   6.337 +        ois.close();
   6.338 +
   6.339 +        testPristine();
   6.340 +
   6.341 +    }
   6.342 +
   6.343 +
   6.344 +    // --------------------------------------------------------- Support Methods
   6.345 +
   6.346 +
   6.347 +    /**
   6.348 +     * <p>Ensure that the array returned by <code>getFieldKeys()</code>
   6.349 +     * does not include any keys that should not be there.</p>
   6.350 +     */
   6.351 +    private void checkExtras() {
   6.352 +
   6.353 +        FieldKey keys[] = dp.getFieldKeys();
   6.354 +        assertNotNull(keys);
   6.355 +        for (int i = 0; i < keys.length; i++) {
   6.356 +            String name = keys[i].getFieldId();
   6.357 +            boolean found = false;
   6.358 +            for (int j = 0; j < properties.length; j++) {
   6.359 +                if (name.equals(properties[j].name)) {
   6.360 +                    found = true;
   6.361 +                    break;
   6.362 +                }
   6.363 +            }
   6.364 +            if (!found && dp.isIncludeFields()) {
   6.365 +                for (int j = 0; j < fieldKeys.length; j++) {
   6.366 +                    if (name.equals(fieldKeys[j].name)) {
   6.367 +                        found = true;
   6.368 +                        break;
   6.369 +                    }
   6.370 +                }
   6.371 +            }
   6.372 +            assertTrue("Id '" + name + "' is valid", found);
   6.373 +        }
   6.374 +
   6.375 +    }
   6.376 +
   6.377 +
   6.378 +    /**
   6.379 +     * <p>Ensure that all the expected fieldKeys are present and have
   6.380 +     * the specified default values (where possible).</p>
   6.381 +     */
   6.382 +    private void checkFields() {
   6.383 +
   6.384 +        FieldKey dk = null;
   6.385 +        String name = null;
   6.386 +        for (int i = 0; i < fieldKeys.length; i++) {
   6.387 +            name = fieldKeys[i].name;
   6.388 +            dk = dp.getFieldKey(name);
   6.389 +            assertNotNull("FieldKey for '" + name + "'", dk);
   6.390 +            assertTrue("Type for '" + name + "'",
   6.391 +                    isAssignableFrom(dp.getType(dk), fieldKeys[i].type));
   6.392 +            assertEquals("ReadOnly for '" + name + "'",
   6.393 +                    fieldKeys[i].canSetValue, dp.isReadOnly(dk));
   6.394 +            if (fieldKeys[i].defaultValue != null) {
   6.395 +                assertEquals("Value for '" + name + "'",
   6.396 +                        fieldKeys[i].defaultValue, dp.getValue(dk));
   6.397 +            }
   6.398 +        }
   6.399 +
   6.400 +    }
   6.401 +
   6.402 +
   6.403 +    /**
   6.404 +     * <p>Ensure that all the expected properties are present and have
   6.405 +     * the specified default values (where possible).</p>
   6.406 +     */
   6.407 +    private void checkProperties() {
   6.408 +
   6.409 +        FieldKey dk = null;
   6.410 +        String name = null;
   6.411 +        for (int i = 0; i < properties.length; i++) {
   6.412 +            name = properties[i].name;
   6.413 +            dk = dp.getFieldKey(name);
   6.414 +            assertNotNull("FieldKey for '" + name + "'", dk);
   6.415 +            assertTrue("Type for '" + name + "'",
   6.416 +                    isAssignableFrom(dp.getType(dk), properties[i].type));
   6.417 +            assertEquals("ReadOnly for '" + name + "'",
   6.418 +                    properties[i].canSetValue, dp.isReadOnly(dk));
   6.419 +            if (properties[i].defaultValue != null) {
   6.420 +                assertEquals("Value for '" + name + "'",
   6.421 +                        properties[i].defaultValue, dp.getValue(dk));
   6.422 +            }
   6.423 +        }
   6.424 +
   6.425 +    }
   6.426 +
   6.427 +    private boolean isAssignableFrom(Class to, Class from) {
   6.428 +        if (to.isPrimitive()) {
   6.429 +            if (to == Boolean.TYPE)
   6.430 +                to = Boolean.class;
   6.431 +            else if (to == Character.TYPE)
   6.432 +                to = Character.class;
   6.433 +            else if (to == Byte.TYPE)
   6.434 +                to = Byte.class;
   6.435 +            else if (to == Short.TYPE)
   6.436 +                to = Short.class;
   6.437 +            else if (to == Integer.TYPE)
   6.438 +                to = Integer.class;
   6.439 +            else if (to == Long.TYPE)
   6.440 +                to = Long.class;
   6.441 +            else if (to == Float.TYPE)
   6.442 +                to = Float.class;
   6.443 +            else if (to == Double.TYPE)
   6.444 +                to = Double.class;
   6.445 +        }
   6.446 +        return to.isAssignableFrom(from);
   6.447 +    }
   6.448 +
   6.449 +    /**
   6.450 +     * <p>Ensure that we can update all the simple fieldKeys and properties
   6.451 +     * that should be updatable by default.</p>
   6.452 +     */
   6.453 +    private void checkUpdates() {
   6.454 +
   6.455 +        FieldKey dk = null;
   6.456 +        String name = null;
   6.457 +        for (int i = 0; i < updates.length; i++) {
   6.458 +            name = updates[i].name;
   6.459 +            try {
   6.460 +                dp.setValue(dp.getFieldKey(name), updates[i].value);
   6.461 +            } catch (Exception e) {
   6.462 +                fail("Cannot set value for '" + name + "':" + e);
   6.463 +            }
   6.464 +            assertEquals("Updated value for '" + name + "'",
   6.465 +                    updates[i].value, dp.getValue(dp.getFieldKey(name)));
   6.466 +        }
   6.467 +
   6.468 +    }
   6.469 +
   6.470 +    // Private class to describe the expected properties
   6.471 +    static class Descriptor {
   6.472 +        public Descriptor(String name, Class type, boolean canSetValue, Object defaultValue) {
   6.473 +            this.name = name;
   6.474 +            this.type = type;
   6.475 +            this.canSetValue = canSetValue;
   6.476 +            this.defaultValue = defaultValue;
   6.477 +        }
   6.478 +
   6.479 +        public String name;
   6.480 +        public Class type;
   6.481 +        public boolean canSetValue;
   6.482 +        public Object defaultValue;
   6.483 +    }
   6.484 +
   6.485 +    // Private class to represent an event listener
   6.486 +    static class Listener
   6.487 +        implements DataListener {
   6.488 +        String log = "";
   6.489 +        public String getLog() {
   6.490 +            return this.log;
   6.491 +        }
   6.492 +
   6.493 +        public void clear() {
   6.494 +            this.log = "";
   6.495 +        }
   6.496 +
   6.497 +        public void valueChanged(DataProvider dp, FieldKey dk, Object oldValue,
   6.498 +            Object newValue) {
   6.499 +            log += dk.getFieldId() + "/" + oldValue + "/" + newValue + "//";
   6.500 +        }
   6.501 +
   6.502 +        public void providerChanged(DataProvider dp) {
   6.503 +            log += "providerChanged//";
   6.504 +        }
   6.505 +    }
   6.506 +
   6.507 +    // Private class to describe updates to be performed and checked
   6.508 +    static class Update {
   6.509 +        public Update(String name, Object value) {
   6.510 +            this.name = name;
   6.511 +            this.value = value;
   6.512 +        }
   6.513 +
   6.514 +        public String name;
   6.515 +        public Object value;
   6.516 +    }
   6.517 +
   6.518 +
   6.519 +}
     7.1 --- a/visualweb.dataprovider/test/unit/src/org/netbeans/modules/visualweb/dataprovider/ObjectListDataProviderTest.java	Mon Nov 12 23:34:33 2007 +0000
     7.2 +++ b/visualweb.dataprovider/test/unit/src/org/netbeans/modules/visualweb/dataprovider/ObjectListDataProviderTest.java	Tue Nov 13 01:00:31 2007 +0000
     7.3 @@ -1,4 +1,4 @@
     7.4 -
     7.5 +package org.netbeans.modules.visualweb.dataprovider;
     7.6  
     7.7  /*
     7.8   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     7.9 @@ -38,7 +38,25 @@
    7.10   * 
    7.11   * Portions Copyrighted 2007 Sun Microsystems, Inc.
    7.12   */
    7.13 +import com.sun.data.provider.DataListener;
    7.14 +import com.sun.data.provider.DataProvider;
    7.15 +import com.sun.data.provider.FieldKey;
    7.16 +import com.sun.data.provider.RowKey;
    7.17 +import com.sun.data.provider.TableCursorListener;
    7.18 +import com.sun.data.provider.TableCursorVetoException;
    7.19 +import com.sun.data.provider.TableDataListener;
    7.20 +import com.sun.data.provider.TableDataProvider;
    7.21 +import com.sun.data.provider.TransactionalDataListener;
    7.22 +import com.sun.data.provider.TransactionalDataProvider;
    7.23 +import com.sun.data.provider.impl.IndexRowKey;
    7.24  import com.sun.data.provider.impl.ObjectListDataProvider;
    7.25 +import java.io.ByteArrayInputStream;
    7.26 +import java.io.ByteArrayOutputStream;
    7.27 +import java.io.ObjectInputStream;
    7.28 +import java.io.ObjectOutputStream;
    7.29 +import java.util.ArrayList;
    7.30 +import java.util.List;
    7.31 +import java.util.Map;
    7.32  import org.netbeans.junit.NbTestCase;
    7.33  
    7.34  /**
    7.35 @@ -47,6 +65,86 @@
    7.36   */
    7.37  public class ObjectListDataProviderTest extends NbTestCase {
    7.38  
    7.39 +    // ------------------------------------------------------ Instance Variables
    7.40 +    /**
    7.41 +     * <p>The beans being wrapped by the {@link DataProvider} under test.
    7.42 +     */
    7.43 +    private TestBean beans[] = null;
    7.44 +    /**
    7.45 +     * <p>The {@link DataProvider} instance under test.
    7.46 +     */
    7.47 +    private ObjectListDataProvider dp = null;
    7.48 +    /**
    7.49 +     * <p>List representation of beans being wrapped.</p>
    7.50 +     */
    7.51 +    private List list = null;
    7.52 +    /**
    7.53 +     * <p>Event listener for event testing.</p>
    7.54 +     */
    7.55 +    private Listener listener = null;
    7.56 +    /**
    7.57 +     * <p>Event listener for event testing.</p>
    7.58 +     */
    7.59 +    private MyCursorListener tdcListener = null;
    7.60 +    /**
    7.61 +     * <p>Event listener for event testing.</p>
    7.62 +     */
    7.63 +    private MyDataListener tdpListener = null;
    7.64 +    // -------------------------------------------------------- Static Variables
    7.65 +    // Dummy variables just to provide access to type information
    7.66 +    private static int intArray[] = new int[0];
    7.67 +    private static TestBean nestedArray[] = new TestBean[0];
    7.68 +    /**
    7.69 +     * <p>Descriptors for the set of fieldKeys we expect to be known.</p>
    7.70 +     */
    7.71 +    private static Descriptor[] fieldKeys = {
    7.72 +        // Specific fieldKeys of this class
    7.73 +        new Descriptor("public1", String.class, false, "This is public1"),
    7.74 +        new Descriptor("public2", Integer.class, false, new Integer(8888)),
    7.75 +    };
    7.76 +    /**
    7.77 +     * <p>Descriptors for the set of properties we expect to be known.</p>
    7.78 +     */
    7.79 +    private static Descriptor[] properties = {
    7.80 +        // Specific properties of this class
    7.81 +        new Descriptor("booleanProperty", Boolean.class, false, Boolean.TRUE),
    7.82 +        new Descriptor("byteProperty", Byte.class, false, new Byte((byte) 123)),
    7.83 +        new Descriptor("doubleProperty", Double.class, false, new Double(654.321)),
    7.84 +        new Descriptor("floatProperty", Float.class, false, new Float((float) 123.45)),
    7.85 +        new Descriptor("id", String.class, false, null),
    7.86 +        new Descriptor("intArray", intArray.getClass(), false, null),
    7.87 +        new Descriptor("intList", List.class, false, null),
    7.88 +        new Descriptor("intProperty", Integer.class, false, new Integer(1234)),
    7.89 +        new Descriptor("longProperty", Long.class, false, new Long(54321)),
    7.90 +        new Descriptor("nestedArray", nestedArray.getClass(), false, null),
    7.91 +        new Descriptor("nestedList", List.class, false, null),
    7.92 +        new Descriptor("nestedMap", Map.class, false, null),
    7.93 +        new Descriptor("nestedProperty", TestBean.class, false, null),
    7.94 +        new Descriptor("readOnly", String.class, true, null),
    7.95 +        new Descriptor("shortProperty", Short.class, false, new Short((short) 321)),
    7.96 +        new Descriptor("stringProperty", String.class, false, "This is a String"),
    7.97 +        new Descriptor("nullString", String.class, true, null),
    7.98 +        // Inherited from java.lang.Object
    7.99 +        new Descriptor("class", Class.class, true, null),
   7.100 +    };
   7.101 +    /**
   7.102 +     * <p>Descriptors for updates that should be applied and tested.</p>
   7.103 +     */
   7.104 +    private static Update[] updates = {
   7.105 +        // Updates to read-write properties
   7.106 +        new Update("booleanProperty", Boolean.FALSE),
   7.107 +        new Update("byteProperty", new Byte((byte) 213)),
   7.108 +        new Update("doubleProperty", new Double(123.456)),
   7.109 +        new Update("floatProperty", new Float((float) 111.22)),
   7.110 +        new Update("intProperty", new Integer(23432)),
   7.111 +        new Update("longProperty", new Long((long) 55555)),
   7.112 +        new Update("shortProperty", new Short((short) 123)),
   7.113 +        new Update("stringProperty", "Updated string value"),
   7.114 +        // Public fieldKeys are read-write as well
   7.115 +        new Update("public1", "revised String1 value"),
   7.116 +        new Update("public2", new Integer(55555)),
   7.117 +    };
   7.118 +
   7.119      public ObjectListDataProviderTest(String testName) {
   7.120          super(testName);
   7.121          new ObjectListDataProvider();
   7.122 @@ -55,10 +153,739 @@
   7.123      @Override
   7.124      protected void setUp() throws Exception {
   7.125          super.setUp();
   7.126 +        beans = new TestBean[5];
   7.127 +        list = new ArrayList();
   7.128 +        for (int i = 0; i < beans.length; i++) {
   7.129 +            beans[i] = new TestBean("test" + i);
   7.130 +            list.add(beans[i]);
   7.131 +        }
   7.132 +        dp = new ObjectListDataProvider(list, true);
   7.133      }
   7.134  
   7.135      @Override
   7.136      protected void tearDown() throws Exception {
   7.137          super.tearDown();
   7.138 +        dp = null;
   7.139 +        beans = null;
   7.140 +        list = null;
   7.141 +        listener = null;
   7.142 +        tdcListener = null;
   7.143 +        tdpListener = null;
   7.144 +    }
   7.145 +
   7.146 +    // ------------------------------------------------- Individual Test Methods
   7.147 +    /**
   7.148 +     * <p>Check convenience methods on abstract base class that
   7.149 +     * should still show through the concrete implementation.</p>
   7.150 +     */
   7.151 +    public void testBaseClassMethods() {
   7.152 +
   7.153 +        // Operate on FieldKey or field identifier
   7.154 +        for (int i = 0; i < properties.length; i++) {
   7.155 +            String fieldId = properties[i].name;
   7.156 +            FieldKey fieldKey = dp.getFieldKey(fieldId);
   7.157 +            assertEquals("type(" + fieldId + ")",
   7.158 +                    dp.getType(fieldKey),
   7.159 +                    dp.getType(fieldId));
   7.160 +            assertEquals("value(" + fieldId + ")",
   7.161 +                    dp.getValue(fieldKey),
   7.162 +                    dp.getValue(fieldId));
   7.163 +            assertEquals("readOnly(" + fieldId + ")",
   7.164 +                    dp.isReadOnly(fieldKey),
   7.165 +                    dp.isReadOnly(fieldId));
   7.166 +        }
   7.167 +
   7.168 +    }
   7.169 +
   7.170 +    /**
   7.171 +     * <p>Check for events related to row appending.</p>
   7.172 +     */
   7.173 +    public void testEventsAppend() {
   7.174 +
   7.175 +        // Register listener we will need
   7.176 +        MyTransactionalListener tListener = new MyTransactionalListener();
   7.177 +        dp.addTransactionalDataListener(tListener);
   7.178 +
   7.179 +        // Append a row and allow the DP to create an instance
   7.180 +        assertTrue(dp.canAppendRow());
   7.181 +        RowKey rk1 = dp.appendRow();
   7.182 +        assertNull(dp.getValue("id", rk1));
   7.183 +        dp.setValue("id", rk1, "testA");
   7.184 +        assertEquals("testA", dp.getValue("id", rk1));
   7.185 +
   7.186 +        // Append a row that is a specific object instance
   7.187 +        assertTrue(dp.canAppendRow());
   7.188 +        TestBean beanB = new TestBean("testB");
   7.189 +        RowKey rk2 = dp.appendRow(beanB);
   7.190 +
   7.191 +        // Commit the results and validate the event history
   7.192 +        dp.commitChanges();
   7.193 +        assertEquals("rowAdded/RowKey[5]//" +
   7.194 +                "FieldKey[id]/RowKey[5]/null/testA//" +
   7.195 +                "FieldKey[id]/null/testA//" +
   7.196 +                "rowAdded/RowKey[6]//" +
   7.197 +                "changesCommitted//",
   7.198 +                tListener.getLog());
   7.199 +
   7.200 +    // Validate the remaining beans
   7.201 +        /*
   7.202 +    assertEquals(beans.length - 2, list.size());
   7.203 +    assertEquals("test0", ((TestBean) list.get(0)).getId());
   7.204 +    assertEquals("test2", ((TestBean) list.get(1)).getId());
   7.205 +    assertEquals("test4", ((TestBean) list.get(2)).getId());
   7.206 +     */
   7.207 +
   7.208 +    }
   7.209 +
   7.210 +    /**
   7.211 +     * <p>Check for event propogation for basic DataProvider events.</p>
   7.212 +     */
   7.213 +    public void testEventsBasic() {
   7.214 +
   7.215 +        assertNotNull(dp.getFieldKey("intProperty"));
   7.216 +        assertNotNull(dp.getFieldKey("public1"));
   7.217 +
   7.218 +        // Register a new listener and verify that it worked
   7.219 +        listener = new Listener();
   7.220 +        dp.addDataListener(listener);
   7.221 +        DataListener listeners[] = dp.getDataListeners();
   7.222 +        assertEquals(1, listeners.length);
   7.223 +        assertTrue(listener == listeners[0]);
   7.224 +
   7.225 +        // Make sure we log the update events correctly
   7.226 +        dp.setValue(dp.getFieldKey("intProperty"), new Integer(23432));
   7.227 +        dp.setValue(dp.getFieldKey("public1"), "new public1");
   7.228 +        assertEquals("intProperty/1234/23432//public1/This is public1/new public1//",
   7.229 +                listener.getLog());
   7.230 +
   7.231 +        // Deregister the old listener and verify that it worked
   7.232 +        dp.removeDataListener(listener);
   7.233 +        listeners = dp.getDataListeners();
   7.234 +        assertEquals(0, listeners.length);
   7.235 +
   7.236 +    }
   7.237 +
   7.238 +    /**
   7.239 +     * <p>Check for event propogation for cursor changes.</p>
   7.240 +     */
   7.241 +    public void testEventsCursor() throws Exception {
   7.242 +
   7.243 +        // Register a new listener and verify that it worked
   7.244 +        tdcListener = new MyCursorListener();
   7.245 +        dp.addTableCursorListener(tdcListener);
   7.246 +        TableCursorListener listeners[] = dp.getTableCursorListeners();
   7.247 +        assertEquals(1, listeners.length);
   7.248 +        assertTrue(tdcListener == listeners[0]);
   7.249 +
   7.250 +        // Make sure we log cursor change events correctly
   7.251 +        assertEquals(new IndexRowKey(0), dp.getCursorRow());
   7.252 +        dp.setCursorRow(new IndexRowKey(2));
   7.253 +        assertEquals(new IndexRowKey(2), dp.getCursorRow());
   7.254 +        dp.setCursorRow(new IndexRowKey(1));
   7.255 +        assertEquals(new IndexRowKey(1), dp.getCursorRow());
   7.256 +        assertEquals("cursorChanging/RowKey[0]/RowKey[2]//cursorChanged/RowKey[0]/RowKey[2]//" +
   7.257 +                "cursorChanging/RowKey[2]/RowKey[1]//cursorChanged/RowKey[2]/RowKey[1]//",
   7.258 +                tdcListener.getLog());
   7.259 +
   7.260 +        // Make sure we can deal with vetos as well
   7.261 +        tdcListener.clear();
   7.262 +        tdcListener.setVeto(true);
   7.263 +        try {
   7.264 +            dp.setCursorRow(new IndexRowKey(3));
   7.265 +            fail("Should have thrown TableCursorVetoException");
   7.266 +        } catch (TableCursorVetoException e) {
   7.267 +            ; // Expected result
   7.268 +        }
   7.269 +        assertEquals(new IndexRowKey(1), dp.getCursorRow());
   7.270 +        assertEquals("cursorChanging/RowKey[1]/RowKey[3]//cursorVetoed/RowKey[1]/RowKey[3]//",
   7.271 +                tdcListener.getLog());
   7.272 +
   7.273 +        // Deregister the old listener and verify that it worked
   7.274 +        dp.removeTableCursorListener(tdcListener);
   7.275 +        listeners = dp.getTableCursorListeners();
   7.276 +        assertEquals(0, listeners.length);
   7.277 +
   7.278 +    }
   7.279 +
   7.280 +    /**
   7.281 +     * <p>Check for event propogation on random data changes.</p>
   7.282 +     */
   7.283 +    public void testEventsData() {
   7.284 +
   7.285 +        // Register a new listener and verify that it worked
   7.286 +        tdpListener = new MyDataListener();
   7.287 +        dp.addTableDataListener(tdpListener);
   7.288 +        TableDataListener listeners[] = dp.getTableDataListeners();
   7.289 +        assertEquals(1, listeners.length);
   7.290 +        assertTrue(tdpListener == listeners[0]);
   7.291 +
   7.292 +        dp.cursorFirst();
   7.293 +        // Make sure we log the update events correctly
   7.294 +        dp.setValue(dp.getFieldKey("intProperty"),
   7.295 +                new Integer(23432)); // Change, so event expected
   7.296 +        Object value = dp.getValue(dp.getFieldKey("stringProperty"));
   7.297 +        dp.setValue(dp.getFieldKey("stringProperty"), value); // No change, so no event expected
   7.298 +
   7.299 +
   7.300 +        assertEquals("FieldKey[intProperty]/RowKey[0]/1234/23432//" + // Row-specific event
   7.301 +                "FieldKey[intProperty]/1234/23432//", // Row-independent event
   7.302 +                tdpListener.getLog());
   7.303 +
   7.304 +        // We should get a provider change event too
   7.305 +        tdpListener.clear();
   7.306 +        dp.setList(dp.getList());
   7.307 +        assertEquals("providerChanged//", tdpListener.getLog());
   7.308 +
   7.309 +        // Deregister the old listener and verify that it worked
   7.310 +        dp.removeTableDataListener(tdpListener);
   7.311 +        listeners = dp.getTableDataListeners();
   7.312 +        assertEquals(0, listeners.length);
   7.313 +
   7.314 +    }
   7.315 +
   7.316 +    /**
   7.317 +     * <p>Check for events related to row insertion.</p>
   7.318 +     */
   7.319 +    public void testEventsInsert() {
   7.320 +
   7.321 +        // FIXME - inserts are not currently supported.  When they are,
   7.322 +        // the processing in commitChanges() will need to interleave the
   7.323 +        // deletes and inserts so that references to the pre-commit
   7.324 +        // row keys are not messed up
   7.325 +        assertTrue(!dp.canInsertRow(dp.getCursorRow()));
   7.326 +
   7.327 +    }
   7.328 +
   7.329 +    /**
   7.330 +     * <p>Check for events related to row removal -- ascending ordering.</p>
   7.331 +     */
   7.332 +    public void testEventsRemovesAscending() {
   7.333 +
   7.334 +        // Register listener we will need
   7.335 +        MyTransactionalListener tListener = new MyTransactionalListener();
   7.336 +        dp.addTransactionalDataListener(tListener);
   7.337 +
   7.338 +        // Remove the rows at indexes 1 and 3, and commit the changes
   7.339 +        RowKey rk = null;
   7.340 +        rk = dp.findFirst("id", "test1");
   7.341 +        assertNotNull(rk);
   7.342 +        assertTrue(dp.canRemoveRow(rk));
   7.343 +        dp.removeRow(rk);
   7.344 +        rk = dp.findFirst("id", "test3");
   7.345 +        assertNotNull(rk);
   7.346 +        assertTrue(dp.canRemoveRow(rk));
   7.347 +        dp.removeRow(rk);
   7.348 +        dp.commitChanges();
   7.349 +
   7.350 +        // Validate the event history
   7.351 +        assertEquals("rowRemoved/RowKey[1]//" +
   7.352 +                "rowRemoved/RowKey[3]//" +
   7.353 +                "changesCommitted//",
   7.354 +                tListener.getLog());
   7.355 +
   7.356 +        // Validate the remaining beans
   7.357 +        assertEquals(beans.length - 2, list.size());
   7.358 +        assertEquals("test0", ((TestBean) list.get(0)).getId());
   7.359 +        assertEquals("test2", ((TestBean) list.get(1)).getId());
   7.360 +        assertEquals("test4", ((TestBean) list.get(2)).getId());
   7.361 +
   7.362 +    }
   7.363 +
   7.364 +    /**
   7.365 +     * <p>Check for events related to row removal -- descending ordering.</p>
   7.366 +     */
   7.367 +    public void testEventsRemovesDescending() {
   7.368 +
   7.369 +        // Register listener we will need
   7.370 +        MyTransactionalListener tListener = new MyTransactionalListener();
   7.371 +        dp.addTransactionalDataListener(tListener);
   7.372 +
   7.373 +        // Remove the rows at indexes 3 and 1, and commit the changes
   7.374 +        RowKey rk = null;
   7.375 +        rk = dp.findFirst("id", "test3");
   7.376 +        assertNotNull(rk);
   7.377 +        assertTrue(dp.canRemoveRow(rk));
   7.378 +        dp.removeRow(rk);
   7.379 +        rk = dp.findFirst("id", "test1");
   7.380 +        assertNotNull(rk);
   7.381 +        assertTrue(dp.canRemoveRow(rk));
   7.382 +        dp.removeRow(rk);
   7.383 +        dp.commitChanges();
   7.384 +
   7.385 +        // Validate the event history
   7.386 +        assertEquals("rowRemoved/RowKey[3]//" +
   7.387 +                "rowRemoved/RowKey[1]//" +
   7.388 +                "changesCommitted//",
   7.389 +                tListener.getLog());
   7.390 +
   7.391 +        // Validate the remaining beans
   7.392 +        assertEquals(beans.length - 2, list.size());
   7.393 +        assertEquals("test0", ((TestBean) list.get(0)).getId());
   7.394 +        assertEquals("test2", ((TestBean) list.get(1)).getId());
   7.395 +        assertEquals("test4", ((TestBean) list.get(2)).getId());
   7.396 +
   7.397 +    }
   7.398 +
   7.399 +    /**
   7.400 +     * <p>Check for transactional updates to existing rows.</p>
   7.401 +     */
   7.402 +    public void testEventsUpdates() {
   7.403 +
   7.404 +        // Register listeners we will need for verification
   7.405 +        TableDataListener aListener = new MyDataListener();
   7.406 +        MyTransactionalListener tListener = new MyTransactionalListener();
   7.407 +        dp.addTableDataListener(aListener);
   7.408 +        TableDataListener aListeners[] = dp.getTableDataListeners();
   7.409 +        assertEquals(1, aListeners.length);
   7.410 +        assertTrue(aListener == aListeners[0]);
   7.411 +        dp.addTransactionalDataListener(tListener);
   7.412 +        aListeners = dp.getTableDataListeners();
   7.413 +        assertEquals(2, aListeners.length);
   7.414 +        assertTrue(aListener == aListeners[0]);
   7.415 +        assertTrue(tListener == aListeners[1]);
   7.416 +        TransactionalDataListener tListeners[] = dp.getTransactionalDataListeners();
   7.417 +        assertEquals(1, tListeners.length);
   7.418 +        assertTrue(tListener == tListeners[0]);
   7.419 +
   7.420 +        // Perform an update, check for event and new value showing
   7.421 +        dp.cursorFirst();
   7.422 +        dp.setValue(dp.getFieldKey("intProperty"),
   7.423 +                new Integer(23432)); // Change, so event expected
   7.424 +        assertEquals("FieldKey[intProperty]/RowKey[0]/1234/23432//" + // Row-specific event
   7.425 +                "FieldKey[intProperty]/1234/23432//", // Row-independent event
   7.426 +                tListener.getLog());
   7.427 +        assertEquals(new Integer(23432),
   7.428 +                (Integer) dp.getValue(dp.getFieldKey("intProperty")));
   7.429 +
   7.430 +        // Fake an update, check for no event and no change in value showing
   7.431 +        tListener.clear();
   7.432 +        dp.setValue(dp.getFieldKey("intProperty"),
   7.433 +                new Integer(23432)); // Change, so event expected
   7.434 +        assertEquals("", tListener.getLog());
   7.435 +        assertEquals(new Integer(23432),
   7.436 +                (Integer) dp.getValue(dp.getFieldKey("intProperty")));
   7.437 +
   7.438 +        // Revert and ensure that old value shows again
   7.439 +        tListener.clear();
   7.440 +        dp.revertChanges();
   7.441 +        assertEquals("changesReverted//",
   7.442 +                tListener.getLog());
   7.443 +        assertEquals(new Integer(1234),
   7.444 +                (Integer) dp.getValue(dp.getFieldKey("intProperty")));
   7.445 +
   7.446 +        // Make a change, commit, and ensure revert does not erase it
   7.447 +        tListener.clear();
   7.448 +        dp.setValue(dp.getFieldKey("intProperty"),
   7.449 +                new Integer(43234)); // Change, so event expected
   7.450 +        assertEquals("FieldKey[intProperty]/RowKey[0]/1234/43234//" + // Row-specific event
   7.451 +                "FieldKey[intProperty]/1234/43234//", // Row-independent event
   7.452 +                tListener.getLog());
   7.453 +        assertEquals(new Integer(43234),
   7.454 +                (Integer) dp.getValue(dp.getFieldKey("intProperty")));
   7.455 +        tListener.clear();
   7.456 +        dp.commitChanges();
   7.457 +        assertEquals(new Integer(43234),
   7.458 +                (Integer) dp.getValue(dp.getFieldKey("intProperty")));
   7.459 +        dp.revertChanges();
   7.460 +        assertEquals(new Integer(43234),
   7.461 +                (Integer) dp.getValue(dp.getFieldKey("intProperty")));
   7.462 +        assertEquals("changesCommitted//changesReverted//",
   7.463 +                tListener.getLog());
   7.464 +
   7.465 +    }
   7.466 +
   7.467 +    /**
   7.468 +     * <p>Check some things that should <strong>not</strong> work.</p>
   7.469 +     */
   7.470 +    public void testNegative() {
   7.471 +
   7.472 +        // Access to unknown fieldKey/property
   7.473 +        try {
   7.474 +            dp.getFieldKey("unknown id value");
   7.475 +            fail("Should have thrown IllegalArgumentException");
   7.476 +        } catch (IllegalArgumentException e) {
   7.477 +            ; // Expected result
   7.478 +        }
   7.479 +
   7.480 +        // Attempt to update a read only value
   7.481 +        try {
   7.482 +            dp.setValue(dp.getFieldKey("readOnly"), "xyz");
   7.483 +            fail("Should have thrown IllegalStateException");
   7.484 +        } catch (IllegalStateException e) {
   7.485 +            ; // Expected result
   7.486 +        }
   7.487 +
   7.488 +        // Attempt to set value with an incorrect data type
   7.489 +        try {
   7.490 +            dp.setValue(dp.getFieldKey("intProperty"), "string value");
   7.491 +            fail("Should have thrown IllegalArgumentException");
   7.492 +        } catch (IllegalArgumentException e) {
   7.493 +            ; // Expected result
   7.494 +        }
   7.495 +
   7.496 +    }
   7.497 +
   7.498 +    /**
   7.499 +     * <p>Ensure that access to public fields can be turned off.</p>
   7.500 +     */
   7.501 +    public void testNoFields() {
   7.502 +
   7.503 +        dp = new ObjectListDataProvider(list, false);
   7.504 +        try {
   7.505 +            dp.getFieldKey("public1");
   7.506 +            fail("Should have thrown IllegalArgumentException");
   7.507 +        } catch (IllegalArgumentException e) {
   7.508 +            ; // Expected result
   7.509 +        }
   7.510 +        try {
   7.511 +            dp.getFieldKey("public2");
   7.512 +            fail("Should have thrown IllegalArgumentException");
   7.513 +        } catch (IllegalArgumentException e) {
   7.514 +            ; // Expected result
   7.515 +        }
   7.516 +
   7.517 +        // Check the available properties for expected characteristics
   7.518 +        checkProperties();
   7.519 +        checkExtras();
   7.520 +
   7.521 +    }
   7.522 +
   7.523 +    /**
   7.524 +     * <p>Test a pristine instance.</p>
   7.525 +     */
   7.526 +    public void testPristine() throws Exception {
   7.527 +
   7.528 +        assertTrue(dp.isIncludeFields());
   7.529 +        assertEquals(beans.length, dp.getRowCount());
   7.530 +
   7.531 +        // Check the available fieldKeys and properties for expected characteristics
   7.532 +        for (int i = 0; i < beans.length; i++) {
   7.533 +            dp.setCursorRow(dp.getRowKey("" + i));
   7.534 +            assertEquals("test" + i, dp.getValue(dp.getFieldKey("id")));
   7.535 +            checkFields();
   7.536 +            checkProperties();
   7.537 +            checkExtras();
   7.538 +        }
   7.539 +
   7.540 +        // Check random access on the id property
   7.541 +        for (int i = 0; i < beans.length; i++) {
   7.542 +            assertEquals("test" + i, dp.getValue(dp.getFieldKey("id"), dp.getRowKey("" + i)));
   7.543 +        }
   7.544 +
   7.545 +    }
   7.546 +
   7.547 +    /**
   7.548 +     * <p>Test serializability of this data provider.</p>
   7.549 +     */
   7.550 +    public void testSerializable() throws Exception {
   7.551 +
   7.552 +        ByteArrayOutputStream baos = new ByteArrayOutputStream();
   7.553 +        ObjectOutputStream oos = new ObjectOutputStream(baos);
   7.554 +        oos.writeObject(dp);
   7.555 +        oos.close();
   7.556 +        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
   7.557 +        ObjectInputStream ois = new ObjectInputStream(bais);
   7.558 +        dp = (ObjectListDataProvider) ois.readObject();
   7.559 +        ois.close();
   7.560 +
   7.561 +        testPristine();
   7.562 +
   7.563 +    }
   7.564 +
   7.565 +    /**
   7.566 +     * <p>Test updates to updateable fieldKeys and properties.</p>
   7.567 +     */
   7.568 +    public void testUpdates() {
   7.569 +
   7.570 +        // Do the easy cases
   7.571 +        checkUpdates();
   7.572 +
   7.573 +    }
   7.574 +
   7.575 +
   7.576 +    // --------------------------------------------------------- Support Methods
   7.577 +    /**
   7.578 +     * <p>Ensure that the array returned by <code>getFieldKeys()</code>
   7.579 +     * does not include any keys that should not be there.</p>
   7.580 +     */
   7.581 +    private void checkExtras() {
   7.582 +
   7.583 +        FieldKey keys[] = dp.getFieldKeys();
   7.584 +        assertNotNull(keys);
   7.585 +        for (int i = 0; i < keys.length; i++) {
   7.586 +            String name = keys[i].getFieldId();
   7.587 +            boolean found = false;
   7.588 +            for (int j = 0; j < properties.length; j++) {
   7.589 +                if (name.equals(properties[j].name)) {
   7.590 +                    found = true;
   7.591 +                    break;
   7.592 +                }
   7.593 +            }
   7.594 +            if (!found && dp.isIncludeFields()) {
   7.595 +                for (int j = 0; j < fieldKeys.length; j++) {
   7.596 +                    if (name.equals(fieldKeys[j].name)) {
   7.597 +                        found = true;
   7.598 +                        break;
   7.599 +                    }
   7.600 +                }
   7.601 +            }
   7.602 +            assertTrue("Id '" + name + "' is valid", found);
   7.603 +        }
   7.604 +
   7.605 +    }
   7.606 +
   7.607 +    /**
   7.608 +     * <p>Ensure that all the expected fieldKeys are present and have
   7.609 +     * the specified default values (where possible).</p>
   7.610 +     */
   7.611 +    private void checkFields() {
   7.612 +
   7.613 +        FieldKey dk = null;
   7.614 +        String name = null;
   7.615 +        for (int i = 0; i < fieldKeys.length; i++) {
   7.616 +            name = fieldKeys[i].name;
   7.617 +            dk = dp.getFieldKey(name);
   7.618 +            assertNotNull("FieldKey for '" + name + "'", dk);
   7.619 +            assertTrue("Type for '" + name + "'",
   7.620 +                    isAssignableFrom(dp.getType(dk), fieldKeys[i].type));
   7.621 +            assertEquals("ReadOnly for '" + name + "'",
   7.622 +                    fieldKeys[i].canSetValue, dp.isReadOnly(dk));
   7.623 +            if (fieldKeys[i].defaultValue != null) {
   7.624 +                assertEquals("Value for '" + name + "'",
   7.625 +                        fieldKeys[i].defaultValue, dp.getValue(dk));
   7.626 +            }
   7.627 +        }
   7.628 +
   7.629 +    }
   7.630 +
   7.631 +    /**
   7.632 +     * <p>Ensure that all the expected properties are present and have
   7.633 +     * the specified default values (where possible).</p>
   7.634 +     */
   7.635 +    private void checkProperties() {
   7.636 +
   7.637 +        FieldKey dk = null;
   7.638 +        String name = null;
   7.639 +        for (int i = 0; i < properties.length; i++) {
   7.640 +            name = properties[i].name;
   7.641 +            dk = dp.getFieldKey(name);
   7.642 +            assertNotNull("FieldKey for '" + name + "'", dk);
   7.643 +            assertTrue("Type for '" + name + "'",
   7.644 +                    isAssignableFrom(dp.getType(dk), properties[i].type));
   7.645 +            assertEquals("ReadOnly for '" + name + "'",
   7.646 +                    properties[i].canSetValue, dp.isReadOnly(dk));
   7.647 +            if (properties[i].defaultValue != null) {
   7.648 +                assertEquals("Value for '" + name + "'",
   7.649 +                        properties[i].defaultValue, dp.getValue(dk));
   7.650 +            }
   7.651 +        }
   7.652 +
   7.653 +    }
   7.654 +
   7.655 +    private boolean isAssignableFrom(Class to, Class from) {
   7.656 +        if (to.isPrimitive()) {
   7.657 +            if (to == Boolean.TYPE) {
   7.658 +                to = Boolean.class;
   7.659 +            } else if (to == Character.TYPE) {
   7.660 +                to = Character.class;
   7.661 +            } else if (to == Byte.TYPE) {
   7.662 +                to = Byte.class;
   7.663 +            } else if (to == Short.TYPE) {
   7.664 +                to = Short.class;
   7.665 +            } else if (to == Integer.TYPE) {
   7.666 +                to = Integer.class;
   7.667 +            } else if (to == Long.TYPE) {
   7.668 +                to = Long.class;
   7.669 +            } else if (to == Float.TYPE) {
   7.670 +                to = Float.class;
   7.671 +            } else if (to == Double.TYPE) {
   7.672 +                to = Double.class;
   7.673 +            }
   7.674 +        }
   7.675 +        return to.isAssignableFrom(from);
   7.676 +    }
   7.677 +
   7.678 +    /**
   7.679 +     * <p>Ensure that we can update all the simple fieldKeys and properties
   7.680 +     * that should be updatable by default.</p>
   7.681 +     */
   7.682 +    private void checkUpdates() {
   7.683 +
   7.684 +        FieldKey dk = null;
   7.685 +        String name = null;
   7.686 +        for (int i = 0; i < updates.length; i++) {
   7.687 +            name = updates[i].name;
   7.688 +            try {
   7.689 +                dp.setValue(dp.getFieldKey(name), updates[i].value);
   7.690 +            } catch (Exception e) {
   7.691 +                fail("Cannot set value for '" + name + "':" + e);
   7.692 +            }
   7.693 +            assertEquals("Updated value for '" + name + "'",
   7.694 +                    updates[i].value, dp.getValue(dp.getFieldKey(name)));
   7.695 +        }
   7.696 +
   7.697 +    }
   7.698 +
   7.699 +    // Private class to describe the expected properties
   7.700 +    static class Descriptor {
   7.701 +
   7.702 +        public Descriptor(String name, Class type, boolean canSetValue, Object defaultValue) {
   7.703 +            this.name = name;
   7.704 +            this.type = type;
   7.705 +            this.canSetValue = canSetValue;
   7.706 +            this.defaultValue = defaultValue;
   7.707 +        }
   7.708 +        public String name;
   7.709 +        public Class type;
   7.710 +        public boolean canSetValue;
   7.711 +        public Object defaultValue;
   7.712 +    }
   7.713 +
   7.714 +    // Private class to represent an event listener
   7.715 +    static class Listener
   7.716 +            implements DataListener {
   7.717 +
   7.718 +        String log = "";
   7.719 +
   7.720 +        public String getLog() {
   7.721 +            return this.log;
   7.722 +        }
   7.723 +
   7.724 +        public void clear() {
   7.725 +            this.log = "";
   7.726 +        }
   7.727 +
   7.728 +        public void valueChanged(DataProvider dp, FieldKey dk, Object oldValue,
   7.729 +                Object newValue) {
   7.730 +            log += dk.getFieldId() + "/" + oldValue + "/" + newValue + "//";
   7.731 +        }
   7.732 +
   7.733 +        public void providerChanged(DataProvider dp) {
   7.734 +            log += "providerChanged//";
   7.735 +        }
   7.736 +    }
   7.737 +
   7.738 +    // Private class to represent a TableDataProvider cursor listener
   7.739 +    static class MyCursorListener implements TableCursorListener {
   7.740 +
   7.741 +        boolean veto = false;
   7.742 +        String log = "";
   7.743 +
   7.744 +        public String getLog() {
   7.745 +            return this.log;
   7.746 +        }
   7.747 +
   7.748 +        public void clear() {
   7.749 +            this.log = "";
   7.750 +        }
   7.751 +
   7.752 +        public void cursorChanged(TableDataProvider dp, RowKey oldRow, RowKey newRow) {
   7.753 +            log += "cursorChanged/" + oldRow + "/" + newRow + "//";
   7.754 +        }
   7.755 +
   7.756 +        public void cursorChanging(TableDataProvider dp, RowKey oldRow, RowKey newRow)
   7.757 +                throws TableCursorVetoException {
   7.758 +            log += "cursorChanging/" + oldRow + "/" + newRow + "//";
   7.759 +            if (veto) {
   7.760 +                log += "cursorVetoed/" + oldRow + "/" + newRow + "//";
   7.761 +                throw new TableCursorVetoException("No way, Jose");
   7.762 +            }
   7.763 +        }
   7.764 +
   7.765 +        public boolean isVeto() {
   7.766 +            return this.veto;
   7.767 +        }
   7.768 +
   7.769 +        public void setVeto(boolean veto) {
   7.770 +            this.veto = veto;
   7.771 +        }
   7.772 +    }
   7.773 +
   7.774 +    // Private class to represent a TableDataProvider event listener
   7.775 +    class MyDataListener implements TableDataListener {
   7.776 +
   7.777 +        String log = "";
   7.778 +
   7.779 +        public String getLog() {
   7.780 +            return this.log;
   7.781 +        }
   7.782 +
   7.783 +        public void clear() {
   7.784 +            this.log = "";
   7.785 +        }
   7.786 +
   7.787 +        public void valueChanged(DataProvider dp, FieldKey fk, Object oldValue, Object newValue) {
   7.788 +            log += fk + "/" + oldValue + "/" + newValue + "//";
   7.789 +        }
   7.790 +
   7.791 +        public void providerChanged(DataProvider dp) {
   7.792 +            log += "providerChanged//";
   7.793 +        }
   7.794 +
   7.795 +        public void rowAdded(TableDataProvider dp, RowKey rk) {
   7.796 +            log += "rowAdded/" + rk + "//";
   7.797 +        }
   7.798 +
   7.799 +        public void rowRemoved(TableDataProvider dp, RowKey rk) {
   7.800 +            log += "rowRemoved/" + rk + "//";
   7.801 +        }
   7.802 +
   7.803 +        public void valueChanged(TableDataProvider dp, FieldKey fk, RowKey rk, Object oldValue, Object newValue) {
   7.804 +            log += fk + "/" + rk + "/" + oldValue + "/" + newValue + "//";
   7.805 +        }
   7.806 +    }
   7.807 +
   7.808 +    // Private class to represent a TransactionalDataProvider event listener
   7.809 +    class MyTransactionalListener implements TransactionalDataListener, TableDataListener {
   7.810 +
   7.811 +        String log = "";
   7.812 +
   7.813 +        public String getLog() {
   7.814 +            return this.log;
   7.815 +        }
   7.816 +
   7.817 +        public void clear() {
   7.818 +            this.log = "";
   7.819 +        }
   7.820 +
   7.821 +        public void changesCommitted(TransactionalDataProvider tdp) {
   7.822 +            log += "changesCommitted//";
   7.823 +        }
   7.824 +
   7.825 +        public void changesReverted(TransactionalDataProvider tdp) {
   7.826 +            log += "changesReverted//";
   7.827 +        }
   7.828 +
   7.829 +        public void providerChanged(DataProvider dp) {
   7.830 +            log += "providerChanged//";
   7.831 +        }
   7.832 +
   7.833 +        public void rowAdded(TableDataProvider dp, RowKey rk) {
   7.834 +            log += "rowAdded/" + rk + "//";
   7.835 +        }
   7.836 +
   7.837 +        public void rowRemoved(TableDataProvider dp, RowKey rk) {
   7.838 +            log += "rowRemoved/" + rk + "//";
   7.839 +        }
   7.840 +
   7.841 +        public void valueChanged(DataProvider dp, FieldKey fk, Object oldValue,
   7.842 +                Object newValue) {
   7.843 +            log += fk + "/" + oldValue + "/" + newValue + "//";
   7.844 +        }
   7.845 +
   7.846 +        public void valueChanged(TableDataProvider dp, FieldKey fk, RowKey rk, Object oldValue, Object newValue) {
   7.847 +            log += fk + "/" + rk + "/" + oldValue + "/" + newValue + "//";
   7.848 +        }
   7.849 +    }
   7.850 +
   7.851 +    // Private class to describe updates to be performed and checked
   7.852 +    static class Update {
   7.853 +
   7.854 +        public Update(String name, Object value) {
   7.855 +            this.name = name;
   7.856 +            this.value = value;
   7.857 +        }
   7.858 +        public String name;
   7.859 +        public Object value;
   7.860      }
   7.861  }
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/visualweb.dataprovider/test/unit/src/org/netbeans/modules/visualweb/dataprovider/TestBean.java	Tue Nov 13 01:00:31 2007 +0000
     8.3 @@ -0,0 +1,240 @@
     8.4 +/*
     8.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     8.6 + * 
     8.7 + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
     8.8 + * 
     8.9 + * The contents of this file are subject to the terms of either the GNU
    8.10 + * General Public License Version 2 only ("GPL") or the Common
    8.11 + * Development and Distribution License("CDDL") (collectively, the
    8.12 + * "License"). You may not use this file except in compliance with the
    8.13 + * License. You can obtain a copy of the License at
    8.14 + * http://www.netbeans.org/cddl-gplv2.html
    8.15 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    8.16 + * specific language governing permissions and limitations under the
    8.17 + * License.  When distributing the software, include this License Header
    8.18 + * Notice in each file and include the License file at
    8.19 + * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
    8.20 + * particular file as subject to the "Classpath" exception as provided
    8.21 + * by Sun in the GPL Version 2 section of the License file that
    8.22 + * accompanied this code. If applicable, add the following below the
    8.23 + * License Header, with the fields enclosed by brackets [] replaced by
    8.24 + * your own identifying information:
    8.25 + * "Portions Copyrighted [year] [name of copyright owner]"
    8.26 + * 
    8.27 + * If you wish your version of this file to be governed by only the CDDL
    8.28 + * or only the GPL Version 2, indicate your decision by adding
    8.29 + * "[Contributor] elects to include this software in this distribution
    8.30 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
    8.31 + * single choice of license, a recipient has the option to distribute
    8.32 + * your version of this file under either the CDDL, the GPL Version 2 or
    8.33 + * to extend the choice of license to its licensees as provided above.
    8.34 + * However, if you add GPL Version 2 code and therefore, elected the GPL
    8.35 + * Version 2 license, then the option applies only if the new code is
    8.36 + * made subject to such option by the copyright holder.
    8.37 + * 
    8.38 + * Contributor(s):
    8.39 + * 
    8.40 + * Portions Copyrighted 2007 Sun Microsystems, Inc.
    8.41 + */
    8.42 +
    8.43 +package org.netbeans.modules.visualweb.dataprovider;
    8.44 +
    8.45 +import java.io.Serializable;
    8.46 +import java.util.ArrayList;
    8.47 +import java.util.HashMap;
    8.48 +import java.util.List;
    8.49 +import java.util.Map;
    8.50 +
    8.51 +
    8.52 +/**
    8.53 + * <p>JavaBean for data provider unit tests.</p>
    8.54 + */
    8.55 +public class TestBean implements Serializable {
    8.56 +
    8.57 +
    8.58 +    public TestBean() {
    8.59 +    }
    8.60 +
    8.61 +
    8.62 +    public TestBean(String id) {
    8.63 +        this.id = id;
    8.64 +    }
    8.65 +
    8.66 +    // Public id (set in constructor) for easy identification
    8.67 +    private String id = null;
    8.68 +    public String getId() { return this.id; }
    8.69 +    public void setId(String id) { this.id = id; }
    8.70 +
    8.71 +
    8.72 +    // Read-only property for testing
    8.73 +    private String readOnly = "readOnly Property";
    8.74 +    public String getReadOnly() { return this.readOnly; }
    8.75 +
    8.76 +    // Public fieldKeys with no getter/setter for tests related to accessing fieldKeys
    8.77 +    public String public1 = "This is public1";
    8.78 +    public int public2 = 8888;
    8.79 +
    8.80 +
    8.81 +    private boolean booleanProperty = true;
    8.82 +    public boolean getBooleanProperty() {
    8.83 +        return this.booleanProperty;
    8.84 +    }
    8.85 +    public void setBooleanProperty(boolean booleanProperty) {
    8.86 +        this.booleanProperty = booleanProperty;
    8.87 +    }
    8.88 +
    8.89 +
    8.90 +    private byte byteProperty = 123;
    8.91 +    public byte getByteProperty() {
    8.92 +        return this.byteProperty;
    8.93 +    }
    8.94 +    public void setByteProperty(byte byteProperty) {
    8.95 +        this.byteProperty = byteProperty;
    8.96 +    }
    8.97 +
    8.98 +
    8.99 +    private double doubleProperty = 654.321;
   8.100 +    public double getDoubleProperty() {
   8.101 +        return this.doubleProperty;
   8.102 +    }
   8.103 +    public void setDoubleProperty(double doubleProperty) {
   8.104 +        this.doubleProperty = doubleProperty;
   8.105 +    }
   8.106 +
   8.107 +
   8.108 +    private float floatProperty = (float) 123.45;
   8.109 +    public float getFloatProperty() {
   8.110 +        return this.floatProperty;
   8.111 +    }
   8.112 +    public void setFloatProperty(float floatProperty) {
   8.113 +        this.floatProperty = floatProperty;
   8.114 +    }
   8.115 +
   8.116 +
   8.117 +    private int intArray[] = {1, 2, 3};
   8.118 +    public int[] getIntArray() {
   8.119 +        return this.intArray;
   8.120 +    }
   8.121 +    public void setIntArray(int intArray[]) {
   8.122 +        this.intArray = intArray;
   8.123 +    }
   8.124 +
   8.125 +
   8.126 +    private List intList = null;
   8.127 +    public List getIntList() {
   8.128 +        if (intList == null) {
   8.129 +            intList = new ArrayList();
   8.130 +            intList.add(new Integer(10));
   8.131 +            intList.add(new Integer(20));
   8.132 +            intList.add(new Integer(30));
   8.133 +            intList.add(new Integer(40));
   8.134 +            intList.add(new Integer(50));
   8.135 +        }
   8.136 +        return intList;
   8.137 +    }
   8.138 +    public void setIntList(List intList) {
   8.139 +        this.intList = intList;
   8.140 +    }
   8.141 +
   8.142 +
   8.143 +    private int intProperty = 1234;
   8.144 +    public int getIntProperty() {
   8.145 +        return this.intProperty;
   8.146 +    }
   8.147 +    public void setIntProperty(int intProperty) {
   8.148 +        this.intProperty = intProperty;
   8.149 +    }
   8.150 +
   8.151 +
   8.152 +    private long longProperty = 54321;
   8.153 +    public long getLongProperty() {
   8.154 +        return this.longProperty;
   8.155 +    }
   8.156 +    public void setLongProperty(long longProperty) {
   8.157 +        this.longProperty = longProperty;
   8.158 +    }
   8.159 +
   8.160 +
   8.161 +    private TestBean nestedArray[] = null;
   8.162 +    public TestBean[] getNestedArray() {
   8.163 +        if (nestedArray == null) {
   8.164 +            nestedArray = new TestBean[2];
   8.165 +            nestedArray[0] = new TestBean("array0");
   8.166 +            nestedArray[1] = new TestBean("array1");
   8.167 +        }
   8.168 +        return this.nestedArray;
   8.169 +    }
   8.170 +    public void setNestedArray(TestBean nestedArray[]) {
   8.171 +        this.nestedArray = nestedArray;
   8.172 +    }
   8.173 +
   8.174 +
   8.175 +    private List nestedList = null;
   8.176 +    public List getNestedList() {
   8.177 +        if (nestedList == null) {
   8.178 +            nestedList = new ArrayList();
   8.179 +            nestedList.add(new TestBean("list0"));
   8.180 +            nestedList.add(new TestBean("list1"));
   8.181 +            nestedList.add(new TestBean("list2"));
   8.182 +            nestedList.add(new TestBean("list3"));
   8.183 +        }
   8.184 +        return this.nestedList;
   8.185 +    }
   8.186 +    public void setNestedList(List nestedList) {
   8.187 +        this.nestedList = nestedList;
   8.188 +    }
   8.189 +
   8.190 +
   8.191 +    private Map nestedMap = null;
   8.192 +    public Map getNestedMap() {
   8.193 +        if (nestedMap == null) {
   8.194 +            nestedMap = new HashMap();
   8.195 +            nestedMap.put("map0", new TestBean("map0"));
   8.196 +            nestedMap.put("map1", new TestBean("map1"));
   8.197 +            nestedMap.put("map2", new TestBean("map2"));
   8.198 +        }
   8.199 +        return (this.nestedMap);
   8.200 +    }
   8.201 +    public void setNestedMap(Map nestedMap) {
   8.202 +        this.nestedMap = nestedMap;
   8.203 +    }
   8.204 +
   8.205 +
   8.206 +    private TestBean nestedProperty = null;
   8.207 +    public TestBean getNestedProperty() {
   8.208 +        if (nestedProperty == null) {
   8.209 +            nestedProperty = new TestBean();
   8.210 +        }
   8.211 +        return this.nestedProperty;
   8.212 +    }
   8.213 +    public void setNestedProperty(TestBean nestedProperty) {
   8.214 +        this.nestedProperty = nestedProperty;
   8.215 +    }
   8.216 +
   8.217 +
   8.218 +    private short shortProperty = 321;
   8.219 +    public short getShortProperty() {
   8.220 +        return this.shortProperty;
   8.221 +    }
   8.222 +    public void setShortProperty(short shortProperty) {
   8.223 +        this.shortProperty = shortProperty;
   8.224 +    }
   8.225 +
   8.226 +
   8.227 +    private String stringProperty = "This is a String";
   8.228 +    public String getStringProperty() {
   8.229 +        return this.stringProperty;
   8.230 +    }
   8.231 +    public void setStringProperty(String stringProperty) {
   8.232 +        this.stringProperty = stringProperty;
   8.233 +    }
   8.234 +
   8.235 +
   8.236 +    // This property is also read-only
   8.237 +    private String nullString = null;
   8.238 +    public String getNullString() {
   8.239 +        return this.nullString;
   8.240 +    }
   8.241 +
   8.242 +
   8.243 +}