object ExternalReferences2 {
import java.util.regex._
import collection.mutable._
private object Mapping {
def fromXml(mapping: scala.xml.NodeSeq) = {
new Mapping(mapping \ "vendor" text, mapping \ "match" text, mapping \ "format" text)
}
}
private case class Mapping(vendor: String, matches: String, format: String) {
private val pattern = Pattern.compile(matches)
private var currentMatcher: Matcher = null
def hasValue(entity: String) = {
currentMatcher = pattern.matcher(entity);
currentMatcher.matches
}
def getValue = {
val range = 0 until currentMatcher.groupCount()
val groups = range
.map (currentMatcher.group(_))
.filterNot (_ == null)
.map (_.replace('.', '/'))
format.format(groups: _*)
}
}
private val config =
<external-links>
<mapping>
<vendor>OpenJDK</vendor>
<match>{ """^(javax?|sunw?|com.sun|org\.(ietf\.jgss|omg|w3c\.dom|xml\.sax))(\.[^.]+)+$""" }</match>
<format>{ "http://download.oracle.com/javase/7/docs/api/%s.html" }</format>
</mapping>
</external-links>
private def lookUp(entity: String) =
(config \ "mapping").view
.map(m => Mapping.fromXml(m))
.find(_.hasValue(entity))
.map(_.getValue)
private val links: Map[String, Option[String]] = Map[String, Option[String]]()
.withDefault(entry => {val result = lookUp(entry); links += ((entry, result)); result})
def getLink(entity: String) = links(entity)
}