org.geotoolkit.parameter.ParameterWriter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of geotk-referencing Show documentation
Show all versions of geotk-referencing Show documentation
Implementations of Coordinate Reference Systems (CRS),
conversion and transformation services derived from ISO 19111.
/*
* Geotoolkit.org - An Open Source Java GIS Toolkit
* http://www.geotoolkit.org
*
* (C) 2004-2011, Open Source Geospatial Foundation (OSGeo)
* (C) 2009-2011, Geomatys
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package org.geotoolkit.parameter;
import java.util.*;
import java.io.Writer;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.FilterWriter;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.text.DecimalFormat;
import java.lang.reflect.Array;
import javax.measure.unit.Unit;
import javax.measure.unit.UnitFormat;
import org.opengis.parameter.*;
import org.opengis.util.GenericName;
import org.opengis.referencing.IdentifiedObject;
import org.opengis.referencing.ReferenceIdentifier;
import org.opengis.referencing.operation.OperationMethod;
import org.geotoolkit.io.X364;
import org.geotoolkit.io.TableWriter;
import org.geotoolkit.lang.Decorator;
import org.geotoolkit.measure.Angle;
import org.geotoolkit.measure.AngleFormat;
import org.geotoolkit.resources.Vocabulary;
import org.geotoolkit.util.converter.Classes;
import org.geotoolkit.util.Localized;
import org.geotoolkit.internal.io.IOUtilities;
import static org.geotoolkit.io.TableWriter.*;
import static org.geotoolkit.util.collection.XCollections.hashMapCapacity;
/**
* Formats {@linkplain ParameterDescriptorGroup parameter descriptors} or
* {@linkplain ParameterValueGroup parameter values} in a tabular format.
* This writer assumes a monospaced font and an encoding capable to provide
* drawing box characters (e.g. unicode).
*
* @author Martin Desruisseaux (IRD, Geomatys)
* @version 3.17
*
* @since 2.1
* @module
*/
@Decorator(Writer.class)
public class ParameterWriter extends FilterWriter implements Localized {
/**
* Special authority name for requesting the display of EPSG codes.
*/
private static final String SHOW_EPSG_CODES = "EPSG:#";
/**
* If the identifier of only some authorities should be written, the authorities.
* Otherwise {@code null}.
*/
private Set scopes;
/**
* The locale.
*/
private Locale locale = Locale.getDefault();
/**
* The formatter to use for numbers. Will be created only when first needed.
*/
private transient NumberFormat numberFormat;
/**
* The formatter to use for dates. Will be created only when first needed.
*/
private transient DateFormat dateFormat;
/**
* The formatter to use for angles. Will be created only when first needed.
*/
private transient AngleFormat angleFormat;
/**
* {@code true} if we are allowed to invoke {@link DecimalFormat#setPositivePrefix}.
*/
private boolean canSetPositivePrefix;
/**
* {@code true} if the positive prefix should be set, if we are allowed to.
*/
private boolean wantPositivePrefix;
/**
* {@code true} if colors are allowed for an output on X3.64 compatible terminal.
*/
private boolean colorEnabled;
/**
* {@code true} if the table should be formatted in a brief format. If {@code true}, then
* for each descriptor only the {@linkplain IdentifiedObject#getName() name} is formatted;
* {@linkplain IdentifiedObject#getAlias() aliases} and {@linkplain IdentifiedObject#getIdentifiers()
* identifiers} are omitted. In addition, no line separator will be inserted between
* parameters since most parameters will fit on a single line.
*
* @since 3.17
*/
private boolean brief;
/**
* Creates a new formatter writing parameters to the {@linkplain System#console() console}
* if there is one, or to the {@linkplain System#out default output stream} otherwise. If
* the output is the console and the {@linkplain X364 X3.64} standard is enabled, then the
* default value of {@link #isColorEnabled()} will be {@code true}.
*/
public ParameterWriter() {
super(IOUtilities.standardWriter());
if (out instanceof PrintWriter) { // Implies out == System.console().writer();
colorEnabled = X364.isSupported();
}
}
/**
* Creates a new formatter writing parameters to the specified output writer.
*
* @param out Where to write the parameters.
*/
public ParameterWriter(final Writer out) {
super(out);
}
/**
* Prints the elements of an operation to the {@linkplain System#console() console} with colored
* syntax if possible, or to the {@linkplain System#out default output stream} otherwise.
* This is a convenience method for:
*
* {@preformat java
* new ParameterWriter().format(operation)
* }
*
* @param operation The operation for which to write the parameters.
*/
public static void print(final OperationMethod operation) {
final ParameterWriter writer = new ParameterWriter();
try {
writer.format(operation);
} catch (IOException exception) {
// Should never happen, since we are writing to System.out.
throw new AssertionError(exception);
}
}
/**
* Prints the elements of a descriptor group to the {@linkplain System#console() console} with
* colored syntax if possible, or to the {@linkplain System#out default output stream} otherwise.
* This is a convenience method for:
*
* {@preformat java
* new ParameterWriter().format(descriptor)
* }
*
* @param descriptor The parameter descriptor to write.
*/
public static void print(final ParameterDescriptorGroup descriptor) {
final ParameterWriter writer = new ParameterWriter();
try {
writer.format(descriptor);
} catch (IOException exception) {
// Should never happen, since we are writing to System.out.
throw new AssertionError(exception);
}
}
/**
* Prints the elements of a parameter group to the {@linkplain System#console() console} with
* colored syntax if possible, or to the {@linkplain System#out default output stream} otherwise.
* This is a convenience method for:
*
* {@preformat java
* new ParameterWriter().format(values)
* }
*
* @param values The parameter values to write.
*/
public static void print(final ParameterValueGroup values) {
final ParameterWriter writer = new ParameterWriter();
try {
writer.format(values);
} catch (IOException exception) {
// Should never happen, since we are writing to System.out.
throw new AssertionError(exception);
}
}
// There is no toString(OperationMethod) convenience method, because
// they already have a toString() implementation producing pseudo-WKT.
/**
* Returns a string representation of the given descriptor group in the
* {@linkplain #isBrief() brief} format. This is a convenience method for:
*
* {@preformat java
* StringWriter buffer = new StringWriter();
* ParameterWriter writer = new ParameterWriter(buffer);
* writer.setBrief(true);
* writer.format(descriptor);
* return buffer.toString();
* }
*
* @param descriptor The parameter descriptor to format.
* @return The string representation of the given parameter descriptor.
*
* @since 3.17
*/
public static String toString(final ParameterDescriptorGroup descriptor) {
final StringWriter buffer = new StringWriter();
final ParameterWriter writer = new ParameterWriter(buffer);
writer.brief = true;
try {
writer.format(descriptor);
} catch (IOException exception) {
// Should never happen, since we are writing to a StringBuffer.
throw new AssertionError(exception);
}
return buffer.toString();
}
/**
* Returns a string representation of the given parameter group in the
* {@linkplain #isBrief() brief} format. This is a convenience method for:
*
* {@preformat java
* StringWriter buffer = new StringWriter();
* ParameterWriter writer = new ParameterWriter(buffer);
* writer.setBrief(true);
* writer.format(values);
* return buffer.toString();
* }
*
* @param values The parameter values to format.
* @return The string representation of the given parameter values.
*
* @since 3.17
*/
public static String toString(final ParameterValueGroup values) {
final StringWriter buffer = new StringWriter();
final ParameterWriter writer = new ParameterWriter(buffer);
writer.brief = true;
try {
writer.format(values);
} catch (IOException exception) {
// Should never happen, since we are writing to a StringBuffer.
throw new AssertionError(exception);
}
return buffer.toString();
}
/**
* Prints the elements of an operation to the output stream.
*
* @param operation The operation method to format.
* @throws IOException if an error occurred will writing to the stream.
*/
public void format(final OperationMethod operation) throws IOException {
synchronized (lock) {
format(operation.getName().getCode(), operation.getParameters(), null);
}
}
/**
* Prints the elements of a descriptor group to the output stream.
*
* @param descriptor The descriptor group to format.
* @throws IOException if an error occurred will writing to the stream.
*/
public void format(final ParameterDescriptorGroup descriptor) throws IOException {
synchronized (lock) {
format(descriptor.getName().getCode(), descriptor, null);
}
}
/**
* Prints the elements of a parameter group to the output stream.
*
* @param values The parameter group to format.
* @throws IOException if an error occurred will writing to the stream.
*/
public void format(final ParameterValueGroup values) throws IOException {
final ParameterDescriptorGroup descriptor = values.getDescriptor();
synchronized (lock) {
format(descriptor.getName().getCode(), descriptor, values);
}
}
/**
* Implementation of public {@code format} methods.
*
* @param name The group name, usually {@code descriptor.getCode().getName()}.
* @param descriptor The parameter descriptor. Should be equal to
* {@code values.getDescriptor()} if {@code values} is non null.
* @param values The parameter values, or {@code null} if none.
* @throws IOException if an error occurred will writing to the stream.
*/
private void format(final String name, final ParameterDescriptorGroup group,
final ParameterValueGroup values) throws IOException
{
/*
* Gets the constants that are going to be used in the whole method. We get them as final
* local constants as a safety for protecting them from unintended changes. Then writes
* the operation name and its aliases. Those names are formatted before the table.
*/
final Writer out = this.out;
final Locale locale = this.locale;
final boolean brief = this.brief;
final boolean colorEnabled = this.colorEnabled;
final String lineSeparator = System.getProperty("line.separator", "\n");
final Vocabulary resources = Vocabulary.getResources(locale);
new ParameterTableRow(group, locale, null, brief).write(out, colorEnabled, false, lineSeparator);
out.write(lineSeparator);
/*
* Formats the table header (i.e. the column names).
*/
char horizontalLine = brief ? SINGLE_HORIZONTAL_LINE : DOUBLE_HORIZONTAL_LINE;
final TableWriter table = new TableWriter(out);
table.setMultiLinesCells(true);
table.nextLine(DOUBLE_HORIZONTAL_LINE);
header: for (int i=0; ; i++) {
boolean eol = false;
final int key;
switch (i) {
case 0: key = Vocabulary.Keys.NAME; break;
case 1: key = Vocabulary.Keys.TYPE; break;
case 2: key = Vocabulary.Keys.MINIMUM; break;
case 3: key = Vocabulary.Keys.MAXIMUM; break;
case 4: key = (values == null) ? Vocabulary.Keys.DEFAULT : Vocabulary.Keys.VALUE; break;
case 5: key = Vocabulary.Keys.UNITS; eol = true; break;
default: break header;
}
if (colorEnabled) table.write(X364.BOLD.sequence());
table.write(resources.getString(key));
if (colorEnabled) table.write(X364.NORMAL.sequence());
if (eol) table.nextLine();
else table.nextColumn();
}
/*
* Prepares the informations to be printed later as table rows. We scan all rows before
* to print them in order to compute the width of authority names. During this process,
* we split the objects to be printed later in two collections: simple parameters are
* stored as (descriptor,value) pairs, while groups are stored in an other collection
* for deferred printing after the simple parameters.
*/
int authorityLength = 0;
final Collection> elements = (values != null) ? values.values() : group.descriptors();
final Map descriptorValues =
new LinkedHashMap(
hashMapCapacity(elements.size()));
List