Skip to content

Commit 695d446

Browse files
authored
Merge pull request #58 from 2m/wip-scaladoc-for-java-class-2m
Link to scaladocs when javadoc link is not found
2 parents 0550957 + 3bbf65a commit 695d446

File tree

9 files changed

+64
-13
lines changed

9 files changed

+64
-13
lines changed

src/main/scala/com/lightbend/paradox/apidoc/ApidocDirective.scala

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,13 @@ import com.lightbend.paradox.markdown.InlineDirective
2020
import org.pegdown.Printer
2121
import org.pegdown.ast.{DirectiveNode, TextNode, Visitor}
2222

23-
class ApidocDirective(allClassesAndObjects: IndexedSeq[String]) extends InlineDirective("apidoc") {
23+
class ApidocDirective(allClassesAndObjects: IndexedSeq[String], properties: Map[String, String])
24+
extends InlineDirective("apidoc") {
25+
final val JavadocProperty = raw"""javadoc\.(.*)\.base_url""".r
26+
final val JavadocBaseUrls = properties.collect {
27+
case (JavadocProperty(pkg), url) => pkg -> url
28+
}
29+
2430
val allClasses = allClassesAndObjects.filterNot(_.endsWith("$"))
2531

2632
private case class Query(pattern: String, generics: String, linkToObject: Boolean) {
@@ -74,7 +80,7 @@ class ApidocDirective(allClassesAndObjects: IndexedSeq[String]) extends InlineDi
7480
}
7581
}
7682

77-
def syntheticNode(group: String, label: String, fqcn: String, node: DirectiveNode): DirectiveNode = {
83+
def syntheticNode(group: String, doctype: String, label: String, fqcn: String, node: DirectiveNode): DirectiveNode = {
7884
val syntheticSource = new DirectiveNode.Source.Direct(fqcn)
7985
val attributes = new org.pegdown.ast.DirectiveAttributes.AttributeMap()
8086
new DirectiveNode(
@@ -86,7 +92,7 @@ class ApidocDirective(allClassesAndObjects: IndexedSeq[String]) extends InlineDi
8692
null,
8793
new DirectiveNode(
8894
DirectiveNode.Format.Inline,
89-
group + "doc",
95+
doctype + "doc",
9096
label,
9197
syntheticSource,
9298
node.attributes,
@@ -111,14 +117,22 @@ class ApidocDirective(allClassesAndObjects: IndexedSeq[String]) extends InlineDi
111117
case 1 if matches(0).contains("adsl") =>
112118
throw new java.lang.IllegalStateException(s"Match for $query only found in one language: ${matches(0)}")
113119
case 1 =>
114-
syntheticNode("scala", query.scalaLabel(matches(0)), matches(0) + scalaClassSuffix, node).accept(visitor)
115-
syntheticNode("java", query.javaLabel(matches(0)), matches(0), node).accept(visitor)
120+
val pkg = matches(0)
121+
syntheticNode("scala", "scala", query.scalaLabel(pkg), pkg + scalaClassSuffix, node).accept(visitor)
122+
if (hasJavadocUrl(pkg))
123+
syntheticNode("java", "java", query.javaLabel(pkg), pkg, node).accept(visitor)
124+
else
125+
syntheticNode("java", "scala", query.scalaLabel(pkg), pkg + scalaClassSuffix, node).accept(visitor)
116126
case 2 if matches.forall(_.contains("adsl")) =>
117-
matches.foreach(m => {
118-
if (!m.contains("javadsl"))
119-
syntheticNode("scala", query.scalaLabel(m), m + scalaClassSuffix, node).accept(visitor)
120-
if (!m.contains("scaladsl"))
121-
syntheticNode("java", query.javaLabel(m), m, node).accept(visitor)
127+
matches.foreach(pkg => {
128+
if (!pkg.contains("javadsl"))
129+
syntheticNode("scala", "scala", query.scalaLabel(pkg), pkg + scalaClassSuffix, node).accept(visitor)
130+
if (!pkg.contains("scaladsl")) {
131+
if (hasJavadocUrl(pkg))
132+
syntheticNode("java", "java", query.javaLabel(pkg), pkg, node).accept(visitor)
133+
else
134+
syntheticNode("java", "scala", query.scalaLabel(pkg), pkg + scalaClassSuffix, node).accept(visitor)
135+
}
122136
})
123137
case n =>
124138
throw new java.lang.IllegalStateException(
@@ -128,4 +142,15 @@ class ApidocDirective(allClassesAndObjects: IndexedSeq[String]) extends InlineDi
128142
}
129143
}
130144

145+
/**
146+
* Logic borrowed from Paradox project:
147+
* https://github.com/lightbend/paradox/blob/b271a6bbd249515405a06df58f298a57c34afeb5/core/src/main/scala/com/lightbend/paradox/markdown/Directive.scala#L276
148+
*/
149+
private def hasJavadocUrl(pkg: String) = {
150+
val levels = pkg.split("[.]")
151+
val packages = (1 until levels.size).map(levels.take(_).mkString("."))
152+
val javadocUrl = packages.reverse.collectFirst(JavadocBaseUrls)
153+
javadocUrl.exists(!_.isEmpty)
154+
}
155+
131156
}

src/main/scala/com/lightbend/paradox/apidoc/ApidocPlugin.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ object ApidocPlugin extends AutoPlugin {
5454
val allClasses = scanner.getAllClasses.getNames.asScala.toVector
5555
Def.task {
5656
Seq(
57-
{ _: Writer.Context
58-
new ApidocDirective(allClasses)
57+
{ ctx: Writer.Context =>
58+
new ApidocDirective(allClasses, ctx.properties)
5959
}
6060
)
6161
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
libraryDependencies += "com.typesafe.akka" %% "akka-stream-typed" % "2.5.25"
2+
3+
enablePlugins(ParadoxPlugin)
4+
paradoxTheme := None
5+
paradoxGroups := Map("Language" -> Seq("Java", "Scala"))
6+
paradoxProperties ++= Map(
7+
"scaladoc.akka.base_url" -> "akka-scaladoc",
8+
"scaladoc.akka.stream.base_url" -> "akka-stream-scaladoc",
9+
"javadoc.akka.base_url" -> "akka-javadoc",
10+
"javadoc.akka.stream.base_url" -> ""
11+
)
12+
13+
apidocRootPackage := "akka"
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<p>Api link to a class that is both in scaladsl and javadsl packages, but has no javadoc configured: <span class="group-java"><a href="akka-stream-scaladoc/akka/stream/javadsl/Flow.html">Flow</a></span><span class="group-scala"><a href="akka-stream-scaladoc/akka/stream/scaladsl/Flow.html">Flow</a></span></p>
2+
<p>Api link to a class that is in common package, but has no javadoc configured <span class="group-scala"><a href="akka-stream-scaladoc/akka/stream/stage/GraphStage.html">GraphStage</a></span><span class="group-java"><a href="akka-stream-scaladoc/akka/stream/stage/GraphStage.html">GraphStage</a></span></p>
3+
<p>Api link to a class that is both in scaladsl and javadsl packages, and has javadoc configured: <span class="group-java"><a href="akka-javadoc/?akka/actor/typed/javadsl/Behaviors.html">Behaviors</a></span><span class="group-scala"><a href="akka-scaladoc/akka/actor/typed/scaladsl/Behaviors.html">Behaviors</a></span></p>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
addSbtPlugin("com.lightbend.paradox" % "sbt-paradox-apidoc" % sys.props("project.version"))
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
$page.content$
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Api link to a class that is both in scaladsl and javadsl packages, but has no javadoc configured: @apidoc[Flow]
2+
3+
Api link to a class that is in common package, but has no javadoc configured @apidoc[GraphStage]
4+
5+
Api link to a class that is both in scaladsl and javadsl packages, and has javadoc configured: @apidoc[Behaviors]
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
> paradox
2+
3+
$ must-mirror target/paradox/site/main/index.html expected/index.html

src/test/scala/com/lightbend/paradox/apidoc/ApidocDirectiveSpec.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class ApidocDirectiveSpec extends MarkdownBaseSpec {
5353
verbatimSerializers = Writer.defaultVerbatims,
5454
serializerPlugins = Writer.defaultPlugins(
5555
Writer.defaultDirectives ++ Seq(
56-
(_: Writer.Context) => new ApidocDirective(allClasses)
56+
(ctx: Writer.Context) => new ApidocDirective(allClasses, ctx.properties)
5757
)
5858
)
5959
)

0 commit comments

Comments
 (0)