args) {
+ StabilityOptions.setLevel(StabilityOptions.Level.UNSTABLE);
+ return true;
+ }
+ });
+ return s;
+ }
+
+ @Override
+ public SourceVersion getSupportedSourceVersion() {
+ return delegate.getSupportedSourceVersion();
+ }
+
+ @Override
+ public boolean run(DocletEnvironment env) {
+ System.out.println(getName());
+ RootDocProcessor.setTreatUnannotatedClassesAsPrivate(true);
+ StabilityOptions.applyToRootProcessor();
+ DocletEnvironment filtered = RootDocProcessor.process(env);
+ return delegate.run(filtered);
+ }
+
+ /**
+ * Legacy doclet entry point used by Javadoc.
+ *
+ * @param env the doclet environment
+ * @return true if the doclet completed successfully
+ */
+ public static boolean start(DocletEnvironment env) {
+ return new IncludePublicAnnotationsStandardDoclet().run(env);
+ }
+
+ /**
+ * Returns the length of a supported option.
+ *
+ * @param option the option name
+ * @return the number of arguments including the option itself
+ */
+ public static int optionLength(String option) {
+ Integer length = StabilityOptions.optionLength(option);
+ if (length != null) {
+ return length;
+ }
+ for (jdk.javadoc.doclet.Doclet.Option o :
+ new StandardDoclet().getSupportedOptions()) {
+ for (String name : o.getNames()) {
+ if (name.equals(option)) {
+ return o.getArgumentCount() + 1;
+ }
+ }
+ }
+ return 0;
+ }
+
+ /**
+ * Validates options before running the doclet.
+ *
+ * @param options the options to validate
+ * @param reporter the reporter to use for diagnostics
+ * @return true if the options are valid
+ */
+ public static boolean validOptions(String[][] options, Reporter reporter) {
+ StabilityOptions.validOptions(options, reporter);
+ return true;
+ }
+}
diff --git a/hadoop-common-project/hadoop-annotations/src/main/java/org/apache/hadoop/classification/tools/RootDocProcessor.java b/hadoop-common-project/hadoop-annotations/src/main/java/org/apache/hadoop/classification/tools/RootDocProcessor.java
new file mode 100644
index 0000000000000..741a1c7d06841
--- /dev/null
+++ b/hadoop-common-project/hadoop-annotations/src/main/java/org/apache/hadoop/classification/tools/RootDocProcessor.java
@@ -0,0 +1,369 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.classification.tools;
+
+import jdk.javadoc.doclet.DocletEnvironment;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.WeakHashMap;
+import java.util.stream.Collectors;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.classification.InterfaceStability;
+
+/**
+ * Process the {@link DocletEnvironment} by substituting with (nested) proxy objects that
+ * exclude elements with Private or LimitedPrivate annotations.
+ *
+ * Based on code from http://www.sixlegs.com/blog/java/exclude-javadoc-tag.html.
+ */
+final class RootDocProcessor {
+
+ private static String stability = StabilityOptions.UNSTABLE_OPTION;
+ private static boolean treatUnannotatedClassesAsPrivate = false;
+
+ static void setStability(String value) {
+ stability = value;
+ }
+
+ private RootDocProcessor() {
+ // no instances
+ }
+
+
+ static String getStability() {
+ return stability;
+ }
+
+ static void setTreatUnannotatedClassesAsPrivate(boolean value) {
+ treatUnannotatedClassesAsPrivate = value;
+ }
+
+ static boolean isTreatUnannotatedClassesAsPrivate() {
+ return treatUnannotatedClassesAsPrivate;
+ }
+
+ public static DocletEnvironment process(DocletEnvironment root) {
+ return (DocletEnvironment) wrap(root, DocletEnvironment.class);
+ }
+
+ private static final Map PROXIES = new WeakHashMap<>();
+
+ private static Object wrap(Object obj, Class> expectedType) {
+ if (obj == null) {
+ return null;
+ }
+
+ if (obj instanceof DocletEnvironment) {
+ return getProxy(obj, new Class>[]{DocletEnvironment.class},
+ new EnvHandler((DocletEnvironment) obj));
+ }
+
+ if (obj instanceof Element) {
+ return getElementProxy((Element) obj);
+ }
+
+ if (obj instanceof Set) {
+ return filterAndWrapIterable((Iterable>) obj, true);
+ }
+ if (obj instanceof Collection) {
+ return filterAndWrapIterable((Iterable>) obj, false);
+ }
+ if (obj instanceof Iterable) {
+ return filterAndWrapIterable((Iterable>) obj, false);
+ }
+
+ if (obj.getClass().isArray()) {
+ int len = Array.getLength(obj);
+ Object[] res = new Object[len];
+ for (int i = 0; i < len; i++) {
+ Object v = Array.get(obj, i);
+ res[i] = wrap(v, v != null ? v.getClass() : Object.class);
+ }
+ return res;
+ }
+
+ return obj;
+ }
+
+ private static Object getElementProxy(Element el) {
+ Object cached = PROXIES.get(el);
+ if (cached != null) {
+ return cached;
+ }
+
+ Set> ifaces = new LinkedHashSet<>();
+ Collections.addAll(ifaces, el.getClass().getInterfaces());
+ ifaces.add(Element.class);
+ if (el instanceof TypeElement) {
+ ifaces.add(TypeElement.class);
+ }
+ if (el instanceof PackageElement) {
+ ifaces.add(PackageElement.class);
+ }
+ if (el instanceof ExecutableElement) {
+ ifaces.add(ExecutableElement.class);
+ }
+ if (el instanceof VariableElement) {
+ ifaces.add(VariableElement.class);
+ }
+
+ Object proxy = getProxy(el, ifaces.toArray(new Class>[0]), new ElementHandler(el));
+ PROXIES.put(el, proxy);
+ return proxy;
+ }
+
+ private static Object getProxy(Object target, Class>[] ifaces, InvocationHandler h) {
+ Object cached = PROXIES.get(target);
+ if (cached != null) {
+ return cached;
+ }
+ Object p = Proxy.newProxyInstance(target.getClass().getClassLoader(), ifaces, h);
+ PROXIES.put(target, p);
+ return p;
+ }
+
+ @SuppressWarnings("unchecked")
+ private static Object filterAndWrapIterable(Iterable> iterable, boolean preserveSet) {
+ if (iterable == null) {
+ return null;
+ }
+ if (preserveSet) {
+ Set out = new LinkedHashSet<>();
+ for (Object o : iterable) {
+ if (o instanceof Element) {
+ Element el = (Element) o;
+ if (!exclude(el)) {
+ out.add(getElementProxy(el));
+ }
+ } else {
+ out.add(wrap(o, o != null ? o.getClass() : Object.class));
+ }
+ }
+ return out;
+ } else {
+ List out = new ArrayList<>();
+ for (Object o : iterable) {
+ if (o instanceof Element) {
+ Element el = (Element) o;
+ if (!exclude(el)) {
+ out.add(getElementProxy(el));
+ }
+ } else {
+ out.add(wrap(o, o != null ? o.getClass() : Object.class));
+ }
+ }
+ return out;
+ }
+ }
+
+ private static Object unwrap(Object maybeProxy) {
+ if (!(maybeProxy instanceof Proxy)) {
+ return maybeProxy;
+ }
+ InvocationHandler ih = Proxy.getInvocationHandler(maybeProxy);
+ if (ih instanceof BaseHandler) {
+ return ((BaseHandler) ih).target;
+ }
+ return maybeProxy;
+ }
+
+ private static boolean exclude(Element el) {
+ boolean sawPublic = false;
+
+ for (AnnotationMirror am : el.getAnnotationMirrors()) {
+ final String qname = am.getAnnotationType().toString();
+
+ if (qname.equals(InterfaceAudience.Private.class.getCanonicalName())
+ || qname.equals(InterfaceAudience.LimitedPrivate.class.getCanonicalName())) {
+ return true;
+ }
+
+ if (stability.equals(StabilityOptions.EVOLVING_OPTION)) {
+ if (qname.equals(InterfaceStability.Unstable.class.getCanonicalName())) {
+ return true;
+ }
+ }
+ if (stability.equals(StabilityOptions.STABLE_OPTION)) {
+ if (qname.equals(InterfaceStability.Unstable.class.getCanonicalName())
+ || qname.equals(InterfaceStability.Evolving.class.getCanonicalName())) {
+ return true;
+ }
+ }
+
+ if (qname.equals(InterfaceAudience.Public.class.getCanonicalName())) {
+ sawPublic = true;
+ }
+ }
+
+ if (sawPublic) {
+ return false;
+ }
+
+ if (isTreatUnannotatedClassesAsPrivate()) {
+ ElementKind k = el.getKind();
+ if (k == ElementKind.CLASS || k == ElementKind.INTERFACE ||
+ k == ElementKind.ANNOTATION_TYPE) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private static abstract class BaseHandler implements InvocationHandler {
+ private final Object target;
+
+ BaseHandler(Object target) {
+ this.target = target;
+ }
+
+ protected Object getTarget() {
+ return target;
+ }
+
+ Object wrapReturn(Object ret) {
+ if (ret == null) {
+ return null;
+ }
+ if (ret instanceof DocletEnvironment) {
+ return wrap(ret, DocletEnvironment.class);
+ }
+ if (ret instanceof Element) {
+ return getElementProxy((Element) ret);
+ }
+ if (ret instanceof Set) {
+ return filterAndWrapIterable((Set>) ret, true);
+ }
+ if (ret instanceof Collection) {
+ return filterAndWrapIterable((Collection>) ret, false);
+ }
+ if (ret instanceof Iterable) {
+ return filterAndWrapIterable((Iterable>) ret, false);
+ }
+ if (ret.getClass().isArray()) {
+ return wrap(ret, ret.getClass());
+ }
+ return ret;
+ }
+
+ Object[] unwrapArgs(Object[] args) {
+ if (args == null) {
+ return null;
+ }
+ Object[] r = new Object[args.length];
+ for (int i = 0; i < args.length; i++) {
+ r[i] = unwrap(args[i]);
+ }
+ return r;
+ }
+ }
+
+ private static final class EnvHandler extends BaseHandler {
+ private final DocletEnvironment env;
+
+ EnvHandler(DocletEnvironment env) {
+ super(env);
+ this.env = env;
+ }
+
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ String name = method.getName();
+ Object[] uargs = unwrapArgs(args);
+
+ if ("getDocTrees".equals(name)) {
+ return env.getDocTrees();
+ } else if ("isIncluded".equals(name)) {
+ Element e = (Element) uargs[0];
+ boolean base = env.isIncluded(e);
+ return base && !exclude(e);
+ } else if ("getIncludedElements".equals(name)) {
+ Set extends Element> base = env.getIncludedElements();
+ return base.stream()
+ .filter(e -> !exclude(e))
+ .collect(Collectors.toCollection(LinkedHashSet::new));
+ } else if ("getSpecifiedElements".equals(name)) {
+ Set extends Element> base = env.getSpecifiedElements();
+ return base.stream()
+ .filter(e -> !exclude(e))
+ .collect(Collectors.toCollection(LinkedHashSet::new));
+ }
+
+ Object ret = method.invoke(getTarget(), uargs);
+ return wrapReturn(ret);
+ }
+ }
+
+ private static final class ElementHandler extends BaseHandler {
+ private final Element element;
+
+ ElementHandler(Element element) {
+ super(element);
+ this.element = element;
+ }
+
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ String name = method.getName();
+ Object[] uargs = unwrapArgs(args);
+
+ if ("equals".equals(name) && uargs != null && uargs.length == 1) {
+ return Objects.equals(element, unwrap(uargs[0]));
+ }
+ if ("hashCode".equals(name) && (uargs == null || uargs.length == 0)) {
+ return element.hashCode();
+ }
+ if ("toString".equals(name) && (uargs == null || uargs.length == 0)) {
+ return element.toString();
+ }
+
+ if ("getEnclosedElements".equals(name) && (uargs == null || uargs.length == 0)) {
+ List extends Element> enclosed = element.getEnclosedElements();
+ List filtered = new ArrayList<>();
+ for (Element e : enclosed) {
+ if (!exclude(e)) {
+ filtered.add(e);
+ }
+ }
+ return filtered;
+ }
+
+ Object ret = method.invoke(getTarget(), uargs);
+ return wrapReturn(ret);
+ }
+ }
+}
diff --git a/hadoop-common-project/hadoop-annotations/src/main/java8/org/apache/hadoop/classification/tools/StabilityOptions.java b/hadoop-common-project/hadoop-annotations/src/main/java/org/apache/hadoop/classification/tools/StabilityOptions.java
similarity index 50%
rename from hadoop-common-project/hadoop-annotations/src/main/java8/org/apache/hadoop/classification/tools/StabilityOptions.java
rename to hadoop-common-project/hadoop-annotations/src/main/java/org/apache/hadoop/classification/tools/StabilityOptions.java
index 5b2d70ded3fe7..c9d23ab472b72 100644
--- a/hadoop-common-project/hadoop-annotations/src/main/java8/org/apache/hadoop/classification/tools/StabilityOptions.java
+++ b/hadoop-common-project/hadoop-annotations/src/main/java/org/apache/hadoop/classification/tools/StabilityOptions.java
@@ -17,39 +17,111 @@
*/
package org.apache.hadoop.classification.tools;
-import com.sun.javadoc.DocErrorReporter;
+import jdk.javadoc.doclet.Reporter;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
-class StabilityOptions {
+/**
+ * Doclet option helpers for API stability filtering.
+ */
+public final class StabilityOptions {
+
+ /** Option flag: {@code -stable}. */
public static final String STABLE_OPTION = "-stable";
+
+ /** Option flag: {@code -evolving}. */
public static final String EVOLVING_OPTION = "-evolving";
+
+ /** Option flag: {@code -unstable}. */
public static final String UNSTABLE_OPTION = "-unstable";
+ enum Level { STABLE, EVOLVING, UNSTABLE }
+ private static volatile Level level = Level.STABLE;
+
+ static void setLevel(Level l) {
+ if (l != null) {
+ level = l;
+ }
+ }
+
+ private StabilityOptions() {
+ }
+
+ /**
+ * Return option length for a supported stability option.
+ *
+ * @param option option name
+ * @return {@code 1} if supported; otherwise {@code null}
+ */
public static Integer optionLength(String option) {
String opt = option.toLowerCase(Locale.ENGLISH);
- if (opt.equals(UNSTABLE_OPTION)) return 1;
- if (opt.equals(EVOLVING_OPTION)) return 1;
- if (opt.equals(STABLE_OPTION)) return 1;
+ if (opt.equals(UNSTABLE_OPTION)) {
+ return 1;
+ }
+ if (opt.equals(EVOLVING_OPTION)) {
+ return 1;
+ }
+ if (opt.equals(STABLE_OPTION)) {
+ return 1;
+ }
return null;
}
+ static void setFromOptionName(String optName) {
+ String opt = optName.toLowerCase(Locale.ENGLISH);
+ Level next = null;
+ if (opt.equals(UNSTABLE_OPTION)) {
+ next = Level.UNSTABLE;
+ } else if (opt.equals(EVOLVING_OPTION)) {
+ next = Level.EVOLVING;
+ } else if (opt.equals(STABLE_OPTION)) {
+ next = Level.STABLE;
+ }
+ if (next != null && next.ordinal() > level.ordinal()) {
+ level = next;
+ }
+ }
+
+ static Level getLevel() {
+ return level;
+ }
+
+ static void applyToRootProcessor() {
+ switch (level) {
+ case UNSTABLE:
+ RootDocProcessor.setStability(UNSTABLE_OPTION);
+ break;
+ case EVOLVING:
+ RootDocProcessor.setStability(EVOLVING_OPTION);
+ break;
+ default:
+ RootDocProcessor.setStability(STABLE_OPTION);
+ }
+ }
+
+ /**
+ * Validate and apply stability options.
+ *
+ * @param options doclet options
+ * @param reporter reporter
+ */
public static void validOptions(String[][] options,
- DocErrorReporter reporter) {
+ Reporter reporter) {
for (int i = 0; i < options.length; i++) {
String opt = options[i][0].toLowerCase(Locale.ENGLISH);
- if (opt.equals(UNSTABLE_OPTION)) {
- RootDocProcessor.stability = UNSTABLE_OPTION;
- } else if (opt.equals(EVOLVING_OPTION)) {
- RootDocProcessor.stability = EVOLVING_OPTION;
- } else if (opt.equals(STABLE_OPTION)) {
- RootDocProcessor.stability = STABLE_OPTION;
- }
+ setFromOptionName(opt);
}
+ applyToRootProcessor();
}
-
+
+ /**
+ * Filter out stability options from the doclet options array.
+ *
+ * @param options doclet options
+ * @return options without stability flags
+ */
public static String[][] filterOptions(String[][] options) {
List optionsList = new ArrayList();
for (int i = 0; i < options.length; i++) {
diff --git a/hadoop-common-project/hadoop-annotations/src/main/java8/org/apache/hadoop/classification/tools/ExcludePrivateAnnotationsStandardDoclet.java b/hadoop-common-project/hadoop-annotations/src/main/java8/org/apache/hadoop/classification/tools/ExcludePrivateAnnotationsStandardDoclet.java
deleted file mode 100644
index 5c535c8e9e3b2..0000000000000
--- a/hadoop-common-project/hadoop-annotations/src/main/java8/org/apache/hadoop/classification/tools/ExcludePrivateAnnotationsStandardDoclet.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.hadoop.classification.tools;
-
-import com.sun.javadoc.DocErrorReporter;
-import com.sun.javadoc.LanguageVersion;
-import com.sun.javadoc.RootDoc;
-import com.sun.tools.doclets.standard.Standard;
-
-/**
- * A Doclet
- * for excluding elements that are annotated with
- * {@link org.apache.hadoop.classification.InterfaceAudience.Private} or
- * {@link org.apache.hadoop.classification.InterfaceAudience.LimitedPrivate}.
- * It delegates to the Standard Doclet, and takes the same options.
- */
-public class ExcludePrivateAnnotationsStandardDoclet {
-
- public static LanguageVersion languageVersion() {
- return LanguageVersion.JAVA_1_5;
- }
-
- public static boolean start(RootDoc root) {
- System.out.println(
- ExcludePrivateAnnotationsStandardDoclet.class.getSimpleName());
- RootDoc excludedDoc = RootDocProcessor.process(root);
- if (excludedDoc.specifiedPackages().length == 0) {
- return true;
- }
- return Standard.start(excludedDoc);
- }
-
- public static int optionLength(String option) {
- Integer length = StabilityOptions.optionLength(option);
- if (length != null) {
- return length;
- }
- return Standard.optionLength(option);
- }
-
- public static boolean validOptions(String[][] options,
- DocErrorReporter reporter) {
- StabilityOptions.validOptions(options, reporter);
- String[][] filteredOptions = StabilityOptions.filterOptions(options);
- return Standard.validOptions(filteredOptions, reporter);
- }
-}
diff --git a/hadoop-common-project/hadoop-annotations/src/main/java8/org/apache/hadoop/classification/tools/IncludePublicAnnotationsJDiffDoclet.java b/hadoop-common-project/hadoop-annotations/src/main/java8/org/apache/hadoop/classification/tools/IncludePublicAnnotationsJDiffDoclet.java
deleted file mode 100644
index 91b3a9ddf2549..0000000000000
--- a/hadoop-common-project/hadoop-annotations/src/main/java8/org/apache/hadoop/classification/tools/IncludePublicAnnotationsJDiffDoclet.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.hadoop.classification.tools;
-
-import com.sun.javadoc.DocErrorReporter;
-import com.sun.javadoc.LanguageVersion;
-import com.sun.javadoc.RootDoc;
-
-import jdiff.JDiff;
-
-/**
- * A Doclet
- * that only includes class-level elements that are annotated with
- * {@link org.apache.hadoop.classification.InterfaceAudience.Public}.
- * Class-level elements with no annotation are excluded.
- * In addition, all elements that are annotated with
- * {@link org.apache.hadoop.classification.InterfaceAudience.Private} or
- * {@link org.apache.hadoop.classification.InterfaceAudience.LimitedPrivate}
- * are also excluded.
- * It delegates to the JDiff Doclet, and takes the same options.
- */
-public class IncludePublicAnnotationsJDiffDoclet {
-
- public static LanguageVersion languageVersion() {
- return LanguageVersion.JAVA_1_5;
- }
-
- public static boolean start(RootDoc root) {
- System.out.println(
- IncludePublicAnnotationsJDiffDoclet.class.getSimpleName());
- RootDocProcessor.treatUnannotatedClassesAsPrivate = true;
- return JDiff.start(RootDocProcessor.process(root));
- }
-
- public static int optionLength(String option) {
- Integer length = StabilityOptions.optionLength(option);
- if (length != null) {
- return length;
- }
- return JDiff.optionLength(option);
- }
-
- public static boolean validOptions(String[][] options,
- DocErrorReporter reporter) {
- StabilityOptions.validOptions(options, reporter);
- String[][] filteredOptions = StabilityOptions.filterOptions(options);
- return JDiff.validOptions(filteredOptions, reporter);
- }
-}
diff --git a/hadoop-common-project/hadoop-annotations/src/main/java8/org/apache/hadoop/classification/tools/IncludePublicAnnotationsStandardDoclet.java b/hadoop-common-project/hadoop-annotations/src/main/java8/org/apache/hadoop/classification/tools/IncludePublicAnnotationsStandardDoclet.java
deleted file mode 100644
index 10d554d07b5c1..0000000000000
--- a/hadoop-common-project/hadoop-annotations/src/main/java8/org/apache/hadoop/classification/tools/IncludePublicAnnotationsStandardDoclet.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.hadoop.classification.tools;
-
-import com.sun.javadoc.DocErrorReporter;
-import com.sun.javadoc.LanguageVersion;
-import com.sun.javadoc.RootDoc;
-import com.sun.tools.doclets.standard.Standard;
-
-/**
- * A Doclet
- * that only includes class-level elements that are annotated with
- * {@link org.apache.hadoop.classification.InterfaceAudience.Public}.
- * Class-level elements with no annotation are excluded.
- * In addition, all elements that are annotated with
- * {@link org.apache.hadoop.classification.InterfaceAudience.Private} or
- * {@link org.apache.hadoop.classification.InterfaceAudience.LimitedPrivate}
- * are also excluded.
- * It delegates to the Standard Doclet, and takes the same options.
- */
-public class IncludePublicAnnotationsStandardDoclet {
-
- public static LanguageVersion languageVersion() {
- return LanguageVersion.JAVA_1_5;
- }
-
- public static boolean start(RootDoc root) {
- System.out.println(
- IncludePublicAnnotationsStandardDoclet.class.getSimpleName());
- RootDocProcessor.treatUnannotatedClassesAsPrivate = true;
- return Standard.start(RootDocProcessor.process(root));
- }
-
- public static int optionLength(String option) {
- Integer length = StabilityOptions.optionLength(option);
- if (length != null) {
- return length;
- }
- return Standard.optionLength(option);
- }
-
- public static boolean validOptions(String[][] options,
- DocErrorReporter reporter) {
- StabilityOptions.validOptions(options, reporter);
- String[][] filteredOptions = StabilityOptions.filterOptions(options);
- return Standard.validOptions(filteredOptions, reporter);
- }
-}
diff --git a/hadoop-common-project/hadoop-annotations/src/main/java8/org/apache/hadoop/classification/tools/RootDocProcessor.java b/hadoop-common-project/hadoop-annotations/src/main/java8/org/apache/hadoop/classification/tools/RootDocProcessor.java
deleted file mode 100644
index 60c2a6f6e93b0..0000000000000
--- a/hadoop-common-project/hadoop-annotations/src/main/java8/org/apache/hadoop/classification/tools/RootDocProcessor.java
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.hadoop.classification.tools;
-
-import com.sun.javadoc.AnnotationDesc;
-import com.sun.javadoc.AnnotationTypeDoc;
-import com.sun.javadoc.ClassDoc;
-import com.sun.javadoc.ConstructorDoc;
-import com.sun.javadoc.Doc;
-import com.sun.javadoc.FieldDoc;
-import com.sun.javadoc.MethodDoc;
-import com.sun.javadoc.PackageDoc;
-import com.sun.javadoc.ProgramElementDoc;
-import com.sun.javadoc.RootDoc;
-
-import java.lang.reflect.Array;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.WeakHashMap;
-
-import org.apache.hadoop.classification.InterfaceAudience;
-import org.apache.hadoop.classification.InterfaceStability;
-
-/**
- * Process the {@link RootDoc} by substituting with (nested) proxy objects that
- * exclude elements with Private or LimitedPrivate annotations.
- *
- * Based on code from http://www.sixlegs.com/blog/java/exclude-javadoc-tag.html.
- */
-class RootDocProcessor {
-
- static String stability = StabilityOptions.UNSTABLE_OPTION;
- static boolean treatUnannotatedClassesAsPrivate = false;
-
- public static RootDoc process(RootDoc root) {
- return (RootDoc) process(root, RootDoc.class);
- }
-
- private static Object process(Object obj, Class> type) {
- if (obj == null) {
- return null;
- }
- Class> cls = obj.getClass();
- if (cls.getName().startsWith("com.sun.")) {
- return getProxy(obj);
- } else if (obj instanceof Object[]) {
- Class> componentType = type.isArray() ? type.getComponentType()
- : cls.getComponentType();
- Object[] array = (Object[]) obj;
- Object[] newArray = (Object[]) Array.newInstance(componentType,
- array.length);
- for (int i = 0; i < array.length; ++i) {
- newArray[i] = process(array[i], componentType);
- }
- return newArray;
- }
- return obj;
- }
-
- private static Map proxies =
- new WeakHashMap();
-
- private static Object getProxy(Object obj) {
- Object proxy = proxies.get(obj);
- if (proxy == null) {
- proxy = Proxy.newProxyInstance(obj.getClass().getClassLoader(),
- obj.getClass().getInterfaces(), new ExcludeHandler(obj));
- proxies.put(obj, proxy);
- }
- return proxy;
- }
-
- private static class ExcludeHandler implements InvocationHandler {
- private Object target;
-
- public ExcludeHandler(Object target) {
- this.target = target;
- }
-
- @Override
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- String methodName = method.getName();
- if (target instanceof Doc) {
- if (methodName.equals("isIncluded")) {
- Doc doc = (Doc) target;
- return !exclude(doc) && doc.isIncluded();
- }
- if (target instanceof RootDoc) {
- if (methodName.equals("classes")) {
- return filter(((RootDoc) target).classes(), ClassDoc.class);
- } else if (methodName.equals("specifiedClasses")) {
- return filter(((RootDoc) target).specifiedClasses(), ClassDoc.class);
- } else if (methodName.equals("specifiedPackages")) {
- return filter(((RootDoc) target).specifiedPackages(), PackageDoc.class);
- }
- } else if (target instanceof ClassDoc) {
- if (isFiltered(args)) {
- if (methodName.equals("methods")) {
- return filter(((ClassDoc) target).methods(true), MethodDoc.class);
- } else if (methodName.equals("fields")) {
- return filter(((ClassDoc) target).fields(true), FieldDoc.class);
- } else if (methodName.equals("innerClasses")) {
- return filter(((ClassDoc) target).innerClasses(true),
- ClassDoc.class);
- } else if (methodName.equals("constructors")) {
- return filter(((ClassDoc) target).constructors(true),
- ConstructorDoc.class);
- }
- } else {
- if (methodName.equals("methods")) {
- return filter(((ClassDoc) target).methods(true), MethodDoc.class);
- }
- }
- } else if (target instanceof PackageDoc) {
- if (methodName.equals("allClasses")) {
- if (isFiltered(args)) {
- return filter(((PackageDoc) target).allClasses(true),
- ClassDoc.class);
- } else {
- return filter(((PackageDoc) target).allClasses(), ClassDoc.class);
- }
- } else if (methodName.equals("annotationTypes")) {
- return filter(((PackageDoc) target).annotationTypes(),
- AnnotationTypeDoc.class);
- } else if (methodName.equals("enums")) {
- return filter(((PackageDoc) target).enums(),
- ClassDoc.class);
- } else if (methodName.equals("errors")) {
- return filter(((PackageDoc) target).errors(),
- ClassDoc.class);
- } else if (methodName.equals("exceptions")) {
- return filter(((PackageDoc) target).exceptions(),
- ClassDoc.class);
- } else if (methodName.equals("interfaces")) {
- return filter(((PackageDoc) target).interfaces(),
- ClassDoc.class);
- } else if (methodName.equals("ordinaryClasses")) {
- return filter(((PackageDoc) target).ordinaryClasses(),
- ClassDoc.class);
- }
- }
- }
-
- if (args != null) {
- if (methodName.equals("compareTo") || methodName.equals("equals")
- || methodName.equals("overrides")
- || methodName.equals("subclassOf")) {
- args[0] = unwrap(args[0]);
- }
- }
- try {
- return process(method.invoke(target, args), method.getReturnType());
- } catch (InvocationTargetException e) {
- throw e.getTargetException();
- }
- }
-
- private static boolean exclude(Doc doc) {
- AnnotationDesc[] annotations = null;
- if (doc instanceof ProgramElementDoc) {
- annotations = ((ProgramElementDoc) doc).annotations();
- } else if (doc instanceof PackageDoc) {
- annotations = ((PackageDoc) doc).annotations();
- }
- if (annotations != null) {
- for (AnnotationDesc annotation : annotations) {
- String qualifiedTypeName = annotation.annotationType().qualifiedTypeName();
- if (qualifiedTypeName.equals(
- InterfaceAudience.Private.class.getCanonicalName())
- || qualifiedTypeName.equals(
- InterfaceAudience.LimitedPrivate.class.getCanonicalName())) {
- return true;
- }
- if (stability.equals(StabilityOptions.EVOLVING_OPTION)) {
- if (qualifiedTypeName.equals(
- InterfaceStability.Unstable.class.getCanonicalName())) {
- return true;
- }
- }
- if (stability.equals(StabilityOptions.STABLE_OPTION)) {
- if (qualifiedTypeName.equals(
- InterfaceStability.Unstable.class.getCanonicalName())
- || qualifiedTypeName.equals(
- InterfaceStability.Evolving.class.getCanonicalName())) {
- return true;
- }
- }
- }
- for (AnnotationDesc annotation : annotations) {
- String qualifiedTypeName =
- annotation.annotationType().qualifiedTypeName();
- if (qualifiedTypeName.equals(
- InterfaceAudience.Public.class.getCanonicalName())) {
- return false;
- }
- }
- }
- if (treatUnannotatedClassesAsPrivate) {
- return doc.isClass() || doc.isInterface() || doc.isAnnotationType();
- }
- return false;
- }
-
- private static Object[] filter(Doc[] array, Class> componentType) {
- if (array == null || array.length == 0) {
- return array;
- }
- List list = new ArrayList(array.length);
- for (Doc entry : array) {
- if (!exclude(entry)) {
- list.add(process(entry, componentType));
- }
- }
- return list.toArray((Object[]) Array.newInstance(componentType, list
- .size()));
- }
-
- private Object unwrap(Object proxy) {
- if (proxy instanceof Proxy)
- return ((ExcludeHandler) Proxy.getInvocationHandler(proxy)).target;
- return proxy;
- }
-
- private boolean isFiltered(Object[] args) {
- return args != null && Boolean.TRUE.equals(args[0]);
- }
-
- }
-
-}
diff --git a/hadoop-mapreduce-project/hadoop-mapreduce-client/pom.xml b/hadoop-mapreduce-project/hadoop-mapreduce-client/pom.xml
index f236c8770d360..f8c7ad3d4b978 100644
--- a/hadoop-mapreduce-project/hadoop-mapreduce-client/pom.xml
+++ b/hadoop-mapreduce-project/hadoop-mapreduce-client/pom.xml
@@ -246,7 +246,7 @@
- jdiff
+ io.github.zhtttylz
jdiff
${jdiff.version}
false
diff --git a/hadoop-project-dist/pom.xml b/hadoop-project-dist/pom.xml
index 68d29e84fbf02..f09a22f23c50f 100644
--- a/hadoop-project-dist/pom.xml
+++ b/hadoop-project-dist/pom.xml
@@ -178,7 +178,7 @@
- jdiff
+ io.github.zhtttylz
jdiff
${jdiff.version}
false
@@ -462,5 +462,30 @@
+
+ doclet-jdk17
+
+ [17,)
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+
+ org.apache.hadoop.classification.tools.ExcludePrivateAnnotationsStandardDoclet
+
+
+ org.apache.hadoop
+ hadoop-annotations
+ ${hadoop.version}
+
+
+ true
+
+
+
+
+
diff --git a/hadoop-project/pom.xml b/hadoop-project/pom.xml
index 802e1b48da2d9..69c6a5cff926e 100644
--- a/hadoop-project/pom.xml
+++ b/hadoop-project/pom.xml
@@ -45,7 +45,7 @@
- 1.0.9
+ 1.1.2-hadoop
2.12.2
@@ -268,7 +268,7 @@
test
- jdiff
+ io.github.zhtttylz
jdiff
${jdiff.version}
diff --git a/hadoop-yarn-project/hadoop-yarn/pom.xml b/hadoop-yarn-project/hadoop-yarn/pom.xml
index db4a50542fde5..7c216f90043a0 100644
--- a/hadoop-yarn-project/hadoop-yarn/pom.xml
+++ b/hadoop-yarn-project/hadoop-yarn/pom.xml
@@ -151,7 +151,7 @@
- jdiff
+ io.github.zhtttylz
jdiff
${jdiff.version}
false