use of java.text.FieldPosition in project Payara by payara.
the class GFFileHandler method rotate.
/**
* A Simple rotate method to close the old file and start the new one
* when the limit is reached.
*/
public void rotate() {
final GFFileHandler thisInstance = this;
doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
synchronized (thisInstance.rotationLock) {
if (thisInstance.meter != null && thisInstance.meter.written <= 0) {
return null;
}
thisInstance.flush();
thisInstance.close();
try {
if (!absoluteFile.exists()) {
File creatingDeletedLogFile = new File(absoluteFile.getAbsolutePath());
if (creatingDeletedLogFile.createNewFile()) {
absoluteFile = creatingDeletedLogFile;
}
} else {
File oldFile = absoluteFile;
StringBuffer renamedFileName = new StringBuffer(absoluteFile + "_");
logRotateDateFormatter.format(new Date(), renamedFileName, new FieldPosition(0));
File rotatedFile = new File(renamedFileName.toString());
boolean renameSuccess = oldFile.renameTo(rotatedFile);
if (!renameSuccess) {
// If we don't succeed with file rename which
// most likely can happen on Windows because
// of multiple file handles opened. We go through
// Plan B to copy bytes explicitly to a renamed
// file.
FileUtils.copy(absoluteFile, rotatedFile);
File freshServerLogFile = getLogFileName();
// We do this to make sure that server.log
// contents are flushed out to start from a
// clean file again after the rename..
FileOutputStream fo = new FileOutputStream(freshServerLogFile);
fo.close();
}
FileOutputStream oldFileFO = new FileOutputStream(oldFile);
oldFileFO.close();
openFile(getLogFileName());
absoluteFile = getLogFileName();
// for time based log rotation
if (dayBasedFileRotation) {
if (cname.equals(GF_FILE_HANDER)) {
LogRotationTimer.getInstance().restartTimerForDayBasedRotation();
} else {
PayaraNotificationLogRotationTimer.getInstance().restartTimerForDayBasedRotation();
}
} else {
if (cname.equals(GF_FILE_HANDER)) {
LogRotationTimer.getInstance().restartTimer();
} else {
PayaraNotificationLogRotationTimer.getInstance().restartTimer();
}
}
if (compressLogs) {
boolean compressed = gzipFile(rotatedFile);
if (compressed) {
boolean deleted = rotatedFile.delete();
if (!deleted) {
throw new IOException("Could not delete uncompressed log file: " + rotatedFile.getAbsolutePath());
}
} else {
throw new IOException("Could not compress log file: " + rotatedFile.getAbsolutePath());
}
}
cleanUpHistoryLogFiles();
}
} catch (IOException ix) {
new ErrorManager().error("Error, could not rotate log file", ix, ErrorManager.GENERIC_FAILURE);
}
return null;
}
}
});
}
use of java.text.FieldPosition in project karaf by apache.
the class FastDateFormat method getDate.
/**
* Get the date formatted with the given pattern.
*/
public String getDate(long now, String pattern) {
sameDay(now);
String date = cache.get(pattern);
if (date == null) {
if (MMM_D2.equals(pattern)) {
StringBuffer sb = new StringBuffer();
FieldPosition fp = new FieldPosition(DateFormat.Field.DAY_OF_MONTH);
new SimpleDateFormat("MMM dd", locale).format(new Date(now), sb, fp);
if (sb.charAt(fp.getBeginIndex()) == '0') {
sb.setCharAt(fp.getBeginIndex(), ' ');
}
date = sb.toString();
} else {
SimpleDateFormat sdf = new SimpleDateFormat(pattern, locale);
sdf.setCalendar(Calendar.getInstance(timeZone, locale));
date = sdf.format(new Date(now));
}
cache.put(pattern, date);
}
return date;
}
use of java.text.FieldPosition in project sis by apache.
the class FeatureFormat method format.
/**
* Formats the given object to the given stream of buffer.
* The object may be an instance of any of the following types:
*
* <ul>
* <li>{@code Feature}</li>
* <li>{@code FeatureType}</li>
* </ul>
*
* @throws IOException if an error occurred while writing to the given appendable.
*/
@Override
public void format(final Object object, final Appendable toAppendTo) throws IOException {
ArgumentChecks.ensureNonNull("object", object);
ArgumentChecks.ensureNonNull("toAppendTo", toAppendTo);
/*
* Separate the Feature (optional) and the FeatureType (mandatory) instances.
*/
final DefaultFeatureType featureType;
final AbstractFeature feature;
if (object instanceof AbstractFeature) {
feature = (AbstractFeature) 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()));
}
/*
* Computes the columns to show. We start with the set of columns specified by setAllowedColumns(Set),
* then we check if some of those columns are empty. For example in many cases there is no attribute
* with characteritic, in which case we will ommit the whole "characteristics" column. We perform such
* check only for optional information, not for mandatory information like property names.
*/
final EnumSet<Column> visibleColumns = columns.clone();
{
boolean hasDesignation = false;
boolean hasCharacteristics = false;
boolean hasDeprecatedTypes = false;
for (final AbstractIdentifiedType propertyType : featureType.getProperties(true)) {
if (!hasDesignation) {
hasDesignation = propertyType.getDesignation() != null;
}
if (!hasCharacteristics && propertyType instanceof DefaultAttributeType<?>) {
hasCharacteristics = !((DefaultAttributeType<?>) propertyType).characteristics().isEmpty();
}
if (!hasDeprecatedTypes && propertyType instanceof Deprecable) {
hasDeprecatedTypes = ((Deprecable) propertyType).isDeprecated();
}
}
if (!hasDesignation)
visibleColumns.remove(Column.DESIGNATION);
if (!hasCharacteristics)
visibleColumns.remove(Column.CHARACTERISTICS);
if (!hasDeprecatedTypes)
visibleColumns.remove(Column.REMARKS);
}
/*
* Format the feature type name. In the case of feature type, format also the names of super-type
* after the UML symbol for inheritance (an arrow with white head). We do not use the " : " ASCII
* character for avoiding confusion with the ":" separator in namespaces. After the feature (type)
* name, format the column header: property name, type, cardinality and (default) value.
*/
toAppendTo.append(toString(featureType.getName()));
if (feature == null) {
// UML symbol for inheritance.
String separator = " ⇾ ";
for (final FeatureType parent : featureType.getSuperTypes()) {
toAppendTo.append(separator).append(toString(parent.getName()));
separator = SEPARATOR;
}
}
toAppendTo.append(getLineSeparator());
/*
* Create a table and format the header. Columns will be shown in Column enumeration order.
*/
final Vocabulary resources = Vocabulary.getResources(displayLocale);
final TableAppender table = new TableAppender(toAppendTo, columnSeparator);
table.setMultiLinesCells(true);
table.nextLine('─');
boolean isFirstColumn = true;
for (final Column column : visibleColumns) {
short key = column.resourceKey;
if (key == Vocabulary.Keys.Value && feature == null) {
key = Vocabulary.Keys.DefaultValue;
}
if (!isFirstColumn)
nextColumn(table);
table.append(resources.getString(key));
isFirstColumn = false;
}
table.nextLine();
table.nextLine('─');
/*
* Done writing the header. Now write all property rows. For each row, the first part in the loop
* extracts all information needed without formatting anything yet. If we detect in that part that
* a row has no value, it will be skipped if and only if that row is optional (minimum occurrence
* of zero).
*/
final StringBuffer buffer = new StringBuffer();
final FieldPosition dummyFP = new FieldPosition(-1);
final List<String> remarks = new ArrayList<>();
for (final AbstractIdentifiedType propertyType : featureType.getProperties(true)) {
Object value = null;
int cardinality = -1;
if (feature != null) {
if (!(propertyType instanceof DefaultAttributeType<?>) && !(propertyType instanceof DefaultAssociationRole) && !DefaultFeatureType.isParameterlessOperation(propertyType)) {
continue;
}
value = feature.getPropertyValue(propertyType.getName().toString());
if (value == null) {
if (propertyType instanceof FieldType && ((FieldType) propertyType).getMinimumOccurs() == 0) {
// If optional and no value, skip the full row.
continue;
}
cardinality = 0;
} else if (value instanceof Collection<?>) {
cardinality = ((Collection<?>) value).size();
} else {
cardinality = 1;
}
} else if (propertyType instanceof DefaultAttributeType<?>) {
value = ((DefaultAttributeType<?>) propertyType).getDefaultValue();
} else if (propertyType instanceof AbstractOperation) {
buffer.append(" = ");
try {
((AbstractOperation) propertyType).formatResultFormula(buffer);
} catch (IOException e) {
// Should never happen since we write in a StringBuffer.
throw new UncheckedIOException(e);
}
value = CharSequences.trimWhitespaces(buffer).toString();
buffer.setLength(0);
}
// The value to write in the type column.
final String valueType;
// AttributeType.getValueClass() if applicable.
final Class<?> valueClass;
// Negative values mean no cardinality.
final int minimumOccurs, maximumOccurs;
// Result of operation if applicable.
final AbstractIdentifiedType resultType;
if (propertyType instanceof AbstractOperation) {
// May be null
resultType = ((AbstractOperation) propertyType).getResult();
} else {
resultType = propertyType;
}
if (resultType instanceof DefaultAttributeType<?>) {
final DefaultAttributeType<?> pt = (DefaultAttributeType<?>) resultType;
minimumOccurs = pt.getMinimumOccurs();
maximumOccurs = pt.getMaximumOccurs();
valueClass = pt.getValueClass();
valueType = getFormat(Class.class).format(valueClass, buffer, dummyFP).toString();
buffer.setLength(0);
} else if (resultType instanceof DefaultAssociationRole) {
final DefaultAssociationRole pt = (DefaultAssociationRole) resultType;
minimumOccurs = pt.getMinimumOccurs();
maximumOccurs = pt.getMaximumOccurs();
valueType = toString(DefaultAssociationRole.getValueTypeName(pt));
valueClass = AbstractFeature.class;
} else {
valueType = (resultType != null) ? toString(resultType.getName()) : "";
valueClass = null;
minimumOccurs = -1;
maximumOccurs = -1;
}
/*
* At this point we determined that the row should not be skipped
* and we got all information to format.
*/
isFirstColumn = true;
for (final Column column : visibleColumns) {
if (!isFirstColumn)
nextColumn(table);
isFirstColumn = false;
switch(column) {
/*
* Human-readable name of the property. May contains any characters (spaces, ideographs, etc).
* In many cases, this information is not provided and the whole column is skipped.
*/
case DESIGNATION:
{
final InternationalString d = propertyType.getDesignation();
if (d != null)
table.append(d.toString(displayLocale));
break;
}
/*
* Machine-readable name of the property (identifier). This information is mandatory.
* This name is usually shorter than the designation and should contain only valid
* Unicode identifier characters (e.g. no spaces).
*/
case NAME:
{
table.append(toString(propertyType.getName()));
break;
}
/*
* The base class or interface for all values in properties of the same type.
* This is typically String, Number, Integer, Geometry or URL.
*/
case TYPE:
{
table.append(valueType);
break;
}
/*
* Minimum and maximum number of occurrences allowed for this property.
* If we are formatting a Feature instead than a FeatureType, then the
* actual number of values is also formatted. Example: 42 ∈ [0 … ∞]
*/
case CARDINALITY:
{
table.setCellAlignment(TableAppender.ALIGN_RIGHT);
if (cardinality >= 0) {
table.append(getFormat(Integer.class).format(cardinality, buffer, dummyFP));
buffer.setLength(0);
}
if (maximumOccurs >= 0) {
if (cardinality >= 0) {
table.append(' ').append((cardinality >= minimumOccurs && cardinality <= maximumOccurs) ? '∈' : '∉').append(' ');
}
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(']');
}
break;
}
/*
* If formatting a FeatureType, the default value. If formatting a Feature, the actual value.
* A java.text.Format instance dedicated to the value class is used if possible. In addition
* to types for which a java.text.Format may be available, we also have to check for other
* special cases. If there is more than one value, they are formatted as a coma-separated list.
*/
case VALUE:
{
table.setCellAlignment(TableAppender.ALIGN_LEFT);
// Null if valueClass is null.
final Format format = getFormat(valueClass);
final Iterator<?> it = CollectionsExt.toCollection(value).iterator();
String separator = "";
int length = 0;
while (it.hasNext()) {
value = it.next();
if (value != null) {
if (propertyType instanceof DefaultAssociationRole) {
final String p = DefaultAssociationRole.getTitleProperty((DefaultAssociationRole) propertyType);
if (p != null) {
value = ((AbstractFeature) value).getPropertyValue(p);
if (value == null)
continue;
}
} else if (format != null && valueClass.isInstance(value)) {
// Null safe because of getFormat(valueClass) contract.
/*
* Convert numbers, dates, angles, etc. to character sequences before to append them in the table.
* Note that DecimalFormat writes Not-a-Number as "NaN" in some locales and as "�" in other locales
* (U+FFFD - Unicode replacement character). The "�" seems to be used mostly for historical reasons;
* as of 2017 the Unicode Common Locale Data Repository (CLDR) seems to define "NaN" for all locales.
* We could configure DecimalFormatSymbols for using "NaN", but (for now) we rather substitute "�" by
* "NaN" here for avoiding to change the DecimalFormat configuration and for distinguishing the NaNs.
*/
final StringBuffer t = format.format(value, buffer, dummyFP);
if (value instanceof Number) {
final float f = ((Number) value).floatValue();
if (Float.isNaN(f)) {
if ("�".contentEquals(t)) {
t.setLength(0);
t.append("NaN");
}
try {
final int n = MathFunctions.toNanOrdinal(f);
if (n > 0)
t.append(" #").append(n);
} catch (IllegalArgumentException e) {
// May happen if the NaN is a signaling NaN instead than a quiet NaN.
final int bits = Float.floatToRawIntBits(f);
if (bits != illegalNaN) {
illegalNaN = bits;
Logging.recoverableException(Logging.getLogger(Modules.FEATURE), FeatureFormat.class, "format", e);
}
}
}
}
value = t;
}
/*
* All values: the numbers, dates, angles, etc. formatted above, any other character sequences
* (e.g. InternationalString), or other kind of values - some of them handled in a special way.
*/
length = formatValue(value, table.append(separator), length);
buffer.setLength(0);
// Value is too long, abandon remaining iterations.
if (length < 0)
break;
separator = SEPARATOR;
length += SEPARATOR.length();
}
}
break;
}
/*
* Characteristics are optional information attached to some values. For example if a property
* value is a temperature measurement, a characteritic of that value may be the unit of measure.
* Characteristics are handled as "attributes of attributes".
*/
case CHARACTERISTICS:
{
if (propertyType instanceof DefaultAttributeType<?>) {
int length = 0;
String separator = "";
format: for (final DefaultAttributeType<?> ct : ((DefaultAttributeType<?>) propertyType).characteristics().values()) {
/*
* Format the characteristic name. We will append the value(s) later.
* We keep trace of the text length in order to stop formatting if the
* text become too long.
*/
final GenericName cn = ct.getName();
final String cs = toString(cn);
table.append(separator).append(cs);
length += separator.length() + cs.length();
Collection<?> cv = CollectionsExt.singletonOrEmpty(ct.getDefaultValue());
if (feature != null) {
/*
* Usually, the property 'cp' below is null because all features use the same
* characteristic value (for example the same unit of measurement), which is
* given by the default value 'cv'. Nevertheless we have to check if current
* feature overrides this characteristic.
*/
final Object cp = feature.getProperty(propertyType.getName().toString());
if (cp instanceof AbstractAttribute<?>) {
// Should always be true, but we are paranoiac.
AbstractAttribute<?> ca = ((AbstractAttribute<?>) cp).characteristics().get(cn.toString());
if (ca != null)
cv = ca.getValues();
}
}
/*
* Now format the value, separated from the name with " = ". Example: unit = m/s
* If the value accepts multi-occurrences, we will format the value between {…}.
* We use {…} because we may have more than one characteristic in the same cell,
* so we need a way to distinguish multi-values from multi-characteristics.
*/
final boolean multi = ct.getMaximumOccurs() > 1;
String sep = multi ? " = {" : " = ";
for (Object c : cv) {
length = formatValue(c, table.append(sep), length += sep.length());
// Value is too long, abandon remaining iterations.
if (length < 0)
break format;
sep = SEPARATOR;
}
separator = SEPARATOR;
if (multi && sep == SEPARATOR) {
table.append('}');
}
}
}
break;
}
case REMARKS:
{
if (org.apache.sis.feature.Field.isDeprecated(propertyType)) {
table.append(resources.getString(Vocabulary.Keys.Deprecated));
final InternationalString r = ((Deprecable) propertyType).getRemarks();
if (r != null) {
remarks.add(r.toString(displayLocale));
appendSuperscript(remarks.size(), table);
}
}
break;
}
}
}
table.nextLine();
}
table.nextLine('─');
table.flush();
/*
* If there is any remarks, write them below the table.
*/
final int n = remarks.size();
for (int i = 0; i < n; i++) {
appendSuperscript(i + 1, toAppendTo);
toAppendTo.append(' ').append(remarks.get(i)).append(lineSeparator);
}
}
use of java.text.FieldPosition in project sis by apache.
the class MonolineFormatter method formatMessage.
/**
* Returns the localized message from the given log record.
* First this method gets the {@linkplain LogRecord#getMessage() raw message} from the given record.
* Then there is choices:
*
* <ul>
* <li>If the given record specifies a {@linkplain LogRecord#getResourceBundle() resource bundle},
* then the message is used as a key for fetching the localized resources in the given bundle.</li>
* <li>If the given record specifies one or more {@linkplain LogRecord#getParameters() parameters}
* and if the message seems to use the {@link MessageFormat} syntax, then the message is formatted
* by {@code MessageFormat}.</li>
* </ul>
*
* @param record The log record from which to get a localized message.
* @return the localized message.
*/
@Override
public String formatMessage(final LogRecord record) {
/*
* Same work than java.util.logging.Formatter.formatMessage(LogRecord) except for the synchronization lock,
* the reuse of existing MessageFormat and StringBuffer instances, and not catching formatting exceptions
* (we want to know if our messages have a problem).
*/
String message = record.getMessage();
ResourceBundle resources = record.getResourceBundle();
if (resources != null) {
message = resources.getString(message);
}
final Object[] parameters = record.getParameters();
if (parameters != null && parameters.length != 0) {
int i = message.indexOf('{');
if (i >= 0 && ++i < message.length()) {
final char c = message.charAt(i);
if (c >= '0' && c <= '9') {
synchronized (buffer) {
if (messageFormat == null) {
messageFormat = new MessageFormat(message);
} else if (!message.equals(messagePattern)) {
messageFormat.applyPattern(message);
}
messagePattern = message;
final int base = buffer.length();
try {
message = messageFormat.format(parameters, buffer, new FieldPosition(0)).substring(base);
} finally {
buffer.setLength(base);
}
}
}
}
}
return message;
}
use of java.text.FieldPosition in project sis by apache.
the class MonolineFormatter method format.
/**
* Formats the given log record and return the formatted string.
* See the <a href="#overview">class javadoc</a> for information on the log format.
*
* @param record the log record to be formatted.
* @return a formatted log record.
*/
@Override
public String format(final LogRecord record) {
// Whether to use faint text for level < INFO.
boolean faint = false;
// ANSI escape sequence for bold text if we use it.
String emphaseStart = "";
// ANSI escape sequence for stopping bold text if we use it.
String emphaseEnd = "";
final Level level = record.getLevel();
final StringBuffer buffer = this.buffer;
synchronized (buffer) {
final boolean colors = (this.colors != null);
if (colors && level.intValue() >= LEVEL_THRESHOLD.intValue()) {
emphaseStart = X364.BOLD.sequence();
emphaseEnd = X364.NORMAL.sequence();
faint = faintSupported;
}
buffer.setLength(header.length());
/*
* Appends the time (e.g. "00:00:12.365"). The time pattern can be set either
* programmatically by a call to 'setTimeFormat(…)', or in logging.properties
* file with the "org.apache.sis.util.logging.MonolineFormatter.time" property.
*/
if (timeFormat != null) {
Date time = new Date(Math.max(0, record.getMillis() - startMillis));
timeFormat.format(time, buffer, new FieldPosition(0));
buffer.append(' ');
}
/*
* Appends the level (e.g. "FINE"). We do not provide the option to turn level off for now.
* This level will be formatted with a colorized background if ANSI escape sequences are enabled.
*/
int margin = buffer.length();
String levelColor = "", levelReset = "";
if (SHOW_LEVEL) {
if (colors) {
levelColor = colorAt(level);
levelReset = X364.BACKGROUND_DEFAULT.sequence();
}
final int offset = buffer.append(levelColor).append(emphaseStart).length();
final int length = buffer.append(level.getLocalizedName()).length() - offset;
buffer.append(emphaseEnd).append(CharSequences.spaces(levelWidth - length));
margin += buffer.length() - emphaseEnd.length() - offset;
buffer.append(levelReset).append(' ');
}
/*
* Appends the logger name or source class name, in long of short form.
* The name may be formatted in bold characters if ANSI escape sequences are enabled.
*/
String source;
switch(sourceFormat) {
// Fall through
case LOGGER_SHORT:
case LOGGER_LONG:
source = record.getLoggerName();
break;
// Fall through
case METHOD:
// Fall through
case CLASS_SHORT:
case CLASS_LONG:
source = record.getSourceClassName();
break;
default:
source = null;
break;
}
if (source != null) {
switch(sourceFormat) {
// Fall through
case METHOD:
// Fall through
case LOGGER_SHORT:
case CLASS_SHORT:
{
// Works even if there is no '.' since we get -1 as index.
source = source.substring(source.lastIndexOf('.') + 1);
break;
}
}
if (sourceFormat == METHOD) {
source = source + '.' + record.getSourceMethodName();
}
buffer.append(emphaseStart).append('[').append(source).append(']').append(emphaseEnd).append(' ');
}
/*
* Now prepare the LineAppender for the message. We set a line separator prefixed by some
* amount of spaces in order to align message body on the column after the level name.
*/
String bodyLineSeparator = writer.getLineSeparator();
final String lineSeparator = System.lineSeparator();
if (bodyLineSeparator.length() != lineSeparator.length() + margin + 1) {
final int highlight = Math.min(CONTINUATION_MARGIN, margin);
bodyLineSeparator = lineSeparator + levelColor + CharSequences.spaces(highlight) + levelReset + CharSequences.spaces(margin - highlight + 1);
writer.setLineSeparator(bodyLineSeparator);
}
if (faint) {
buffer.append(X364.FAINT.sequence());
}
final Throwable exception = record.getThrown();
String message = formatMessage(record);
int length = 0;
if (message != null) {
length = CharSequences.skipTrailingWhitespaces(message, 0, message.length());
}
/*
* Up to this point, we wrote directly in the StringBuilder for performance reasons.
* Now for the message part, we need to use the LineAppender in order to replace EOL
* and tabulations.
*/
try {
if (message != null) {
writer.append(message, 0, length);
}
if (exception != null) {
if (message != null) {
// LineAppender will replace '\n' by the system EOL.
writer.append("\nCaused by: ");
}
if (level.intValue() >= LEVEL_THRESHOLD.intValue()) {
exception.printStackTrace(printer);
} else {
printAbridged(exception, writer, record.getLoggerName(), record.getSourceClassName(), record.getSourceMethodName());
}
}
writer.flush();
} catch (IOException e) {
throw new AssertionError(e);
}
buffer.setLength(CharSequences.skipTrailingWhitespaces(buffer, 0, buffer.length()));
if (faint) {
buffer.append(X364.NORMAL.sequence());
}
buffer.append(lineSeparator);
return buffer.toString();
}
}
Aggregations