You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2014/05/16 16:50:31 UTC
svn commit: r1595219 - in /sis/branches/JDK8/core:
sis-feature/src/main/java/org/apache/sis/feature/
sis-feature/src/test/java/org/apache/sis/feature/
sis-feature/src/test/java/org/apache/sis/test/suite/
sis-referencing/src/main/java/org/apache/sis/par...
Author: desruisseaux
Date: Fri May 16 14:50:30 2014
New Revision: 1595219
URL: http://svn.apache.org/r1595219
Log:
Implemented the String representation of Feature in a tabular format.
Added:
sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureFormat.java
- copied, changed from r1595029, sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterFormat.java
sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/FeatureFormatTest.java (with props)
Modified:
sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAssociation.java
sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAssociationRole.java
sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeature.java
sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeatureType.java
sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/FieldType.java
sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultAssociationTest.java
sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultFeatureTest.java
sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/test/suite/FeatureTestSuite.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterFormat.java
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/io/CompoundFormat.java
Modified: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAssociation.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAssociation.java?rev=1595219&r1=1595218&r2=1595219&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAssociation.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAssociation.java [UTF-8] Fri May 16 14:50:30 2014
@@ -223,7 +223,7 @@ public class DefaultAssociation extends
@Debug
@Override
public String toString() {
- final StringBuilder buffer = role.toString("FeatureAssociation", role.getValueType().getName().toString());
+ final StringBuilder buffer = role.toString("FeatureAssociation", role.getValueType().getName());
if (value != null) {
final String pt = role.getTitleProperty();
if (pt != null) {
Modified: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAssociationRole.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAssociationRole.java?rev=1595219&r1=1595218&r2=1595219&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAssociationRole.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultAssociationRole.java [UTF-8] Fri May 16 14:50:30 2014
@@ -212,6 +212,6 @@ public class DefaultAssociationRole exte
@Debug
@Override
public String toString() {
- return toString("FeatureAssociationRole", valueType.getName().toString()).toString();
+ return toString("FeatureAssociationRole", valueType.getName()).toString();
}
}
Modified: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeature.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeature.java?rev=1595219&r1=1595218&r2=1595219&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeature.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeature.java [UTF-8] Fri May 16 14:50:30 2014
@@ -22,7 +22,6 @@ import java.util.ConcurrentModificationE
import java.io.Serializable;
import org.opengis.metadata.quality.DataQuality;
import org.opengis.metadata.maintenance.ScopeCode;
-import org.apache.sis.util.Debug;
import org.apache.sis.util.ArgumentChecks;
import org.apache.sis.util.resources.Errors;
import org.apache.sis.util.collection.Containers;
@@ -206,8 +205,12 @@ public class DefaultFeature implements S
if (element != null) {
if (!propertiesAreInstantiated) {
return element;
- } else {
+ } else if (element instanceof DefaultAttribute<?>) {
return ((DefaultAttribute<?>) element).getValue();
+ } else if (element instanceof DefaultAssociation) {
+ return ((DefaultAssociation) element).getValue();
+ } else {
+ throw new UnsupportedOperationException(Errors.format(Errors.Keys.UnknownType_1, element.getClass()));
}
} else if (properties.containsKey(name)) {
return null; // Null has been explicitely set.
@@ -215,8 +218,10 @@ public class DefaultFeature implements S
final PropertyType pt = getPropertyType(name);
if (pt instanceof DefaultAttributeType<?>) {
return ((DefaultAttributeType<?>) pt).getDefaultValue();
+ } else if (pt instanceof DefaultAssociationRole) {
+ return null;
} else {
- throw new UnsupportedOperationException(); // TODO
+ throw new UnsupportedOperationException(Errors.format(Errors.Keys.UnknownType_1, pt.getClass()));
}
}
}
@@ -283,17 +288,29 @@ public class DefaultFeature implements S
}
/**
- * Returns {@code true} if the given type is an attribute type, and if the given value
- * is valid for that attribute type.
+ * Returns {@code true} if the given type is an attribute type or association role,
+ * and if the given value is valid for that type or role.
*/
private static boolean isValidAttributeValue(final PropertyType type, final Object value) {
- if (!(type instanceof DefaultAttributeType<?>)) {
- return false;
+ if (type instanceof DefaultAttributeType<?>) {
+ if (value == null) {
+ return true;
+ }
+ if (((DefaultAttributeType<?>) type).getValueClass().isInstance(value)) {
+ return true;
+ }
}
- if (value == null) {
- return true;
+ if (type instanceof DefaultAssociationRole) {
+ if (value == null) {
+ return true;
+ }
+ if (value instanceof DefaultFeature) {
+ if (((DefaultAssociationRole) type).getValueType().maybeAssignableFrom(((DefaultFeature) value).getType())) {
+ return true;
+ }
+ }
}
- return ((DefaultAttributeType<?>) type).getValueClass().isInstance(value);
+ return false;
}
/**
@@ -386,27 +403,14 @@ public class DefaultFeature implements S
}
/**
- * Returns a string representation of this feature.
- * The returned string is for debugging purpose and may change in any future SIS version.
+ * Formats this feature in a tabular format.
+ *
+ * @return A string representation of this feature in a tabular format.
*
- * @return A string representation of this feature for debugging purpose.
+ * @see FeatureFormat
*/
- @Debug
@Override
public String toString() {
- final StringBuilder sb = new StringBuilder();
- final String lineSeparator = System.lineSeparator();
- for (final Map.Entry<String,Object> entry : properties.entrySet()) {
- final PropertyType pt;
- Object element = entry.getValue();
- if (propertiesAreInstantiated) {
- pt = ((DefaultAttribute<?>) element).getType();
- element = ((DefaultAttribute<?>) element).getValue();
- } else {
- pt = type.getProperty(entry.getKey());
- }
- sb.append(pt.getName()).append(": ").append(element).append(lineSeparator);
- }
- return sb.toString();
+ return FeatureFormat.sharedFormat(this);
}
}
Modified: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeatureType.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeatureType.java?rev=1595219&r1=1595218&r2=1595219&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeatureType.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeatureType.java [UTF-8] Fri May 16 14:50:30 2014
@@ -538,4 +538,16 @@ public class DefaultFeatureType extends
}
return false;
}
+
+ /**
+ * Formats this feature in a tabular format.
+ *
+ * @return A string representation of this feature in a tabular format.
+ *
+ * @see FeatureFormat
+ */
+ @Override
+ public String toString() {
+ return FeatureFormat.sharedFormat(this);
+ }
}
Copied: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureFormat.java (from r1595029, sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterFormat.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureFormat.java?p2=sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureFormat.java&p1=sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterFormat.java&r1=1595029&r2=1595219&rev=1595219&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterFormat.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureFormat.java [UTF-8] Fri May 16 14:50:30 2014
@@ -14,15 +14,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.sis.parameter;
+package org.apache.sis.feature;
-import java.util.Map;
-import java.util.Set;
-import java.util.List;
-import java.util.Arrays;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.TimeZone;
import java.io.IOException;
@@ -30,202 +23,40 @@ import java.text.Format;
import java.text.FieldPosition;
import java.text.ParsePosition;
import java.text.ParseException;
-import java.io.Console;
import java.util.concurrent.atomic.AtomicReference;
-import javax.measure.unit.Unit;
-
-import org.opengis.parameter.*;
-import org.opengis.util.ScopedName;
+import org.opengis.util.InternationalString;
import org.opengis.util.GenericName;
-import org.opengis.referencing.IdentifiedObject;
-import org.opengis.referencing.ReferenceIdentifier;
-import org.opengis.referencing.operation.OperationMethod;
-
-import org.apache.sis.measure.Range;
-import org.apache.sis.io.wkt.Colors;
import org.apache.sis.io.TableAppender;
import org.apache.sis.io.TabularFormat;
-import org.apache.sis.util.CharSequences;
import org.apache.sis.util.ArgumentChecks;
import org.apache.sis.util.resources.Errors;
import org.apache.sis.util.resources.Vocabulary;
-import org.apache.sis.referencing.IdentifiedObjects;
-import org.apache.sis.internal.referencing.NameToIdentifier;
-import org.apache.sis.internal.util.CollectionsExt;
import org.apache.sis.internal.util.X364;
-import static org.apache.sis.util.collection.Containers.hashMapCapacity;
-
/**
- * Formats {@linkplain DefaultParameterDescriptorGroup parameter descriptors} or
- * {@linkplain DefaultParameterValueGroup parameter values} in a tabular format.
- * This format assumes a monospaced font and an encoding supporting drawing box
- * characters (e.g. UTF-8).
- *
- * <p>This class can format parameters with different levels of verbosity, specified by the {@link ContentLevel}
- * property. The content level controls whether the formatter should write all names and aliases (at the cost of
- * multi-line rows), or to pickup one name per parameter for a more compact table. See {@link ContentLevel}
- * javadoc for output examples.</p>
- *
- * <div class="note"><b>Example:</b>
- * The <cite>Mercator (variant A)</cite> example given in {@link DefaultParameterDescriptorGroup} javadoc
- * will be formatted by default as below:
- *
- * {@preformat text
- * EPSG: Mercator (variant A)
- * ┌────────────────────────────────┬────────┬────────────┬───────────────┬───────────────┐
- * │ Name (EPSG) │ Type │ Obligation │ Value domain │ Default value │
- * ├────────────────────────────────┼────────┼────────────┼───────────────┼───────────────┤
- * │ Latitude of natural origin │ Double │ Mandatory │ [-80 … 84]° │ 0.0° │
- * │ Longitude of natural origin │ Double │ Mandatory │ [-180 … 180]° │ 0.0° │
- * │ Scale factor at natural origin │ Double │ Mandatory │ (0 … ∞) │ 1.0 │
- * │ False easting │ Double │ Mandatory │ (-∞ … ∞) m │ 0.0 m │
- * │ False northing │ Double │ Mandatory │ (-∞ … ∞) m │ 0.0 m │
- * └────────────────────────────────┴────────┴────────────┴───────────────┴───────────────┘
- * }
- * </div>
- *
- * The kind of objects accepted by this formatter are:
- * <table class="sis">
- * <caption>Formattable object types</caption>
- * <tr><th>Class</th> <th>Remarks</th></tr>
- * <tr><td>{@link ParameterValueGroup}</td><td><cite>Default values</cite> column is replaced by a column of the actual values.</td></tr>
- * <tr><td>{@link ParameterDescriptorGroup}</td><td>Table title is the parameter group name.</td></tr>
- * <tr><td>{@link OperationMethod}</td><td>Table title is the method name (not necessarily the same than parameter group name).</td></tr>
- * <tr><td><code>{@linkplain IdentifiedObject}[]</code></td><td>Accepted only for {@link ContentLevel#NAME_SUMMARY}.</td></tr>
- * </table>
+ * Formats {@linkplain DefaultFeature features} or {@linkplain DefaultFeatureType feature types} in a tabular format.
+ * This format assumes a monospaced font and an encoding supporting drawing box characters (e.g. UTF-8).
*
* <div class="warning"><b>Limitation:</b>
* Current implementation supports only formatting, not parsing.
* </div>
*
- * @author Martin Desruisseaux (IRD, Geomatys)
- * @since 0.4 (derived from geotk-2.1)
- * @version 0.4
+ * @author Martin Desruisseaux (Geomatys)
+ * @since 0.5
+ * @version 0.5
* @module
*/
-public class ParameterFormat extends TabularFormat<Object> {
+public class FeatureFormat extends TabularFormat<Object> {
/**
* For cross-version compatibility.
*/
- private static final long serialVersionUID = -1345231739800152411L;
+ private static final long serialVersionUID = 8866440357566645070L;
/**
* An instance created when first needed and potentially shared.
*/
- private static final AtomicReference<ParameterFormat> INSTANCE = new AtomicReference<>();
-
- /**
- * The default column separator. User can change the separator
- * by a call to {@link #setColumnSeparatorPattern(String)}.
- */
- private static final String SEPARATOR = " │ ";
-
- /**
- * The amount of information to include in the table formatted by {@link ParameterFormat}.
- * The content level controls whether the formatter should write all names and aliases
- * (at the cost of multi-line rows), or to pickup one name per parameter for a more compact table.
- *
- * <p>The enumeration value javadoc provide examples of formatting output.</p>
- *
- * @since 0.4
- * @version 0.4
- * @module
- */
- public static enum ContentLevel {
- /**
- * The most detailed content, which includes
- * {@linkplain org.apache.sis.referencing.AbstractIdentifiedObject#getName() name} and
- * {@linkplain org.apache.sis.referencing.AbstractIdentifiedObject#getAlias() aliases}.
- * Each parameter may be formatted on many lines if they have aliases.
- *
- * <div class="note"><b>Example:</b>
- * The <cite>Mercator (variant A)</cite> example given in {@link DefaultParameterDescriptorGroup} javadoc,
- * (augmented with parameter aliases) formatted at this level produces a text like below:
- *
- * {@preformat text
- * EPSG: Mercator (variant A) (9804)
- * EPSG: Mercator (1SP)
- * OGC: Mercator_1SP
- * ╔══════════════════════════════════════╤════════╤════════════╤═══════════════╤═══════════════╗
- * ║ Name │ Type │ Obligation │ Value domain │ Default value ║
- * ╟──────────────────────────────────────┼────────┼────────────┼───────────────┼───────────────╢
- * ║ EPSG: Latitude of natural origin │ Double │ Mandatory │ [-80 … 84]° │ 0.0° ║
- * ║ OGC: latitude_of_origin │ │ │ │ ║
- * ╟──────────────────────────────────────┼────────┼────────────┼───────────────┼───────────────╢
- * ║ EPSG: Longitude of natural origin │ Double │ Mandatory │ [-180 … 180]° │ 0.0° ║
- * ║ OGC: central_meridian │ │ │ │ ║
- * ╟──────────────────────────────────────┼────────┼────────────┼───────────────┼───────────────╢
- * ║ EPSG: Scale factor at natural origin │ Double │ Mandatory │ (0 … ∞) │ 1.0 ║
- * ║ OGC: scale_factor │ │ │ │ ║
- * ╟──────────────────────────────────────┼────────┼────────────┼───────────────┼───────────────╢
- * ║ EPSG: False easting │ Double │ Mandatory │ (-∞ … ∞) m │ 0.0 m ║
- * ║ OGC: false_easting │ │ │ │ ║
- * ╟──────────────────────────────────────┼────────┼────────────┼───────────────┼───────────────╢
- * ║ EPSG: False northing │ Double │ Mandatory │ (-∞ … ∞) m │ 0.0 m ║
- * ║ OGC: false_northing │ │ │ │ ║
- * ╚══════════════════════════════════════╧════════╧════════════╧═══════════════╧═══════════════╝
- * }
- * </div>
- */
- DETAILED,
-
- /**
- * A medium level of content which formats each parameter on a single line. For each parameter only the
- * {@linkplain org.apache.sis.referencing.AbstractIdentifiedObject#getName() name} is formatted —
- * {@linkplain org.apache.sis.referencing.AbstractIdentifiedObject#getAlias() aliases} and
- * {@linkplain org.apache.sis.referencing.AbstractIdentifiedObject#getIdentifiers() identifiers} are omitted.
- *
- * <div class="note"><b>Example:</b>
- * The <cite>Mercator (variant A)</cite> example given in {@link DefaultParameterDescriptorGroup} javadoc
- * formatted at this level produces a text like below:
- *
- * {@preformat text
- * EPSG: Mercator (variant A)
- * ┌────────────────────────────────┬────────┬────────────┬───────────────┬───────────────┐
- * │ Name (EPSG) │ Type │ Obligation │ Value domain │ Default value │
- * ├────────────────────────────────┼────────┼────────────┼───────────────┼───────────────┤
- * │ Latitude of natural origin │ Double │ Mandatory │ [-80 … 84]° │ 0.0° │
- * │ Longitude of natural origin │ Double │ Mandatory │ [-180 … 180]° │ 0.0° │
- * │ Scale factor at natural origin │ Double │ Mandatory │ (0 … ∞) │ 1.0 │
- * │ False easting │ Double │ Mandatory │ (-∞ … ∞) m │ 0.0 m │
- * │ False northing │ Double │ Mandatory │ (-∞ … ∞) m │ 0.0 m │
- * └────────────────────────────────┴────────┴────────────┴───────────────┴───────────────┘
- * }
- * </div>
- */
- BRIEF,
-
- /**
- * Limits the content to names and aliases in a tabular format. In addition to parameters,
- * this level can also format array of operation method, coordinate reference system, <i>etc.</i>
- * The summary contains the identifier names and aliases aligned in a table.
- *
- * <div class="note"><b>Example:</b>
- * The <cite>Mercator (variant A)</cite> example given in {@link ParameterBuilder} javadoc
- * formatted at this level produces a text like below:
- *
- * {@preformat text
- * EPSG: Mercator (variant A)
- * ┌────────────────────────────────┬────────────────────┐
- * │ EPSG │ OGC │
- * ├────────────────────────────────┼────────────────────┤
- * │ Latitude of natural origin │ latitude_of_origin │
- * │ Longitude of natural origin │ central_meridian │
- * │ Scale factor at natural origin │ scale_factor │
- * │ False easting │ false_easting │
- * │ False northing │ false_northing │
- * └────────────────────────────────┴────────────────────┘
- * }
- * </div>
- *
- * <p><b>Tip:</b> The table formatted by default may be quite large. It is recommended to invoke
- * {@link ParameterFormat#setPreferredCodespaces(String[])} before to format in order to reduce the
- * amount of columns to display.</p>
- */
- NAME_SUMMARY
- }
+ private static final AtomicReference<FeatureFormat> INSTANCE = new AtomicReference<>();
/**
* The locale for international strings.
@@ -233,34 +64,12 @@ public class ParameterFormat extends Tab
private final Locale displayLocale;
/**
- * The amount of information to put in the table.
- *
- * @see #getContentLevel()
- */
- private ContentLevel contentLevel = ContentLevel.BRIEF;
-
- /**
- * If the identifier should be written only for some code spaces, those code spaces.
- * Otherwise {@code null}.
- *
- * @see #getPreferredCodespaces()
- */
- private Set<String> preferredCodespaces;
-
- /**
- * The colors for an output on X3.64 compatible terminal, or {@code null} if none.
- *
- * @see #getColors()
- */
- private Colors colors;
-
- /**
* Creates a new formatter for the default locale and timezone.
*/
- public ParameterFormat() {
+ public FeatureFormat() {
super(Locale.getDefault(Locale.Category.FORMAT), TimeZone.getDefault());
displayLocale = Locale.getDefault(Locale.Category.DISPLAY);
- columnSeparator = SEPARATOR;
+ columnSeparator = " │ ";
}
/**
@@ -269,15 +78,15 @@ public class ParameterFormat extends Tab
* @param locale The locale, or {@code null} for {@code Locale.ROOT}.
* @param timezone The timezone, or {@code null} for UTC.
*/
- public ParameterFormat(final Locale locale, final TimeZone timezone) {
+ public FeatureFormat(final Locale locale, final TimeZone timezone) {
super(locale, timezone);
displayLocale = (locale != null) ? locale : Locale.ROOT;
- columnSeparator = SEPARATOR;
+ columnSeparator = " │ ";
}
/**
* Returns the type of objects formatted by this class. This method has to return {@code Object.class}
- * since it is the only common parent to all object types accepted by this formatter.
+ * since it is the only common parent to {@link Feature} and {@link FeatureType}.
*
* @return {@code Object.class}
*/
@@ -303,82 +112,6 @@ public class ParameterFormat extends Tab
}
/**
- * Returns the amount of information to put in the table.
- * The default value is {@link ContentLevel#BRIEF}.
- *
- * @return The table content.
- */
- public ContentLevel getContentLevel() {
- return contentLevel;
- }
-
- /**
- * Sets the amount of information to put in the table.
- *
- * @param level The amount of information to put in the table.
- */
- public void setContentLevel(final ContentLevel level) {
- ArgumentChecks.ensureNonNull("level", level);
- this.contentLevel = level;
- }
-
- /**
- * Returns the code spaces of names, aliases and identifiers to show, or {@code null} if there is no restriction.
- * This method returns the sequence specified by the last call to {@link #setPreferredCodespaces(String[])},
- * without duplicated values.
- *
- * <p>The default value is {@code null}.</p>
- *
- * @return The code spaces of names and identifiers to show, or {@code null} if no restriction.
- */
- public String[] getPreferredCodespaces() {
- return (preferredCodespaces != null) ? preferredCodespaces.toArray(new String[preferredCodespaces.size()]) : null;
- }
-
- /**
- * Filters names, aliases and identifiers by their code spaces. If the given array is non-null, then the only names,
- * aliases and identifiers to be formatted are those having a {@link ReferenceIdentifier#getCodeSpace()},
- * {@link ScopedName#head()} or {@link GenericName#scope()} value in the given list, unless no name or alias
- * matches this criterion.
- *
- * @param codespaces The preferred code spaces of names, aliases and identifiers to format, or {@code null}
- * for accepting all of them. Some typical values are {@code "EPSG"}, {@code "OGC"} or {@code "GeoTIFF"}.
- */
- public void setPreferredCodespaces(final String... codespaces) {
- Set<String> copy = null;
- if (codespaces != null) {
- copy = CollectionsExt.immutableSet(true, codespaces);
- }
- this.preferredCodespaces = copy;
- }
-
- /**
- * Returns {@code true} if a name, alias or identifier in the given codespace should be formatted.
- */
- private boolean isPreferredCodespace(final String codespace) {
- return (preferredCodespaces == null) || preferredCodespaces.contains(codespace);
- }
-
- /**
- * Returns the colors for an output on X3.64 compatible terminal, or {@code null} if none.
- * The default value is {@code null}.
- *
- * @return The colors for an output on X3.64 compatible terminal, or {@code null} if none.
- */
- public Colors getColors() {
- return colors;
- }
-
- /**
- * Sets the colors for an output on X3.64 compatible terminal.
- *
- * @param colors The colors for an output on X3.64 compatible terminal, or {@code null} if none.
- */
- public void setColors(final Colors colors) {
- this.colors = colors;
- }
-
- /**
* Invoked when the formatter needs to move to the next column.
*/
private void nextColumn(final TableAppender table) {
@@ -391,10 +124,8 @@ public class ParameterFormat extends Tab
* The object may be an instance of any of the following types:
*
* <ul>
- * <li>{@link ParameterValueGroup}</li>
- * <li>{@link ParameterDescriptorGroup}</li>
- * <li>{@link OperationMethod}</li>
- * <li><code>{@linkplain IdentifiedObject}[]</code> — accepted only for {@link ContentLevel#NAME_SUMMARY}.</li>
+ * <li>{@link Feature}</li>
+ * <li>{@link FeatureType}</li>
* </ul>
*
* @throws IOException If an error occurred while writing to the given appendable.
@@ -403,506 +134,144 @@ public class ParameterFormat extends Tab
public void format(final Object object, final Appendable toAppendTo) throws IOException {
ArgumentChecks.ensureNonNull("object", object);
ArgumentChecks.ensureNonNull("toAppendTo", toAppendTo);
- final boolean isSummary = contentLevel == ContentLevel.NAME_SUMMARY;
- final ParameterDescriptorGroup descriptor;
- final ParameterValueGroup values;
- final ReferenceIdentifier name;
- if (object instanceof ParameterValueGroup) {
- values = (ParameterValueGroup) object;
- descriptor = values.getDescriptor();
- name = descriptor.getName();
- } else if (object instanceof ParameterDescriptorGroup) {
- descriptor = (ParameterDescriptorGroup) object;
- values = null;
- name = descriptor.getName();
- } else if (object instanceof OperationMethod) {
- final OperationMethod operation = (OperationMethod) object;
- descriptor = operation.getParameters();
- values = null;
- name = operation.getName();
- } else if (isSummary && object instanceof IdentifiedObject[]) {
- formatSummary((IdentifiedObject[]) object, toAppendTo);
- return;
+ final DefaultFeatureType featureType;
+ final DefaultFeature feature;
+ if (object instanceof DefaultFeature) {
+ feature = (DefaultFeature) object;
+ featureType = feature.getType();
+ } else if (object instanceof DefaultFeatureType) {
+ featureType = (DefaultFeatureType) object;
+ feature = null;
} else {
throw new IllegalArgumentException(Errors.getResources(displayLocale)
.getString(Errors.Keys.UnsupportedType_1, object.getClass()));
}
- if (isSummary) {
- final List<GeneralParameterDescriptor> parameters = descriptor.descriptors();
- formatSummary(parameters.toArray(new IdentifiedObject[parameters.size()]), toAppendTo);
- } else {
- format(name.getCode(), descriptor, values, toAppendTo);
- }
- }
-
- /**
- * Implementation of public {@code format(…)} methods for all content levels except {@code NAME_SUMMARY}.
- *
- * @param name The group name, usually {@code descriptor.getName().getCode()}.
- * @param descriptor The parameter descriptor, usually {@code values.getDescriptor()}.
- * @param values The parameter values, or {@code null} if none.
- * @throws IOException If an error occurred while writing to the given appendable.
- */
- private void format(final String name, final ParameterDescriptorGroup group,
- final ParameterValueGroup values, final Appendable out) throws IOException
- {
- final boolean isBrief = (contentLevel == ContentLevel.BRIEF);
- final boolean showObligation = !isBrief || (values == null);
- final boolean hasColors = (colors != null);
- final String lineSeparator = this.lineSeparator;
- final ParameterTableRow header = new ParameterTableRow(group, displayLocale, preferredCodespaces, isBrief);
- final String groupCodespace = header.getCodeSpace();
- /*
- * 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 codespaces. 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 formatting after the simple parameters.
- */
- int codespaceWidth = 0;
- final Collection<?> elements = (values != null) ? values.values() : group.descriptors();
- final Map<GeneralParameterDescriptor, ParameterTableRow> descriptorValues =
- new LinkedHashMap<>(hashMapCapacity(elements.size()));
- List<Object> deferredGroups = null; // To be created only if needed (it is usually not).
- for (final Object element : elements) {
- final GeneralParameterValue parameter;
- final GeneralParameterDescriptor descriptor;
- if (values != null) {
- parameter = (GeneralParameterValue) element;
- descriptor = parameter.getDescriptor();
- } else {
- parameter = null;
- descriptor = (GeneralParameterDescriptor) element;
- }
- if (descriptor instanceof ParameterDescriptorGroup) {
- if (deferredGroups == null) {
- deferredGroups = new ArrayList<>(4);
- }
- deferredGroups.add(element);
- continue;
- }
- /*
- * In the vast majority of cases, there is only one value for each parameter. However
- * if we find more than one value, we will append all extra occurrences in a "multiple
- * values" list to be formatted in the same row.
- */
- Object value = null;
- Unit<?> unit = null;
- if (parameter instanceof ParameterValue<?>) {
- final ParameterValue<?> p = (ParameterValue<?>) parameter;
- value = p.getValue();
- unit = p.getUnit();
- } else if (descriptor instanceof ParameterDescriptor<?>) {
- final ParameterDescriptor<?> p = (ParameterDescriptor<?>) descriptor;
- value = p.getDefaultValue();
- unit = p.getUnit();
- }
- ParameterTableRow row = descriptorValues.get(descriptor);
- if (row == null) {
- row = new ParameterTableRow(descriptor, displayLocale, preferredCodespaces, isBrief);
- descriptorValues.put(descriptor, row);
- if (row.codespaceWidth > codespaceWidth) {
- codespaceWidth = row.codespaceWidth;
- }
- }
- row.addValue(value, unit);
- }
- /*
- * Finished to collect the values. Now transform the values:
- *
- * - Singleton value of array types (either primitive or not) are expanded to a list.
- * - Values are formatted.
- * - Value domains are formatted.
- * - Position of the character on which to do the alignment are remembered.
- */
- int unitWidth = 0;
- int valueDomainAlignment = 0;
- boolean writeCodespaces = (groupCodespace == null);
- final StringBuffer buffer = new StringBuffer();
- final FieldPosition dummyFP = new FieldPosition(-1);
- for (final Map.Entry<GeneralParameterDescriptor,ParameterTableRow> entry : descriptorValues.entrySet()) {
- final GeneralParameterDescriptor descriptor = entry.getKey();
- if (descriptor instanceof ParameterDescriptor<?>) {
- final ParameterTableRow row = entry.getValue();
- /*
- * Verify if all rows use the same codespace than the header, in which case we can omit
- * row codespace formatting.
- */
- if (!writeCodespaces && !groupCodespace.equals(entry.getValue().getCodeSpace())) {
- writeCodespaces = true;
- }
- /*
- * Format the value domain, so we can compute the character position on which to perform alignment.
- */
- final Range<?> valueDomain = Parameters.getValueDomain((ParameterDescriptor<?>) descriptor);
- if (valueDomain != null) {
- final int p = row.setValueDomain(valueDomain, getFormat(Range.class), buffer);
- if (p > valueDomainAlignment) {
- valueDomainAlignment = p;
- }
- }
- /*
- * Singleton array conversion. Because it may be an array of primitive types, we can not just
- * cast to Object[]. Then formats the units, with a space before the unit if the symbol is a
- * letter or digit (i.e. we do not put a space in front of ° symbol for instance).
- */
- row.expandSingleton();
- final int length = row.units.size();
- for (int i=0; i<length; i++) {
- final Object unit = row.units.get(i);
- if (unit != null) {
- if (getFormat(Unit.class).format(unit, buffer, dummyFP).length() != 0) {
- if (Character.isLetterOrDigit(buffer.codePointAt(0))) {
- buffer.insert(0, ' ');
- }
- }
- final String symbol = buffer.toString();
- row.units.set(i, symbol);
- buffer.setLength(0);
- final int p = symbol.length();
- if (p > unitWidth) {
- unitWidth = p;
- }
- }
- }
- }
- }
- /*
- * Finished to prepare information. Now begin the actual writing.
- * First, formats the table header (i.e. the column names).
- */
- final Vocabulary resources = Vocabulary.getResources(displayLocale);
- header.writeIdentifiers(out, true, colors, false, lineSeparator);
- out.append(lineSeparator);
- final char horizontalBorder = isBrief ? '─' : '═';
- final TableAppender table = (isBrief || !columnSeparator.equals(SEPARATOR)) ?
- new TableAppender(out, columnSeparator) : new TableAppender(out);
+ toAppendTo.append(toString(featureType.getName())).append(getLineSeparator());
+ final StringBuffer buffer = new StringBuffer();
+ final FieldPosition dummyFP = new FieldPosition(-1);
+ final Vocabulary resources = Vocabulary.getResources(displayLocale);
+ final TableAppender table = new TableAppender(toAppendTo, columnSeparator);
table.setMultiLinesCells(true);
- table.nextLine(horizontalBorder);
- for (int i=0; ; i++) {
- boolean end = false;
+ table.nextLine('─');
+header: for (int i=0; ; i++) {
final short key;
switch (i) {
- case 0: {
- key = Vocabulary.Keys.Name;
- break;
- }
- case 1: {
- key = Vocabulary.Keys.Type;
- break;
- }
- case 2: {
- if (!showObligation) {
- continue;
- }
- key = Vocabulary.Keys.Obligation;
- break;
- }
- case 3: {
- key = Vocabulary.Keys.ValueDomain;
- break;
- }
- case 4: {
- key = (values == null) ? Vocabulary.Keys.DefaultValue : Vocabulary.Keys.Value;
- end = true;
- break;
- }
- default: throw new AssertionError(i);
+ case 0: key = Vocabulary.Keys.Name; break;
+ case 1: nextColumn(table); key = Vocabulary.Keys.Type; break;
+ case 2: nextColumn(table); key = Vocabulary.Keys.Cardinality; break;
+ case 3: nextColumn(table); key = (feature != null) ? Vocabulary.Keys.Value : Vocabulary.Keys.DefaultValue; break;
+ default: break header;
}
- if (hasColors) table.append(X364.BOLD.sequence());
table.append(resources.getString(key));
- if (hasColors) table.append(X364.NORMAL.sequence());
- if (!writeCodespaces && i == 0) {
- table.append(" (").append(groupCodespace).append(')');
- }
- if (end) break;
- nextColumn(table);
}
table.nextLine();
+ table.nextLine('─');
/*
- * Now process to the formatting of (descriptor,value) pairs. Each descriptor's alias
- * will be formatted on its own line in a table row. If there is more than one value,
- * then each value will be formatted on its own line as well. Note that the values may
- * be null if there is none.
+ * Done writing the header. Now write all property rows.
+ * Rows without value will be skipped only if optional.
*/
- char horizontalLine = horizontalBorder;
- for (final Map.Entry<GeneralParameterDescriptor,ParameterTableRow> entry : descriptorValues.entrySet()) {
- if (horizontalLine != 0) {
- table.nextLine('─');
- }
- horizontalLine = isBrief ? 0 : '─';
- final ParameterTableRow row = entry.getValue();
- row.codespaceWidth = codespaceWidth;
- row.writeIdentifiers(table, writeCodespaces, null, hasColors, lineSeparator);
- nextColumn(table);
- final GeneralParameterDescriptor generalDescriptor = entry.getKey();
- if (generalDescriptor instanceof ParameterDescriptor<?>) {
- /*
- * Writes value type.
- */
- final ParameterDescriptor<?> descriptor = (ParameterDescriptor<?>) generalDescriptor;
- final Class<?> valueClass = descriptor.getValueClass();
- table.append(getFormat(Class.class).format(valueClass, buffer, dummyFP).toString());
- nextColumn(table);
- buffer.setLength(0);
- /*
- * Writes the obligation (mandatory or optional).
- */
- if (showObligation) {
- final int minimumOccurs = descriptor.getMinimumOccurs();
- final int maximumOccurs = descriptor.getMaximumOccurs();
- if (maximumOccurs == 1) {
- table.append(resources.getString(minimumOccurs == 0 ?
- Vocabulary.Keys.Optional : Vocabulary.Keys.Mandatory));
- } else {
- final Format f = getFormat(Integer.class);
- table.append(f.format(minimumOccurs, buffer, dummyFP).toString()).append(" … ");
- buffer.setLength(0);
- if (maximumOccurs == Integer.MAX_VALUE) {
- table.append('∞');
- } else {
- table.append(f.format(maximumOccurs, buffer, dummyFP).toString());
- buffer.setLength(0);
- }
- }
- nextColumn(table);
- }
- /*
- * Writes minimum and maximum values, together with the unit of measurement (if any).
- */
- final String valueDomain = row.valueDomain;
- if (valueDomain != null) {
- table.append(CharSequences.spaces(valueDomainAlignment - row.valueDomainAlignment)).append(valueDomain);
- }
- nextColumn(table);
- /*
- * Writes the values, each on its own line, together with their unit of measurement.
- */
- table.setCellAlignment(TableAppender.ALIGN_RIGHT);
- final int length = row.values.size();
- for (int i=0; i<length; i++) {
- Object value = row.values.get(i);
- if (value != null) {
- if (i != 0) {
- table.append(lineSeparator);
- }
- final Format format = getFormat(value.getClass());
- if (format != null) {
- value = format.format(value, buffer, dummyFP);
- }
- table.append(value.toString());
- buffer.setLength(0);
- int pad = unitWidth;
- final String unit = (String) row.units.get(i);
- if (unit != null) {
- table.append(unit);
- pad -= unit.length();
- }
- table.append(CharSequences.spaces(pad));
+ for (final AbstractIdentifiedType propertyType : featureType.getProperties(true)) {
+ Object value;
+ if (feature != null) {
+ value = feature.getPropertyValue(propertyType.getName().toString());
+ if (value == null) {
+ if (propertyType instanceof FieldType && ((FieldType) propertyType).getMinimumOccurs() == 0) {
+ continue; // If no value, skip the full row.
}
}
+ } else if (propertyType instanceof DefaultAttributeType<?>) {
+ value = ((DefaultAttributeType<?>) propertyType).getDefaultValue();
+ } else {
+ value = null;
}
- table.nextLine();
- table.setCellAlignment(TableAppender.ALIGN_LEFT);
- }
- table.nextLine(horizontalBorder);
- table.flush();
- /*
- * Now formats all groups deferred to the end of this table, with recursive calls to
- * this method (recursive calls use their own TableWriter instance, so they may result
- * in a different cell layout). Most of the time, there is no such additional group.
- */
- if (deferredGroups != null) {
- for (final Object element : deferredGroups) {
- final ParameterValueGroup value;
- final ParameterDescriptorGroup descriptor;
- if (element instanceof ParameterValueGroup) {
- value = (ParameterValueGroup) element;
- descriptor = value.getDescriptor();
- } else {
- value = null;
- descriptor = (ParameterDescriptorGroup) element;
- }
- out.append(lineSeparator);
- format(name + '/' + descriptor.getName().getCode(), descriptor, value, out);
- }
- }
- }
-
- /**
- * Implementation of public {@code format(…)} methods for {@code NAME_SUMMARY} content level.
- *
- * @param objects The collection of objects to format.
- * @param out The stream or buffer where to write the summary.
- * @throws IOException if an error occurred will writing to the given appendable.
- */
- private void formatSummary(final IdentifiedObject[] objects, final Appendable out) throws IOException {
- final Vocabulary resources = Vocabulary.getResources(displayLocale);
- /*
- * Prepares all rows before we write them to the output stream, because not all
- * identified objects may have names with the same scopes in the same order. We
- * also need to iterate over all rows in order to know the number of columns.
- *
- * The first column is reserved for the identifier. We put null as a sentinal key for
- * that column name, to be replaced later by "Identifier" in user locale. We can not
- * put the localized strings in the map right now because they could conflict with
- * the scope of some alias to be processed below.
- */
- boolean hasIdentifiers = false;
- final List<String[]> rows = new ArrayList<>();
- final Map<String,Integer> columnIndices = new LinkedHashMap<>();
- columnIndices.put(null, 0); // See above comment for the meaning of "null" here.
- if (preferredCodespaces != null) {
- for (final String codespace : preferredCodespaces) {
- columnIndices.put(codespace, columnIndices.size());
- }
- }
- for (final IdentifiedObject object : objects) {
- String[] row = new String[columnIndices.size()]; // Will growth later if needed.
/*
- * Put the first identifier in the first column. If no identifier has a codespace in the list
- * supplied by the user, then we will use the first identifier (any codespace) as a fallback.
+ * Column 0 - Name.
*/
- final Set<ReferenceIdentifier> identifiers = object.getIdentifiers();
- if (identifiers != null) { // Paranoiac check.
- ReferenceIdentifier identifier = null;
- for (final ReferenceIdentifier candidate : identifiers) {
- if (candidate != null) { // Paranoiac check.
- if (isPreferredCodespace(candidate.getCodeSpace())) {
- identifier = candidate;
- break; // Format now.
- }
- if (identifier == null) {
- identifier = candidate; // To be used as a fallback if we find nothing better.
- }
- }
- }
- if (identifier != null) {
- row[0] = IdentifiedObjects.toString(identifier);
- hasIdentifiers = true;
- }
- }
+ table.append(toString(propertyType.getName()));
+ nextColumn(table);
/*
- * If the name's codespace is in the list of codespaces asked by the user, add that name
- * in the current row and clear the 'name' locale variable. Otherwise, keep the 'name'
- * locale variable in case we found no alias to format.
+ * Column 1 and 2 - Type and cardinality.
*/
- ReferenceIdentifier name = object.getName();
- if (name != null) { // Paranoiac check.
- final String codespace = name.getCodeSpace();
- if (isPreferredCodespace(codespace)) {
- row = putIfAbsent(resources, row, columnIndices, codespace, name.getCode());
- name = null;
- }
+ final String valueType;
+ final Class<?> valueClass;
+ final int minimumOccurs, maximumOccurs;
+ if (propertyType instanceof DefaultAttributeType<?>) {
+ final DefaultAttributeType<?> pt = (DefaultAttributeType<?>) propertyType;
+ minimumOccurs = pt.getMinimumOccurs();
+ maximumOccurs = pt.getMaximumOccurs();
+ valueClass = pt.getValueClass();
+ valueType = getFormat(Class.class).format(valueClass, buffer, dummyFP).toString();
+ buffer.setLength(0);
+ } else if (propertyType instanceof DefaultAssociationRole) {
+ final DefaultAssociationRole pt = (DefaultAssociationRole) propertyType;
+ minimumOccurs = pt.getMinimumOccurs();
+ maximumOccurs = pt.getMaximumOccurs();
+ valueType = toString(pt.getValueType().getName());
+ valueClass = DefaultFeature.class;
+ } else if (propertyType instanceof DefaultOperation) {
+ final DefaultAttributeType<?> resultType = ((DefaultOperation) propertyType).getResult();
+ valueType = toString(resultType.getName());
+ valueClass = null;
+ minimumOccurs = -1;
+ maximumOccurs = -1;
+ } else {
+ valueType = "";
+ valueClass = null;
+ minimumOccurs = -1;
+ maximumOccurs = -1;
}
- /*
- * Put all aliases having a codespace in the list asked by the user.
- */
- final Collection<GenericName> aliases = object.getAlias();
- if (aliases != null) { // Paranoiac check.
- for (final GenericName alias : aliases) {
- if (alias != null) { // Paranoiac check.
- final String codespace = NameToIdentifier.getCodespaceOrAuthority(alias, displayLocale);
- if (isPreferredCodespace(codespace)) {
- row = putIfAbsent(resources, row, columnIndices, codespace,
- alias.tip().toInternationalString().toString(displayLocale));
- name = null;
- }
- }
+ table.append(valueType);
+ nextColumn(table);
+ if (maximumOccurs >= 0) {
+ final Format format = getFormat(Integer.class);
+ table.append('[').append(format.format(minimumOccurs, buffer, dummyFP)).append(" … ");
+ buffer.setLength(0);
+ if (maximumOccurs != Integer.MAX_VALUE) {
+ table.append(format.format(maximumOccurs, buffer, dummyFP));
+ } else {
+ table.append('∞');
}
+ buffer.setLength(0);
+ table.append(']');
}
+ nextColumn(table);
/*
- * If no name and no alias have a codespace in the list of codespaces asked by the user,
- * force the addition of primary name regardless its codespace.
+ * Column 3 - Value or default value.
*/
- if (name != null) {
- row = putIfAbsent(resources, row, columnIndices, name.getCodeSpace(), name.getCode());
- }
- rows.add(row);
- }
- /*
- * Writes the table. The header will contain one column for each codespace in the order declared
- * by the user. If the user did not specified any codespace, or if we had to write codespace not
- * on the user list, then those codespaces will be written in the order we found them.
- */
- final boolean hasColors = (colors != null);
- final TableAppender table = new TableAppender(out, columnSeparator);
- table.setMultiLinesCells(true);
- table.appendHorizontalSeparator();
- for (String codespace : columnIndices.keySet()) {
- if (codespace == null) {
- if (!hasIdentifiers) continue; // Skip empty column.
- codespace = resources.getString(Vocabulary.Keys.Identifier);
- }
- if (hasColors) {
- codespace = X364.BOLD.sequence() + codespace + X364.NORMAL.sequence();
- }
- table.append(codespace);
- nextColumn(table);
- }
- table.appendHorizontalSeparator();
- /*
- * Writes row content.
- */
- final int numColumns = columnIndices.size();
- for (final String[] row : rows) {
- for (int i=hasIdentifiers ? 0 : 1; i<numColumns; i++) {
- if (i < row.length) {
- final String name = row[i];
- if (name != null) {
- table.append(name);
- }
+ if (value != null) {
+ final Format format = getFormat(valueClass);
+ if (format != null) {
+ value = format.format(value, buffer, dummyFP);
+ } else if (value instanceof InternationalString) {
+ value = ((InternationalString) value).toString(displayLocale);
+ } else if (value instanceof DefaultFeature && propertyType instanceof DefaultAssociationRole) {
+ value = ((DefaultFeature) value).getPropertyValue(
+ ((DefaultAssociationRole) propertyType).getTitleProperty());
}
- nextColumn(table);
+ table.append(value.toString());
+ buffer.setLength(0);
}
table.nextLine();
}
- table.appendHorizontalSeparator();
+ table.nextLine('─');
table.flush();
}
/**
- * Stores a value in the given position of the given row, expanding the array if needed.
- * This operation is performed only if no value already exists in the cell.
- *
- * @param row All columns in a single row.
- * @param columnIndices Indices of columns for each codespace.
- * @param codespace The codespace of the name or alias to add.
- * @param name The code of the name or alias to add.
- * @return {@code row}, or a new array if it was necessary to expand the row.
- */
- private static String[] putIfAbsent(final Vocabulary resources, String[] row,
- final Map<String,Integer> columnIndices, String codespace, final String name)
- {
- if (codespace == null) {
- codespace = resources.getString(Vocabulary.Keys.Unnamed);
- }
- final Integer columnIndex = columnIndices.get(codespace);
- final int i;
- if (columnIndex != null) {
- i = columnIndex;
- } else {
- i = columnIndices.size();
- columnIndices.put(codespace, i);
- }
- if (i >= row.length) {
- row = Arrays.copyOf(row, i + 1);
- }
- if (row[i] == null) {
- row[i] = name;
- }
- return row;
- }
-
- /**
- * Returns a shared instance of {@code ParameterFormat} if possible, or a new one otherwise.
+ * Returns the display name for the given {@code GenericName}.
*/
- private static ParameterFormat getSharedInstance(final Colors colors) {
- ParameterFormat f = INSTANCE.getAndSet(null);
- if (f == null) {
- f = new ParameterFormat();
+ private String toString(final GenericName name) {
+ if (name == null) { // Should not be null, but let be safe.
+ return "";
+ }
+ final InternationalString i18n = name.toInternationalString();
+ if (i18n != null) { // Should not be null, but let be safe.
+ final String s = i18n.toString(displayLocale);
+ if (s != null) {
+ return s;
+ }
}
- f.setColors(colors);
- return f;
+ return name.toString();
}
/**
@@ -910,28 +279,16 @@ public class ParameterFormat extends Tab
* This is used for {@link DefaultParameterDescriptorGroup#toString()} implementation.
*/
static String sharedFormat(final Object object) {
- final ParameterFormat f = getSharedInstance(null);
+ FeatureFormat f = INSTANCE.getAndSet(null);
+ if (f == null) {
+ f = new FeatureFormat();
+ }
final String s = f.format(object);
INSTANCE.set(f);
return s;
}
/**
- * Writes the given object to the console using a shared instance of {@code ParameterFormat}.
- */
- static void print(final Object object) {
- final Console console = System.console();
- final Appendable out = (console != null) ? console.writer() : System.out;
- final ParameterFormat f = getSharedInstance(Colors.NAMING);
- try {
- f.format(object, out);
- } catch (IOException e) {
- throw new AssertionError(e); // Should never happen, since we are writing to stdout.
- }
- INSTANCE.set(f);
- }
-
- /**
* Not yet supported.
*
* @return Currently never return.
Modified: sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/FieldType.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/FieldType.java?rev=1595219&r1=1595218&r2=1595219&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/FieldType.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/main/java/org/apache/sis/feature/FieldType.java [UTF-8] Fri May 16 14:50:30 2014
@@ -116,7 +116,7 @@ abstract class FieldType extends Propert
/**
* Implementation of {@link #toString()} to be shared by subclasses and {@link DefaultAttribute#toString()}.
*/
- final StringBuilder toString(final String typeName, final String valueName) {
+ final StringBuilder toString(final String typeName, final Object valueName) {
final StringBuilder buffer = new StringBuilder(40).append(typeName).append('[');
final GenericName name = getName();
if (name != null) {
Modified: sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultAssociationTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultAssociationTest.java?rev=1595219&r1=1595218&r2=1595219&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultAssociationTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultAssociationTest.java [UTF-8] Fri May 16 14:50:30 2014
@@ -46,7 +46,7 @@ public final strictfp class DefaultAssoc
static DefaultAssociation twinTown() {
final DefaultFeature twinTown = new DefaultFeature(DefaultFeatureTypeTest.city());
twinTown.setPropertyValue("city", "Le Mans");
- twinTown.setPropertyValue("population", 148169);
+ twinTown.setPropertyValue("population", 143240); // In 2011.
final DefaultAssociation association = new DefaultAssociation(DefaultAssociationRoleTest.twinTown());
association.setValue(twinTown);
return association;
Modified: sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultFeatureTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultFeatureTest.java?rev=1595219&r1=1595218&r2=1595219&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultFeatureTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/DefaultFeatureTest.java [UTF-8] Fri May 16 14:50:30 2014
@@ -21,6 +21,7 @@ import org.apache.sis.test.TestCase;
import org.junit.Test;
import static org.junit.Assert.*;
+import static java.util.Collections.singletonMap;
/**
@@ -38,6 +39,27 @@ import static org.junit.Assert.*;
})
public final strictfp class DefaultFeatureTest extends TestCase {
/**
+ * Creates a feature for twin towns.
+ */
+ static DefaultFeature twinTown() {
+ final DefaultAssociationRole twinTown = DefaultAssociationRoleTest.twinTown();
+ final DefaultFeatureType city = twinTown.getValueType();
+ final DefaultFeatureType type = new DefaultFeatureType(
+ singletonMap(DefaultFeatureType.NAME_KEY, "Twin town"), false,
+ new DefaultFeatureType[] {city}, twinTown);
+
+ final DefaultFeature leMans = new DefaultFeature(type);
+ leMans.setPropertyValue("city", "Le Mans");
+ leMans.setPropertyValue("population", 143240); // In 2011.
+
+ final DefaultFeature paderborn = new DefaultFeature(type);
+ paderborn.setPropertyValue("city", "Paderborn");
+ paderborn.setPropertyValue("population", 143174); // December 31th, 2011
+ paderborn.setPropertyValue("twin town", leMans);
+ return paderborn;
+ }
+
+ /**
* Tests the construction of a simple feature without super-types.
*/
@Test
Added: sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/FeatureFormatTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/FeatureFormatTest.java?rev=1595219&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/FeatureFormatTest.java (added)
+++ sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/FeatureFormatTest.java [UTF-8] Fri May 16 14:50:30 2014
@@ -0,0 +1,73 @@
+/*
+ * 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.feature;
+
+import java.util.Locale;
+import org.apache.sis.test.DependsOn;
+import org.apache.sis.test.TestCase;
+import org.junit.Test;
+
+import static org.apache.sis.test.Assert.*;
+
+
+/**
+ * Tests {@link FeatureFormat}.
+ *
+ * @author Martin Desruisseaux (Geomatys)
+ * @since 0.5
+ * @version 0.5
+ * @module
+ */
+@DependsOn(DefaultFeatureTest.class)
+public final strictfp class FeatureFormatTest extends TestCase {
+ /**
+ * Tests the formatting of a {@link DefaultFeatureType}.
+ */
+ @Test
+ public void testFeatureType() {
+ final DefaultFeatureType feature = DefaultFeatureTypeTest.metropolis();
+ final FeatureFormat format = new FeatureFormat(Locale.US, null);
+ final String text = format.format(feature);
+ assertMultilinesEquals("Metropolis\n" +
+ "┌────────────┬──────────────┬─────────────┬───────────────┐\n" +
+ "│ Name │ Type │ Cardinality │ Default value │\n" +
+ "├────────────┼──────────────┼─────────────┼───────────────┤\n" +
+ "│ city │ String │ [1 … 1] │ Utopia │\n" +
+ "│ population │ Integer │ [1 … 1] │ │\n" +
+ "│ region │ CharSequence │ [1 … 1] │ │\n" +
+ "│ isGlobal │ Boolean │ [1 … 1] │ │\n" +
+ "└────────────┴──────────────┴─────────────┴───────────────┘\n", text);
+ }
+
+ /**
+ * Tests the formatting of a {@link DefaultFeature}.
+ */
+ @Test
+ public void testFeature() {
+ final DefaultFeature feature = DefaultFeatureTest.twinTown();
+ final FeatureFormat format = new FeatureFormat(Locale.US, null);
+ final String text = format.format(feature);
+ assertMultilinesEquals("Twin town\n" +
+ "┌────────────┬─────────┬─────────────┬───────────┐\n" +
+ "│ Name │ Type │ Cardinality │ Value │\n" +
+ "├────────────┼─────────┼─────────────┼───────────┤\n" +
+ "│ city │ String │ [1 … 1] │ Paderborn │\n" +
+ "│ population │ Integer │ [1 … 1] │ 143,174 │\n" +
+ "│ twin town │ City │ [0 … ∞] │ Le Mans │\n" +
+ "└────────────┴─────────┴─────────────┴───────────┘\n", text);
+ }
+}
Propchange: sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/FeatureFormatTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/feature/FeatureFormatTest.java
------------------------------------------------------------------------------
svn:mime-type = text/plain;charset=UTF-8
Modified: sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/test/suite/FeatureTestSuite.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/test/suite/FeatureTestSuite.java?rev=1595219&r1=1595218&r2=1595219&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/test/suite/FeatureTestSuite.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-feature/src/test/java/org/apache/sis/test/suite/FeatureTestSuite.java [UTF-8] Fri May 16 14:50:30 2014
@@ -37,7 +37,8 @@ import org.junit.BeforeClass;
org.apache.sis.feature.DefaultFeatureTest.class,
org.apache.sis.feature.DefaultAssociationRoleTest.class,
org.apache.sis.feature.DefaultAssociationTest.class,
- org.apache.sis.feature.DefaultOperationTest.class
+ org.apache.sis.feature.DefaultOperationTest.class,
+ org.apache.sis.feature.FeatureFormatTest.class
})
public final strictfp class FeatureTestSuite extends TestSuite {
/**
Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterFormat.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterFormat.java?rev=1595219&r1=1595218&r2=1595219&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterFormat.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/ParameterFormat.java [UTF-8] Fri May 16 14:50:30 2014
@@ -91,8 +91,8 @@ import static org.apache.sis.util.collec
* <caption>Formattable object types</caption>
* <tr><th>Class</th> <th>Remarks</th></tr>
* <tr><td>{@link ParameterValueGroup}</td><td><cite>Default values</cite> column is replaced by a column of the actual values.</td></tr>
- * <tr><td>{@link ParameterDescriptorGroup}</td><td>Table title is the parameter group name.</td></tr>
- * <tr><td>{@link OperationMethod}</td><td>Table title is the method name (not necessarily the same than parameter group name).</td></tr>
+ * <tr><td>{@link ParameterDescriptorGroup}</td><td>Table caption is the parameter group name.</td></tr>
+ * <tr><td>{@link OperationMethod}</td><td>Table caption is the method name (not necessarily the same than parameter group name).</td></tr>
* <tr><td><code>{@linkplain IdentifiedObject}[]</code></td><td>Accepted only for {@link ContentLevel#NAME_SUMMARY}.</td></tr>
* </table>
*
Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/io/CompoundFormat.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/io/CompoundFormat.java?rev=1595219&r1=1595218&r2=1595219&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/io/CompoundFormat.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/io/CompoundFormat.java [UTF-8] Fri May 16 14:50:30 2014
@@ -358,7 +358,7 @@ public abstract class CompoundFormat<T>
* See {@link #createFormat(Class)} for the list of value types recognized by the default
* {@code CompoundFormat} implementation.
*
- * @param valueType The base type of values to parse or format.
+ * @param valueType The base type of values to parse or format, or {@code null} if unknown.
* @return The format to use for parsing and formatting values of the given type or any
* parent type, or {@code null} if none.
*/