From 1b50f1e629ebe5eb1eec762acdbadfcf9dd35a9d Mon Sep 17 00:00:00 2001 From: thomas Date: Mon, 7 Oct 2019 10:53:05 +0200 Subject: [PATCH 1/3] Add parsing support for javadoc 9+ output --- .../modules/java/source/JavadocHelper.java | 42 +- .../api/java/source/ui/HTMLJavadocParser.java | 5 +- .../java/source/ui/HTMLJavadocParserTest.java | 91 +++- .../api/java/source/ui/Javadoc11Class.html | 360 ++++++++++++++++ .../api/java/source/ui/Javadoc11Enum.html | 406 ++++++++++++++++++ .../api/java/source/ui/Javadoc8Class.html | 322 ++++++++++++++ .../api/java/source/ui/Javadoc8Enum.html | 367 ++++++++++++++++ 7 files changed, 1584 insertions(+), 9 deletions(-) create mode 100644 java/java.sourceui/test/unit/src/org/netbeans/api/java/source/ui/Javadoc11Class.html create mode 100644 java/java.sourceui/test/unit/src/org/netbeans/api/java/source/ui/Javadoc11Enum.html create mode 100644 java/java.sourceui/test/unit/src/org/netbeans/api/java/source/ui/Javadoc8Class.html create mode 100644 java/java.sourceui/test/unit/src/org/netbeans/api/java/source/ui/Javadoc8Enum.html diff --git a/java/java.source.base/src/org/netbeans/modules/java/source/JavadocHelper.java b/java/java.source.base/src/org/netbeans/modules/java/source/JavadocHelper.java index e6ba8e0d5c0b..48f36360c4be 100644 --- a/java/java.source.base/src/org/netbeans/modules/java/source/JavadocHelper.java +++ b/java/java.source.base/src/org/netbeans/modules/java/source/JavadocHelper.java @@ -827,10 +827,10 @@ private static List findJavadoc( @NonNull private static Collection getFragment(Element e) { - final FragmentBuilder fb = new FragmentBuilder(); + final FragmentBuilder fb = new FragmentBuilder(e.getKind()); if (!e.getKind().isClass() && !e.getKind().isInterface()) { if (e.getKind() == ElementKind.CONSTRUCTOR) { - fb.append(e.getEnclosingElement().getSimpleName()); + fb.constructor(e.getEnclosingElement().getSimpleName()); } else { fb.append(e.getSimpleName()); } @@ -870,21 +870,43 @@ private static final class FragmentBuilder { final List> tmp = new ArrayList<>(); tmp.add(Convertors.identity()); tmp.add(new JDoc8025633()); + tmp.add(new JDoc8046068()); FILTERS = Collections.unmodifiableList(tmp); }; private final StringBuilder[] sbs; - FragmentBuilder() { - this.sbs = new StringBuilder[FILTERS.size()]; + FragmentBuilder(@NonNull ElementKind kind) { + int size = FILTERS.size(); + // JDK-8046068 changed the constructor format from "Name" to "" + if (kind == ElementKind.CONSTRUCTOR) { + size *= 2; + } + this.sbs = new StringBuilder[size]; for (int i = 0; i < sbs.length; i++) { sbs[i] = new StringBuilder(); } } + + @NonNull + FragmentBuilder constructor(@NonNull final CharSequence text) { + CharSequence constructor = text; + for (int i = 0; i < sbs.length;) { + for (int j = 0; j < FILTERS.size(); j++) { + sbs[i].append(FILTERS.get(j).convert(constructor)); + i++; + } + constructor = ""; + } + return this; + } @NonNull FragmentBuilder append(@NonNull final CharSequence text) { - for (int i = 0; i < sbs.length; i++) { - sbs[i].append(FILTERS.get(i).convert(text)); + for (int i = 0; i < sbs.length;) { + for (int j = 0; j < FILTERS.size(); j++) { + sbs[i].append(FILTERS.get(j).convert(text)); + i++; + } } return this; } @@ -938,6 +960,14 @@ public CharSequence convert(@NonNull final CharSequence text) { return sb.toString(); } } + + private static final class JDoc8046068 implements Convertor { + @Override + @NonNull + public CharSequence convert(@NonNull final CharSequence text) { + return text.toString().replace(" ", ""); + } + } } } diff --git a/java/java.sourceui/src/org/netbeans/api/java/source/ui/HTMLJavadocParser.java b/java/java.sourceui/src/org/netbeans/api/java/source/ui/HTMLJavadocParser.java index 1399fd9689fd..410da0a823fb 100644 --- a/java/java.sourceui/src/org/netbeans/api/java/source/ui/HTMLJavadocParser.java +++ b/java/java.sourceui/src/org/netbeans/api/java/source/ui/HTMLJavadocParser.java @@ -381,11 +381,12 @@ public void handleSimpleTag(HTML.Tag t, MutableAttributeSet a, int pos) { public void handleStartTag(HTML.Tag t, MutableAttributeSet a, int pos) { if (t == HTML.Tag.A) { String attrName = (String)a.getAttribute(HTML.Attribute.NAME); - if (names.contains(attrName)){ + String attrId = (String)a.getAttribute(HTML.Attribute.ID); + if (names.contains(attrName) || names.contains(attrId)){ // we have found desired javadoc member info anchor state[0] = A_OPEN; } else { - if ((state[0] == PRE_CLOSE) && attrName!=null && hrPos != -1){ + if ((state[0] == PRE_CLOSE) && (attrName != null || attrId != null) && hrPos != -1){ // reach the end of retrieved javadoc info state[0] = INIT; offset[1] = hrPos; diff --git a/java/java.sourceui/test/unit/src/org/netbeans/api/java/source/ui/HTMLJavadocParserTest.java b/java/java.sourceui/test/unit/src/org/netbeans/api/java/source/ui/HTMLJavadocParserTest.java index ca9e12eab489..1ff3f14368d2 100644 --- a/java/java.sourceui/test/unit/src/org/netbeans/api/java/source/ui/HTMLJavadocParserTest.java +++ b/java/java.sourceui/test/unit/src/org/netbeans/api/java/source/ui/HTMLJavadocParserTest.java @@ -19,7 +19,9 @@ package org.netbeans.api.java.source.ui; import java.net.MalformedURLException; +import java.net.URI; import java.net.URL; +import java.net.URLEncoder; import junit.framework.TestCase; /** @@ -68,7 +70,87 @@ public void testGetAndroidJavadocText() throws MalformedURLException { assertTrue(result.contains("See Also")); } - + + /** + * Test of getJavadocText method used with class output from javadoc 11. + */ + public void testJavadoc11Class() throws Exception { + URL root = HTMLJavadocParserTest.class.getResource("Javadoc11Class.html"); + String result = HTMLJavadocParser.getJavadocText(root, false); + assertNotNull(result); + assertTrue(result.contains("This is an example class.")); + + URL url = appendFragment(root, "(java.lang.String)"); + result = HTMLJavadocParser.getJavadocText(url, false); + assertTrue(result.contains("This is a constructor taking a single String parameter.")); + + url = appendFragment(root, "(java.lang.String,java.lang.String)"); + result = HTMLJavadocParser.getJavadocText(url, false); + assertTrue(result.contains("This is a constructor taking two String parameters.")); + + url = appendFragment(root, "hi()"); + result = HTMLJavadocParser.getJavadocText(url, false); + assertTrue(result.contains("A method.")); + } + + /** + * Test of getJavadocText method used with enum output from javadoc 11. + */ + public void testJavadoc11Enum() throws Exception { + URL root = HTMLJavadocParserTest.class.getResource("Javadoc11Enum.html"); + String result = HTMLJavadocParser.getJavadocText(root, false); + assertNotNull(result); + assertTrue(result.contains("This is an example enum.")); + + URL url = appendFragment(root, "FIRST"); + result = HTMLJavadocParser.getJavadocText(url, false); + assertTrue(result.contains("The first value.")); + + url = appendFragment(root, "hi()"); + result = HTMLJavadocParser.getJavadocText(url, false); + assertTrue(result.contains("A method.")); + } + + /** + * Test of getJavadocText method used with class output from javadoc 8. + */ + public void testJavadoc8Class() throws Exception { + URL root = HTMLJavadocParserTest.class.getResource("Javadoc8Class.html"); + String result = HTMLJavadocParser.getJavadocText(root, false); + assertNotNull(result); + assertTrue(result.contains("This is an example class.")); + + URL url = appendFragment(root, "Javadoc8Class-java.lang.String-"); + result = HTMLJavadocParser.getJavadocText(url, false); + assertTrue(result.contains("This is a constructor taking a single String parameter.")); + + url = appendFragment(root, "Javadoc8Class-java.lang.String-java.lang.String-"); + result = HTMLJavadocParser.getJavadocText(url, false); + assertTrue(result.contains("This is a constructor taking two String parameters.")); + + url = appendFragment(root, "hi--"); + result = HTMLJavadocParser.getJavadocText(url, false); + assertTrue(result.contains("A method.")); + } + + /** + * Test of getJavadocText method used with enum output from javadoc 8. + */ + public void testJavadoc8Enum() throws Exception { + URL root = HTMLJavadocParserTest.class.getResource("Javadoc8Enum.html"); + String result = HTMLJavadocParser.getJavadocText(root, false); + assertNotNull(result); + assertTrue(result.contains("This is an example enum.")); + + URL url = appendFragment(root, "FIRST"); + result = HTMLJavadocParser.getJavadocText(url, false); + assertTrue(result.contains("The first value.")); + + url = appendFragment(root, "hi--"); + result = HTMLJavadocParser.getJavadocText(url, false); + assertTrue(result.contains("A method.")); + } + public void test199194() throws MalformedURLException { URL url = HTMLJavadocParserTest.class.getResource("JavaApplication1.html"); String result = HTMLJavadocParser.getJavadocText(url, false); @@ -91,4 +173,11 @@ public void test209707() throws MalformedURLException { assertNotNull(result); assertTrue(result.contains("the selected file or")); } + + private static URL appendFragment(URL root, String unencodedFragment) throws Exception { + StringBuilder uri = new StringBuilder(root.toExternalForm()); + uri.append("#"); + uri.append(URLEncoder.encode(unencodedFragment, "UTF-8").replace("+", "%20")); + return new URI(uri.toString()).toURL(); + } } diff --git a/java/java.sourceui/test/unit/src/org/netbeans/api/java/source/ui/Javadoc11Class.html b/java/java.sourceui/test/unit/src/org/netbeans/api/java/source/ui/Javadoc11Class.html new file mode 100644 index 000000000000..36f8796068c1 --- /dev/null +++ b/java/java.sourceui/test/unit/src/org/netbeans/api/java/source/ui/Javadoc11Class.html @@ -0,0 +1,360 @@ + + + + + +Javadoc11Class + + + + + + + + + + + + + + + +
+ +
+ +
+
+

Class Javadoc11Class

+
+
+
    +
  • java.lang.Object
  • +
  • +
      +
    • Javadoc11Class
    • +
    +
  • +
+
+
    +
  • +
    +
    public class Javadoc11Class
    +extends java.lang.Object
    +
    This is an example class.
    +
    +
    Since:
    +
    now
    +
    +
  • +
+
+
+
    +
  • + +
    +
      +
    • + + +

      Constructor Summary

      + + + + + + + + + + + + + + + + + + +
      Constructors 
      ConstructorDescription
      Javadoc11Class() +
      This is the default constructor.
      +
      Javadoc11Class​(java.lang.String param) +
      This is a constructor taking a single String parameter.
      +
      Javadoc11Class​(java.lang.String param1, + java.lang.String param2) +
      This is a constructor taking two String parameters.
      +
      +
    • +
    +
    + +
    +
      +
    • + + +

      Method Summary

      + + + + + + + + + + + + +
      All Methods Instance Methods Concrete Methods 
      Modifier and TypeMethodDescription
      java.lang.Stringhi() +
      A method.
      +
      +
        +
      • + + +

        Methods inherited from class java.lang.Object

        +clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
      • +
      +
    • +
    +
    +
  • +
+
+
+
    +
  • + +
    +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        Javadoc11Class

        +
        public Javadoc11Class()
        +
        This is the default constructor.
        +
      • +
      + + + +
        +
      • +

        Javadoc11Class

        +
        public Javadoc11Class​(java.lang.String param)
        +
        This is a constructor taking a single String parameter.
        +
        +
        Parameters:
        +
        param - A parameter
        +
        +
      • +
      + + + +
        +
      • +

        Javadoc11Class

        +
        public Javadoc11Class​(java.lang.String param1,
        +                      java.lang.String param2)
        +
        This is a constructor taking two String parameters.
        +
        +
        Parameters:
        +
        param1 - Parameter one.
        +
        param2 - Parameter two.
        +
        +
      • +
      +
    • +
    +
    + +
    +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        hi

        +
        public java.lang.String hi()
        +
        A method.
        +
        +
        Returns:
        +
        "hi"
        +
        +
      • +
      +
    • +
    +
    +
  • +
+
+
+
+ +
+ +
+ + diff --git a/java/java.sourceui/test/unit/src/org/netbeans/api/java/source/ui/Javadoc11Enum.html b/java/java.sourceui/test/unit/src/org/netbeans/api/java/source/ui/Javadoc11Enum.html new file mode 100644 index 000000000000..392755629b56 --- /dev/null +++ b/java/java.sourceui/test/unit/src/org/netbeans/api/java/source/ui/Javadoc11Enum.html @@ -0,0 +1,406 @@ + + + + + +Javadoc11Enum + + + + + + + + + + + + + + + +
+ +
+ +
+
+

Enum Javadoc11Enum

+
+
+
    +
  • java.lang.Object
  • +
  • + +
  • +
+
+
    +
  • +
    +
    All Implemented Interfaces:
    +
    java.io.Serializable, java.lang.Comparable<Javadoc11Enum>
    +
    +
    +
    public enum Javadoc11Enum
    +extends java.lang.Enum<Javadoc11Enum>
    +
    This is an example enum.
    +
    +
    Since:
    +
    now
    +
    +
  • +
+
+
+
    +
  • + +
    +
      +
    • + + +

      Enum Constant Summary

      + + + + + + + + + + + + + + +
      Enum Constants 
      Enum ConstantDescription
      FIRST +
      The first value.
      +
      SECOND +
      The second value.
      +
      +
    • +
    +
    + +
    +
      +
    • + + +

      Method Summary

      + + + + + + + + + + + + + + + + + + + + + + +
      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and TypeMethodDescription
      java.lang.Stringhi() +
      A method.
      +
      static Javadoc11EnumvalueOf​(java.lang.String name) +
      Returns the enum constant of this type with the specified name.
      +
      static Javadoc11Enum[]values() +
      Returns an array containing the constants of this enum type, in +the order they are declared.
      +
      +
        +
      • + + +

        Methods inherited from class java.lang.Enum

        +clone, compareTo, equals, finalize, getDeclaringClass, hashCode, name, ordinal, toString, valueOf
      • +
      +
        +
      • + + +

        Methods inherited from class java.lang.Object

        +getClass, notify, notifyAll, wait, wait, wait
      • +
      +
    • +
    +
    +
  • +
+
+
+
    +
  • + +
    +
      +
    • + + +

      Enum Constant Detail

      + + + +
        +
      • +

        FIRST

        +
        public static final Javadoc11Enum FIRST
        +
        The first value.
        +
      • +
      + + + +
        +
      • +

        SECOND

        +
        public static final Javadoc11Enum SECOND
        +
        The second value.
        +
      • +
      +
    • +
    +
    + +
    +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        values

        +
        public static Javadoc11Enum[] values()
        +
        Returns an array containing the constants of this enum type, in +the order they are declared. This method may be used to iterate +over the constants as follows: +
        +for (Javadoc11Enum c : Javadoc11Enum.values())
        +    System.out.println(c);
        +
        +
        +
        Returns:
        +
        an array containing the constants of this enum type, in the order they are declared
        +
        +
      • +
      + + + +
        +
      • +

        valueOf

        +
        public static Javadoc11Enum valueOf​(java.lang.String name)
        +
        Returns the enum constant of this type with the specified name. +The string must match exactly an identifier used to declare an +enum constant in this type. (Extraneous whitespace characters are +not permitted.)
        +
        +
        Parameters:
        +
        name - the name of the enum constant to be returned.
        +
        Returns:
        +
        the enum constant with the specified name
        +
        Throws:
        +
        java.lang.IllegalArgumentException - if this enum type has no constant with the specified name
        +
        java.lang.NullPointerException - if the argument is null
        +
        +
      • +
      + + + +
        +
      • +

        hi

        +
        public java.lang.String hi()
        +
        A method.
        +
        +
        Returns:
        +
        "hi"
        +
        +
      • +
      +
    • +
    +
    +
  • +
+
+
+
+ + + + diff --git a/java/java.sourceui/test/unit/src/org/netbeans/api/java/source/ui/Javadoc8Class.html b/java/java.sourceui/test/unit/src/org/netbeans/api/java/source/ui/Javadoc8Class.html new file mode 100644 index 000000000000..2d298f7e634d --- /dev/null +++ b/java/java.sourceui/test/unit/src/org/netbeans/api/java/source/ui/Javadoc8Class.html @@ -0,0 +1,322 @@ + + + + + +Javadoc8Class + + + + + + + + + + + + +
+

Class Javadoc8Class

+
+
+
    +
  • java.lang.Object
  • +
  • +
      +
    • Javadoc8Class
    • +
    +
  • +
+
+
    +
  • +
    +
    +
    public class Javadoc8Class
    +extends java.lang.Object
    +
    This is an example class.
    +
    +
    Since:
    +
    now
    +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Constructor Summary

      + + + + + + + + + + + + + + +
      Constructors 
      Constructor and Description
      Javadoc8Class() +
      This is the default constructor.
      +
      Javadoc8Class(java.lang.String param) +
      This is a constructor taking a single String parameter.
      +
      Javadoc8Class(java.lang.String param1, + java.lang.String param2) +
      This is a constructor taking two String parameters.
      +
      +
    • +
    + +
      +
    • + + +

      Method Summary

      + + + + + + + + + + +
      All Methods Instance Methods Concrete Methods 
      Modifier and TypeMethod and Description
      java.lang.Stringhi() +
      A method.
      +
      +
        +
      • + + +

        Methods inherited from class java.lang.Object

        +clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
      • +
      +
    • +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Constructor Detail

      + + + +
        +
      • +

        Javadoc8Class

        +
        public Javadoc8Class()
        +
        This is the default constructor.
        +
      • +
      + + + +
        +
      • +

        Javadoc8Class

        +
        public Javadoc8Class(java.lang.String param)
        +
        This is a constructor taking a single String parameter.
        +
        +
        Parameters:
        +
        param - A parameter
        +
        +
      • +
      + + + +
        +
      • +

        Javadoc8Class

        +
        public Javadoc8Class(java.lang.String param1,
        +                     java.lang.String param2)
        +
        This is a constructor taking two String parameters.
        +
        +
        Parameters:
        +
        param1 - Parameter one.
        +
        param2 - Parameter two.
        +
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        hi

        +
        public java.lang.String hi()
        +
        A method.
        +
        +
        Returns:
        +
        "hi"
        +
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + diff --git a/java/java.sourceui/test/unit/src/org/netbeans/api/java/source/ui/Javadoc8Enum.html b/java/java.sourceui/test/unit/src/org/netbeans/api/java/source/ui/Javadoc8Enum.html new file mode 100644 index 000000000000..6295039fe29f --- /dev/null +++ b/java/java.sourceui/test/unit/src/org/netbeans/api/java/source/ui/Javadoc8Enum.html @@ -0,0 +1,367 @@ + + + + + +Javadoc8Enum + + + + + + + + + + + + +
+

Enum Javadoc8Enum

+
+
+
    +
  • java.lang.Object
  • +
  • + +
  • +
+
+
    +
  • +
    +
    All Implemented Interfaces:
    +
    java.io.Serializable, java.lang.Comparable<Javadoc8Enum>
    +
    +
    +
    +
    public enum Javadoc8Enum
    +extends java.lang.Enum<Javadoc8Enum>
    +
    This is an example enum.
    +
    +
    Since:
    +
    now
    +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Enum Constant Summary

      + + + + + + + + + + + +
      Enum Constants 
      Enum Constant and Description
      FIRST +
      The first value.
      +
      SECOND +
      The second value.
      +
      +
    • +
    + +
      +
    • + + +

      Method Summary

      + + + + + + + + + + + + + + + + + + +
      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and TypeMethod and Description
      java.lang.Stringhi() +
      A method.
      +
      static Javadoc8EnumvalueOf(java.lang.String name) +
      Returns the enum constant of this type with the specified name.
      +
      static Javadoc8Enum[]values() +
      Returns an array containing the constants of this enum type, in +the order they are declared.
      +
      +
        +
      • + + +

        Methods inherited from class java.lang.Enum

        +clone, compareTo, equals, finalize, getDeclaringClass, hashCode, name, ordinal, toString, valueOf
      • +
      +
        +
      • + + +

        Methods inherited from class java.lang.Object

        +getClass, notify, notifyAll, wait, wait, wait
      • +
      +
    • +
    +
  • +
+
+
+
    +
  • + +
      +
    • + + +

      Enum Constant Detail

      + + + +
        +
      • +

        FIRST

        +
        public static final Javadoc8Enum FIRST
        +
        The first value.
        +
      • +
      + + + +
        +
      • +

        SECOND

        +
        public static final Javadoc8Enum SECOND
        +
        The second value.
        +
      • +
      +
    • +
    + +
      +
    • + + +

      Method Detail

      + + + +
        +
      • +

        values

        +
        public static Javadoc8Enum[] values()
        +
        Returns an array containing the constants of this enum type, in +the order they are declared. This method may be used to iterate +over the constants as follows: +
        +for (Javadoc8Enum c : Javadoc8Enum.values())
        +    System.out.println(c);
        +
        +
        +
        Returns:
        +
        an array containing the constants of this enum type, in the order they are declared
        +
        +
      • +
      + + + +
        +
      • +

        valueOf

        +
        public static Javadoc8Enum valueOf(java.lang.String name)
        +
        Returns the enum constant of this type with the specified name. +The string must match exactly an identifier used to declare an +enum constant in this type. (Extraneous whitespace characters are +not permitted.)
        +
        +
        Parameters:
        +
        name - the name of the enum constant to be returned.
        +
        Returns:
        +
        the enum constant with the specified name
        +
        Throws:
        +
        java.lang.IllegalArgumentException - if this enum type has no constant with the specified name
        +
        java.lang.NullPointerException - if the argument is null
        +
        +
      • +
      + + + +
        +
      • +

        hi

        +
        public java.lang.String hi()
        +
        A method.
        +
        +
        Returns:
        +
        "hi"
        +
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + From 35afb62e8fe3601006df4b1f8371f16e7af52c68 Mon Sep 17 00:00:00 2001 From: thomas Date: Mon, 7 Oct 2019 11:09:18 +0200 Subject: [PATCH 2/3] [NETBEANS-1396] Fall back to main javadoc and source jars for Maven dependencies with classifiers OpenJFX uses Maven classifiers for platform dependent code, i.e. javafx-graphics-13.jar does not contain any code, but it depends through build profiles on javafx-graphics-13-linux.jar. There is however no javafx-graphics-13-linux-javadoc.jar, only a javafx-graphics-13-javadoc.jar, which NetBeans doesn't find. This patch lets NetBeans fall back to the main javadoc jar if there is none associated with the one with the classifier. The contents of the javadoc jars of OpenJFX are prefixed by module name, which is different from the default output of the maven-javadoc-plugin. This patch does some bytecode reading to still find the correct .html file. Fix RepositoryForBinaryQueryImplTest::testResultChanging which was broken because of a missing test resource. --- .../modules/java/source/JavadocHelper.java | 28 ++++- .../queries/RepositoryForBinaryQueryImpl.java | 30 ++++- .../RepositoryForBinaryQueryImplTest.java | 111 +++++++++++++++++- 3 files changed, 164 insertions(+), 5 deletions(-) diff --git a/java/java.source.base/src/org/netbeans/modules/java/source/JavadocHelper.java b/java/java.source.base/src/org/netbeans/modules/java/source/JavadocHelper.java index 48f36360c4be..c0db82ecd2ef 100644 --- a/java/java.source.base/src/org/netbeans/modules/java/source/JavadocHelper.java +++ b/java/java.source.base/src/org/netbeans/modules/java/source/JavadocHelper.java @@ -77,6 +77,8 @@ import org.netbeans.api.java.queries.SourceForBinaryQuery; import org.netbeans.api.java.source.SourceUtils; import org.netbeans.api.progress.ProgressHandle; +import org.netbeans.modules.classfile.ClassFile; +import org.netbeans.modules.classfile.Module; import org.netbeans.modules.java.source.base.Bundle; import org.netbeans.modules.java.source.indexing.JavaIndex; import org.netbeans.modules.java.source.parsing.CachingArchiveProvider; @@ -768,7 +770,31 @@ private static List findJavadoc( LOG.log(Level.FINE, "assumed valid Javadoc stream at {0}", url); } else if (!speculative || !isRemote) { try { - is = openStream(url, Bundle.LBL_HTTPJavadocDownload()); + try { + is = openStream(url, Bundle.LBL_HTTPJavadocDownload()); + } catch (InterruptedIOException iioe) { + throw iioe; + } catch (IOException x) { + // Some libraries like OpenJFX prefix their + // javadoc by module, similar to the JDK. + // Only search there when the default fails + // to avoid additional I/O. + // NOTE: No multi-release jar support for now. + URL moduleInfo = new URL(binary, "module-info.class"); + try (InputStream classData = moduleInfo.openStream()) { + ClassFile clazz = new ClassFile(classData, false); + Module module = clazz.getModule(); + if (module == null) { + throw x; + } + String moduleName = module.getName(); + if (moduleName == null) { + throw x; + } + url = new URL(root, moduleName + "/" + pkgName + "/" + pageName + ".html"); + is = openStream(url, Bundle.LBL_HTTPJavadocDownload()); + } + } if (useKnownGoodRoots) { knownGoodRoots.add(rootS); LOG.log(Level.FINE, "found valid Javadoc stream at {0}", url); diff --git a/java/maven/src/org/netbeans/modules/maven/queries/RepositoryForBinaryQueryImpl.java b/java/maven/src/org/netbeans/modules/maven/queries/RepositoryForBinaryQueryImpl.java index f2b29543c7ff..8898f270d399 100644 --- a/java/maven/src/org/netbeans/modules/maven/queries/RepositoryForBinaryQueryImpl.java +++ b/java/maven/src/org/netbeans/modules/maven/queries/RepositoryForBinaryQueryImpl.java @@ -263,7 +263,7 @@ public JavadocForBinaryQuery.Result findJavadoc(URL url) { //we have classifier here.. String end = jarFile.getName().substring((start + "-").length()); if (end.indexOf('.') > -1) { - classifier = end.substring(end.indexOf('.')); + classifier = end.substring(0, end.indexOf('.')); } } File javadoc = new File(parent, start + (classifier != null ? ("-" + ("tests".equals(classifier) ? "test" : classifier)) : "") + "-javadoc.jar"); //NOI18N @@ -290,6 +290,7 @@ private static class SrcResult implements SourceForBinaryQueryImplementation2.Re private static final String ATTR_PATH = "lastRootCheckPath"; //NOI18N private static final String ATTR_STAMP = "lastRootCheckStamp"; //NOI18N private final File sourceJarFile; + private final File fallbackSourceJarFile; private final ChangeSupport support; private final ChangeListener mfoListener; private final PropertyChangeListener projectListener; @@ -365,7 +366,17 @@ public void fileDataCreated(FileEvent fe) { if (sourceJarFile != null) { FileUtil.addFileChangeListener(FileUtil.weakFileChangeListener(sourceJarChangeListener, null)); + if (classifier != null) { + // fall back to regular sources if attached sources for classifier are missing + String regularSources = artifactId + "-" + version + "-sources.jar"; //NOI18N + if (!sourceJarFile.getName().equals(regularSources)) { + fallbackSourceJarFile = new File(sourceJarFile.getParentFile(), regularSources); + // already listening for changes through the file change listener above + return; + } + } } + fallbackSourceJarFile = null; } private void checkChanges(boolean fireChanges) { @@ -448,7 +459,9 @@ public FileObject[] getRoots() { // the only way to let user decide would be some sort of stamp file inside maven local repository. if (sourceJarFile != null && sourceJarFile.exists()) { add(fos, getSourceJarRoot(sourceJarFile)); - } + } else if (fallbackSourceJarFile != null && fallbackSourceJarFile.exists()) { + add(fos, getSourceJarRoot(fallbackSourceJarFile)); + } add(fos, getShadedJarSources()); toRet = fos.toArray(new FileObject[0]); } @@ -635,6 +648,7 @@ public static List getJarMetadataCoordinates(File binaryFile) { private static class JavadocResult implements JavadocForBinaryQuery.Result { private final File javadocJarFile; + private final File fallbackJavadocJarFile; private final String groupId; private final String artifactId; private final String version; @@ -689,7 +703,17 @@ public void fileDataCreated(FileEvent fe) { WeakListeners.create(ChangeListener.class, mfoListener, MavenFileOwnerQueryImpl.getInstance())); if (javadocJarFile != null) { FileUtil.addFileChangeListener(javadocJarChangeListener, javadocJarFile); + if (classifier != null) { + // listen for regular javadoc because attached javadoc for classifier might be missing + String regularJavadoc = artifactId + "-" + version + "-javadoc.jar"; //NOI18N + if (!javadocJarFile.getName().equals(regularJavadoc)) { + fallbackJavadocJarFile = new File(javadocJarFile.getParentFile(), regularJavadoc); + FileUtil.addFileChangeListener(javadocJarChangeListener, fallbackJavadocJarFile); + return; + } + } } + fallbackJavadocJarFile = null; } @Override @@ -713,6 +737,8 @@ public synchronized URL[] getRoots() { toRet = accum.toArray(new URL[0]); } else if (javadocJarFile != null && javadocJarFile.exists()) { toRet = getJavadocJarRoot(javadocJarFile); + } else if (fallbackJavadocJarFile != null && fallbackJavadocJarFile.exists()) { + toRet = getJavadocJarRoot(fallbackJavadocJarFile); } else { toRet = checkShadedMultiJars(); } diff --git a/java/maven/test/unit/src/org/netbeans/modules/maven/queries/RepositoryForBinaryQueryImplTest.java b/java/maven/test/unit/src/org/netbeans/modules/maven/queries/RepositoryForBinaryQueryImplTest.java index a9aaa30ffa66..0aee9e38a13a 100644 --- a/java/maven/test/unit/src/org/netbeans/modules/maven/queries/RepositoryForBinaryQueryImplTest.java +++ b/java/maven/test/unit/src/org/netbeans/modules/maven/queries/RepositoryForBinaryQueryImplTest.java @@ -26,6 +26,8 @@ import java.util.Arrays; import org.junit.Test; import static org.junit.Assert.*; +import org.netbeans.api.java.queries.JavadocForBinaryQuery; +import org.netbeans.api.java.queries.SourceForBinaryQuery; import org.netbeans.api.project.ProjectManager; import org.netbeans.junit.NbTestCase; import org.netbeans.modules.maven.NbMavenProjectImpl; @@ -59,6 +61,10 @@ protected void tearDown() throws Exception { super.tearDown(); File prj10 = new File(getWorkDir(), "prj10"); org.codehaus.plexus.util.FileUtils.deleteDirectory(prj10); + + File repo = EmbedderFactory.getProjectEmbedder().getLocalRepositoryFile(); + File nbtest = new File(repo, "nbtest"); + org.codehaus.plexus.util.FileUtils.deleteDirectory(nbtest); } @@ -79,9 +85,8 @@ public void testResultChanging() throws IOException { // now create source jar - File sourceJar = new File(this.getDataDir(), "source.jar"); File repoSourceJar = new File(art10.getParentFile(), "testprj-1.0-sources.jar"); - org.codehaus.plexus.util.FileUtils.copyFile(sourceJar, repoSourceJar); + org.codehaus.plexus.util.FileUtils.copyFile(art10, repoSourceJar); assertEquals(1, result.getRoots().length); assertEquals(FileUtil.getArchiveRoot(FileUtil.toFileObject(repoSourceJar)), result.getRoots()[0]); @@ -128,5 +133,107 @@ public void testResultChanging() throws IOException { } + + @Test + public void testFindJavadoc() throws IOException { + File repo = EmbedderFactory.getProjectEmbedder().getLocalRepositoryFile(); + File parent = new File(repo, "nbtest/testprj/1.0"); + RepositoryForBinaryQueryImpl query = new RepositoryForBinaryQueryImpl(); + + // find nothing + File artifact = new File(parent, "testprj-1.0.jar"); + TestFileUtils.writeZipFile(artifact, "META-INF/MANIFEST.MF:Version:1.0"); + URL artifactRoot = FileUtil.getArchiveRoot(artifact.toURI().toURL()); + JavadocForBinaryQuery.Result result = query.findJavadoc(artifactRoot); + assertNotNull(result); + assertEquals(0, result.getRoots().length); + + // find regular javadoc + File javadoc = new File(parent, "testprj-1.0-javadoc.jar"); + TestFileUtils.writeZipFile(javadoc, "META-INF/MANIFEST.MF:Version:1.0"); + URL javadocRoot = FileUtil.getArchiveRoot(javadoc.toURI().toURL()); + result = query.findJavadoc(artifactRoot); + assertEquals(1, result.getRoots().length); + assertEquals(javadocRoot, result.getRoots()[0]); + + // classifier attachments should fall back to the regular javadoc + File attachment = new File(parent, "testprj-1.0-attachment.jar"); + TestFileUtils.writeZipFile(attachment, "META-INF/MANIFEST.MF:Version:1.0"); + URL attachmentRoot = FileUtil.getArchiveRoot(attachment.toURI().toURL()); + result = query.findJavadoc(attachmentRoot); + assertEquals(1, result.getRoots().length); + assertEquals(javadocRoot, result.getRoots()[0]); + + // classifier attachments should find their own javadoc + File attachmentJavadoc = new File(parent, "testprj-1.0-attachment-javadoc.jar"); + TestFileUtils.writeZipFile(attachmentJavadoc, "META-INF/MANIFEST.MF:Version:1.0"); + URL attachmentJavadocRoot = FileUtil.getArchiveRoot(attachmentJavadoc.toURI().toURL()); + result = query.findJavadoc(attachmentRoot); + assertEquals(1, result.getRoots().length); + assertEquals(attachmentJavadocRoot, result.getRoots()[0]); + + // result reacts to filesystem changes + org.codehaus.plexus.util.FileUtils.forceDelete(attachmentJavadoc); + assertEquals(1, result.getRoots().length); + assertEquals(javadocRoot, result.getRoots()[0]); + + org.codehaus.plexus.util.FileUtils.forceDelete(javadoc); + assertEquals(0, result.getRoots().length); + + TestFileUtils.writeZipFile(javadoc, "META-INF/MANIFEST.MF:Version:1.0"); + assertEquals(1, result.getRoots().length); + assertEquals(javadocRoot, result.getRoots()[0]); + } + + @Test + public void testFindSources() throws IOException { + File repo = EmbedderFactory.getProjectEmbedder().getLocalRepositoryFile(); + File parent = new File(repo, "nbtest/testprj/1.0"); + RepositoryForBinaryQueryImpl query = new RepositoryForBinaryQueryImpl(); + + // find nothing + File artifact = new File(parent, "testprj-1.0.jar"); + TestFileUtils.writeZipFile(artifact, "META-INF/MANIFEST.MF:Version:1.0"); + URL artifactRoot = FileUtil.getArchiveRoot(artifact.toURI().toURL()); + SourceForBinaryQuery.Result result = query.findSourceRoots(artifactRoot); + assertNotNull(result); + assertEquals(0, result.getRoots().length); + + // find regular sources + File sources = new File(parent, "testprj-1.0-sources.jar"); + TestFileUtils.writeZipFile(sources, "META-INF/MANIFEST.MF:Version:1.0"); + URL sourcesRoot = FileUtil.getArchiveRoot(sources.toURI().toURL()); + result = query.findSourceRoots(artifactRoot); + assertEquals(1, result.getRoots().length); + assertEquals(sourcesRoot, result.getRoots()[0].toURL()); + + // classifier attachments should fall back to the regular sources + File attachment = new File(parent, "testprj-1.0-attachment.jar"); + TestFileUtils.writeZipFile(attachment, "META-INF/MANIFEST.MF:Version:1.0"); + URL attachmentRoot = FileUtil.getArchiveRoot(attachment.toURI().toURL()); + result = query.findSourceRoots(attachmentRoot); + assertEquals(1, result.getRoots().length); + assertEquals(sourcesRoot, result.getRoots()[0].toURL()); + + // classifier attachments should find their own sources + File attachmentSources = new File(parent, "testprj-1.0-attachment-sources.jar"); + TestFileUtils.writeZipFile(attachmentSources, "META-INF/MANIFEST.MF:Version:1.0"); + URL attachmentSourcesRoot = FileUtil.getArchiveRoot(attachmentSources.toURI().toURL()); + result = query.findSourceRoots(attachmentRoot); + assertEquals(1, result.getRoots().length); + assertEquals(attachmentSourcesRoot, result.getRoots()[0].toURL()); + + // result reacts to filesystem changes + org.codehaus.plexus.util.FileUtils.forceDelete(attachmentSources); + assertEquals(1, result.getRoots().length); + assertEquals(sourcesRoot, result.getRoots()[0].toURL()); + + org.codehaus.plexus.util.FileUtils.forceDelete(sources); + assertEquals(0, result.getRoots().length); + + TestFileUtils.writeZipFile(sources, "META-INF/MANIFEST.MF:Version:1.0"); + assertEquals(1, result.getRoots().length); + assertEquals(sourcesRoot, result.getRoots()[0].toURL()); + } } From 6256c2a1c7498aa40ce7e89636ab151ec81b6d72 Mon Sep 17 00:00:00 2001 From: thomas Date: Fri, 8 Nov 2019 20:37:02 +0100 Subject: [PATCH 3/3] Add license headers --- .../api/java/source/ui/Javadoc11Class.html | 16 ++++++++++++++++ .../api/java/source/ui/Javadoc11Enum.html | 16 ++++++++++++++++ .../api/java/source/ui/Javadoc8Class.html | 16 ++++++++++++++++ .../api/java/source/ui/Javadoc8Enum.html | 16 ++++++++++++++++ 4 files changed, 64 insertions(+) diff --git a/java/java.sourceui/test/unit/src/org/netbeans/api/java/source/ui/Javadoc11Class.html b/java/java.sourceui/test/unit/src/org/netbeans/api/java/source/ui/Javadoc11Class.html index 36f8796068c1..49ca324e9543 100644 --- a/java/java.sourceui/test/unit/src/org/netbeans/api/java/source/ui/Javadoc11Class.html +++ b/java/java.sourceui/test/unit/src/org/netbeans/api/java/source/ui/Javadoc11Class.html @@ -1,4 +1,20 @@ + diff --git a/java/java.sourceui/test/unit/src/org/netbeans/api/java/source/ui/Javadoc11Enum.html b/java/java.sourceui/test/unit/src/org/netbeans/api/java/source/ui/Javadoc11Enum.html index 392755629b56..2c3bf10ac738 100644 --- a/java/java.sourceui/test/unit/src/org/netbeans/api/java/source/ui/Javadoc11Enum.html +++ b/java/java.sourceui/test/unit/src/org/netbeans/api/java/source/ui/Javadoc11Enum.html @@ -1,4 +1,20 @@ + diff --git a/java/java.sourceui/test/unit/src/org/netbeans/api/java/source/ui/Javadoc8Class.html b/java/java.sourceui/test/unit/src/org/netbeans/api/java/source/ui/Javadoc8Class.html index 2d298f7e634d..c1c30550c3f5 100644 --- a/java/java.sourceui/test/unit/src/org/netbeans/api/java/source/ui/Javadoc8Class.html +++ b/java/java.sourceui/test/unit/src/org/netbeans/api/java/source/ui/Javadoc8Class.html @@ -1,4 +1,20 @@ + diff --git a/java/java.sourceui/test/unit/src/org/netbeans/api/java/source/ui/Javadoc8Enum.html b/java/java.sourceui/test/unit/src/org/netbeans/api/java/source/ui/Javadoc8Enum.html index 6295039fe29f..5ee44a7d21e8 100644 --- a/java/java.sourceui/test/unit/src/org/netbeans/api/java/source/ui/Javadoc8Enum.html +++ b/java/java.sourceui/test/unit/src/org/netbeans/api/java/source/ui/Javadoc8Enum.html @@ -1,4 +1,20 @@ +