Skip to content

Commit

Permalink
Upgrade stringtemplate to version 4
Browse files Browse the repository at this point in the history
- stringtemplate3 depends on a super outdated version of antlr, and
is causing this issue: 47degrees/sbt-microsites#457

- the `setAttributes` method in stringtemplate3 was always broken,
as it goes down a different code path compared to `setAttribute` in
stringtemplate3.
See [setAttributes](https://github.com/antlr/stringtemplate3/blob/e60b23544539d64d2f57a87e87a5b383cc2b0ba9/src/org/antlr/stringtemplate/StringTemplate.java#L918)
and [setAttribute](https://github.com/antlr/stringtemplate3/blob/e60b23544539d64d2f57a87e87a5b383cc2b0ba9/src/org/antlr/stringtemplate/StringTemplate.java#L570),

stringtemplate4 removed the `setAttributes` method, so I had to write a
custom function to handle the '.' characters in the properties.
  • Loading branch information
MaT1g3R committed Apr 10, 2020
1 parent 3eac64f commit 7098c64
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 10 deletions.
4 changes: 2 additions & 2 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,11 @@ lazy val knockoffDeps = Def.setting { Seq(
"org.foundweekends" %% "knockoff" % "0.8.6"
)}
val unfilteredVersion = "0.9.1"
val stringtemplateVersion = "3.2.1"
val stringtemplateVersion = "4.3"
lazy val libraryDeps = Def.setting { Seq(
"ws.unfiltered" %% "unfiltered-filter" % unfilteredVersion,
"ws.unfiltered" %% "unfiltered-jetty" % unfilteredVersion,
"org.antlr" % "stringtemplate" % stringtemplateVersion
"org.antlr" % "ST4" % stringtemplateVersion
)}
val launcherInterfaceVersion = "1.1.2"
val servletApiVersion = "3.1.0"
Expand Down
39 changes: 31 additions & 8 deletions library/src/main/scala/template.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ package pamflet
import java.io.{
File,FileInputStream,InputStreamReader,StringReader}
import java.nio.charset.Charset
import org.antlr.stringtemplate.{StringTemplate => STImpl}
import org.stringtemplate.v4.ST
import collection.immutable.Map
import collection.JavaConverters._
import scala.collection.immutable.Nil

trait Template {
/** Replace template values in input stream with bound properties */
Expand All @@ -25,25 +27,46 @@ case class StringTemplate(files: Seq[File],
extra: Map[AnyRef, AnyRef]) extends Template {
def apply(input: CharSequence) =
if (!files.isEmpty) {
import collection.JavaConverters._
val st = new STImpl
st.setTemplate(input.toString)
st.setAttributes((properties.asScala ++ extra).asJava)
st.toString
val st = new ST(input.toString, '$', '$')
(properties.asScala ++ extra).foreach {
case (key, value) =>
pairToAttribute(key.toString(), value).fold(
pair => st.add(pair._1, pair._2), pair => st.add(pair._1, pair._2)
)
}
st.render()
} else input

private def pairToAttribute(key: String, value: Object): Either[(String, Object), (String, Map[String, Object])] = {
def pairToAttributeMap(first: String, rest: List[String], value: Object): Map[String, Object] = {
rest match {
case Nil => Map(first -> value)
case head :: tail => Map(first -> pairToAttributeMap(head, tail, value))
}
}

key.split('.').toList match {
case first :: second :: tail => Right(first -> pairToAttributeMap(second, tail, value))
case _ => Left(key -> value)
}
}

private def properties = {
val p = new java.util.Properties
for (f <- files) {
val q = new java.util.Properties
q.load(new InputStreamReader(new FileInputStream(f),
Charset.forName("UTF-8")))
p.putAll(q)
q.asScala.foreach {
case (key, value) => p.put(key, value)
}
}
for (s <- str) {
val q = new java.util.Properties
q.load(new StringReader(s))
p.putAll(q)
q.asScala.foreach {
case (key, value) => p.put(key, value)
}
}
p
}
Expand Down

0 comments on commit 7098c64

Please sign in to comment.