Bug 539406 - Multi-fix for since tag operations in API tool errors
Change-Id: I6148821d5d75bd724b3d6f6cf1cf33db00139ce7
Signed-off-by: Vikas Chandra <Vikas.Chandra@in.ibm.com>
diff --git a/apitools/org.eclipse.pde.api.tools.ui/src/org/eclipse/pde/api/tools/ui/internal/markers/SinceTagAfterVersionUpdateResolution.java b/apitools/org.eclipse.pde.api.tools.ui/src/org/eclipse/pde/api/tools/ui/internal/markers/SinceTagAfterVersionUpdateResolution.java
index a440dfd..de5ffde 100644
--- a/apitools/org.eclipse.pde.api.tools.ui/src/org/eclipse/pde/api/tools/ui/internal/markers/SinceTagAfterVersionUpdateResolution.java
+++ b/apitools/org.eclipse.pde.api.tools.ui/src/org/eclipse/pde/api/tools/ui/internal/markers/SinceTagAfterVersionUpdateResolution.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2019 IBM Corporation and others.
+ * Copyright (c) 2019, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -48,6 +48,12 @@
 			}
 			this.newVersionValue = markerVersion.getAttribute(IApiMarkerConstants.MARKER_ATTR_VERSION, null);
 		}
+
+		try {
+			marker.setAttribute(IApiMarkerConstants.MARKER_ATTR_VERSION, this.newVersionValue);
+		} catch (CoreException e) {
+			ApiUIPlugin.log(e);
+		}
 		super.run(marker);
 	}
 
@@ -57,4 +63,10 @@
 				markerVersion.getAttribute(IApiMarkerConstants.MARKER_ATTR_VERSION, null));
 	}
 
+	@Override
+	public IMarker[] findOtherMarkers(IMarker[] markers) {
+
+		return new IMarker[0];
+	}
+
 }
diff --git a/apitools/org.eclipse.pde.api.tools.ui/src/org/eclipse/pde/api/tools/ui/internal/markers/SinceTagResolution.java b/apitools/org.eclipse.pde.api.tools.ui/src/org/eclipse/pde/api/tools/ui/internal/markers/SinceTagResolution.java
index 00e1ef5..da4e7bf 100644
--- a/apitools/org.eclipse.pde.api.tools.ui/src/org/eclipse/pde/api/tools/ui/internal/markers/SinceTagResolution.java
+++ b/apitools/org.eclipse.pde.api.tools.ui/src/org/eclipse/pde/api/tools/ui/internal/markers/SinceTagResolution.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2008, 2018 IBM Corporation and others.
+ * Copyright (c) 2008, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -13,6 +13,8 @@
  *******************************************************************************/
 package org.eclipse.pde.api.tools.ui.internal.markers;
 
+import java.util.HashSet;
+
 import org.eclipse.core.resources.IMarker;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
@@ -24,8 +26,8 @@
 import org.eclipse.pde.api.tools.internal.provisional.IApiMarkerConstants;
 import org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblem;
 import org.eclipse.swt.graphics.Image;
-import org.eclipse.ui.IMarkerResolution2;
 import org.eclipse.ui.progress.UIJob;
+import org.eclipse.ui.views.markers.WorkbenchMarkerResolution;
 
 /**
  * This resolution helps users to pick a default API profile when the tooling
@@ -33,11 +35,14 @@
  *
  * @since 1.0.0
  */
