Search in sources :

Example 81 with FieldPosition

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;
            }
        }
    });
}
Also used : ErrorManager(java.util.logging.ErrorManager) FileOutputStream(java.io.FileOutputStream) IOException(java.io.IOException) FieldPosition(java.text.FieldPosition) File(java.io.File) Date(java.util.Date)

Example 82 with FieldPosition

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;
}
Also used : FieldPosition(java.text.FieldPosition) SimpleDateFormat(java.text.SimpleDateFormat) Date(java.util.Date)

Example 83 with FieldPosition

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);
    }
}
Also used : Vocabulary(org.apache.sis.util.resources.Vocabulary) TableAppender(org.apache.sis.io.TableAppender) ArrayList(java.util.ArrayList) UncheckedIOException(java.io.UncheckedIOException) InternationalString(org.opengis.util.InternationalString) GenericName(org.opengis.util.GenericName) Format(java.text.Format) TabularFormat(org.apache.sis.io.TabularFormat) Iterator(java.util.Iterator) Deprecable(org.apache.sis.util.Deprecable) IOException(java.io.IOException) UncheckedIOException(java.io.UncheckedIOException) FieldPosition(java.text.FieldPosition) InternationalString(org.opengis.util.InternationalString) Collection(java.util.Collection) IdentifiedObject(org.opengis.referencing.IdentifiedObject)

Example 84 with FieldPosition

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;
}
Also used : MessageFormat(java.text.MessageFormat) ResourceBundle(java.util.ResourceBundle) FieldPosition(java.text.FieldPosition)

Example 85 with FieldPosition

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();
    }
}
Also used : IOException(java.io.IOException) FieldPosition(java.text.FieldPosition) Date(java.util.Date)

Aggregations

FieldPosition (java.text.FieldPosition)100 Date (java.util.Date)31 SimpleDateFormat (java.text.SimpleDateFormat)28 DecimalFormat (java.text.DecimalFormat)12 NumberFormat (java.text.NumberFormat)12 ParsePosition (java.text.ParsePosition)12 IsoDateFormat (alma.acs.util.IsoDateFormat)9 Test (org.junit.Test)9 ILogEntry (com.cosylab.logging.engine.log.ILogEntry)8 Format (java.text.Format)8 MessageFormat (java.text.MessageFormat)8 DateFormat (java.text.DateFormat)6 ACSLogParser (alma.acs.logging.engine.parser.ACSLogParser)5 IOException (java.io.IOException)3 ParseException (java.text.ParseException)3 Calendar (java.util.Calendar)3 GregorianCalendar (java.util.GregorianCalendar)3 Vector (java.util.Vector)3 ExtendedDateFormat (org.jkiss.utils.time.ExtendedDateFormat)3 LogTypeHelper (com.cosylab.logging.engine.log.LogTypeHelper)2