Package org.apache.sis.util.collection
Class TreeTableFormat
- All Implemented Interfaces:
Serializable,Cloneable,Localized
- Direct Known Subclasses:
MetadataFormat
A parser and formatter for
TreeTable instances.
This formatter is given an arbitrary number of TableColumns
to use during the formatting. The first column is taken as the node label.
If a TreeTable is formatted with only that column,
then the String result is like the following example:
If the same TreeTable is formatted with two columns,
then the String result is like the following example:
This representation can be printed to the console output
(for example) if the stream uses a monospaced font and supports Unicode characters.
Customization
Some formatting characteristics (indentation width, column where to draw the vertical line below nodes) can be modified by calls to the setter methods defined in this formatter. In particular, the dots joining the node labels to their values can be specified by the column separator pattern. The default pattern is"?……[…] ", which means "If the next value is non-null,
then insert the "……" string, repeat the '…' character as many time as needed
(may be zero), and finally insert a space".
Safety against infinite recursivity
SomeTreeTable implementations generate the nodes dynamically as wrappers around Java objects.
Such Java objects may contain cyclic associations (A contains B contains C
contains A), which result in a tree of infinite depth. Some examples can be found in ISO 19115
metadata. This TreeTableFormat class contains a safety against such cycles. The algorithm is based
on the assumption that for each node, the values and children are fully determined by the
user object, if non-null. Consequently, for each node C
to be formatted, if the user object of that node is the same instance (in the sense of the == operator)
than the user object of a parent node A, then the children of the C node will not be formatted.- Since:
- 0.3
- Version:
- 1.1
- See Also:
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprivate final classCreates string representation of the node values.Nested classes/interfaces inherited from class java.text.Format
Format.Field -
Field Summary
FieldsModifier and TypeFieldDescriptionprivate DecimalFormatA clone of the number format to be used with different settings (number of fraction digits, scientific notation).private Map<TableColumn<?>,Integer> The table columns to format, ornullfor formatting all of them.private StringThe default pattern used byadaptableFormat.private intThe number of characters to add on the left side for each indentation level.(package private) static final TreeTableFormatSharedTreeTableFormatinstance forDefaultTreeTable.toString()implementation.private Predicate<TreeTable.Node>A filter for specifying whether a node should be formatted, ornullif no filtering is applied.private Set<TreeTable.Node>The set to be given toTreeTableFormat.Writerconstructor, created when first needed and reused for subsequent formatting.private static final longFor cross-version compatibility.private StringThe tree symbols to write in the left margin, ornullif not yet computed.private StringThe tree symbols to write in the left margin, ornullif not yet computed.private StringThe tree symbols to write in the left margin, ornullif not yet computed.private StringThe tree symbols to write in the left margin, ornullif not yet computed.private booleanWhetheradaptableFormatis using scientific notation.private intThe position of the vertical line, relative to the position of the label of the parent node.Fields inherited from class org.apache.sis.io.TabularFormat
beforeFill, columnSeparator, fillCharacter, lineSeparator, omitTrailingNulls -
Constructor Summary
ConstructorsConstructorDescriptionTreeTableFormat(Locale locale, TimeZone timezone) Creates a new tree table format. -
Method Summary
Modifier and TypeMethodDescriptionprivate voidClears the symbols used when writing the tree.clone()Returns a clone of this format.protected FormatcreateFormat(Class<?> valueType) Creates a new format to use for parsing and formatting values of the given type.private voidvoidformat(TreeTable tree, Appendable toAppendTo) Writes a graphical representation of the specified tree table in the given stream or buffer.TableColumn<?>[]Returns the table columns to parse and format, ornullfor the default list of columns.private LocaleReturns the locale to use for code lists, international strings and localized messages of exceptions.(package private) final Format[]getFormats(TableColumn<?>[] columns, boolean mandatory) Returns the formats to use for parsing and formatting the values of each column.intReturns the number of spaces to add on the left margin for each indentation level.Returns the filter that specify whether a node should be formatted or ignored.(package private) final StringgetTreeSymbols(boolean isParent, boolean isLast) Returns the string to write before a node.Returns the type of objects formatted by this class.intReturns the position of the vertical line, relative to the position of the root label.parse(CharSequence text, ParsePosition pos) Creates a tree from the given character sequence, or returnsnullif the given text does not look like a tree for this method.private <V> voidparseValue(TreeTable.Node node, TableColumn<V> column, Format format, String text) Parses the given string using a format appropriate for the type of values in the given column, and stores the value in the given node.voidsetColumns(TableColumn<?>... columns) Sets the table columns to parse and format.voidsetIndentation(int indentation) Sets the number of spaces to add on the left margin for each indentation level.voidsetNodeFilter(Predicate<TreeTable.Node> filter) Sets a filter specifying whether a node should be formatted or ignored.voidsetVerticalLinePosition(int verticalLinePosition) Sets the position of the vertical line, relative to the position of the root label.protected voidwriteColumnSeparator(int nextColumn, TableAppender out) Writes characters between columns.Methods inherited from class org.apache.sis.io.TabularFormat
getColumnSeparatorMatcher, getColumnSeparatorPattern, getLineSeparator, setColumnSeparatorPattern, setLineSeparatorMethods inherited from class org.apache.sis.io.CompoundFormat
format, getFormat, getLocale, getLocale, getTimeZone, parseObject, parseObjectMethods inherited from class java.text.Format
format, formatToCharacterIterator
-
Field Details
-
serialVersionUID
private static final long serialVersionUIDFor cross-version compatibility.- See Also:
-
INSTANCE
SharedTreeTableFormatinstance forDefaultTreeTable.toString()implementation. Usage of this instance shall be done in a synchronized block. Note that metadata objects defined asAbstractMetadatasubclasses use their own format instance. -
columnIndices
The table columns to format, ornullfor formatting all of them. This map shall not be modified after creation, because it may be shared by many tables.- See Also:
-
indentation
private int indentationThe number of characters to add on the left side for each indentation level. The default value is 4.- See Also:
-
verticalLinePosition
private int verticalLinePositionThe position of the vertical line, relative to the position of the label of the parent node. The default value is 2, which means that the vertical line is drawn below the third letter of the node label. -
treeBlank
The tree symbols to write in the left margin, ornullif not yet computed. The default symbols are as below:treeBlank=" "treeLine=" │ "treeCross=" ├─"treeEnd=" └─"
- See Also:
-
treeLine
The tree symbols to write in the left margin, ornullif not yet computed. The default symbols are as below:treeBlank=" "treeLine=" │ "treeCross=" ├─"treeEnd=" └─"
- See Also:
-
treeCross
The tree symbols to write in the left margin, ornullif not yet computed. The default symbols are as below:treeBlank=" "treeLine=" │ "treeCross=" ├─"treeEnd=" └─"
- See Also:
-
treeEnd
The tree symbols to write in the left margin, ornullif not yet computed. The default symbols are as below:treeBlank=" "treeLine=" │ "treeCross=" ├─"treeEnd=" └─"
- See Also:
-
nodeFilter
A filter for specifying whether a node should be formatted, ornullif no filtering is applied. This is ignored at parsing time.- See Also:
-
recursivityGuard
The set to be given toTreeTableFormat.Writerconstructor, created when first needed and reused for subsequent formatting. -
adaptableFormat
A clone of the number format to be used with different settings (number of fraction digits, scientific notation). We use a clone for avoiding to change the setting of potentially user supplied number format. This is used only for floating point numbers, not for integers. -
defaultPattern
The default pattern used byadaptableFormat. Used for switching back to default mode after scientific notation. -
usingScientificNotation
private transient boolean usingScientificNotationWhetheradaptableFormatis using scientific notation.
-
-
Constructor Details
-
TreeTableFormat
Creates a new tree table format.- Parameters:
locale- the locale to use for numbers, dates and angles formatting, ornullfor the root locale.timezone- the timezone, ornullfor UTC.
-
-
Method Details
-
clearTreeSymbols
private void clearTreeSymbols()Clears the symbols used when writing the tree. They will be computed again when first needed.- See Also:
-
getValueType
Returns the type of objects formatted by this class.- Specified by:
getValueTypein classCompoundFormat<TreeTable>- Returns:
TreeTable.class
-
getColumns
Returns the table columns to parse and format, ornullfor the default list of columns. The default is:- On parsing, a single column containing the node label as a
String. - On formatting, all
TreeTablecolumns.
- Returns:
- the table columns to parse and format, or
nullfor the default.
- On parsing, a single column containing the node label as a
-
setColumns
Sets the table columns to parse and format. Anullvalue means to use the default list of columns, as defined in thegetColumns()method.- Parameters:
columns- the table columns to parse and format, ornullfor the default.- Throws:
IllegalArgumentException- if the given array is empty, contains a null element or a duplicated value.
-
getIndentation
public int getIndentation()Returns the number of spaces to add on the left margin for each indentation level. The default value is 4.- Returns:
- the current indentation.
-
setIndentation
Sets the number of spaces to add on the left margin for each indentation level. If the new indentation is smaller than the vertical line position, then the latter is also set to the given indentation value.- Parameters:
indentation- the new indentation.- Throws:
IllegalArgumentException- if the given value is negative.
-
getVerticalLinePosition
public int getVerticalLinePosition()Returns the position of the vertical line, relative to the position of the root label. The default value is 2, which means that the vertical line is drawn below the third letter of the root label.- Returns:
- the current vertical line position.
-
setVerticalLinePosition
Sets the position of the vertical line, relative to the position of the root label. The given value cannot be greater than the indentation.- Parameters:
verticalLinePosition- the new vertical line position.- Throws:
IllegalArgumentException- if the given value is negative or greater than the indentation.
-
getNodeFilter
Returns the filter that specify whether a node should be formatted or ignored. This is the predicate specified in the last call tosetNodeFilter(Predicate). If no filter has been set, then this method returnsnull.- Returns:
- a filter for specifying whether a node should be formatted, or
nullif no filtering is applied. - Since:
- 1.0
-
setNodeFilter
Sets a filter specifying whether a node should be formatted or ignored. Filters are tested at formatting time for all children of the root node (but not for the root node itself). Filters are ignored at parsing time.- Parameters:
filter- filter for specifying whether a node should be formatted, ornullfor no filtering.- Since:
- 1.0
-
getDisplayLocale
Returns the locale to use for code lists, international strings and localized messages of exceptions. -
getFormats
Returns the formats to use for parsing and formatting the values of each column. The returned array may containnullelements, which means that the values in that column can be stored asStrings.- Parameters:
mandatory-trueif an exception shall be thrown for unrecognized types, orfalsefor storing anullvalue in the array instead.- Throws:
IllegalStateException- ifmandatoryistrueand a column contains values of an unsupported type.
-
parse
Creates a tree from the given character sequence, or returnsnullif the given text does not look like a tree for this method. This method can parse the trees created by theformat(…)methods defined in this class.Parsing rules
- Each node shall be represented by a single line made of two parts, in that order:
- white spaces and tree drawing characters (
'│','├','└'or'─'); - string representations of node values, separated by the colunm separator.
- white spaces and tree drawing characters (
- The number of spaces and drawing characters before the node values determines the node
indentation. This indentation does not need to be a factor of the
getIndentation()value, but must be consistent across all the parsed tree. - The indentation determines the parent of each node.
- Parsing stops at first empty line (ignoring whitespaces), or at the end of the given text.
Error index
If the given text does not seem to be a tree table, then this method returnsnull. Otherwise if parsing started but failed, then:ParsePosition.getErrorIndex()will give the index at the beginning of line or beginning of cell where the error occurred, andParseException.getErrorOffset()will give either the same value, or a slightly more accurate value inside the cell.
- Specified by:
parsein classCompoundFormat<TreeTable>- Parameters:
text- the character sequence for the tree to parse.pos- the position where to start the parsing.- Returns:
- the parsed tree, or
nullif the given character sequence cannot be parsed. - Throws:
ParseException- if an error occurred while parsing a node value.
- Each node shall be represented by a single line made of two parts, in that order:
-
parseValue
private <V> void parseValue(TreeTable.Node node, TableColumn<V> column, Format format, String text) throws ParseException Parses the given string using a format appropriate for the type of values in the given column, and stores the value in the given node.This work is done in a separated method instead of inlined in the
parse(…)method because of the<V>parametric value.- Type Parameters:
V- the type of values in the given column.- Parameters:
node- the node in which to set the value.column- the column in which to set the value.format- the format to use for parsing the value, ornull.text- the textual representation of the value.- Throws:
ParseException- if an error occurred while parsing.ClassCastException- if the parsed value is not of the expected type.
-
createTreeSymbols
private void createTreeSymbols()- See Also:
-
getTreeSymbols
Returns the string to write before a node.- Parameters:
isParent-truefor a parent node, orfalsefor the actual node.isLast-trueif the node is the last children of its parent node.
-
format
Writes a graphical representation of the specified tree table in the given stream or buffer. This method iterates recursively over all children. For each column to format in each node, this method gets a textual representation of the value in that column using the formatter obtained by a call toCompoundFormat.getFormat(Class).- Specified by:
formatin classCompoundFormat<TreeTable>- Parameters:
tree- the tree to format.toAppendTo- where to format the tree.- Throws:
IOException- if an error occurred while writing to the given appendable.- See Also:
-
createFormat
Creates a new format to use for parsing and formatting values of the given type. This method is invoked the first time that a format is needed for the given type. Subclasses can override this method if they want to configure the way dates, numbers or other objects are formatted. See parent class documentation for more information.The implementation in
TreeTableFormatdiffers from the default implementation in the following aspects:UnitFormatusesUnitFormat.Style.NAME.
- Overrides:
createFormatin classCompoundFormat<TreeTable>- Parameters:
valueType- the base type of values to parse or format.- Returns:
- the format to use for parsing of formatting values of the given type, or
nullif none.
-
writeColumnSeparator
Writes characters between columns. The default implementation applies the configuration specified byTabularFormat.setColumnSeparatorPattern(String)as below:
The output with default values is like below: Subclasses can override this method if different column separators are desired. Note however that doing so may prevent theout.append(beforeFill); out.nextColumn(fillCharacter); out.append(columnSeparator);parse(…)method to work.- Parameters:
nextColumn- zero-based index of the column to be written after the separator.out- where to write the column separator.- Since:
- 1.0
- See Also:
-
clone
Returns a clone of this format.- Overrides:
clonein classTabularFormat<TreeTable>- Returns:
- a clone of this format.
-