Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature - Scala 2.13 support #32

Merged
merged 6 commits into from
Aug 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
language: scala
jdk: oraclejdk8
scala: 2.12.2
jdk: openjdk8
scala: 2.12.9
env:
global:
- secure: "T284bq+EzkaCQOH12GyVt/WV3XOpr8JofrNwDQfImxE3PUjPPeTNrVId30uJmraunEIxEth1qxI+TL4WLjVGtKiNJTgsWq8OFaZy9eCD/hHtJV6vbQzEx2kUuJVROJjrxrpV+PqFnOYNpeyocrahwxKlvyksDWFnXMgPLJgzoqNMUamlZs9ZM+H7YnA3Sg81dYIHZDOmku0k36WZUKw6pF2kKv0MzLdrn9F9JpNX+oAH82yP4OCfoTInOHMcGBPqpebH1atxOeOQ/L4h17okpPWkyDsbK0OQzz2CbuaQDkfE++nDinFpU7R6IOLYNl29DGQATJX29bpfD7xOUWD7Z08Dx87sld+gEeQquECCoOHYDjH63/DmHrjVSXh9t94DptJPmrXQeI0kxAd5YNpoAuA41ilyJCJrRMeAoThxBwrWvxrkUvESTDLFbqlUd+ZYaP+nNoNPSYkFS3wYQCkOxUJ8zUSeJ8vkoPZwW49igRubUafBIbnd7ybU2AWx7hK1yzKzMe5Jlgiv/13gOBlAqSjfnQnh86HYpxpP1RoeMkpRQB5DGsi7C0Y5npG7eNCO5aeh2Uw6A3eIU4SjY3T7vVARswx0WKMS+Z72Euu7FGw5BuFhwRnP1H6CuBiC342eQIp3bS6VP4BxWyL7lpVgSYk806/LWi2xp4UGnnUzST4="
Expand All @@ -9,5 +9,6 @@ env:
- MODULE_DIR=modules/play24
- MODULE_DIR=modules/play25
- MODULE_DIR=modules/play26
- MODULE_DIR=modules/play27
script: cd $MODULE_DIR && ../../scripts/test.sh
after_success: test $TRAVIS_BRANCH = "master" && ../../scripts/publish.sh
22 changes: 11 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ It simply renders Play Framework HTML and CSS-based view templates to PDF via [F

The supported Scala and Play versions as follows:

| | Scala 2.10 | Scala 2.11 | Scala 2.12 |
| --------- |:----------:|:----------:|:----------:|
| Play 2.4 | `YES` | `YES` | |
| Play 2.5 | | `YES` | |
| Play 2.6 | | `YES` | `YES` |
| Play 2.7 | | `YES` | `YES` |
| | Scala 2.10 | Scala 2.11 | Scala 2.12 | Scala 2.13 |
| --------- |:----------:|:----------:|:----------:|:----------:|
| Play 2.4 | `YES` | `YES` | | |
| Play 2.5 | | `YES` | | |
| Play 2.6 | | `YES` | `YES` | |
| Play 2.7 | | `YES` | `YES` | `YES` |

### Play Framework Java

Expand All @@ -35,7 +35,7 @@ def providePdfGenerator(): PdfGenerator = {
pdfGen.loadLocalFonts(Seq("fonts/opensans-regular.ttf"))
pdfGen
}
```
```

Currently, the module is hosted at Maven Central Repository. Include the following lines in ```build.sbt```, then reload SBT to resolve and enable the module:
``` scala
Expand All @@ -52,7 +52,7 @@ resolvers ++= Seq(
)
```

*NOTE: If you are using an IDE like Eclipse, remember to re-generate your project files.*
*NOTE: If you are using an IDE like Eclipse, remember to re-generate your project files.*

## Usage

Expand All @@ -70,9 +70,9 @@ You can use a standard Play Framework Scala template like this one:
Then this template, after having imported ```com.hhandoko.play.pdf.PdfGenerator```, can simply be rendered as:
``` scala
class HomeController @Inject() (pdfGen: PdfGenerator) extends Controller {

def examplePdf = Action { pdfGen.ok(views.html.example(), "http://localhost:9000") }

}
```

Expand All @@ -89,7 +89,7 @@ Please observe the following constraints to avoid issues when using this module:
- Non-system fonts must be loaded explicitly (see below for example)
- External assets such as images need to be loaded as base64-encoded string
- External such as stylesheets will be loaded as per normal HTML page load

*NOTE: If the specified URI is a path into Play Framework app classpath, the resource is loaded directly instead. See the above sample template for an example.*

Fonts can be loaded by invoking `PdfGenerator.loadLocalFonts` method. For example:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import com.hhandoko.play.pdf.PdfGenerator
class ApplicationModule extends AbstractModule with ScalaModule {

/** Module configuration + binding */
def configure(): Unit = {}
override def configure(): Unit = {}

/**
* Provides PDF generator implementation.
Expand Down
2 changes: 1 addition & 1 deletion examples/play24-example/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ crossScalaVersions := Seq("2.10.7", "2.11.12")

libraryDependencies ++= Seq(
// Utilities
"net.codingwell" %% "scala-guice" % "4.1.0",
"net.codingwell" %% "scala-guice" % "4.1.1",

// WebJars
"org.webjars.bower" % "jquery" % "1.12.4",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import com.hhandoko.play.pdf.PdfGenerator
class ApplicationModule extends AbstractModule with ScalaModule {

/** Module configuration + binding */
def configure(): Unit = {}
override def configure(): Unit = {}

/**
* Provides PDF generator implementation.
Expand Down
2 changes: 1 addition & 1 deletion examples/play25-example/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ crossScalaVersions := Seq("2.11.12")

libraryDependencies ++= Seq(
// Utilities
"net.codingwell" %% "scala-guice" % "4.1.0",
"net.codingwell" %% "scala-guice" % "4.2.6",

// WebJars
"org.webjars.bower" % "jquery" % "1.12.4",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import com.hhandoko.play.pdf.PdfGenerator
class ApplicationModule extends AbstractModule with ScalaModule {

/** Module configuration + binding */
def configure(): Unit = {}
override def configure(): Unit = {}

/**
* Provides PDF generator implementation.
Expand Down
6 changes: 3 additions & 3 deletions examples/play26-example/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@ name := """play26-scala-pdf-example"""

version := "1.0.0"

scalaVersion := "2.12.8"
scalaVersion := "2.12.9"

crossScalaVersions := Seq("2.11.12", "2.12.8")
crossScalaVersions := Seq("2.11.12", "2.12.9")

libraryDependencies ++= Seq(
guice,

// Utilities
"net.codingwell" %% "scala-guice" % "4.1.0",
"net.codingwell" %% "scala-guice" % "4.2.6",

// WebJars
"org.webjars.bower" % "jquery" % "1.12.4",
Expand Down
2 changes: 1 addition & 1 deletion examples/play26-example/project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
// Play Framework plugin
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.21")
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.23")
8 changes: 4 additions & 4 deletions examples/play27-example/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -28,23 +28,23 @@ name := """play27-scala-pdf-example"""

version := "1.0.0"

scalaVersion := "2.12.8"
scalaVersion := "2.13.0"

crossScalaVersions := Seq("2.11.12", "2.12.8")
crossScalaVersions := Seq("2.11.12", "2.12.9", "2.13.0")

libraryDependencies ++= Seq(
guice,

// Utilities
"net.codingwell" %% "scala-guice" % "4.1.0",
"net.codingwell" %% "scala-guice" % "4.2.6",

// WebJars
"org.webjars.bower" % "jquery" % "1.12.4",
"org.webjars.bower" % "bootstrap" % "3.3.7",

// ScalaTest + Play plugin
// - http://www.scalatest.org/plus/play
"org.scalatestplus.play" %% "scalatestplus-play" % "4.0.1" % Test
"org.scalatestplus.play" %% "scalatestplus-play" % "4.0.3" % Test
)

resolvers += "scalaz-bintray" at "http://dl.bintray.com/scalaz/releases"
Expand Down
2 changes: 1 addition & 1 deletion examples/play27-example/project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
// Play Framework plugin
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.7.0")
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.7.3")
4 changes: 2 additions & 2 deletions modules/play26/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ organization := "com.hhandoko"

version := Source.fromFile("../../VERSION.txt").mkString.trim

scalaVersion := "2.12.8"
scalaVersion := "2.12.9"

crossScalaVersions := Seq("2.11.12", "2.12.8")
crossScalaVersions := Seq("2.11.12", "2.12.9")

libraryDependencies ++= Seq(
guice,
Expand Down
2 changes: 1 addition & 1 deletion modules/play26/project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Play Framework plugin
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.21")
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.23")

// Maven publishing-specific
// ~~~~~
Expand Down
25 changes: 19 additions & 6 deletions modules/play27/app/com/hhandoko/play/pdf/PdfGenerator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,9 @@ class PdfGenerator(env: Environment, val xhtml: Boolean = false) {
* @param fonts the external / additional fonts to load.
* @return Generated PDF result (with "application/pdf" MIME type).
*/
def ok(html: Html, documentBaseUrl: String, fonts: Seq[String] = defaultFonts): Result = {
Results.Ok(toBytes(parseString(html), documentBaseUrl, fonts)).as("application/pdf")
def ok(html: Html, documentBaseUrl: String, fonts: Seq[String] = Nil): Result = {
val loadedFonts = defaultIfEmpty(fonts)
Results.Ok(toBytes(parseString(html), documentBaseUrl, loadedFonts)).as("application/pdf")
}

/**
Expand All @@ -133,7 +134,7 @@ class PdfGenerator(env: Environment, val xhtml: Boolean = false) {
def toBytes(html: Html, documentBaseUrl: String, fonts: Seq[String]): Array[Byte] = {
// NOTE: Use default value assignment in method body,
// as Scala compiler does not like overloaded methods with default params
val loadedFonts = if (fonts.isEmpty) defaultFonts else fonts
val loadedFonts = defaultIfEmpty(fonts)
toBytes(parseString(html), documentBaseUrl, loadedFonts)
}

Expand All @@ -148,7 +149,7 @@ class PdfGenerator(env: Environment, val xhtml: Boolean = false) {
def toBytes(string: String, documentBaseUrl: String, fonts: Seq[String]): Array[Byte] = {
// NOTE: Use default value assignment in method body,
// as Scala compiler does not like overloaded methods with default params
val loadedFonts = if (fonts.isEmpty) defaultFonts else fonts
val loadedFonts = defaultIfEmpty(fonts)
val output = new ByteArrayOutputStream()
toStream(output)(string, documentBaseUrl, loadedFonts)
output.toByteArray
Expand All @@ -162,10 +163,11 @@ class PdfGenerator(env: Environment, val xhtml: Boolean = false) {
* @param documentBaseUrl the document / page base URL.
* @param fonts the external / additional fonts to load.
*/
def toStream(output: OutputStream)(string: String, documentBaseUrl: String, fonts: Seq[String] = defaultFonts): Unit = {
def toStream(output: OutputStream)(string: String, documentBaseUrl: String, fonts: Seq[String] = Nil): Unit = {
val loadedFonts = defaultIfEmpty(fonts)
val input = new ByteArrayInputStream(string.getBytes("UTF-8"))
val renderer = new ITextRenderer()
fonts.foreach { font => renderer.getFontResolver.addFont(font, BaseFont.IDENTITY_H, BaseFont.EMBEDDED) }
loadedFonts.foreach { font => renderer.getFontResolver.addFont(font, BaseFont.IDENTITY_H, BaseFont.EMBEDDED) }
val userAgent = new PdfUserAgent(env, renderer.getOutputDevice)
userAgent.setSharedContext(renderer.getSharedContext)
renderer.getSharedContext.setUserAgentCallback(userAgent)
Expand All @@ -190,4 +192,15 @@ class PdfGenerator(env: Environment, val xhtml: Boolean = false) {
} else html.body
}

/**
* Use default fonts if given fonts list is empty.
*
* @note `defaultFonts.toSeq` is used as a universal conversion method due to `Seq` predef changes from mutable to
* immutable collections.
* @param fonts the fonts to load.
* @return Fonts to load or default fonts as fallback.
*/
private[this] def defaultIfEmpty(fonts: Seq[String]): Seq[String] =
if (fonts.isEmpty) defaultFonts.toSeq else fonts

}
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ class PdfUserAgent(env: Environment, outputDevice: ITextOutputDevice) extends IT
*/
private def toByteArray(stream: InputStream): Array[Byte] = {
val buffer = new BufferedInputStream(stream)
Stream.continually(buffer.read).takeWhile(-1 !=).map(_.toByte).toArray
Stream.continually(buffer.read).takeWhile(-1 != _).map(_.toByte).toArray
}

/**
Expand Down
6 changes: 3 additions & 3 deletions modules/play27/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ organization := "com.hhandoko"

version := Source.fromFile("../../VERSION.txt").mkString.trim

scalaVersion := "2.12.8"
scalaVersion := "2.13.0"

crossScalaVersions := Seq("2.11.12", "2.12.8")
crossScalaVersions := Seq("2.11.12", "2.12.9", "2.13.0")

libraryDependencies ++= Seq(
guice,
Expand All @@ -55,7 +55,7 @@ libraryDependencies ++= Seq(

// ScalaTest + Play plugin
// - http://www.scalatest.org/plus/play
"org.scalatestplus.play" %% "scalatestplus-play" % "4.0.1" % Test
"org.scalatestplus.play" %% "scalatestplus-play" % "4.0.3" % Test
)

resolvers += "scalaz-bintray" at "http://dl.bintray.com/scalaz/releases"
Expand Down
2 changes: 1 addition & 1 deletion modules/play27/project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Play Framework plugin
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.7.0")
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.7.3")

// Maven publishing-specific
// ~~~~~
Expand Down