I'm investigating some feature for the ScalaDoc tool, which would allow library writers to link to documentation created by third party tools like JavaDoc. My idea is to have some (XML) configuration which specifies which package prefixes belong to which vendor and how to create a valid URL from the the class name, stored in the XML as regular expressions and format strings. I only need one public method `getLink(entity: String): Option[String]` which either returns `Some(validURL)` or `None`, if the package name is not supported by the given configuration. Everything else can be changed as much as I want if it improves the code. Consider this code: 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) } How can I improve that code? - The necessity to call `hasValue` before `getValue` is pretty bad, but I don't want to create the matcher twice. - Which environment variables do I have to use so that the tool can pick up the configuration from the current directory or from an arbitrary place with a command line switch? - Is there a better way to do simple caching than using `withDefault` to mutate the underlying map? - Any idea on how to improve `lookUp`? - Are there any ideas for better names? I'm not happy with `Mapping`, `Link`, `Reference` ... things are all over the place.