sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1427048 - in /sis/branches/JDK7/sis-utility/src: main/java/org/apache/sis/util/collection/ test/java/org/apache/sis/util/collection/
Date Mon, 31 Dec 2012 07:36:15 GMT
Author: desruisseaux
Date: Mon Dec 31 07:36:15 2012
New Revision: 1427048

URL: http://svn.apache.org/viewvc?rev=1427048&view=rev
Log:
Added a newChild() method TreeTable.Node in order to avoid the need to use the implementation-specific
constructor.
Added a set of static methods in TreeTables and moved there the static toString(TreeTable)
method.

Added:
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTables.java
  (with props)
    sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/collection/TreeTablesTest.java
  (with props)
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/TreeTable.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java
    sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/collection/DefaultTreeTableTest.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=1427048&r1=1427047&r2=1427048&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
Mon Dec 31 07:36:15 2012
@@ -21,7 +21,6 @@ import java.util.Map;
 import java.util.LinkedHashMap;
 import java.util.Collections;
 import java.io.Serializable;
-import java.text.Format;
 import net.jcip.annotations.NotThreadSafe;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.resources.Errors;
@@ -50,19 +49,18 @@ import java.util.Objects;
  *
  *         public TreeTable createTable() {
  *             DefaultTreeTable table = new DefaultTreeTable(CITY_NAME, LATITUDE, LONGITUDE);
- *             TreeTable.Node   city  = new DefaultTreeTable.Node(table);
+ *             TreeTable.Node   city  = table.getRoot();
  *             city.setValue(CITY_NAME, "Rimouski");
  *             city.setValue(LATITUDE,   48.470417);
  *             city.setValue(LONGITUDE, -68.521385);
- *             table.setRoot(city);
  *             return table;
  *         }
  *     }
  * }
  *
- * {@code DefaultTreeTable} accepts arbitrary {@link TreeTable.Node} implementations.
- * However it is likely to be safer and more memory efficient when used together with
- * the implementation provided in the {@link Node} inner class.
+ * The {@code setRoot(…)} method accepts arbitrary {@link TreeTable.Node} implementations.
+ * However it is likely to be safer and more memory efficient when used together with the
+ * implementation provided in the {@link Node} inner class.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
@@ -77,11 +75,6 @@ public class DefaultTreeTable implements
     private static final long serialVersionUID = 1951201018202846555L;
 
     /**
-     * Shared {@code TreeTableFormat} instance for {@link #toString()} implementation.
-     */
-    private static Format format;
-
-    /**
      * The root node, or {@code null} if not yet specified.
      *
      * @see #getRoot()
@@ -103,8 +96,8 @@ public class DefaultTreeTable implements
      * map shall be read-only since many {@code Node} instances may share it.
      *
      * {@note This field and the {@link #columns} field could be computed from each other.
-     *        We serialize this field because children nodes will typically hold a reference
-     *        to that map, and we want to preserve the references tree.}
+     *        But we serialize this field anyway because children nodes will typically hold
+     *        a reference to that map, and we want to preserve the references tree.}
      *
      * @see DefaultTreeTable.Node#columnIndices
      */
@@ -121,9 +114,6 @@ public class DefaultTreeTable implements
      * Creates a new tree table with the given columns. The given array shall not be null
or
      * empty, and shall not contain null or duplicated elements.
      *
