/**
* Copyright (c) 2012 by JP Moresmau
* This code is made available under the terms of the Eclipse Public License,
* version 1.0 (EPL). See http://www.eclipse.org/legal/epl-v10.html
*/
package net.sf.eclipsefp.haskell.buildwrapper.types;
import java.util.Map;
import net.sf.eclipsefp.haskell.buildwrapper.BuildWrapperPlugin;
import net.sf.eclipsefp.haskell.buildwrapper.util.BWText;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.text.IDocument;
import org.eclipse.ui.editors.text.TextFileDocumentProvider;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.MarkerUtilities;
import org.json.JSONException;
import org.json.JSONObject;
/**
* Represents a warning or an error from buildwrapper (Cabal, GHC, Haskell-src-exts message)
* @author JP Moresmau
*
*/
public class Note {
public enum Kind { ERROR, WARNING, INFO, OTHER }
private Kind kind; // error, warning, info or other
private Location location;
private String message;
private String additionalInfo;
public Note(JSONObject json) throws JSONException {
String kind = json.getString("kind");
if (kind.equals("error")){
this.kind = Kind.ERROR;
} else if (kind.equals("warning")){
this.kind = Kind.WARNING;
} else if (kind.equals("info")){
this.kind = Kind.INFO;
} else{
this.kind = Kind.OTHER;
}
this.location = new Location(json.getJSONObject("location"));
this.message = json.getString("message");
this.additionalInfo = null;
}
public Note(Kind kind, Location location, String message, String additionalInfo) {
this.kind = kind;
this.location = location;
this.message = message;
this.additionalInfo = additionalInfo;
}
public Kind getKind() {
return kind;
}
public Location getLocation() {
return location;
}
public String getMessage() {
return message;
}
public String getAdditionalInfo() {
return additionalInfo;
}
public void applyAsMarker(IResource resource,IDocument doc) throws CoreException {
applyAsMarker(resource,doc,Integer.MAX_VALUE);
}
public void applyAsMarker(IResource resource,IDocument doc,int maxLines) throws CoreException {
if (resource != null && resource.isAccessible()) {
/**
* this causes scheduling rule issues sometimes
*/
// if (!resource.getWorkspace().isTreeLocked()){
// try {
// resource.refreshLocal(0, new NullProgressMonitor());
// } catch (CoreException ce){
// // ignore
// }
// }
int severity;
switch (kind) {
case ERROR: severity = IMarker.SEVERITY_ERROR; break;
case WARNING: severity = IMarker.SEVERITY_WARNING; break;
case INFO: severity = IMarker.SEVERITY_INFO; break;
default: severity = IMarker.SEVERITY_INFO; break;
}
String msg= message + (additionalInfo != null ? "\n" + additionalInfo : "");
addMarker(resource,doc, severity, maxLines, msg);
}
}
private void addMarker(final IResource resource,IDocument doc, int severity, int maxLines, String msg) throws CoreException {
int line= Math.min(location.getStartLine(),maxLines);
int start=location.getStartColumn();
// duplicate
for (IMarker m:resource.findMarkers(BuildWrapperPlugin.PROBLEM_MARKER_ID, false, 0)){
if (m.getAttribute(IMarker.SEVERITY, -1)==severity
&& m.getAttribute(IMarker.LINE_NUMBER, -1)==line
&& m.getAttribute(IMarker.CHAR_START, -1)==start
&& m.getAttribute(IMarker.MESSAGE, "").equals(msg)
)
return;
}
Map<Object,Object> attributes=null;
if (doc==null){
IDocumentProvider prov=new TextFileDocumentProvider();
try {
prov.connect( resource );
doc=prov.getDocument( resource );
if (doc!=null){
try {
attributes=location.getMarkerProperties(doc);
} finally {
prov.disconnect( resource );
}
}
} catch (Exception ce){
BuildWrapperPlugin.log(IStatus.ERROR,ce.getLocalizedMessage(), ce );
}
} else {
attributes=location.getMarkerProperties(doc);
}
if (attributes==null){
attributes=location.getMarkerProperties(maxLines);
}
attributes.put(IMarker.SEVERITY, severity);
attributes.put(IMarker.MESSAGE,msg);
final Map<Object,Object> attributesf=attributes;
/**
* this locks the workspace, so fire a new thread
*/
new Thread(new Runnable(){
@Override
public void run() {
try {
MarkerUtilities.createMarker(resource, attributesf, BuildWrapperPlugin.PROBLEM_MARKER_ID);
} catch (CoreException ex){
BuildWrapperPlugin.logError(BWText.process_apply_note_error, ex);
}
}
}).start();
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Note)) {
return false;
}
Note other = (Note)obj;
return
kind.equals(other.kind) &&
location.equals(other.location) &&
message.equals(other.message) &&
((additionalInfo==null && other.additionalInfo==null) || (additionalInfo!=null && additionalInfo.equals(other.additionalInfo)));
}
@Override
public int hashCode() {
return kind.hashCode()+location.hashCode();
}
@Override
public String toString() {
return String.format("%s:%s: %s", kind.toString(), location.toString(), message);
}
}