Bug 508100: [Doclet] no help text created for interface methods 

  fixed help comment lookup for interfaces
  further integrated constants lookup in interfaces

Change-Id: If1df64b3949a07e84c6a4d78f6ce739e91339060
diff --git a/developers/org.eclipse.ease.helpgenerator/bin/org/eclipse/ease/helpgenerator/HTMLWriter$1.class b/developers/org.eclipse.ease.helpgenerator/bin/org/eclipse/ease/helpgenerator/HTMLWriter$1.class
index 464c767..0f611ed 100644
--- a/developers/org.eclipse.ease.helpgenerator/bin/org/eclipse/ease/helpgenerator/HTMLWriter$1.class
+++ b/developers/org.eclipse.ease.helpgenerator/bin/org/eclipse/ease/helpgenerator/HTMLWriter$1.class
Binary files differ
diff --git a/developers/org.eclipse.ease.helpgenerator/bin/org/eclipse/ease/helpgenerator/HTMLWriter$2.class b/developers/org.eclipse.ease.helpgenerator/bin/org/eclipse/ease/helpgenerator/HTMLWriter$2.class
index e0e93cc..8870558 100644
--- a/developers/org.eclipse.ease.helpgenerator/bin/org/eclipse/ease/helpgenerator/HTMLWriter$2.class
+++ b/developers/org.eclipse.ease.helpgenerator/bin/org/eclipse/ease/helpgenerator/HTMLWriter$2.class
Binary files differ
diff --git a/developers/org.eclipse.ease.helpgenerator/bin/org/eclipse/ease/helpgenerator/HTMLWriter$Overview.class b/developers/org.eclipse.ease.helpgenerator/bin/org/eclipse/ease/helpgenerator/HTMLWriter$Overview.class
index eaf5814..53de1b6 100644
--- a/developers/org.eclipse.ease.helpgenerator/bin/org/eclipse/ease/helpgenerator/HTMLWriter$Overview.class
+++ b/developers/org.eclipse.ease.helpgenerator/bin/org/eclipse/ease/helpgenerator/HTMLWriter$Overview.class
Binary files differ
diff --git a/developers/org.eclipse.ease.helpgenerator/bin/org/eclipse/ease/helpgenerator/HTMLWriter.class b/developers/org.eclipse.ease.helpgenerator/bin/org/eclipse/ease/helpgenerator/HTMLWriter.class
index bcd6976..86a98d1 100644
--- a/developers/org.eclipse.ease.helpgenerator/bin/org/eclipse/ease/helpgenerator/HTMLWriter.class
+++ b/developers/org.eclipse.ease.helpgenerator/bin/org/eclipse/ease/helpgenerator/HTMLWriter.class
Binary files differ
diff --git a/developers/org.eclipse.ease.helpgenerator/bin/org/eclipse/ease/helpgenerator/ModuleDoclet.class b/developers/org.eclipse.ease.helpgenerator/bin/org/eclipse/ease/helpgenerator/ModuleDoclet.class
index 5023a22..aca161f 100644
--- a/developers/org.eclipse.ease.helpgenerator/bin/org/eclipse/ease/helpgenerator/ModuleDoclet.class
+++ b/developers/org.eclipse.ease.helpgenerator/bin/org/eclipse/ease/helpgenerator/ModuleDoclet.class
Binary files differ
diff --git a/developers/org.eclipse.ease.helpgenerator/src/org/eclipse/ease/helpgenerator/HTMLWriter.java b/developers/org.eclipse.ease.helpgenerator/src/org/eclipse/ease/helpgenerator/HTMLWriter.java
index acc429f..681e1ca 100644
--- a/developers/org.eclipse.ease.helpgenerator/src/org/eclipse/ease/helpgenerator/HTMLWriter.java
+++ b/developers/org.eclipse.ease.helpgenerator/src/org/eclipse/ease/helpgenerator/HTMLWriter.java
@@ -1,6 +1,7 @@
 package org.eclipse.ease.helpgenerator;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
@@ -62,7 +63,8 @@
 		addLine(buffer, "<html>");
 		addLine(buffer, "<head>");
 		addLine(buffer, "	<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/>");
