sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1412021 - in /sis/branches/JDK7/sis-utility/src: main/java/org/apache/sis/util/collection/ main/java/org/apache/sis/util/resources/ test/java/org/apache/sis/test/ test/java/org/apache/sis/test/foreigner/ test/java/org/apache/sis/test/suite...
Date Wed, 21 Nov 2012 09:02:19 GMT
Author: desruisseaux
Date: Wed Nov 21 09:02:17 2012
New Revision: 1412021

URL: http://svn.apache.org/viewvc?rev=1412021&view=rev
Log:
Changed the TableColumn interface to a class in an attempt to simplify the framework
(this is not SIS role to design elaborated non-spatial tree structure - we want just
enough for our needs), and added more tests.

Added:
    sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/foreigner/
    sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/foreigner/SerializableTableColumn.java
  (with props)
    sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/foreigner/package-info.java
  (with props)
    sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/collection/TableColumnTest.java
  (with props)
Removed:
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/ColumnConstant.java
    sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/collection/StringColumn.java
Modified:
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/DefaultTreeTable.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/TableColumn.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTables.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java
    sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/Assert.java
    sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java
    sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/CharSequencesTest.java
    sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/collection/DefaultTreeTableTest.java
    sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/collection/TreeTableFormatTest.java

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/DefaultTreeTable.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/DefaultTreeTable.java?rev=1412021&r1=1412020&r2=1412021&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/DefaultTreeTable.java
(original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/DefaultTreeTable.java
Wed Nov 21 09:02:17 2012
@@ -25,8 +25,12 @@ import net.jcip.annotations.NotThreadSaf
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.resources.Errors;
 
+import static org.apache.sis.util.collection.Collections.isNullOrEmpty;
 import static org.apache.sis.util.collection.Collections.hashMapCapacity;
 
+// Related to JDK7
+import java.util.Objects;
+
 
 /**
  * A {@link TreeTable} implementation with a {@linkplain #getColumns() list of columns} given
at
@@ -218,6 +222,37 @@ public class DefaultTreeTable implements
     }
 
     /**
+     * Compares the given object with this tree table for equality. This method compares
the
+     * {@linkplain #getColumns() columns} and the {@linkplain #getRoot() root node}. If the
+     * later is an instance of the {@link Node} inner class, then all node values and children
+     * will be {@linkplain Node#equals(Object) compared} recursively.
+     *
+     * @param  other The object to compare with this table.
+     * @return {@code true} if the two objects are equal.
+     */
+    @Override
+    public boolean equals(final Object other) {
+        if (other == this) {
+            return true;
+        }
+        if (other != null && other.getClass() == getClass()) {
+            final DefaultTreeTable that = (DefaultTreeTable) other;
+            return columnIndices.equals(that.columnIndices) &&
+                    Objects.equals(root, that.root);
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hash code value for this table.
+     * This method is defined for consistency with {@link #equals(Object)} contract.
+     */
+    @Override
+    public int hashCode() {
+        return (columnIndices.hashCode() + 31*Objects.hashCode(root)) ^ (int) serialVersionUID;
+    }
+
+    /**
      * Returns a string representation of this tree table.
      * The default implementation delegates to {@link TreeTables#toString(TreeTable)}.
      * This is okay for debugging or occasional usages. However for more extensive usages,
@@ -495,6 +530,77 @@ public class DefaultTreeTable implements
         }
 
         /**
+         * Compares the given object with this node for {@linkplain #getValue(TableColumn)
values}
+         * and {@linkplain #getChildren() children} equality, ignoring the {@linkplain #getParent()
+         * parent}. This method can be used for determining if two branches of a same tree
or of two
+         * different trees are identical.
+         *
+         * <p>This method compares children recursively, which is another reason why
the parents
+         * need to be ignored.</p>
+         *
+         * @param  other The object to compare with this node.
+         * @return {@code true} if the two objects are equal, ignoring the parent node.
+         */
+        @Override
+        public boolean equals(final Object other) {
+            if (other == this) {
+                return true;
+            }
+            if (other != null && other.getClass() == getClass()) {
+                final Node that = (Node) other;
+                if (columnIndices.equals(that.columnIndices)) {
+                    final Object[] v1 = this.values;
+                    final Object[] v2 = that.values;
+                    if (v1 != v2) { // For skipping the loop if v1 and v2 are null.
+                        for (int i=columnIndices.size(); --i>=0;) {
+                            if (!Objects.equals((v1 != null) ? v1[i] : null,
+                                                (v2 != null) ? v2[i] : null))
+                            {
+                                return false;
+                            }
+                        }
+                    }
+                    final List<TreeTable.Node> c1 = this.children;
+                    final List<TreeTable.Node> c2 = that.children;
+                    final int n = (c1 != null) ? c1.size() : 0;
+                    if (((c2 != null) ? c2.size() : 0) == n) {
+                        for (int i=0; i<n; i++) {
+                            if (!c1.get(i).equals(c2.get(i))) {
+                                return false;
+                            }
+                        }
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }
+
+        /**
+         * Returns a hash-code value computed from the {@linkplain #getValue(TableColumn)
values}
+         * and {@linkplain #getChildren() children}, ignoring the {@linkplain #getParent()
parent}.
+         * This method is defined for consistency with {@link #equals(Object)} contract.
+         */
+        @Override
+        public int hashCode() {
+            int hash = 0;
+            final Object[] values = this.values;
+            if (values != null) {
+                // Do not use Objects.hashCode(...) because we want the result of array
+                // containing only null elements to be the same than null array (zero).
+                for (int i=values.length; --i>=0;) {
+                    hash = 31*hash + Objects.hash(values[i]);
+                }
+            }
+            // Do not use Objects.hashCode(...) because we
+            // want the same result for null and empty list.
+            if (!isNullOrEmpty(children)) {
+                hash += 37 * children.hashCode();
+            }
+            return hash ^ (int) serialVersionUID;
+        }
+
+        /**
          * Returns a string representation of this node, for identification in error message
          * or in debugger.
          *

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/TableColumn.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/TableColumn.java?rev=1412021&r1=1412020&r2=1412021&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/TableColumn.java
(original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/TableColumn.java
Wed Nov 21 09:02:17 2012
@@ -16,7 +16,14 @@
  */
 package org.apache.sis.util.collection;
 
+import java.util.Map;
+import java.util.Collections;
+import java.io.Serializable;
+import java.io.InvalidObjectException;
 import org.opengis.util.InternationalString;
+import org.apache.sis.util.type.Types;
+import org.apache.sis.util.ArgumentChecks;
+import org.apache.sis.util.resources.Vocabulary;
 
 
 /**
@@ -27,22 +34,30 @@ import org.opengis.util.InternationalStr
  *
  * {@preformat java
  *     class CityLocation {
- *         public static final TableColumn<String> CITY_NAME  = new MyColumn<>(String.class);
- *         public static final TableColumn<Float>  LATITUDE   = new MyColumn<>(Float
.class);
- *         public static final TableColumn<Float>  LONGTITUDE = new MyColumn<>(Float
.class);
- *
- *         private String city;
+ *         private String name;
  *         private float  latitude;
  *         private float  longitude;
  *
  *         CityLocation(TreeTable.Node myNode) {
- *             city      = myNode.getValue(CITY_NAME);
- *             latitude  = myNode.getValue(LATITUDE );
+ *             name      = myNode.getValue(NAME);
+ *             latitude  = myNode.getValue(LATITUDE);
  *             longitude = myNode.getValue(LONGITUDE);
  *         }
  *     }
  * }
  *
+ * {@section Identity comparisons and serialization}
+ * This base class relies on <cite>identity comparisons</cite> instead than defining
the
+ * {@code equals(Object)} method, because the {@linkplain #getElementType() element type}
+ * is not a sufficient criterion for differentiating the columns (many columns have values
+ * of the same type) and the {@linkplain #getHeader() header} is arbitrary. Developers who
+ * create their own instances are encouraged to declare them as static final constants.
+ *
+ * <p>This base class is not {@linkplain Serializable serializable}. However the pre-defined
+ * constants defined in this class are serializable. Developers who need custom serializable
+ * columns are encouraged to create their own subclass and resolve to the singleton instance
+ * on deserialization.</p>
+ *
  * @param <V> Base type of all values in the column identified by this instance.
  *
  * @author  Martin Desruisseaux (Geomatys)
@@ -50,18 +65,181 @@ import org.opengis.util.InternationalStr
  * @version 0.3
  * @module
  */
-public interface TableColumn<V> extends CheckedContainer<V> {
+public class TableColumn<V> implements CheckedContainer<V> {
+    /**
+     * Frequently-used constant for a column of object names.
+     * The values are typically instances of {@link String} or {@link InternationalString},
+     * depending on whether the data provide localization support or not.
+     */
+    public static final TableColumn<CharSequence> NAME = new Constant<>("NAME",
+            CharSequence.class, Vocabulary.Keys.Name);
+
+    /**
+     * Frequently-used constant for a column of object types.
+     * The values are instances of {@link Class}.
+     */
+    @SuppressWarnings("unchecked")
+    public static final TableColumn<Class<?>> TYPE = new Constant<>("TYPE",
+            (Class) Class.class, Vocabulary.Keys.Type);
+
+    /**
+     * A map containing only the {@link #NAME} column.
+     * This is the default set of columns when parsing a table tree.
+     */
+    static final Map<TableColumn<?>,Integer> NAME_MAP =
+            Collections.<TableColumn<?>,Integer>singletonMap(NAME, 0);
+
+    /**
+     * Base type of all values in the column identified by this {@code ColumnTable} instance.
+     */
+    private final Class<V> type;
+
+    /**
+     * The column header, or {@code null} if not yet created.
+     */
+    CharSequence header;
+
+    /**
+     * Implementation of {@link TableColumn} for the pre-defined constants.
+     * This implementation differs resource bundle loading until first needed,
+     * and resolves deserialized instances to the singleton instances.
+     *
+     * @param <V> Base type of all values in the column identified by this instance.
+     *
+     * @author  Martin Desruisseaux (Geomatys)
+     * @since   0.3
+     * @version 0.3
+     * @module
+     */
+    private static final class Constant<V> extends TableColumn<V> implements
Serializable {
+        /**
+         * For cross-version compatibility.
+         */
+        private static final long serialVersionUID = -2486202389234601560L;
+
+        /**
+         * The programmatic name of the static final field holding this constant.
+         */
+        private final String field;
+
+        /**
+         * The resource key for the column header.
+         */
+        private final transient int resourceKey;
+
+        /**
+         * Creates a new instance for a build-in constant.
+         *
+         * @param field  The programmatic name of the static final field holding this constant.
+         * @param type   Base type of all values in the column identified by this instance.
+         * @param header The resource key for the column header.
+         */
+        Constant(final String field, final Class<V> type, final int header) {
+            super(type);
+            this.field       = field;
+            this.resourceKey = header;
+        }
+
+        /**
+         * Returns the text to display as column header.
+         */
+        @Override
+        public synchronized InternationalString getHeader() {
+            InternationalString i18n = (InternationalString) header;
+            if (i18n == null) {
+                header = i18n = Vocabulary.formatInternational(resourceKey);
+            }
+            return i18n;
+        }
+
+        /**
+         * Invoked on deserialization for resolving this instance to one of the predefined
constants.
+         *
+         * @return One of the predefined constants.
+         * @throws InvalidObjectException If this instance can not be resolved.
+         */
+        private Object readResolve() throws InvalidObjectException {
+            try {
+                return TableColumn.class.getField(field).get(null);
+            } catch (Exception cause) { // Many exceptions, including unchecked ones.
+                InvalidObjectException e = new InvalidObjectException(cause.toString());
+                e.initCause(cause);
+                throw e;
+            }
+        }
+    }
+
+    /**
+     * Invoked on deserialization for creating an initially empty instance.
+     * This constructor has {@code protected} visibility only because the Java deserialization
+     * mechanism requires so; this constructor shall not be invoked in any other context.
+     *
+     * <p>Subclasses are responsible for resolving the deserialized instance to a singleton
+     * instance. This can be done by the following method, which assume that the subclass
+     * declares a public static field named {@code fieldName}:</p>
+     *
+     * {@preformat java
+     *     private Object readResolve() throws InvalidObjectException {
+     *         try {
+     *             return getClass().getField(fieldName).get(null);
+     *         } catch (Exception cause) { // Many exceptions, including unchecked ones.
+     *             InvalidObjectException e = new InvalidObjectException(cause.toString());
+     *             e.initCause(cause);
+     *             throw e;
+     *         }
+     *     }
+     * }
+     */
+    protected TableColumn() {
+        type = null;
+    }
+
+    /**
+     * Creates a new instance for a build-in constant.
+     *
+     * @param type Base type of all values in the column identified by this instance.
+     */
+    TableColumn(final Class<V> type) {
+        this.type = type;
+    }
+
+    /**
+     * Creates a new instance for the given type of values.
+     *
+     * @param type   Base type of all values in the column identified by this instance.
+     * @param header The text to display as column header.
+     */
+    public TableColumn(final Class<V> type, final CharSequence header) {
+        ArgumentChecks.ensureNonNull("type",   this.type   = type);
+        ArgumentChecks.ensureNonNull("header", this.header = header);
+        this.header = Types.toInternationalString(header);
+    }
+
     /**
      * Returns the text to display as column header.
      *
      * @return The text to display as column header.
      */
-    InternationalString getHeader();
+    public synchronized InternationalString getHeader() {
+        final InternationalString i18n = Types.toInternationalString(header);
+        header = i18n;
+        return i18n;
+    }
 
     /**
      * Returns the base type of all values in any column identified by this {@code TableColumn}
      * instance.
      */
     @Override
-    Class<V> getElementType();
+    public final Class<V> getElementType() {
+        return type;
+    }
+
+    /**
+     * Returns a string representation of this table column.
+     */
+    @Override
+    public String toString() {
+        return getHeader().toString(null);
+    }
 }

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java?rev=1412021&r1=1412020&r2=1412021&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java
(original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java
Wed Nov 21 09:02:17 2012
@@ -377,7 +377,7 @@ public class TreeTableFormat extends Com
         int[] indentations      = new int[16];      // Number of spaces (ignoring drawing
characters) for each level.
         TreeTable.Node lastNode = null;             // Last parsed node, having 'indentation[level]'
characters before its content.
         TreeTable.Node root     = null;             // First node found while parsing.
-        final DefaultTreeTable table = new DefaultTreeTable(columnIndices != null ? columnIndices
: ColumnConstant.NAME_MAP);
+        final DefaultTreeTable table = new DefaultTreeTable(columnIndices != null ? columnIndices
: TableColumn.NAME_MAP);
         final TableColumn<?>[] columns = DefaultTreeTable.getColumns(table.columnIndices);
         final Format[] formats = getFormats(columns, true);
         do {

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTables.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTables.java?rev=1412021&r1=1412020&r2=1412021&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTables.java
(original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTables.java
Wed Nov 21 09:02:17 2012
@@ -19,7 +19,6 @@ package org.apache.sis.util.collection;
 import java.text.Format;
 import org.apache.sis.util.Static;
 import org.apache.sis.util.ArgumentChecks;
-import org.apache.sis.util.resources.Vocabulary;
 
 
 /**
@@ -34,22 +33,6 @@ import org.apache.sis.util.resources.Voc
  */
 public final class TreeTables extends Static {
     /**
-     * Frequently-used constant for a column of object names.
-     * The values are typically instances of {@link String} or
-     * {@link org.opengis.util.InternationalString}, depending
-     * if the data provide localization support or not.
-     */
-    public static final TableColumn<CharSequence> NAME = ColumnConstant.NAME;
-
-    /**
-     * Frequently-used constant for a column of object types.
-     * The values are instances of {@link Class}.
-     */
-    @SuppressWarnings("unchecked")
-    public static final TableColumn<Class<?>> TYPE = new ColumnConstant<>("TYPE",
-            (Class) Class.class, Vocabulary.Keys.Type);
-
-    /**
      * Shared {@code TreeTableFormat} instance for {@link #toString()} implementation.
      */
     private static Format format;
@@ -64,7 +47,7 @@ public final class TreeTables extends St
      * Creates a node with a single column for object names.
      * The node will have the following columns:
      *
-     * <table>
+     * <table class="sis">
      *   <tr><th>Header</th> <th>Type</th>                
<th>Initial value</th></tr>
      *   <tr><td>"Name"</td> <td>{@link CharSequence}</td>
<td>{@code name}</td></tr>
      * </table>
@@ -73,7 +56,7 @@ public final class TreeTables extends St
      * @return A new node with a name column initialized to the given value.
      */
     public static TreeTable.Node createNode(final CharSequence name) {
-        return new DefaultTreeTable.Node(ColumnConstant.NAME_MAP, (name != null) ? new CharSequence[]
{name} : null);
+        return new DefaultTreeTable.Node(TableColumn.NAME_MAP, (name != null) ? new CharSequence[]
{name} : null);
     }
 
     /**

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java?rev=1412021&r1=1412020&r2=1412021&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java
(original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java
Wed Nov 21 09:02:17 2012
@@ -88,8 +88,8 @@ public final class Vocabulary extends In
      * @return Resources in the given locale.
      * @throws MissingResourceException if resources can't be found.
      */
-    public static Messages getResources(final Locale locale) throws MissingResourceException
{
-        return getBundle(Messages.class, locale);
+    public static Vocabulary getResources(final Locale locale) throws MissingResourceException
{
+        return getBundle(Vocabulary.class, locale);
     }
 
     /**

Modified: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/Assert.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/Assert.java?rev=1412021&r1=1412020&r2=1412021&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/Assert.java (original)
+++ sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/Assert.java Wed Nov 21
09:02:17 2012
@@ -366,7 +366,7 @@ public strictfp class Assert extends org
                 }
             }
         } catch (IOException e) {
-            throw new AssertionError(e);
+            throw new AssertionError(e.toString(), e);
         }
         // Compares with the original object and returns it.
         @SuppressWarnings("unchecked")

Added: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/foreigner/SerializableTableColumn.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/foreigner/SerializableTableColumn.java?rev=1412021&view=auto
==============================================================================
--- sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/foreigner/SerializableTableColumn.java
(added)
+++ sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/foreigner/SerializableTableColumn.java
Wed Nov 21 09:02:17 2012
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.test.foreigner;
+
+import java.io.Serializable;
+import java.io.InvalidObjectException;
+import org.apache.sis.util.collection.TableColumn;
+
+
+/**
+ * For testing {@link TableColumn} deserialization.
+ *
+ * @param <V> Base type of all values in the column identified by this instance.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.3
+ * @version 0.3
+ * @module
+ */
+@SuppressWarnings("serial")
+public final strictfp class SerializableTableColumn<V> extends TableColumn<V>
implements Serializable {
+    /**
+     * A constant for column of latitudes as floating point value.
+     */
+    public static final TableColumn<Float> LATITUDE = new SerializableTableColumn<>("LATITUDE",
Float.class, "Latitude");
+
+    /**
+     * A constant for column of longitudes as floating point value.
+     */
+    public static final TableColumn<Float> LONGITUDE = new SerializableTableColumn<>("LONGITUDE",
Float.class, "Longitude");
+
+    /**
+     * The programmatic name of the static final field holding this constant.
+     */
+    private final String field;
+
+
+    /**
+     * Creates a new instance for the given type of values.
+     *
+     * @param field  The programmatic name of the static final field holding this constant.
+     * @param type   Base type of all values in the column identified by this instance.
+     * @param header The text to display as column header.
+     */
+    private SerializableTableColumn(final String field, final Class<V> type, final
CharSequence header) {
+        super(type, header);
+        this.field = field;
+    }
+
+    /**
+     * Invoked on deserialization for resolving this instance to one of the predefined constants.
+     *
+     * @return One of the predefined constants.
+     * @throws InvalidObjectException If this instance can not be resolved.
+     */
+    private Object readResolve() throws InvalidObjectException {
+        try {
+            return SerializableTableColumn.class.getField(field).get(null);
+        } catch (Exception cause) { // Many exceptions, including unchecked ones.
+            InvalidObjectException e = new InvalidObjectException(cause.toString());
+            e.initCause(cause);
+            throw e;
+        }
+    }
+}

Propchange: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/foreigner/SerializableTableColumn.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/foreigner/SerializableTableColumn.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/foreigner/package-info.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/foreigner/package-info.java?rev=1412021&view=auto
==============================================================================
--- sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/foreigner/package-info.java
(added)
+++ sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/foreigner/package-info.java
Wed Nov 21 09:02:17 2012
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * A package for test classes defined outside the package of the Apache SIS class to test.
+ * We use this foreigner package for testing if subclasses can work without access to the
+ * package-privated members of the SIS class. This precaution is recommended for testing
+ * functionalities that make use of Java reflection.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.3
+ * @version 0.3
+ * @module
+ */
+package org.apache.sis.test.foreigner;

Propchange: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/foreigner/package-info.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/foreigner/package-info.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java?rev=1412021&r1=1412020&r2=1412021&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java
(original)
+++ sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java
Wed Nov 21 09:02:17 2012
@@ -51,6 +51,7 @@ import org.junit.runners.Suite;
   org.apache.sis.util.collection.CacheTest.class,
   org.apache.sis.util.collection.DerivedSetTest.class,
   org.apache.sis.util.collection.DerivedMapTest.class,
+  org.apache.sis.util.collection.TableColumnTest.class,
   org.apache.sis.util.collection.DefaultTreeTableTest.class,
 
   // GeoAPI most basic types.

Modified: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/CharSequencesTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/CharSequencesTest.java?rev=1412021&r1=1412020&r2=1412021&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/CharSequencesTest.java
(original)
+++ sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/CharSequencesTest.java
Wed Nov 21 09:02:17 2012
@@ -324,7 +324,7 @@ public final strictfp class CharSequence
     public void testIsUpperCase() {
         assertTrue ("ABC", isUpperCase("ABC"));
         assertFalse("AbC", isUpperCase("AbC"));
-        assertFalse("A2C", isUpperCase("A2C")); // TODO: actually an unspecified behavior;
we can change that.
+        assertFalse("A2C", isUpperCase("A2C"));
     }
 
     /**

Modified: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/collection/DefaultTreeTableTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/collection/DefaultTreeTableTest.java?rev=1412021&r1=1412020&r2=1412021&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/collection/DefaultTreeTableTest.java
(original)
+++ sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/collection/DefaultTreeTableTest.java
Wed Nov 21 09:02:17 2012
@@ -20,10 +20,11 @@ import java.util.List;
 import org.junit.Test;
 import org.apache.sis.test.TestCase;
 import org.apache.sis.test.TestStep;
+import org.apache.sis.test.DependsOn;
 
-import static org.junit.Assert.*;
+import static org.apache.sis.test.Assert.*;
 import static org.apache.sis.test.TestUtilities.getSingleton;
-import static org.apache.sis.util.collection.TreeTables.*;
+import static org.apache.sis.util.collection.TableColumn.*;
 
 
 /**
@@ -35,6 +36,7 @@ import static org.apache.sis.util.collec
  * @version 0.3
  * @module
  */
+@DependsOn(TableColumnTest.class)
 public final strictfp class DefaultTreeTableTest extends TestCase {
     /**
      * Tests the creation of an {@link DefaultTreeTable} with initially no root node.
@@ -112,7 +114,8 @@ public final strictfp class DefaultTreeT
      * Tests the displacement of nodes, in particular ensures that the parent is updated.
      *
      * <p>This method is part of a chain.
-     * The previous method is {@link #testNodeCreation(DefaultTreeTable)}.</p>
+     * The previous method is {@link #testNodeCreation(DefaultTreeTable)} and
+     * the next method is {@link #testSerialization(TreeTable)}.</p>
      *
      * @param root The root node where to move children.
      */
@@ -139,12 +142,31 @@ public final strictfp class DefaultTreeT
     }
 
     /**
+     * Tests {@link DefaultTreeTable} serialization.
+     *
+     * <p>This method is part of a chain.
+     * The previous method is {@link #testNodeDisplacement(TreeTable.Node)}.</p>
+     */
+    @TestStep
+    private void testSerialization(final TreeTable table) {
+        final TreeTable newTable = assertSerializedEquals(table);
+        newTable.getRoot().getChildren().get(1).setValue(NAME, "New name");
+        assertFalse("newTable.equals(table)", newTable.equals(table));
+    }
+
+    /**
      * Tests the creation of a tree table with a few nodes, and tests the displacement of
a node
-     * from one branch to another. This test is actually a chain of {@link TestStep} methods.
+     * from one branch to another. Finally tests the serialization of that table and the
comparison
+     * with the original object.
+     *
+     * <p>This test is actually a chain of {@link TestStep} methods.</p>
      */
     @Test
     public void testTreeTableCreation() {
-        testNodeDisplacement(testNodeCreation(testTableCreation()));
+        final DefaultTreeTable table = testTableCreation();
+        final TreeTable.Node   root  = testNodeCreation(table);
+        testNodeDisplacement(root);
+        testSerialization(table);
     }
 
     /**

Added: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/collection/TableColumnTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/collection/TableColumnTest.java?rev=1412021&view=auto
==============================================================================
--- sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/collection/TableColumnTest.java
(added)
+++ sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/collection/TableColumnTest.java
Wed Nov 21 09:02:17 2012
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.util.collection;
+
+import java.util.Locale;
+import org.opengis.util.InternationalString;
+import org.junit.Test;
+import org.apache.sis.test.TestCase;
+
+import static org.apache.sis.test.Assert.*;
+import org.apache.sis.test.foreigner.SerializableTableColumn;
+import static org.apache.sis.util.collection.TableColumn.*;
+
+
+/**
+ * Tests the {@link TableColumn}.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.3
+ * @version 0.3
+ * @module
+ */
+public final strictfp class TableColumnTest extends TestCase {
+    /**
+     * Test the header of some constants.
+     */
+    @Test
+    public void testConstantHeader() {
+        InternationalString i18n = NAME.getHeader();
+        assertEquals("Name", i18n.toString(Locale.ENGLISH));
+        assertEquals("Nom",  i18n.toString(Locale.FRENCH));
+        assertSame("Test caching", i18n, NAME.getHeader());
+
+        i18n = TYPE.getHeader();
+        assertEquals("Type", i18n.toString(Locale.ENGLISH));
+        assertEquals("Type", i18n.toString(Locale.FRENCH));
+        assertSame("Test caching", i18n, TYPE.getHeader());
+    }
+
+    /**
+     * Tests the serialization of predefined constants.
+     */
+    @Test
+    public void testConstantSerialization() {
+        assertSame(NAME, assertSerializedEquals(NAME));
+        assertSame(TYPE, assertSerializedEquals(TYPE));
+    }
+
+    /**
+     * Tests the serialization of custom constants declared in a foreigner package.
+     */
+    @Test
+    public void testCustomSerialization() {
+        assertSame(SerializableTableColumn.LATITUDE,  assertSerializedEquals(SerializableTableColumn.LATITUDE));
+        assertSame(SerializableTableColumn.LONGITUDE, assertSerializedEquals(SerializableTableColumn.LONGITUDE));
+    }
+}

Propchange: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/collection/TableColumnTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/collection/TableColumnTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/collection/TreeTableFormatTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/collection/TreeTableFormatTest.java?rev=1412021&r1=1412020&r2=1412021&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/collection/TreeTableFormatTest.java
(original)
+++ sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/collection/TreeTableFormatTest.java
Wed Nov 21 09:02:17 2012
@@ -22,7 +22,7 @@ import org.apache.sis.test.TestCase;
 import org.apache.sis.test.DependsOn;
 
 import static org.apache.sis.test.Assert.*;
-import static org.apache.sis.util.collection.ColumnConstant.*;
+import static org.apache.sis.util.collection.TableColumn.*;
 
 
 /**
@@ -90,8 +90,8 @@ public final strictfp class TreeTableFor
      */
     @Test
     public void testTreeTableFormat() {
-        final StringColumn     valueA = new StringColumn("value #1");
-        final StringColumn     valueB = new StringColumn("value #2");
+        final TableColumn<String> valueA = new TableColumn<>(String.class, "value
#1");
+        final TableColumn<String> valueB = new TableColumn<>(String.class, "value
#2");
         final DefaultTreeTable table  = new DefaultTreeTable(NAME, valueA, valueB);
         final TreeTable.Node   root   = new DefaultTreeTable.Node(table);
         root.setValue(NAME,   "Node #1");



Mime
View raw message