alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*
 *                 Sun Public License Notice
 *
 * The contents of this file are subject to the Sun Public License
 * Version 1.0 (the "License"). You may not use this file except in
 * compliance with the License. A copy of the License is available at
 * http://www.sun.com/
 *
 * The Original Code is NetBeans. The Initial Developer of the Original
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun
 * Microsystems, Inc. All Rights Reserved.
 */

package org.netbeans.modules.tasklist.compiler;

import java.awt.Image;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.ConsoleHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.text.BadLocationException;
import javax.swing.text.Element;
import javax.swing.text.StyledDocument;
import org.netbeans.modules.tasklist.core.TLUtils;
import org.netbeans.modules.tasklist.core.Task;
import org.openide.ErrorManager;
import org.openide.compiler.ErrorEvent;
import org.openide.cookies.EditorCookie;
import org.openide.cookies.LineCookie;
import org.openide.cookies.SourceCookie;
import org.openide.filesystems.FileObject;
import org.openide.loaders.DataObject;
import org.openide.loaders.DataObjectNotFoundException;
import org.openide.nodes.Node;
import org.openide.text.Line;
import org.openide.text.NbDocument;
import org.openide.util.NbBundle;
import org.openide.util.Utilities;

/**
 * Build message
 *
 * @author Tim Lebedkov 
 */
public class CompileError extends Task {
    private static final Logger LOGGER = TLUtils.getLogger(CompileError.class);
    
    static {
        LOGGER.setLevel(Level.OFF);
    }
    
    /** severity constant for an error */
    public static final int SEVERITY_ERROR = 0;

    /** severity constant for a warning */
    public static final int SEVERITY_WARNING = 1;

    /** severity constant for an info */
    public static final int SEVERITY_INFO = 2;
    
    public static final Image ERROR_IMAGE = 
        Utilities.loadImage("org/netbeans/modules/tasklist/compiler/error.gif"); // NOI18N
    public static final Image WARNING_IMAGE =
        Utilities.loadImage("org/netbeans/modules/tasklist/compiler/warning.png"); // NOI18N
    public static final Image INFO_IMAGE =
        Utilities.loadImage("org/netbeans/modules/tasklist/compiler/info.png"); // NOI18N
    
    private static final String[] SEVERITY = {
        NbBundle.getMessage(CompileError.class, "Error"), //NOI18N
        NbBundle.getMessage(CompileError.class, "Warning"), //NOI18N
        NbBundle.getMessage(CompileError.class, "Info") //NOI18N
    };
    
    /**
     * Returns localized description of the given severity level.
     * SEVERITY_* constants could be used to acces values from the returned 
     * array.
     *
     * @return descriptions 
     */
    public static String[] getSeverityNames() {
        return SEVERITY;
    }
    
    private FileObject file;
    private int column = -1;
    private int severity = SEVERITY_ERROR;
    private Line.Part linePart = null;
    private org.openide.src.Element javaElement = null;
    
    /**
     * This is only used for constructing a root task.
     * It is a workaround for TreeTableView bug: summary of the root node
     * will be shown as the name of the first column
     */
    public CompileError() {
        setSummary(NbBundle.getMessage(CompileError.class, "Summary")); // NOI18N
    }

    /** 
     * Creates a new instance of CompileError 
     * 
     * @param ev error message
     */
    public CompileError(ErrorEvent ev) {
        String msg = ev.getMessage().replace('\n', ' ').replace('\r', ' ').trim();
        setSummary(msg);
        setDetails(ev.getMessage());
        this.file = ev.getFile();
        
        // ErrorEvent.getColumn() is 1-based
        this.column = ev.getColumn() - 1;
        
        // XXX HACK javac column
        boolean success = false;
        if (this.column <= 0)
            success = hackJavacColumn(ev);
        
        // XXX HACK warning messages
        if (getSummary().startsWith("warning:")) { // NOI18N
            this.severity = SEVERITY_WARNING;
            setSummary(getSummary().substring(8).trim());
        }
        
        if (file == null) {
            // XXX HACK #3
            this.severity = SEVERITY_INFO;
            return;
        }
        
        DataObject do_ = null;
        try {
            do_ = DataObject.find(file);
        } catch (DataObjectNotFoundException e) {
            return;
        }
        
        LineCookie lc = (LineCookie) do_.getCookie(LineCookie.class);
        if (lc == null) 
            return;
        
        Line.Set ls = lc.getLineSet();
        if (ls == null) 
            return;
        
        int l = ev.getLine() - 1;
        if (l <= 0)
            l = 0;
        Line line = null;
        try {
            line = ls.getCurrent(l);
        } catch (IndexOutOfBoundsException e) {
            return;
        }
        
        setLine(line);
        
        EditorCookie ec = (EditorCookie) do_.getCookie(EditorCookie.class);
        if (ec != null) {
            try { 
                StyledDocument doc = ec.openDocument();
                Element el = NbDocument.findLineRootElement(doc).getElement(l);
                String text = doc.getText(el.getStartOffset(), 
                    el.getEndOffset() - el.getStartOffset());
                int pos = findPosition(text, this.column);
                linePart = line.createPart(pos, 1);
                
                // find java source element if possible
                SourceCookie.Editor sce = (SourceCookie.Editor) do_.getCookie(
                    SourceCookie.Editor.class);
                if (sce != null) {
                    this.javaElement = sce.findElement(el.getStartOffset() + pos);
                }
                
                return;
            } catch (BadLocationException e) {
                ErrorManager.getDefault().notify(e);
            } catch (IOException e) {
                ErrorManager.getDefault().notify(e);
            }
        } else {        
            linePart = line.createPart(this.column, 1);
        }
    }
    
