Package net.percederberg.mibble

Source Code of net.percederberg.mibble.MibLoaderLog$LogEntry

/*
* MibLoaderLog.java
*
* This work is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2 of the License,
* or (at your option) any later version.
*
* This work is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*
* Copyright (c) 2004 Per Cederberg. All rights reserved.
*/

package net.percederberg.mibble;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Iterator;

import net.percederberg.grammatica.parser.ParseException;
import net.percederberg.grammatica.parser.ParserLogException;

/**
* A MIB loader log. This class contains error and warning messages
* from loading a MIB file and all imports not previously loaded.
*
* @author   Per Cederberg, <per at percederberg dot net>
* @version  2.6
* @since    2.0
*/
public class MibLoaderLog {

    /**
     * The log entries.
     */
    private ArrayList entries = new ArrayList();

    /**
     * The log error count.
     */
    private int errors = 0;

    /**
     * The log warning count.
     */
    private int warnings = 0;

    /**
     * Creates a new loader log without entries.
     */
    public MibLoaderLog() {
        // Nothing initialization needed
    }

    /**
     * Returns the number of errors in the log.
     *
     * @return the number of errors in the log
     */
    public int errorCount() {
        return errors;
    }

    /**
     * Returns the number of warnings in the log.
     *
     * @return the number of warnings in the log
     */
    public int warningCount() {
        return warnings;
    }

    /**
     * Adds a log entry to this log.
     *
     * @param entry          the log entry to add
     */
    public void add(LogEntry entry) {
        if (entry.isError()) {
            errors++;
        }
        if (entry.isWarning()) {
            warnings++;
        }
        entries.add(entry);
    }

    /**
     * Adds an internal error message to the log. Internal errors are
     * only issued when possible bugs are encountered. They are
     * counted as errors.
     *
     * @param location       the file location
     * @param message        the error message
     */
    public void addInternalError(FileLocation location, String message) {
        add(new LogEntry(LogEntry.INTERNAL_ERROR, location, message));
    }

    /**
     * Adds an internal error message to the log. Internal errors are
     * only issued when possible bugs are encountered. They are
     * counted as errors.
     *
     * @param file           the file affected
     * @param message        the error message
     */
    public void addInternalError(File file, String message) {
        addInternalError(new FileLocation(file), message);
    }

    /**
     * Adds an error message to the log.
     *
     * @param location       the file location
     * @param message        the error message
     */
    public void addError(FileLocation location, String message) {
        add(new LogEntry(LogEntry.ERROR, location, message));
    }

    /**
     * Adds an error message to the log.
     *
     * @param file           the file affected
     * @param line           the line number
     * @param column         the column number
     * @param message        the error message
     */
    public void addError(File file, int line, int column, String message) {
        addError(new FileLocation(file, line, column), message);
    }

    /**
     * Adds a warning message to the log.
     *
     * @param location       the file location
     * @param message        the warning message
     */
    public void addWarning(FileLocation location, String message) {
        add(new LogEntry(LogEntry.WARNING, location, message));
    }

    /**
     * Adds a warning message to the log.
     *
     * @param file           the file affected
     * @param line           the line number
     * @param column         the column number
     * @param message        the warning message
     */
    public void addWarning(File file, int line, int column, String message) {
        addWarning(new FileLocation(file, line, column), message);
    }

    /**
     * Adds all log entries from another log.
     *
     * @param log            the MIB loader log
     */
    public void addAll(MibLoaderLog log) {
        for (int i = 0; i < log.entries.size(); i++) {
            add((LogEntry) log.entries.get(i));
        }
    }

    /**
     * Adds all errors from a parser log exception.
     *
     * @param file           the file affected
     * @param log            the parser log exception
     */
    void addAll(File file, ParserLogException log) {
        ParseException  e;

        for (int i = 0; i < log.getErrorCount(); i++) {
            e = log.getError(i);
            addError(file, e.getLine(), e.getColumn(), e.getErrorMessage());
        }
    }

    /**
     * Returns an iterator with all the log entries. The iterator
     * will only return LogEntry instances.
     *
     * @return an iterator with all the log entries
     *
     * @see LogEntry
     *
     * @since 2.2
     */
    public Iterator entries() {
        return entries.iterator();
    }

    /**
     * Prints all log entries to the specified output stream.
     *
     * @param output         the output stream to use
     */
    public void printTo(PrintStream output) {
        printTo(new PrintWriter(output));
    }

    /**
     * Prints all log entries to the specified output stream.
     *
     * @param output         the output stream to use
     */
    public void printTo(PrintWriter output) {
        printTo(output, 70);
    }