-     * <p>The {@linkplain #getRoot() root} node is initially {@code null}. Callers
can initialize
-     * it after construction time by a call to the {@link #setRoot(TreeTable.Node)} method.</p>
-     *
      * @param columns The list of table columns.
      */
     public DefaultTreeTable(TableColumn<?>... columns) {
@@ -202,13 +192,11 @@ public class DefaultTreeTable implements
      * Returns the root node. This method returns the node specified at
      * {@linkplain #DefaultTreeTable(Node) construction time} or to the
      * last call of the {@link #setRoot(TreeTable.Node)} method.
-     *
-     * @throws IllegalStateException If the root node has not yet been specified.
      */
     @Override
     public TreeTable.Node getRoot() {
         if (root == null) {
-            throw new IllegalStateException(Errors.format(Errors.Keys.NodeNotFound_1, "root"));
+            root = new Node(this);
         }
         return root;
     }
@@ -287,7 +275,7 @@ public class DefaultTreeTable implements
 
     /**
      * Returns a string representation of this tree table.
-     * The default implementation delegates to {@link #toString(TreeTable)}.
+     * The default implementation performs the same work than {@link TreeTables#toString(TreeTable)}.
      * This is okay for debugging or occasional usages. However for more extensive usages,
      * developers are encouraged to create and configure their own {@link TreeTableFormat}
      * instance.
@@ -296,25 +284,9 @@ public class DefaultTreeTable implements
      */
     @Override
     public String toString() {
-        return toString(this);
-    }
-
-    /**
-     * Returns a string representation of the given tree table.
-     * The default implementation uses a shared instance of {@link TreeTableFormat}.
-     * This is okay for debugging or occasional usages. However for more extensive usages,
-     * developers are encouraged to create and configure their own {@code TreeTableFormat}
-     * instance.
-     *
-     * @param  table The tree table to format.
-     * @return A string representation of the given tree table.
-     */
-    public static synchronized String toString(final TreeTable table) {
-        ArgumentChecks.ensureNonNull("table", table);
-        if (format == null) {
-            format = new TreeTableFormat(null, null);
+        synchronized (TreeTableFormat.INSTANCE) {
+            return TreeTableFormat.INSTANCE.format(this);
         }
-        return format.format(table);
     }
 
 
@@ -533,6 +505,24 @@ public class DefaultTreeTable implements
         }
 
         /**
+         * Adds a new child in the {@linkplain #getChildren() children list}.
+         * The default implementation delegates to {@link #Node(Node)}, which
+         * has the following implications:
+         *
+         * <ul>
+         *   <li>The new node inherits the columns of this node, on the assumption
that
+         *       they are the same set of columns than other children nodes.</li>
+         *   <li>The new node is appended at the end of the children list.</li>
+         * </ul>
+         *
+         * Subclasses may override this method with different behavior.
+         */
+        @Override
+        public Node newChild() {
+            return new Node(this);
+        }
+
+        /**
          * Returns the value in the given column, or {@code null} if none.
          *
          * @param  <V>    The base type of values in the given column.

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=1427048&r1=1427047&r2=1427048&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
Mon Dec 31 07:36:15 2012
@@ -100,7 +100,8 @@ import org.apache.sis.util.resources.Voc
 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},
+     * The column {@linkplain #getHeader() header} is "<cite>Name</cite>" (eventually
localized) and
+     * the column elements 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",
@@ -108,12 +109,31 @@ public class TableColumn<V> implements C
 
     /**
      * Frequently-used constant for a column of object types.
+     * The column {@linkplain #getHeader() header} is "<cite>Type</cite>" (eventually
localized).
      */
     @SuppressWarnings("unchecked")
     public static final TableColumn<Class<?>> TYPE = new Constant<>("TYPE",
             (Class) Class.class, Vocabulary.Keys.Type);
 
     /**
+     * Frequently-used constant for a column of object textual values.
+     * The column {@linkplain #getHeader() header} is "<cite>Value</cite>" (eventually
localized) and
+     * the column elements are typically instances of {@link String} or {@link InternationalString},
+     * depending on whether the data provide localization support or not.
+     */
+    @SuppressWarnings("unchecked")
+    public static final TableColumn<CharSequence> VALUE_AS_TEXT = new Constant<>("VALUE_AS_TEXT",
+            CharSequence.class, Vocabulary.Keys.Value);
+
+    /**
+     * Frequently-used constant for a column of object numerical values.
+     * The column {@linkplain #getHeader() header} is "<cite>Value</cite>" (eventually
localized).
+     */
+    @SuppressWarnings("unchecked")
+    public static final TableColumn<Number> VALUE_AS_NUMBER = new Constant<>("VALUE_AS_NUMBER",
+            Number.class, Vocabulary.Keys.Value);
+
+    /**
      * A map containing only the {@link #NAME} column.
      * This is the default set of columns when parsing a table tree.
      */

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTable.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTable.java?rev=1427048&r1=1427047&r2=1427048&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTable.java
(original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTable.java
Mon Dec 31 07:36:15 2012
@@ -103,7 +103,7 @@ public interface TreeTable {
      * <tr><td><ul>
      *   <li>{@link #getParent()}</li>
      *   <li>{@link #getChildren()}</li>
-     *   <li>{@link #getUserObject()}</li>
+     *   <li>{@link #newChild()}</li>
      * </ul></td>
      * <td><ul>
      *   <li>{@link #getValue(TableColumn)}</li>
@@ -112,6 +112,9 @@ public interface TreeTable {
      * </ul></td></tr>
      * </table>
      *
+     * In addition, each {@code Node} can be associated to an arbitrary object by the
+     * {@link #getUserObject()} method. This object is not used directly by the tree tables.
+     *
      * @author  Martin Desruisseaux (IRD, Geomatys)
      * @since   0.3 (derived from geotk-3.19)
      * @version 0.3
@@ -148,6 +151,16 @@ public interface TreeTable {
         List<Node> getChildren();
 
         /**
+         * Creates a new child with the same columns than the other children, and add it
to
+         * the {@linkplain #getChildren() children list}. The new child is typically added
at
+         * the end of the list, but this is not mandatory: implementations can add the child
+         * at whatever position they see fit.
+         *
+         * @return The new child.
+         */
+        Node newChild();
+
+        /**
          * Returns the value in the given column, or {@code null} if none.
          *
          * @param  <V>    The base type of values in the given column.

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=1427048&r1=1427047&r2=1427048&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
Mon Dec 31 07:36:15 2012
@@ -89,6 +89,12 @@ public class TreeTableFormat extends Tab
     private static final long serialVersionUID = -4476366905386037025L;
 
     /**
+     * Shared {@code TreeTableFormat} instance for {@link TreeTable#toString()} implementation.
+     * Usage of this instance shall be done in a synchronized block.
+     */
+    static final TreeTableFormat INSTANCE = new TreeTableFormat(null, null);
+
+    /**
      * The table columns to format, or {@code null} for formatting all of them.
      * This map shall not be modified after creation, because it may be shared
      * by many tables.

Added: 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=1427048&view=auto
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTables.java
(added)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTables.java
Mon Dec 31 07:36:15 2012
@@ -0,0 +1,284 @@
+/*
+ * 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.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Locale;
+import java.io.File;
+import java.nio.file.Path;
+import java.text.ParseException;
+import org.opengis.util.InternationalString;
+import org.apache.sis.util.Static;
+import org.apache.sis.util.ArgumentChecks;
+
+import static org.apache.sis.util.Arrays.resize;
+
+
+/**
+ * Static methods working on {@link TreeTable} objects and their nodes.
+ * This class provides methods for some tasks considered generic enough,
+ * and example codes for more specialized tasks that developers can customize.
+ *
+ * <p>The remaining of this class javadoc contains example codes placed in public domain.
+ * Developers can copy and adapt those examples as they see fit.</p>
+ *
+ * {@section Example 1: Reduce the depth of a tree}
+ * For every branch containing only one child and no value, the following method merges in-place
+ * that branch and the node together. This method can be used for simplifying depth trees
into
+ * something less verbose. However for any column other than {@code NAME}, this method preserves
+ * the values of the child node but lost all value of the parent node. For this reason, we
perform
+ * the merge only if the parent has no value.
+ *
+ * <p>For example given the tree on the left side, this method transforms it into the
tree on the
+ * right side:</p>
+ *
+ * <table class="compact"><tr><td>
+ * {@preformat text
+ *   root
+ *   ├───users
+ *   │   └───alice
+ *   │       ├───data
+ *   │       │   └───mercator
+ *   │       └───document
+ *   └───lib
+ * }
+ * </td><td>
+ * {@preformat text
+ *   root
+ *   ├───users/alice
+ *   │   ├───data/mercator
+ *   │   └───document
+ *   └───lib
+ * }
+ * </td></tr></table>
+ * {@preformat java
+ * import static org.apache.sis.util.collection.TableColumn.NAME;          // The column
to merge
+ * import static org.apache.sis.util.collection.TableColumn.VALUE_AS_TEXT; // The column
which must be empty
+ *
+ * public class MyClass {
+ *     private static TreeTable.Node concatenateSingletons(final TreeTable.Node node) {
+ *         final List<TreeTable.Node> children = node.getChildren();
+ *         final int size = children.size();
+ *         for (int i=0; i<size; i++) {
+ *             children.set(i, concatenateSingletons(children.get(i)));
+ *         }
+ *         if (size == 1) {
+ *             final TreeTable.Node child = children.get(0);
+ *             if (node.getValue(VALUE_AS_TEXT) == null) {
+ *                 children.remove(0);
+ *                 child.setValue(NAME, node.getValue(NAME) + File.separator + child.getValue(NAME));
+ *                 return child;
+ *             }
+ *         }
+ *         return node;
+ *     }
+ * }
+ *
+ * There is no pre-defined method for this task because there is too many parameters that
+ * developers may want to customize (columns to merge, conditions for accepting the merge,
+ * kind of objects to merge, name separator).
+ *
+ * @author  Martin Desruisseaux
+ * @since   0.3
+ * @version 0.3
+ * @module
+ */
+public final class TreeTables extends Static {
+    /**
+     * Do not allow instantiation of this class.
+     */
+    private TreeTables() {
+    }
+
+    /**
+     * Finds the node for the given path, or creates a new node if none exists.
+     * First, this method searches in the node {@linkplain TreeTable.Node#getChildren()
+     * children list} for the root element of the given path. If no such node is found,
+     * a {@linkplain TreeTable.Node#newChild() new child} is created. Then this method
+     * repeats the process (searching in the children of the child for the second path
+     * element), until the last path element is reached.
+     *
+     * <p>For example if the given path is {@code "users/alice/data"}, then this method
+     * finds or creates the nodes for the following tree, where {@code "from"} is the
+     * node given in argument to this method:</p>
+     *
+     * {@preformat text
+     *   from
+     *   └───users
+     *       └───alice
+     *           └───data
+     * }
+     *
+     * @param  from   The root node from which to start the search.
+     * @param  column The column containing the file name.
+     * @param  path   The path for which to find or create a node.
+     * @return The node for the given path, either as an existing node or a new node.
+     */
+    public static TreeTable.Node nodeForPath(TreeTable.Node from,
+            final TableColumn<? super String> column, final Path path)
+    {
+        final Path parent = path.getParent();
+        if (parent != null) {
+            from = nodeForPath(from, column, parent);
+        }
+        Path filename = path.getFileName();
+        if (filename == null) {
+            filename = path.getRoot();
+        }
+        final String name = filename.toString();
+        for (final TreeTable.Node child : from.getChildren()) {
+            if (name.equals(child.getValue(column))) {
+                return child;
+            }
+        }
+        from = from.newChild();
+        from.setValue(column, name);
+        return from;
+    }
+
+    /**
+     * Finds the node for the given file, or creates a new node if none exists.
+     * This method performs the same work than the above variant, but working on
+     * {@code File} instances rather than {@code Path}.
+     *
+     * @param  from   The root node from which to start the search.
+     * @param  column The column containing the file name.
+     * @param  path   The file for which to find or create a node.
+     * @return The node for the given file, either as an existing node or a new node.
+     */
+    public static TreeTable.Node nodeForPath(TreeTable.Node from,
+            final TableColumn<? super String> column, final File path)
+    {
+        final File parent = path.getParentFile();
+        if (parent != null) {
+            from = nodeForPath(from, column, parent);
+        }
+        String name = path.getName();
+        if (name.isEmpty() && parent == null) {
+            name = File.separator; // Root directory.
+        }
+        for (final TreeTable.Node child : from.getChildren()) {
+            if (name.equals(child.getValue(column))) {
+                return child;
+            }
+        }
+        from = from.newChild();
+        from.setValue(column, name);
+        return from;
+    }
+
+    /**
+     * For every columns having values {@linkplain Class#isAssignableFrom(Class) assignable
from}
+     * {@code String}, converts the values to {@code String}s. During conversions, this method
also
+     * replaces duplicated {@code String} instances by references to the same singleton instance.
+     *
+     * <p>This method may be invoked before to serialize the table in order to reduce
the
+     * serialization stream size.</p>
+     *
+     * @param  table  The table in which to replace values by their string representations.
+     * @param  locale The locale to use when replacing {@link InternationalString} instances.
Can be {@code null}.
+     * @return Number of replacements done.
+     */
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    public static int valuesAsStrings(final TreeTable table, final Locale locale) {
+        ArgumentChecks.ensureNonNull("table", table);
+        final List<TableColumn<?>> columns = table.getColumns();
+        TableColumn<? super String>[] filtered = new TableColumn[columns.size()];
+        int count = 0;
+        for (final TableColumn<?> column : columns) {
+            if (column.getElementType().isAssignableFrom(String.class)) {
+                filtered[count++] = (TableColumn<? super String>) column;
+            }
+        }
+        filtered = resize(filtered, count);
+        return valuesAsStrings(table.getRoot(), filtered, locale, new HashMap<String,String>());
+    }
+
+    /**
+     * Implementation of the public {@link #valuesAsStrings(TreeTable, Locale)} method.
+     *
+     * @param  node    The node in which to replace values by their string representations.
+     * @param  columns The columns where to perform the replacements.
+     * @param  locale  The locale to use when replacing {@link InternationalString} instances.
Can be {@code null}.
+     * @param  pool    An initially empty pool of string representations, to be filled by
this method.
+     * @return Number of replacements done.
+     */
+    private static int valuesAsStrings(final TreeTable.Node node, final TableColumn<?
super String>[] columns,
+            final Locale locale, final Map<String,String> pool)
+    {
+        int changes = 0;
+        for (final TreeTable.Node child : node.getChildren()) {
+            changes += valuesAsStrings(child, columns, locale, pool);
+        }
+        for (final TableColumn<? super String> column : columns) {
+            final Object value = node.getValue(column);
+            if (value != null) {
+                String text;
+                if (value instanceof InternationalString) {
+                    text = ((InternationalString) value).toString(locale);
+                } else {
+                    text = value.toString();
+                }
+                final String old = pool.put(text, text);
+                if (old != null) {
+                    pool.put(old, old);
+                    text = old;
+                }
+                if (text != value) {
+                    node.setValue(column, text);
+                    changes++;
+                }
+            }
+        }
+        return changes;
+    }
+
+    /**
+     * Returns a string representation of the given tree table.
+     * The default implementation uses a shared instance of {@link TreeTableFormat}.
+     * This is okay for debugging or occasional usages. However for more extensive usages,
+     * developers are encouraged to create and configure their own {@code TreeTableFormat}
+     * instance.
+     *
+     * @param  table The tree table to format.
+     * @return A string representation of the given tree table.
+     */
+    public static String toString(final TreeTable table) {
+        ArgumentChecks.ensureNonNull("table", table);
+        synchronized (TreeTableFormat.INSTANCE) {
+            return TreeTableFormat.INSTANCE.format(table);
+        }
+    }
+
+    /**
+     * Parses the given string as tree.
+     * This helper method is sometime useful for quick tests or debugging purposes.
+     * For more extensive use, consider using {@link TreeTableFormat} instead.
+     *
+     * @param  text The string representation to parse.
+     * @return A tree parsed from the given string.
+     * @throws ParseException If an error occurred while parsing the tree.
+     */
+    public static TreeTable parse(final String text) throws ParseException {
+        ArgumentChecks.ensureNonNull("text", text);
+        synchronized (TreeTableFormat.INSTANCE) {
+            return TreeTableFormat.INSTANCE.parseObject(text);
+        }
+    }
+}

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

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

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=1427048&r1=1427047&r2=1427048&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
Mon Dec 31 07:36:15 2012
@@ -55,13 +55,6 @@ public final strictfp class DefaultTreeT
         assertEquals("Index of first column:",  Integer.valueOf(0), table.columnIndices.get(NAME));
         assertEquals("Index of second column:", Integer.valueOf(1), table.columnIndices.get(TYPE));
         assertArrayEquals(new TableColumn<?>[] {NAME, TYPE}, table.getColumns().toArray());
-        try {
-            assertNull(table.getRoot());
-            fail("Expected an IllegalStateException.");
-        } catch (IllegalStateException e) {
-            // This is the expected exception.
-            assertTrue(e.getMessage().contains("root"));
-        }
         return table;
     }
 
@@ -89,7 +82,7 @@ public final strictfp class DefaultTreeT
          * Create a first child node, which should be added automatically
          * to the root list of children.
          */
-        final DefaultTreeTable.Node node1 = new DefaultTreeTable.Node(root);
+        final DefaultTreeTable.Node node1 = root.newChild();
         assertSame("Internal table sharing:",  table.columnIndices, node1.columnIndices);
         assertTrue("Initial children list:",   node1.getChildren().isEmpty());
         assertSame("Specified parent:",        root, node1.getParent());

Added: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/collection/TreeTablesTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/collection/TreeTablesTest.java?rev=1427048&view=auto
==============================================================================
--- sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/collection/TreeTablesTest.java
(added)
+++ sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/collection/TreeTablesTest.java
Mon Dec 31 07:36:15 2012
@@ -0,0 +1,172 @@
+/*
+ * 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.List;
+import java.io.File;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.text.ParseException;
+import org.junit.Test;
+import org.apache.sis.test.TestCase;
+import org.apache.sis.test.DependsOn;
+import org.apache.sis.util.iso.SimpleInternationalString;
+
+import static org.apache.sis.test.Assert.*;
+import static org.apache.sis.util.collection.TreeTables.*;
+import static org.apache.sis.util.collection.TableColumn.*;
+
+
+/**
+ * Tests the {@link TreeTables} class.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.3
+ * @version 0.3
+ * @module
+ */
+@DependsOn({
+    DefaultTreeTableTest.class,
+})
+public final strictfp class TreeTablesTest extends TestCase {
+    /**
+     * The example documented in the {@code TreeTable} javadoc.
+     *
+     * @param  node The root of the node to simplify.
+     * @return The root of the simplified tree. May be the given {@code node} or a child.
+     */
+    public static TreeTable.Node concatenateSingletons(final TreeTable.Node node) {
+        final List<TreeTable.Node> children = node.getChildren();
+        final int size = children.size();
+        for (int i=0; i<size; i++) {
+            children.set(i, concatenateSingletons(children.get(i)));
+        }
+        if (size == 1) {
+            final TreeTable.Node child = children.get(0);
+            if (node.getValue(VALUE_AS_TEXT) == null) {
+                children.remove(0);
+                child.setValue(NAME, node.getValue(NAME) + File.separator + child.getValue(NAME));
+                return child;
+            }
+        }
+        return node;
+    }
+
+    /**
+     * Tests the {@link #concatenateSingletons(TreeTable.Node)} example.
+     *
+     * @throws ParseException Should never happen.
+     */
+    @Test
+    public void testConcatenateSingletons() throws ParseException {
+        final TreeTable table = TreeTables.parse(
+                "root\n" +
+                "├───users\n" +
+                "│   └───alice\n" +
+                "│       ├───data\n" +
+                "│       │   └───mercator\n"
+
+                "│       └───document\n" +
+                "└───lib\n");
+        ((DefaultTreeTable) table).setRoot(concatenateSingletons(table.getRoot()));
+        assertMultilinesEquals(
+                "root\n" +
+                "├───users/alice\n" +
+                "│   ├───data/mercator\n" +
+                "│   └───document\n" +
+                "└───lib\n".replace("/", File.separator), table.toString());
+    }
+
+    /**
+     * Tests the {@link TreeTables#nodeForPath(TreeTable.Node, TableColumn, Path)} method.
+     */
+    @Test
+    public void testNodeForPath() {
+        final FileSystem fs = FileSystems.getDefault();
+        final TreeTable table = new DefaultTreeTable(NAME, VALUE_AS_NUMBER);
+        final TreeTable.Node files = table.getRoot();
+        files.setValue(NAME, "Root");
+        nodeForPath(files, NAME, fs.getPath("users","Alice","data"))           .setValue(VALUE_AS_NUMBER,
10);
+        nodeForPath(files, NAME, fs.getPath("users","Bob","data"))             .setValue(VALUE_AS_NUMBER,
20);
+        nodeForPath(files, NAME, fs.getPath("users","Bob"))                    .setValue(VALUE_AS_NUMBER,
30);
+        nodeForPath(files, NAME, fs.getPath("lib"))                            .setValue(VALUE_AS_NUMBER,
40);
+        nodeForPath(files, NAME, fs.getPath("users","Alice","document"))       .setValue(VALUE_AS_NUMBER,
50);
+        nodeForPath(files, NAME, fs.getPath("users","Alice","data","mercator")).setValue(VALUE_AS_NUMBER,
60);
+        assertMultilinesEquals(
+                "Root\n" +
+                "├───users\n" +
+                "│   ├───Alice\n" +
+                "│   │   ├───data…………………………
10\n" +
+                "│   │   │   └───mercator……
60\n" +
+                "│   │   └───document………………
50\n" +
+                "│   └───Bob………………………………………
30\n" +
+                "│       └───data…………………………
20\n" +
+                "└───lib…………………………………………………
40\n", table.toString());
+    }
+
+    /**
+     * Tests the {@link TreeTables#nodeForPath(TreeTable.Node, TableColumn, File)} method.
+     */
+    @Test
+    public void testNodeForPathAsFile() {
+        final TreeTable table = new DefaultTreeTable(NAME, VALUE_AS_NUMBER);
+        final TreeTable.Node files = table.getRoot();
+        files.setValue(NAME, "Root");
+        nodeForPath(files, NAME, new File("users/Alice/data"))         .setValue(VALUE_AS_NUMBER,
10);
+        nodeForPath(files, NAME, new File("users/Bob/data"))           .setValue(VALUE_AS_NUMBER,
20);
+        nodeForPath(files, NAME, new File("users/Bob"))                .setValue(VALUE_AS_NUMBER,
30);
+        nodeForPath(files, NAME, new File("lib"))                      .setValue(VALUE_AS_NUMBER,
40);
+        nodeForPath(files, NAME, new File("users/Alice/document"))     .setValue(VALUE_AS_NUMBER,
50);
+        nodeForPath(files, NAME, new File("users/Alice/data/mercator")).setValue(VALUE_AS_NUMBER,
60);
+        assertMultilinesEquals(
+                "Root\n" +
+                "├───users\n" +
+                "│   ├───Alice\n" +
+                "│   │   ├───data…………………………
10\n" +
+                "│   │   │   └───mercator……
60\n" +
+                "│   │   └───document………………
50\n" +
+                "│   └───Bob………………………………………
30\n" +
+                "│       └───data…………………………
20\n" +
+                "└───lib…………………………………………………
40\n", table.toString());
+    }
+
+    /**
+     * Tests the {@link TreeTables#valuesAsStrings(TreeTable, Locale)} method.
+     */
+    @Test
+    public void testValuesAsStrings() {
+        final TreeTable table = new DefaultTreeTable(NAME, VALUE_AS_NUMBER);
+        final TreeTable.Node root   = table .getRoot();
+        final TreeTable.Node parent = root  .newChild();
+        final TreeTable.Node child1 = parent.newChild();
+        final TreeTable.Node child2 = root  .newChild();
+        root  .setValue(NAME, new StringBuilder("Root"));
+        parent.setValue(NAME, "A parent");
+        child1.setValue(NAME, new StringBuilder("A child"));
+        child2.setValue(NAME, new SimpleInternationalString("A child"));
+        root  .setValue(VALUE_AS_NUMBER, 8);
+        parent.setValue(VALUE_AS_NUMBER, 4);
+
+        final String asString = table.toString();
+        assertEquals(3, valuesAsStrings(table, null));
+        assertInstanceOf("valuesAsStrings:", String.class, root  .getValue(NAME));
+        assertInstanceOf("valuesAsStrings:", String.class, parent.getValue(NAME));
+        assertInstanceOf("valuesAsStrings:", String.class, child1.getValue(NAME));
+        assertInstanceOf("valuesAsStrings:", String.class, child2.getValue(NAME));
+        assertSame("Expected unique instance of String.", child1.getValue(NAME), child2.getValue(NAME));
+        assertEquals("String representation shall be the same.", asString, table.toString());
+    }
+}

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

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



Mime
View raw message