*/
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);
table.setMultiLinesCells(true);
table.nextLine(horizontalBorder);
for (int i=0; ; i++) {
boolean end = false;
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);
}
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();
/*
* 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.
*/
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));
}
}
}
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.
*/