-		addLine(buffer, "	<link rel=\"stylesheet\" type=\"text/css\" href=\"../../org.eclipse.ease.help/help/css/modules_reference.css\" />");
+		addLine(buffer,
+				"	<link rel=\"stylesheet\" type=\"text/css\" href=\"../../org.eclipse.ease.help/help/css/modules_reference.css\" />");
 		addLine(buffer, "</head>");
 		addLine(buffer, "<body>");
 		addText(buffer, "	<div class=\"module\" title=\"");
@@ -109,7 +111,8 @@
 
 			final StringBuffer buffer = new StringBuffer();
 			addLine(buffer, "\t<h3>Dependencies</h3>");
-			addLine(buffer, "\t<p>This module depends on following other modules which will automatically be loaded.</p>");
+			addLine(buffer,
+					"\t<p>This module depends on following other modules which will automatically be loaded.</p>");
 			addLine(buffer, "\t<ul class=\"dependency\">");
 
 			for (final IMemento dependency : fDependencies)
@@ -137,21 +140,23 @@
 			addText(buffer, method.name());
 			addLine(buffer, "\">");
 
-			addLine(buffer,
-					"\t\t<h3" + (isDeprecated(method) ? " class=\"deprecatedText\"" : "") + "><a id=\"" + method.name() + "\">" + method.name() + "</a></h3>");
+			addLine(buffer, "\t\t<h3" + (isDeprecated(method) ? " class=\"deprecatedText\"" : "") + "><a id=\""
+					+ method.name() + "\">" + method.name() + "</a></h3>");
 
 			// synopsis
 			addLine(buffer, createSynopsis(method));
 
 			// main description
-			addLine(buffer, "\t\t<p class=\"description\">" + fLinkProvider.insertLinks(fClazz, method.commentText()) + "</p>");
+			addLine(buffer, "\t\t<p class=\"description\">"
+					+ fLinkProvider.insertLinks(fClazz, getMethodComment(fClazz, method)) + "</p>");
 
 			if (isDeprecated(method)) {
 				String deprecationText = method.tags("deprecated")[0].text();
 				if (deprecationText.isEmpty())
 					deprecationText = "This method is deprecated and might be removed in future versions.";
 
-				addLine(buffer, "\t\t<p class=\"warning\"><b>Deprecation warning:</b> " + fLinkProvider.insertLinks(fClazz, deprecationText) + "</p>");
+				addLine(buffer, "\t\t<p class=\"warning\"><b>Deprecation warning:</b> "
+						+ fLinkProvider.insertLinks(fClazz, deprecationText) + "</p>");
 			}
 
 			// aliases
@@ -198,7 +203,8 @@
 			final String codeText = (pos > 0) ? fullText.substring(0, pos) : fullText;
 			final String description = "<br />... " + ((pos > 0) ? fullText.substring(pos) : "");
 
-			addLine(buffer, "		<p class=\"example\"><em>Example:</em><code>" + codeText + "</code>" + description + "</p>");
+			addLine(buffer, "		<p class=\"example\"><em>Example:</em><code>" + codeText + "</code>" + description
+					+ "</p>");
 		}
 
 		return buffer;
