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..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); @@ -827,10 +853,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 +896,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 +986,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..49ca324e9543 --- /dev/null +++ b/java/java.sourceui/test/unit/src/org/netbeans/api/java/source/ui/Javadoc11Class.html @@ -0,0 +1,376 @@ + + + + + + +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..2c3bf10ac738 --- /dev/null +++ b/java/java.sourceui/test/unit/src/org/netbeans/api/java/source/ui/Javadoc11Enum.html @@ -0,0 +1,422 @@ + + + + + + +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..c1c30550c3f5 --- /dev/null +++ b/java/java.sourceui/test/unit/src/org/netbeans/api/java/source/ui/Javadoc8Class.html @@ -0,0 +1,338 @@ + + + + + + +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..5ee44a7d21e8 --- /dev/null +++ b/java/java.sourceui/test/unit/src/org/netbeans/api/java/source/ui/Javadoc8Enum.html @@ -0,0 +1,383 @@ + + + + + + +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"
        +
        +
      • +
      +
    • +
    +
  • +
+
+
+ + + + + + + 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()); + } }