001    package org.meta_environment.eclipse.errors;
002    
003    import org.eclipse.core.resources.IFile;
004    import org.eclipse.core.resources.IMarker;
005    import org.eclipse.core.resources.ResourcesPlugin;
006    import org.eclipse.core.runtime.CoreException;
007    import org.eclipse.core.runtime.Path;
008    
009    import toolbus.adapter.eclipse.EclipseTool;
010    import aterm.ATerm;
011    import errorapi.Factory;
012    import errorapi.types.Area;
013    import errorapi.types.Error;
014    import errorapi.types.ErrorList;
015    import errorapi.types.Location;
016    import errorapi.types.Subject;
017    import errorapi.types.SubjectList;
018    import errorapi.types.Summary;
019    
020    public class ErrorViewer extends EclipseTool {
021            private static final String TOOL_NAME = "error-viewer";
022            private static final String PRODUCER = TOOL_NAME + ".producer";
023            private static final String ERROR_ID = TOOL_NAME + ".errorid";
024    
025            private Factory eFactory;
026    
027            private static class InstanceKeeper {
028                    private static ErrorViewer sInstance = new ErrorViewer();
029                    static {
030                            sInstance.connect();
031                    }
032            }
033    
034            private ErrorViewer() {
035                    super(TOOL_NAME);
036                    eFactory = Factory.getInstance(factory);
037    
038            }
039    
040            public static ErrorViewer getInstance() {
041                    return InstanceKeeper.sInstance;
042            }
043    
044            public String getName() {
045                    return TOOL_NAME;
046            }
047    
048            public void showFeedbackSummary(String panelId, ATerm summaryTerm) {
049                    Summary summary = eFactory.SummaryFromTerm(summaryTerm);
050                    ErrorList errors = summary.getList();
051    
052                    try {
053                            for (; !errors.isEmpty(); errors = errors.getTail()) {
054                                    Error error = errors.getHead();
055                                    showError(summary, error, getSeverity(error));
056                            }
057                    } catch (CoreException e) {
058                            e.printStackTrace();
059                    }
060            }
061    
062            private int getSeverity(Error error) {
063                    if (error.isInfo()) {
064                            return IMarker.SEVERITY_INFO;
065                    } else if (error.isWarning()) {
066                            return IMarker.SEVERITY_WARNING;
067                    } else if (error.isError()) {
068                            return IMarker.SEVERITY_ERROR;
069                    } else if (error.isFatal()) {
070                            return IMarker.SEVERITY_ERROR;
071                    }
072    
073                    return IMarker.SEVERITY_INFO;
074            }
075    
076            private void showError(Summary summary, Error error, int severity)
077                            throws CoreException {
078                    String desc = error.getDescription();
079                    SubjectList subjects = error.getList();
080    
081                    for (; !subjects.isEmpty(); subjects = subjects.getTail()) {
082                            Subject subject = subjects.getHead();
083                            showSubject(summary, desc, subject, severity);
084                    }
085            }
086    
087            private void showSubject(Summary summary, String desc, Subject subject,
088                            int severity) throws CoreException {
089                    String msg = subject.getDescription();
090                    
091                    if (subject.hasLocation()) {
092                    Location loc = subject.getLocation();
093                    Area area = loc.getArea();
094                    String filename = loc.getFilename();
095    
096                    IFile file = ResourcesPlugin.getWorkspace().getRoot()
097                                    .getFileForLocation(new Path(filename));
098    
099                    if (file != null) {
100                            IMarker m = file.createMarker(IMarker.PROBLEM);
101    
102                            m.setAttribute(PRODUCER, summary.getProducer());
103                            m.setAttribute(ERROR_ID, summary.getId());
104    
105                            m.setAttribute(IMarker.TRANSIENT, true);
106                            m.setAttribute(IMarker.CHAR_START, area.getOffset());
107                            m.setAttribute(IMarker.CHAR_END, area.getOffset()
108                                            + area.getLength());
109                            m.setAttribute(IMarker.MESSAGE, desc + ": " + msg);
110                            m.setAttribute(IMarker.PRIORITY, IMarker.PRIORITY_HIGH);
111                            m.setAttribute(IMarker.SEVERITY, severity);
112                            m.setAttribute(IMarker.LOCATION, "line: " + area.getBeginLine()
113                                            + ", column: " + area.getBeginColumn());
114                    }
115                    }
116            }
117    
118            public void refreshFeedbackSummary(String panelId, ATerm summaryTerm) {
119                    Summary summary = eFactory.SummaryFromTerm(summaryTerm);
120                    removeFeedbackSummary(summary.getId());
121                    showFeedbackSummary(panelId, summaryTerm);
122            }
123    
124            public void removeFeedbackSummary(String panelId, String producer, String id) {
125                    removeFeedbackSummary(id);
126            }
127    
128            public void removeFeedbackSummary(final String theId) {
129                    IFile file = ResourcesPlugin.getWorkspace().getRoot()
130                                    .getFileForLocation(new Path(theId));
131    
132                    // TODO: this oversimplifies the identification of summaries, and
133                    // assumes all summaries are identified with a file path
134                    // This breaks in many places, but is good enough for demo purposes
135                    if (file != null && file.exists()) {
136                            try {
137                                    file.deleteMarkers(IMarker.PROBLEM, false, 1);
138                            } catch (CoreException e) {
139                                    e.printStackTrace();
140                            }
141                    }
142            }
143    
144            public void removeFeedbackSummary(String panelId, String path) {
145                    removeFeedbackSummary(path);
146            }
147    }