    /**
     * Prints all log entries to the specified output stream.
     *
     * @param output         the output stream to use
     * @param margin         the print margin
     *
     * @since 2.2
     */
    public void printTo(PrintWriter output, int margin) {
        StringBuffer  buffer = new StringBuffer();
        LogEntry      entry;
        String        str;

        for (int i = 0; i < entries.size(); i++) {
            entry = (LogEntry) entries.get(i);
            buffer.setLength(0);
            switch (entry.getType()) {
            case LogEntry.ERROR:
                buffer.append("Error: ");
                break;
            case LogEntry.WARNING:
                buffer.append("Warning: ");
                break;
            default:
                buffer.append("Internal Error: ");
                break;
            }
            buffer.append("in ");
            buffer.append(relativeFilename(entry.getFile()));
            if (entry.getLineNumber() > 0) {
                buffer.append(": line ");
                buffer.append(entry.getLineNumber());
            }
            buffer.append(":\n");
            str = linebreakString(entry.getMessage(), "    ", margin);
            buffer.append(str);
            str = entry.readLine();
            if (str != null && str.length() >= entry.getColumnNumber()) {
                buffer.append("\n\n");
                buffer.append(str);
                buffer.append("\n");
                for (int j = 1; j < entry.getColumnNumber(); j++) {
                    if (str.charAt(j - 1) == '\t') {
                        buffer.append("\t");
                    } else {
                        buffer.append(" ");
                    }
                }
                buffer.append("^");
            }
            output.println(buffer.toString());
        }
        output.flush();
    }

    /**
     * Creates a relative file name from a file. This method will
     * return the absolute file name if the file unless the current
     * directory is a parent to the file.
     *
     * @param file           the file to calculate relative name for
     *
     * @return the relative name if found, or
     *         the absolute name otherwise
     */
    private String relativeFilename(File file) {
        String  currentPath;
        String  filePath;

        if (file == null) {
            return "<unknown file>";
        }
        try {
            currentPath = new File(".").getCanonicalPath();
            filePath = file.getCanonicalPath();
            if (filePath.startsWith(currentPath)) {
                filePath = filePath.substring(currentPath.length());
                if (filePath.charAt(0) == '/'
                 || filePath.charAt(0) == '\\') {

                    return filePath.substring(1);
                } else {
                    return filePath;
                }
            }
        } catch (IOException e) {
            // Do nothing
        }
        return file.toString();
    }

    /**
     * Breaks a string into multiple lines. This method will also add
     * a prefix to each line in the resulting string. The prefix
     * length will be taken into account when breaking the line. Line
     * breaks will only be inserted as replacements for space
     * characters.
     *
     * @param str            the string to line break
     * @param prefix         the prefix to add to each line
     * @param length         the maximum line length
     *
     * @return the new formatted string
     */
    private String linebreakString(String str, String prefix, int length) {
        StringBuffer  buffer = new StringBuffer();
        int           pos;

        while (str.length() + prefix.length() > length) {
            pos = str.lastIndexOf(' ', length - prefix.length());
            if (pos < 0) {
                pos = str.indexOf(' ');
                if (pos < 0) {
                    break;
                }
            }
            buffer.append(prefix);
            buffer.append(str.substring(0, pos));
            str = str.substring(pos + 1);
            buffer.append("\n");
        }
        buffer.append(prefix);
        buffer.append(str);
        return buffer.toString();
    }



    /**
     * A log entry. This class holds all the details in an error or a
     * warning log entry.
     *
     * @author   Per Cederberg, <per at percederberg dot net>
     * @version  2.2
     * @since    2.2
     */
    public class LogEntry {

        /**
         * The internal error log entry type constant.
         */
        public static final int INTERNAL_ERROR = 1;

        /**
         * The error log entry type constant.
         */
        public static final int ERROR = 2;

        /**
         * The warning log entry type constant.
         */
        public static final int WARNING = 3;

        /**
         * The log entry type.
         */
        private int type;

        /**
         * The log entry file reference.
         */
        private FileLocation location;

        /**
         * The log entry message.
         */
        private String message;

        /**
         * Creates a new log entry.
         *
         * @param type           the log entry type
         * @param location       the log entry file reference
         * @param message        the log entry message
         */
        public LogEntry(int type, FileLocation location, String message) {
            this.type = type;
            if (location == null || location.getFile() == null) {
                this.location = new FileLocation(new File("<unknown file>"));
            } else {
                this.location = location;
            }
            this.message = message;
        }

        /**
         * Checks if this is an error log entry.
         *
         * @return true if this is an error log entry, or
         *         false otherwise
         */
        public boolean isError() {
            return type == INTERNAL_ERROR || type == ERROR;
        }

        /**
         * Checks if this is a warning log entry.
         *
         * @return true if this is a warning log entry, or
         *         false otherwise
         */
        public boolean isWarning() {
            return type == WARNING;
        }

        /**
         * Returns the log entry type.
         *
         * @return the log entry type
         *
         * @see #INTERNAL_ERROR
         * @see #ERROR
         * @see #WARNING
         */
        public int getType() {
            return type;
        }

        /**
         * Returns the file this entry applies to.
         *
         * @return the file affected
         */
        public File getFile() {
            return location.getFile();
        }

        /**
         * Returns the line number.
         *
         * @return the line number
         */
        public int getLineNumber() {
            return location.getLineNumber();
        }

        /**
         * Returns the column number.
         *
         * @return the column number
         */
        public int getColumnNumber() {
            return location.getColumnNumber();
        }

        /**
         * Returns the log entry message.
         *
         * @return the log entry message
         */
        public String getMessage() {
            return message;
        }

        /**
         * Reads the line from the referenced file. If the file couldn't
         * be opened or read correctly, null will be returned. The line
         * will NOT contain the terminating '\n' character.
         *
         * @return the line read, or
         *         null if not found
         */
        public String readLine() {
            return location.readLine();
        }
    }
}
TOP

Related Classes of net.percederberg.mibble.MibLoaderLog$LogEntry

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.