-public class SinceTagResolution implements IMarkerResolution2 {
+public class SinceTagResolution extends WorkbenchMarkerResolution {
 	int kind;
 	String newVersionValue;
+	IMarker marker;
+	IMarker[] otherMarkers;
 
 	public SinceTagResolution(IMarker marker) {
+		this.marker = marker;
 		this.kind = ApiProblemFactory.getProblemKind(marker.getAttribute(IApiMarkerConstants.MARKER_ATTR_PROBLEM_ID, 0));
 		this.newVersionValue = marker.getAttribute(IApiMarkerConstants.MARKER_ATTR_VERSION, null);
 	}
@@ -71,6 +76,7 @@
 
 	@Override
 	public void run(final IMarker marker) {
+
 		String title = null;
 		if (IApiProblem.SINCE_TAG_INVALID == this.kind) {
 			title = NLS.bind(MarkerMessages.SinceTagResolution_change_since_tag, this.newVersionValue);
@@ -82,7 +88,13 @@
 		UIJob job = new UIJob(title) {
 			@Override
 			public IStatus runInUIThread(IProgressMonitor monitor) {
-				UpdateSinceTagOperation updateSinceTagOperation = new UpdateSinceTagOperation(marker, SinceTagResolution.this.kind, SinceTagResolution.this.newVersionValue);
+				SinceTagResolution.this.kind = ApiProblemFactory
+						.getProblemKind(marker.getAttribute(IApiMarkerConstants.MARKER_ATTR_PROBLEM_ID, 0));
+				SinceTagResolution.this.newVersionValue = marker.getAttribute(IApiMarkerConstants.MARKER_ATTR_VERSION,
+						null);
+				UpdateSinceTagOperation updateSinceTagOperation = new UpdateSinceTagOperation(marker, otherMarkers,
+						SinceTagResolution.this.kind,
+						marker.getAttribute(IApiMarkerConstants.MARKER_ATTR_VERSION, null));
 				updateSinceTagOperation.run(monitor);
 				return Status.OK_STATUS;
 			}
@@ -90,4 +102,23 @@
 		job.setSystem(true);
 		job.schedule();
 	}
+
+	@Override
+	public IMarker[] findOtherMarkers(IMarker[] markers) {
+		HashSet<IMarker> mset = new HashSet<>(markers.length);
+		for (IMarker iMarker : markers) {
+			if (iMarker.equals(marker)) {
+				continue;
+			}
+			int kind2 = ApiProblemFactory
+					.getProblemKind(iMarker.getAttribute(IApiMarkerConstants.MARKER_ATTR_PROBLEM_ID, 0));
+
+			if (kind2 == this.kind) {
+				mset.add(iMarker);
+			}
+		}
+		int size = mset.size();
+		otherMarkers = mset.toArray(new IMarker[size]);
+		return otherMarkers;
+	}
 }
diff --git a/apitools/org.eclipse.pde.api.tools.ui/src/org/eclipse/pde/api/tools/ui/internal/markers/UpdateSinceTagOperation.java b/apitools/org.eclipse.pde.api.tools.ui/src/org/eclipse/pde/api/tools/ui/internal/markers/UpdateSinceTagOperation.java
index 326eb63..152cbff 100644
--- a/apitools/org.eclipse.pde.api.tools.ui/src/org/eclipse/pde/api/tools/ui/internal/markers/UpdateSinceTagOperation.java
+++ b/apitools/org.eclipse.pde.api.tools.ui/src/org/eclipse/pde/api/tools/ui/internal/markers/UpdateSinceTagOperation.java
@@ -44,11 +44,16 @@
 public class UpdateSinceTagOperation {
 
 	private IMarker fMarker;
+	private IMarker[] otherIMarkers;
 	private int sinceTagType;
 	private String sinceTagVersion;
 
-	public UpdateSinceTagOperation(IMarker marker, int sinceTagType, String sinceTagVersion) {
+	public UpdateSinceTagOperation(IMarker marker, IMarker[] otherMarkers, int sinceTagType, String sinceTagVersion) {
 		this.fMarker = marker;
+		this.otherIMarkers = otherMarkers;
+		if(this.otherIMarkers == null) {
+			this.otherIMarkers = new IMarker[0];
+		}
 		this.sinceTagType = sinceTagType;
 		this.sinceTagVersion = sinceTagVersion;
 	}
@@ -66,8 +71,9 @@
 			int intValue = charStartAttribute.intValue();
 			IJavaElement javaElement = null;
 			IJavaElement handleElement = null;
+			IResource resource = null;
 			if (intValue > 0) {
-				IResource resource = this.fMarker.getResource();
+				resource = this.fMarker.getResource();
 				javaElement = JavaCore.create(resource);
 			} else {
 				// this is a case where the marker is reported against the
@@ -125,65 +131,30 @@
 					unit.recordModifications();
 					AST ast = unit.getAST();
 					ASTRewrite rewrite = ASTRewrite.create(ast);
-					if (IApiProblem.SINCE_TAG_MISSING == this.sinceTagType) {
-						Javadoc docnode = node.getJavadoc();
-						if (docnode == null) {
-							docnode = ast.newJavadoc();
-							// we do not want to create a new empty Javadoc node
-							// in
-							// the AST if there are no missing tags
-							rewrite.set(node, node.getJavadocProperty(), docnode, null);
-						} else {
-							List<TagElement> tags = docnode.tags();
-							boolean found = false;
-							loop: for (TagElement element : tags) {
-								String tagName = element.getTagName();
-								if (TagElement.TAG_SINCE.equals(tagName)) {
-									found = true;
-									break loop;
-								}
+					processNode(unit, rewrite, node);
+					// check otherMarkers if same resource - process together
+					for (IMarker iMarker : otherIMarkers) {
+						BodyDeclaration node2 = null;
+						IResource otherResource = iMarker.getResource();
+						if (otherResource.equals(resource)) {
+							Integer charStartAttribute2 = (Integer) iMarker.getAttribute(IMarker.CHAR_START);
+							int intValue2 = charStartAttribute2.intValue();
+							NodeFinder nodeFinder2 = new NodeFinder(intValue2);
+							unit.accept(nodeFinder2);
+							if (monitor != null) {
+								monitor.worked(1);
 							}
-							if (found) {
-								return;
+							node2 = nodeFinder2.getNode();
+							if (node == node2) {
+								continue;
 							}
+							processNode(unit, rewrite, node2);
+
 						}
-						ListRewrite lrewrite = rewrite.getListRewrite(docnode, Javadoc.TAGS_PROPERTY);
-						// check the existing tags list
-						TagElement newtag = ast.newTagElement();
-						newtag.setTagName(TagElement.TAG_SINCE);
-						TextElement textElement = ast.newTextElement();
-						textElement.setText(this.sinceTagVersion);
-						newtag.fragments().add(textElement);
-						lrewrite.insertLast(newtag, null);
-					} else {
-						Javadoc docnode = node.getJavadoc();
-						List<TagElement> tags = docnode.tags();
-						TagElement sinceTag = null;
-						for (TagElement tagElement : tags) {
-							if (TagElement.TAG_SINCE.equals(tagElement.getTagName())) {
-								sinceTag = tagElement;
-								break;
-							}
-						}
-						if (sinceTag != null) {
-							List<TextElement> fragments = sinceTag.fragments();
-							if (fragments.size() >= 1) {
-								TextElement textElement = fragments.get(0);
-								StringBuilder buffer = new StringBuilder();
-								buffer.append(' ').append(this.sinceTagVersion);
-								rewrite.set(textElement, TextElement.TEXT_PROPERTY, String.valueOf(buffer), null);
-							} else {
-								ListRewrite lrewrite = rewrite.getListRewrite(docnode, Javadoc.TAGS_PROPERTY);
-								// check the existing tags list
-								TagElement newtag = ast.newTagElement();
-								newtag.setTagName(TagElement.TAG_SINCE);
-								TextElement textElement = ast.newTextElement();
-								textElement.setText(this.sinceTagVersion);
-								newtag.fragments().add(textElement);
-								lrewrite.replace(sinceTag, newtag, null);
-							}
-						}
+
 					}
+
+
 					try {
 						if (monitor != null) {
 							monitor.worked(1);
@@ -220,4 +191,71 @@
 			}
 		}
 	}
+
+
+
+	private void processNode(CompilationUnit unit, ASTRewrite rewrite, BodyDeclaration node) {
+		AST ast = unit.getAST();
+
+		if (IApiProblem.SINCE_TAG_MISSING == this.sinceTagType) {
+			Javadoc docnode = node.getJavadoc();
+			if (docnode == null) {
+				docnode = ast.newJavadoc();
+				// we do not want to create a new empty Javadoc node
+				// in
+				// the AST if there are no missing tags
+				rewrite.set(node, node.getJavadocProperty(), docnode, null);
+			} else {
+				List<TagElement> tags = docnode.tags();
+				boolean found = false;
+				loop: for (TagElement element : tags) {
+					String tagName = element.getTagName();
+					if (TagElement.TAG_SINCE.equals(tagName)) {
+						found = true;
+						break loop;
+					}
+				}
+				if (found) {
+					return;
+				}
+			}
+			ListRewrite lrewrite = rewrite.getListRewrite(docnode, Javadoc.TAGS_PROPERTY);
+			// check the existing tags list
+			TagElement newtag = ast.newTagElement();
+			newtag.setTagName(TagElement.TAG_SINCE);
+			TextElement textElement = ast.newTextElement();
+			textElement.setText(this.sinceTagVersion);
+			newtag.fragments().add(textElement);
+			lrewrite.insertLast(newtag, null);
+		} else {
+			Javadoc docnode = node.getJavadoc();
+			List<TagElement> tags = docnode.tags();
+			TagElement sinceTag = null;
+			for (TagElement tagElement : tags) {
+				if (TagElement.TAG_SINCE.equals(tagElement.getTagName())) {
+					sinceTag = tagElement;
+					break;
+				}
+			}
+			if (sinceTag != null) {
+				List<TextElement> fragments = sinceTag.fragments();
+				if (fragments.size() >= 1) {
+					TextElement textElement = fragments.get(0);
+					StringBuilder buffer = new StringBuilder();
+					buffer.append(' ').append(this.sinceTagVersion);
+					rewrite.set(textElement, TextElement.TEXT_PROPERTY, String.valueOf(buffer), null);
+				} else {
+					ListRewrite lrewrite = rewrite.getListRewrite(docnode, Javadoc.TAGS_PROPERTY);
+					// check the existing tags list
+					TagElement newtag = ast.newTagElement();
+					newtag.setTagName(TagElement.TAG_SINCE);
+					TextElement textElement = ast.newTextElement();
+					textElement.setText(this.sinceTagVersion);
+					newtag.fragments().add(textElement);
+					lrewrite.replace(sinceTag, newtag, null);
+				}
+			}
+		}
+
+	}
 }