Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/builder/MarkerCreatorWithBatching.java')
-rw-r--r--archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/builder/MarkerCreatorWithBatching.java286
1 files changed, 286 insertions, 0 deletions
diff --git a/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/builder/MarkerCreatorWithBatching.java b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/builder/MarkerCreatorWithBatching.java
new file mode 100644
index 000000000..cbea7a0b6
--- /dev/null
+++ b/archive/org.eclipse.qvt.declarative.editor.imp.runtime/src/org/eclipse/imp/builder/MarkerCreatorWithBatching.java
@@ -0,0 +1,286 @@
+/*******************************************************************************
+* Copyright (c) 2008 IBM Corporation.
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+* Stan Sutton (suttons@us.ibm.com) - initial API and implementation
+* Copied liberally and adapted from an implementation provided by
+* E. D. Willink as an attachment to Eclipse bugzilla bug #245296 (and
+* copyrighted 2008 under EPL v. 1.0 http://www.eclipse.org/legal/epl-v10.html).
+*
+*******************************************************************************/
+
+package org.eclipse.imp.builder;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.imp.builder.ProblemLimit.LimitExceededException;
+import org.eclipse.imp.core.ErrorHandler;
+import org.eclipse.imp.parser.IParseController;
+
+/**
+ * An implementation of IMessageHandler for collecting messages over time
+ * and then creating a group of corresponding markers in one batch using
+ * a single workspace operation.
+ *
+ * Copied liberally from a MarkerProblemHandler implementation provided by
+ * E. D. Willink as an attachment to Eclipse bugzilla bug #245296 (and
+ * copyrighted 2008 under EPL v. 1.0 http://www.eclipse.org/legal/epl-v10.html).
+ *
+ * @author Stan Sutton (suttons@us.ibm.com)
+ */
+public class MarkerCreatorWithBatching extends MarkerCreator {
+ protected String page = null;
+ protected Map<Integer, List<Map<String, Object>>> entries = null; // Map of line number to list of marker attributes for line
+ protected ProblemLimit problemLimit = null;
+ protected BuilderBase builder = null;
+
+ /*
+ * NOTE: The parse controller that is provided in constructing an instance of this
+ * type is used to obtain a parse stream that is used in processing error messages
+ * received by the instance. In particular, error messages are associated with positions
+ * in the text, those positions are used to identify corresponding parse tokens, and
+ * those parse tokens are used in determining positions for error markers. For that
+ * reason, the given parse controller should provide a parse stream that is consistent
+ * with (if not identical to) the one obtained when the error messages were generated.
+ * Also for that reason, no additional parsing is done within the marker creator.
+ * Violation of this assumption can lead to markers (and marker annotations) that are
+ * not correctly located with respect to the underling error in the text.
+ */
+
+
+ /**
+ * Constructor to use when you want to create markers that are not related to a
+ * particular builder and that will have the marker type provided here.
+ *
+ * @param resource The resource (e.g., file) on which markers are to be placed
+ * @param parseController The source of the parse stream to which error messages will
+ * be related
+ * @param problemType The type of problem marker (i.e., the problem marker id)
+ */
+ public MarkerCreatorWithBatching(
+ IFile file,
+ IParseController parseController,
+ String problemType)
+ {
+ super(file, parseController, problemType);
+ PROBLEM_MARKER_ID = problemType;
+ }
+
+
+ /**
+ * Constructor to use when you want to create markers that are related to a
+ * particular builder and that will have a marker type and builder id based
+ * on that builder.
+ *
+ * @param file The file on which markers are to be placed
+ * @param parseController The source of the parse stream to which error messages will
+ * be related
+ * @param builder The builder that is presumably driving the creation of
+ * markers and that defines the type of marker and builder id
+ * that will be used here
+ */
+ public MarkerCreatorWithBatching(
+ IFile file,
+ IParseController parseController,
+ BuilderBase builder)
+ {
+ super(file, parseController, builder.getErrorMarkerID());
+
+ this.builder = builder;
+ initializeBuidlerID(builder);
+ initializeProblemMarkerID(builder);
+ }
+
+
+ public String BUILDER_ID;
+
+ protected void initializeBuidlerID(BuilderBase builder) {
+ if (builder != null) {
+ BUILDER_ID = builder.getBuilderID();
+ } else {
+ BUILDER_ID = parseController.getLanguage().getName() + ".builder";
+ }
+ }
+
+ public String PROBLEM_MARKER_ID;
+
+ protected void initializeProblemMarkerID(BuilderBase builder) {
+ if (builder != null) {
+ PROBLEM_MARKER_ID = builder.getErrorMarkerID();
+ } else {
+ PROBLEM_MARKER_ID = parseController.getLanguage().getName() + ".builder";
+ }
+ }
+
+
+ public Map<Integer, Integer> severityMap = new HashMap<Integer, Integer>();
+ {
+ severityMap.put(Integer.valueOf(IMarker.SEVERITY_ERROR), Integer.valueOf(IMarker.SEVERITY_ERROR));
+ severityMap.put(IMarker.SEVERITY_INFO, Integer.valueOf(IMarker.SEVERITY_INFO));
+ severityMap.put(IMarker.SEVERITY_WARNING, Integer.valueOf(IMarker.SEVERITY_WARNING));
+ }
+
+ public void setSeverityMap(Map<Integer, Integer> mapOfSeverities) {
+ // TODO: Figure out what to do about target severities that do not correspond
+ // to marker severities
+ severityMap = mapOfSeverities;
+ }
+
+ public Map<Integer, Integer> getSeverityMap() {
+ return severityMap;
+ }
+
+ public void addMarker(int severity, String message, int lineNumber, int charStart, int charEnd)
+ throws ProblemLimit.LimitExceededException
+ {
+ String adjustedMessage = message;
+ if (problemLimit != null) {
+ adjustedMessage = problemLimit.check(severity, message);
+ if (adjustedMessage == null)
+ return;
+ }
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(IMarker.MESSAGE, adjustedMessage);
+ attributes.put(IMarker.SEVERITY, Integer.valueOf(severity));
+ if (lineNumber == -1) {
+ lineNumber = 1;
+ }
+ Integer lineKey = Integer.valueOf(lineNumber);
+ attributes.put(IMarker.LINE_NUMBER, lineKey);
+ if (charStart <= charEnd) {
+ attributes.put(IMarker.CHAR_START, Integer.valueOf(charStart));
+ attributes.put(IMarker.CHAR_END, Integer.valueOf(charEnd));
+ }
+// attributes.put(BUILDER_ID, creationFactory.getBuilderId());
+ if (builder != null)
+ attributes.put(BUILDER_ID, builder.getBuilderID());
+ if (entries == null)
+ entries = new HashMap<Integer, List<Map<String, Object>>>();
+ List<Map<String, Object>> lineEntries = entries.get(lineKey);
+ if (lineEntries == null) {
+ lineEntries = new ArrayList<Map<String, Object>>();
+ entries.put(lineKey, lineEntries);
+ }
+ lineEntries.add(attributes);
+ if (adjustedMessage != message)
+ throw new ProblemLimit.LimitExceededException(adjustedMessage);
+ }
+
+
+ public void clearMessages() {
+ // TODO Auto-generated method stub
+ }
+
+
+ public void endMessageGroup() { }
+
+
+ public void flush(IProgressMonitor monitor) {
+ // Re-use existing markers wherever possible
+ // a) since many rebuilds generate the same errors
+ // b) to avoid a marker being deleted by a refreshMarkers on editor entry before
+ // gotoMarker is invoked to go to a pre-existing context.
+ if (file.exists()) {
+ IWorkspaceRunnable action = new IWorkspaceRunnable() {
+ public void run(IProgressMonitor monitor) throws CoreException {
+ String markerId = PROBLEM_MARKER_ID;
+ if (entries != null) {
+ IMarker[] oldMarkers = file.findMarkers(markerId, false, IFile.DEPTH_ZERO);
+ for (IMarker oldMarker : oldMarkers) {
+ Map<?, ?> oldAttributes = oldMarker.getAttributes();
+ List<Map<String, Object>> lineEntries = entries.get(oldAttributes.get(IMarker.LINE_NUMBER));
+ if (lineEntries != null) {
+ for (Map<String, Object> newAttributes : lineEntries) {
+ if (isSameMarker(oldAttributes, newAttributes)) {
+ lineEntries.remove(newAttributes);
+ oldMarker = null;
+ break;
+ }
+ }
+ }
+ if (oldMarker != null)
+ oldMarker.delete();
+ }
+ for (List<Map<String, Object>> lineEntries : entries.values()) {
+ for (Map<String, Object> entry : lineEntries) {
+ IMarker marker = file.createMarker(markerId);
+ marker.setAttributes(entry);
+ }
+ }
+ } else
+ file.deleteMarkers(markerId, false, IFile.DEPTH_ZERO);
+ }
+ };
+ try {
+ // TODO: Allow for the introduction of a non-null progress monitor
+// IProgressMonitor progressMonitor = monitor != null ? BasicMonitor.toIProgressMonitor(monitor) : new NullProgressMonitor();
+ IProgressMonitor progressMonitor = new NullProgressMonitor();
+ file.getWorkspace().run(action, file, IWorkspace.AVOID_UPDATE, progressMonitor);
+ } catch (CoreException e) {
+ ErrorHandler.logError("Failed to update file markers", e);
+ }
+ }
+ }
+
+ public void handleSimpleMessage(
+ String msg, int startOffset, int endOffset,
+ int startCol, int endCol, int startLine, int endLine)
+ {
+ try {
+ addMarker(IMarker.SEVERITY_ERROR, msg, startLine, startOffset, endOffset+1);
+ } catch (LimitExceededException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Return true if newAttributes and oldAttributes provide the same marker description.
+ */
+ public boolean isSameMarker(Map<?, ?> oldAttributes, Map<String, Object> newAttributes) {
+ Set<?> oldKeys = oldAttributes.keySet();
+ Set<String> newKeys = newAttributes.keySet();
+ if (oldKeys.size() != newKeys.size())
+ return false;
+ for (String key : newKeys) {
+ if (!oldAttributes.containsKey(key))
+ return false;
+ Object oldValue = oldAttributes.get(key);
+ Object newValue = newAttributes.get(key);
+ if (oldValue == newValue)
+ continue;
+ if (oldValue == null)
+ return false;
+ if (newValue == null)
+ return false;
+ if (!oldValue.equals(newValue))
+ return false;
+ }
+ return true;
+ }
+
+ public void setProblemLimit(ProblemLimit problemLimit) {
+ this.problemLimit = problemLimit;
+ }
+
+ public void setPage(String page) {
+ this.page = page;
+ }
+
+ public void startMessageGroup(String groupName) { }
+}

Back to the top