    /**
     * Returns Java element that this message points to
     *
     * @return Java element or null
     */
    public org.openide.src.Element getJavaElement() {
        return javaElement;
    }
    
    /**
     * Returns folder for the file where this error occured
     *
     * @return folder
     */
    public FileObject getFolder() {
        if (file == null)
            return null;
        else
            return file.getParent();
    }
    
    public Node[] createNode() {
        if (LOGGER.isLoggable(Level.FINE)) {
            if (getSummary().equals("Summary")) {
                LOGGER.fine("node.summary = Summary");
                LOGGER.log(Level.FINE, "stack", new Exception());
            }
        }
        
        if (subtasks != null) {  // Want to make root a non-leaf; empty list, not null
            return new Node[] { new CompileErrorNode(this, subtasksIterator())};
        } else {
            return new Node[] { new CompileErrorNode(this)};
        }
    }
    
    /**
     * Returns position in the source.
     *
     * @return position or null if unknown
     */
    public Line.Part getLinePart() {
        return linePart;
    }
    
    /** 
     * Returns the file associated with this error
     *
     * @return file or null
     */
    public FileObject getFile() {
        return file;
    }
    
    /**
     * Returns column number (0, 1, 2, ...)
     *
     * @return column number or -1 if not known
     */
    public int getColumn() {
        return column;
    }
    
    /**
     * Returns severity of this build message
     *
     * @return one of SEVERITY_* constants
     */
    public int getSeverity() {
        return severity;
    }
    
    public Image getIcon() {
        switch (severity) {
            case SEVERITY_WARNING:
                return WARNING_IMAGE;
            case SEVERITY_INFO:
                return INFO_IMAGE;
            case SEVERITY_ERROR:
                return ERROR_IMAGE;
            default:
                throw new InternalError("Wrong severity"); // NOI18N
        }
    }
    
    /**
     * Splits the specified text in lines.
     *
     * @param text text to be splitted
     * @return array of lines. String[]
     */
    private List splitLines(String text) {
        ArrayList lines = new ArrayList();
        BufferedReader br = new BufferedReader(new StringReader(text));
        try {
            while (true) {
                String line = br.readLine();
                if (line == null)
                    break;
                lines.add(line);
            }
        } catch (IOException e) {
            ErrorManager.getDefault().notify(e);
        }
        return lines;
    }

    /**
     * Initializes column number for Javac.
     * Javac's output looks like this (^ points to the error):
     *
     * CompileError.java:171: incompatible types
     * found   : java.lang.String
     * required: int
     *             return line.getLineNumber() + 1;
     *                                         ^
     *
     * @param ev error event
     * @return true = success
     */
    private boolean hackJavacColumn(ErrorEvent ev) {
        List lines = splitLines(ev.getMessage());
        while (lines.size() != 0) {
            String line = (String) lines.get(lines.size() - 1);
            if (line.trim().length() == 0)
                lines.remove(lines.size() - 1);
            else
                break;
        }
        
        if (lines.size() < 3)
            return false;

        String lastLine = (String) lines.get(lines.size() - 1);
        if (!lastLine.trim().equals("^"))
            return false;
        
        this.column = lastLine.indexOf('^');
        
        StringBuffer summary = new StringBuffer();
        StringBuffer details = new StringBuffer();
        for (int i = 0; i < lines.size() - 2; i++) {
            if (i != 0) {
                summary.append(' ');
                details.append('\n');
            }
            summary.append((String) lines.get(i));
            details.append((String) lines.get(i));
        }
        setSummary(summary.toString());
        setDetails(details.toString());
        
        return true;
    }
    
    /**
     * Find text position for the given column number. Tab width = 8
     *
     * @param line a line of text
     * @param col column number
     * @return position in the specified line or line.length() it the position
     * exceeds the length of the line
     */
    private int findPosition(String line, int col) {
        int curColumn = 0;
        for (int i = 0; i < line.length(); i++) {
            if (curColumn >= col)
                return i;
            
            char c = line.charAt(i);
            if (c == '\t')
                curColumn += 8;
            else
                curColumn++;
        }
        return line.length();
    }
}
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.