@@ -209,7 +215,8 @@
 
 		if (!"void".equals(method.returnType().qualifiedTypeName())) {
 			addText(buffer, "		<p class=\"return\"><em>Returns:</em>");
-			addText(buffer, fLinkProvider.createClassText(LinkProvider.resolveClassName(method.returnType().qualifiedTypeName(), fClazz)));
+			addText(buffer, fLinkProvider
+					.createClassText(LinkProvider.resolveClassName(method.returnType().qualifiedTypeName(), fClazz)));
 
 			final Tag[] tags = method.tags("return");
 			if (tags.length > 0) {
@@ -238,18 +245,24 @@
 			for (final Parameter parameter : method.parameters()) {
 				addLine(buffer, "			<tr>");
 				addLine(buffer, "				<td>" + parameter.name() + "</td>");
-				addLine(buffer, "				<td>"
-						+ fLinkProvider.createClassText(LinkProvider.resolveClassName(parameter.type().qualifiedTypeName(), fClazz)) + "</td>");
-				addText(buffer, "				<td>" + fLinkProvider.insertLinks(fClazz, findComment(method, parameter.name())));
+				addLine(buffer,
+						"				<td>"
+								+ fLinkProvider.createClassText(
+										LinkProvider.resolveClassName(parameter.type().qualifiedTypeName(), fClazz))
+								+ "</td>");
+				addText(buffer, "				<td>"
+						+ fLinkProvider.insertLinks(fClazz, findComment(method, parameter.name())));
 
 				final AnnotationDesc parameterAnnotation = getScriptParameterAnnotation(parameter);
 				if (parameterAnnotation != null) {
 					addText(buffer, "<br /><b>Optional:</b> defaults to &lt;<i>");
 					for (final ElementValuePair pair : parameterAnnotation.elementValues()) {
-						if ("org.eclipse.ease.modules.ScriptParameter.defaultValue()".equals(pair.element().toString())) {
+						if ("org.eclipse.ease.modules.ScriptParameter.defaultValue()"
+								.equals(pair.element().toString())) {
 							String defaultValue = pair.value().toString();
 
-							if ((!String.class.getName().equals(parameter.type().qualifiedTypeName())) && (defaultValue.length() > 2))
+							if ((!String.class.getName().equals(parameter.type().qualifiedTypeName()))
+									&& (defaultValue.length() > 2))
 								// remove quotes from default
 								// value
 								defaultValue = defaultValue.substring(1, defaultValue.length() - 1);
@@ -295,7 +308,8 @@
 		final StringBuffer buffer = new StringBuffer();
 
 		addText(buffer, "		<p class=\"synopsis\">");
-		addText(buffer, fLinkProvider.createClassText(LinkProvider.resolveClassName(method.returnType().qualifiedTypeName(), fClazz)));
+		addText(buffer, fLinkProvider
+				.createClassText(LinkProvider.resolveClassName(method.returnType().qualifiedTypeName(), fClazz)));
 		addText(buffer, " ");
 		addText(buffer, method.name());
 		addText(buffer, "(");
@@ -304,7 +318,8 @@
 			if (parameterAnnotation != null)
 				addText(buffer, "[");
 
-			addText(buffer, fLinkProvider.createClassText(LinkProvider.resolveClassName(parameter.type().qualifiedTypeName(), fClazz)));
+			addText(buffer, fLinkProvider
+					.createClassText(LinkProvider.resolveClassName(parameter.type().qualifiedTypeName(), fClazz)));
 			addText(buffer, " ");
 			addText(buffer, parameter.name());
 			if (parameterAnnotation != null)
@@ -334,10 +349,12 @@
 		final List<Overview> overview = new ArrayList<Overview>();
 
 		for (final MethodDoc method : getExportedMethods()) {
-			overview.add(new Overview(method.name(), method.name(), method.commentText(), isDeprecated(method)));
+			overview.add(
+					new Overview(method.name(), method.name(), getMethodComment(fClazz, method), isDeprecated(method)));
 			for (final String alias : getFunctionAliases(method))
-				overview.add(
-						new Overview(alias, method.name(), "Alias for <a href=\"#" + method.name() + "\">" + method.name() + "</a>.", isDeprecated(method)));
+				overview.add(new Overview(alias, method.name(),
+						"Alias for <a href=\"#" + method.name() + "\">" + method.name() + "</a>.",
+						isDeprecated(method)));
 		}
 
 		Collections.sort(overview);
@@ -346,10 +363,12 @@
 			addLine(buffer, "		<tr>");
 			if (!entry.fDeprecated) {
 				addLine(buffer, "			<td><a href=\"#" + entry.fLinkID + "\">" + entry.fTitle + "</a>()</td>");
-				addLine(buffer, "			<td>" + fLinkProvider.insertLinks(fClazz, getFirstSentence(entry.fDescription)) + "</td>");
+				addLine(buffer, "			<td>"
+						+ fLinkProvider.insertLinks(fClazz, getFirstSentence(entry.fDescription)) + "</td>");
 
 			} else {
-				addLine(buffer, "			<td class=\"deprecatedText\"><a href=\"#" + entry.fLinkID + "\">" + entry.fTitle + "</a>()</td>");
+				addLine(buffer, "			<td class=\"deprecatedText\"><a href=\"#" + entry.fLinkID + "\">"
+						+ entry.fTitle + "</a>()</td>");
 				addLine(buffer, "			<td class=\"deprecatedDescription\"><b>Deprecated:</b> "
 						+ fLinkProvider.insertLinks(fClazz, getFirstSentence(entry.fDescription)) + "</td>");
 			}
@@ -362,6 +381,30 @@
 		return buffer;
 	}
 
+	private static String getMethodComment(ClassDoc baseClass, MethodDoc method) {
+		String comment = method.commentText();
+
+		if ((comment == null) || (comment.isEmpty())) {
+			// try to look up interfaces
+			for (ClassDoc iface : baseClass.interfaces()) {
+				for (MethodDoc ifaceMethod : iface.methods()) {
+					if (method.overrides(ifaceMethod)) {
+						comment = ifaceMethod.commentText();
+						if ((comment != null) && (!comment.isEmpty()))
+							return comment;
+					}
+				}
+			}
+
+			// not found, retry with super class
+			ClassDoc parent = baseClass.superclass();
+			if (parent != null)
+				return getMethodComment(parent, method);
+		}
+
+		return comment;
+	}
+
 	private StringBuffer createConstantsSection() {
 		final StringBuffer buffer = new StringBuffer();
 
@@ -380,17 +423,19 @@
 
 				if (!isDeprecated(field)) {
 					addLine(buffer, "			<td><a id=\"" + field.name() + "\">" + field.name() + "</a></td>");
-					addLine(buffer, "			<td>" + fLinkProvider.insertLinks(fClazz, field.commentText()) + "</td>");
+					addLine(buffer,
+							"			<td>" + fLinkProvider.insertLinks(fClazz, field.commentText()) + "</td>");
 
 				} else {
-					addLine(buffer, "			<td><a id=\"" + field.name() + "\" class=\"deprecatedText\">" + field.name() + "</a></td>");
+					addLine(buffer, "			<td><a id=\"" + field.name() + "\" class=\"deprecatedText\">"
+							+ field.name() + "</a></td>");
 					addText(buffer, "			<td>" + fLinkProvider.insertLinks(fClazz, field.commentText()));
 					String deprecationText = field.tags("deprecated")[0].text();
 					if (deprecationText.isEmpty())
 						deprecationText = "This constant is deprecated and might be removed in future versions.";
 
-					addText(buffer, "				<div class=\"warning\"><b>Deprecation warning:</b> " + fLinkProvider.insertLinks(fClazz, deprecationText)
-							+ "</div>");
+					addText(buffer, "				<div class=\"warning\"><b>Deprecation warning:</b> "
+							+ fLinkProvider.insertLinks(fClazz, deprecationText) + "</div>");
 					addLine(buffer, "</td>");
 				}
 
@@ -473,7 +518,7 @@
 
 	private List<MethodDoc> getExportedMethods() {
 		final List<MethodDoc> methods = new ArrayList<MethodDoc>();
-		boolean hasAnnotation = hasWrapToScriptAnnotation();
+		boolean hasAnnotation = hasWrapToScriptAnnotation(fClazz);
 
 		ClassDoc clazzDoc = fClazz;
 		while ((clazzDoc != null) && (!Object.class.getName().equals(clazzDoc.qualifiedName()))) {
@@ -499,16 +544,26 @@
 
 	private List<FieldDoc> getExportedFields() {
 		final List<FieldDoc> fields = new ArrayList<FieldDoc>();
-		ClassDoc clazzDoc = fClazz;
-		boolean hasAnnotation = hasWrapToScriptAnnotation();
-		while ((clazzDoc != null) && (!Object.class.getName().equals(clazzDoc.qualifiedName()))) {
+
+		boolean hasAnnotation = hasWrapToScriptAnnotation(fClazz);
+
+		ArrayList<ClassDoc> candidates = new ArrayList<ClassDoc>();
+		candidates.add(fClazz);
+		while (!candidates.isEmpty()) {
+			ClassDoc clazzDoc = candidates.remove(0);
 
 			for (FieldDoc field : clazzDoc.fields()) {
 				if ((!hasAnnotation) || (getWrapAnnotation(field) != null))
 					fields.add(field);
 			}
 
-			clazzDoc = clazzDoc.superclass();
+			// add interfaces
+			candidates.addAll(Arrays.asList(clazzDoc.interfaces()));
+
+			// add super class/interface
+			ClassDoc nextCandidate = clazzDoc.superclass();
+			if ((nextCandidate != null) && (!Object.class.getName().equals(nextCandidate.qualifiedName())))
+				candidates.add(nextCandidate);
 		}
 
 		// sort fields alphabetically
@@ -523,8 +578,7 @@
 		return fields;
 	}
 
-	private boolean hasWrapToScriptAnnotation() {
-		ClassDoc clazzDoc = fClazz;
+	private static boolean hasWrapToScriptAnnotation(ClassDoc clazzDoc) {
 		while (clazzDoc != null) {
 			for (final MethodDoc method : clazzDoc.methods()) {
 				if (getWrapAnnotation(method) != null)
diff --git a/developers/org.eclipse.ease.helpgenerator/src/org/eclipse/ease/helpgenerator/ModuleDoclet.java b/developers/org.eclipse.ease.helpgenerator/src/org/eclipse/ease/helpgenerator/ModuleDoclet.java
index 3b6426f..40aea3d 100644
--- a/developers/org.eclipse.ease.helpgenerator/src/org/eclipse/ease/helpgenerator/ModuleDoclet.java
+++ b/developers/org.eclipse.ease.helpgenerator/src/org/eclipse/ease/helpgenerator/ModuleDoclet.java
@@ -45,9 +45,11 @@
 
 		final String repositoryRoot = new File(System.getProperty("user.dir")).getParentFile().getParent();
 
-		final String[] javadocargs = { "-sourcepath", "/data/develop/workspaces/EASE/org.eclipse.ease.modules/plugins/org.eclipse.ease.modules.platform/src",
-				"-root", "/data/develop/workspaces/EASE/org.eclipse.ease.modules/plugins/org.eclipse.ease.modules.platform", "-doclet",
-				ModuleDoclet.class.getName(), "-docletpath",
+		final String[] javadocargs = { "-sourcepath",
+				"/data/develop/workspaces/EASE/org.eclipse.ease.modules/plugins/org.eclipse.ease.modules.platform/src",
+				"-root",
+				"/data/develop/workspaces/EASE/org.eclipse.ease.modules/plugins/org.eclipse.ease.modules.platform",
+				"-doclet", ModuleDoclet.class.getName(), "-docletpath",
 				"/data/develop/workspaces/EASE/org.eclipse.ease.core/developers/org.eclipse.ease.helpgenerator/bin",
 
 				"org.eclipse.ease.modules.platform"
@@ -64,24 +66,48 @@
 				"-docletpath", repositoryRoot + "/developers/org.eclipse.ease.helpgenerator/bin",
 
 				"-link", "http://docs.oracle.com/javase/8/docs/api",
-				// "-linkOffline", "http://localhost", "http://docs.oracle.com/javase/8/docs/api",
+				// "-linkOffline", "http://localhost",
+				// "http://docs.oracle.com/javase/8/docs/api",
 
 				"org.eclipse.ease.modules", "org.eclipse.ease" };
 
-		final String[] javadocargs3 = { "-sourcepath", "C:/userdata/workspaces/EASE/org.eclipse.ease.core/plugins/org.eclipse.ease/src",
+		final String[] javadocargs3 = { "-sourcepath",
+				"C:/userdata/workspaces/EASE/org.eclipse.ease.core/plugins/org.eclipse.ease/src",
 
 				"-root", "C:/userdata/workspaces/EASE/org.eclipse.ease.core/plugins/org.eclipse.ease",
 
 				"-doclet", ModuleDoclet.class.getName(),
 
-				"-docletpath", "C:/userdata/workspaces/EASE/org.eclipse.ease.core/developers/org.eclipse.ease.helpgenerator/bin",
+				"-docletpath",
+				"C:/userdata/workspaces/EASE/org.eclipse.ease.core/developers/org.eclipse.ease.helpgenerator/bin",
 
 				// "-link", "http://docs.oracle.com/javase/8/docs/api",
-				// "-linkOffline", "http://localhost", "http://docs.oracle.com/javase/8/docs/api",
+				// "-linkOffline", "http://localhost",
+				// "http://docs.oracle.com/javase/8/docs/api",
 
 				"org.eclipse.ease.modules", "org.eclipse.ease" };
 
-		com.sun.tools.javadoc.Main.execute(javadocargs3);
+		final String[] javadocargs4 = {
+				"test",
+
+				// folder containing source code
+				"-sourcepath", "/home/christian/workspaces/ease_neon/testDocs/src",
+				// project root folder
+				"-root", "/home/christian/workspaces/ease_neon/testDocs",
+				// doclet class name
+				"-doclet", ModuleDoclet.class.getName(),
+				// doclet bin folder
+				"-docletpath",
+				"/home/christian/workspaces/ease_neon/org.eclipse.ease.core/developers/org.eclipse.ease.helpgenerator/bin"
+
+				// "-link", "http://docs.oracle.com/javase/8/docs/api",
+				// "-linkOffline", "http://localhost",
+				// "http://docs.oracle.com/javase/8/docs/api",
+
+				}
+		;
+
+		com.sun.tools.javadoc.Main.execute(javadocargs4);
 	}
 
 	private static final String OPTION_PROJECT_ROOT = "-root";
@@ -130,7 +156,8 @@
 
 			else if (OPTION_LINK.equals(option[0])) {
 				try {
-					fLinkProvider.registerAddress(option[1], parsePackages(new URL(option[1] + "/package-list").openStream()));
+					fLinkProvider.registerAddress(option[1],
+							parsePackages(new URL(option[1] + "/package-list").openStream()));
 				} catch (final MalformedURLException e) {
 					System.out.println("Error: cannot parse external URL " + option[1]);
 				} catch (final IOException e) {
@@ -149,7 +176,8 @@
 
 					try {
 						// try to read from local file
-						fLinkProvider.registerAddress(option[1], parsePackages(new FileInputStream(option[2] + File.separator + "package-list")));
+						fLinkProvider.registerAddress(option[1],
+								parsePackages(new FileInputStream(option[2] + File.separator + "package-list")));
 					} catch (final FileNotFoundException e1) {
 						System.out.println("Error: cannot read from " + option[2]);
 					}
@@ -231,7 +259,8 @@
 			topicNode.putBoolean("sort", true);
 			topicNode.createChild("anchor").putString("id", "modules_anchor");
 
-			final File targetFile = getChild(getChild(fRootFolder, "help"), createCategoryFileName(node.getString("id")));
+			final File targetFile = getChild(getChild(fRootFolder, "help"),
+					createCategoryFileName(node.getString("id")));
 			writeFile(targetFile, memento.toString());
 			created = true;
 		}
@@ -417,11 +446,13 @@
 			// only add classes which are registered in our modules lookup table
 			if (fModuleNodes.containsKey(clazz.qualifiedName())) {
 				// class found to create help for
-				final String content = new HTMLWriter(clazz, fLinkProvider, fModuleNodes.get(clazz.qualifiedName()).getChildren("dependency"))
-						.createContents(fModuleNodes.get(clazz.qualifiedName()).getString("name"));
+				final String content = new HTMLWriter(clazz, fLinkProvider,
+						fModuleNodes.get(clazz.qualifiedName()).getChildren("dependency"))
+								.createContents(fModuleNodes.get(clazz.qualifiedName()).getString("name"));
 
 				// write document
-				final File targetFile = getChild(getChild(fRootFolder, "help"), createHTMLFileName(fModuleNodes.get(clazz.qualifiedName()).getString("id")));
+				final File targetFile = getChild(getChild(fRootFolder, "help"),
+						createHTMLFileName(fModuleNodes.get(clazz.qualifiedName()).getString("id")));
 				writeFile(targetFile, content);
 				createdFiles = true;
 			}