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