Skip to content
Open
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
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package com.riege.scope.gradle.forms

import com.riege.jasperservice.model.PDFRawData
import com.riege.jasperservice.model.TextRawData

import java.nio.file.Path

class FormRenderData {

PDFRawData jasperServiceData
TextRawData textData
File file
String fileName
Set<File> dependencies = new HashSet<>()
Expand All @@ -28,6 +30,9 @@ class FormRenderData {
}

String getOutputName() {
if (textData != null && jasperServiceData == null) {
return fileName.concat(".txt")
}
return fileName.concat(".pdf")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,15 @@ package com.riege.scope.gradle.forms
import com.riege.jasperservice.LocalJasperService
import com.riege.jasperservice.backend.FormsLoader
import com.riege.jasperservice.backend.FormsLoader$
import com.riege.jasperservice.model.DocumentContext
import com.riege.jasperservice.model.Image
import com.riege.jasperservice.model.PDFRawData
import com.riege.jasperservice.model.Report
import scala.Option$
import scala.collection.JavaConverters
import scala.collection.immutable.Map$

import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths

Expand All @@ -31,23 +35,51 @@ class FormRenderDataFactory {

private FormRenderData loadJson(Path file) {
LocalJasperService.startUp(formPath.out.toString())
def data = LocalJasperService.instance().read(file.toString())
DocumentContext context
String formName
def result = new FormRenderData(
jasperServiceData: data,
file: file.toFile(),
fileName: dataDir.relativize(file),
)
def localeOption = Option$.MODULE$.apply(data.context().locale())
def loader = new FormsLoader(data.context(), formPath.out.toString(), false)

if (file.toString().endsWith(".text.json")) {
result.textData = LocalJasperService.instance().readText(file.toString())
context = result.textData.context()
formName = result.textData.formName()
} else {
result.jasperServiceData = LocalJasperService.instance().read(file.toString())
context = result.jasperServiceData.context()
formName = result.jasperServiceData.formName()

if (PDFWithTextSupport.isFormSupported(formName)) {
def textFile = Paths.get(file.toString().replaceFirst("\\.json\$", ".text.json"))
if(Files.exists(textFile)) {
result.textData = LocalJasperService.instance().readText(textFile.toString())
}
result.addDependency(textFile)
}
}

def localeOption = Option$.MODULE$.apply(context.locale())
def loader = new FormsLoader(context, formPath.out.toString(), false)
def formDirUri = loader
.getForm(data.formName(), localeOption)
.getForm(formName, localeOption)
.getProperty(FormsLoader$.MODULE$.PROPERTY_FORM_DIR())
def formDir = Paths.get(new URI(formDirUri).normalize())
def formFile = loader.getFile(data.formName() + ".jasper", localeOption).get().toPath()
result.addDependency(file)
result.addDependency(formFile)
addFileDependencies(result, formDir, new Form(getFormPath(), formFile), loader)
addParameterDependencies(result, JavaConverters.mapAsJavaMap(data.data()), loader)

if (result.jasperServiceData != null) {
def formFile = loader.getFile(result.jasperServiceData.formName() + ".jasper", localeOption).get().toPath()
result.addDependency(formFile)
addFileDependencies(result, formDir, new Form(getFormPath(), formFile), loader)
addParameterDependencies(result, JavaConverters.mapAsJavaMap(result.jasperServiceData.data()), loader)
}

if (result.textData != null) {
def formFile = loader.getFile(result.textData.formName() + ".jasper", localeOption).get().toPath()
result.addDependency(formFile)
}

return result
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.riege.scope.gradle.forms

import com.riege.jasperservice.model.PDFRawData
import scala.collection.JavaConverters
import scala.collection.immutable.Map$

class PDFWithTextSupport {

static boolean isFormSupported(String formName) {
return formName == "CmrWaybill"
}

static PDFRawData replaceEmbeddedText(PDFRawData data, String renderedText) {
if (data.formName() == "CmrWaybill") {
return replaceParameter(data, "mainreport.dataSource", buildCmrTextLineRows(renderedText))
}
return data
}

private static PDFRawData replaceParameter(PDFRawData pdfRawData, String name, Object scalaLines) {
def updatedData = pdfRawData.data().updated(name, scalaLines)
return new PDFRawData(
pdfRawData.context(),
pdfRawData.encryptPDF(),
pdfRawData.pdfa(),
pdfRawData.formName(),
pdfRawData.dataSourceParameterName(),
pdfRawData.backgroundImage(),
updatedData
)
}

static def buildCmrTextLineRows(String text) {
def scalaLineMaps = (text?.readLines() ?: []).collect { line ->
createSingleEntryScalaMap("cmrTextLine", line ?: "")
}
JavaConverters.asScalaBuffer(scalaLineMaps).toList()
}

static def createSingleEntryScalaMap(String key, String value) {
def tupleSeq = JavaConverters.asScalaBuffer([
new scala.Tuple2(key, value)
]).toSeq()
Map$.MODULE$.apply(tupleSeq)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import com.riege.scope.gradle.forms.FormPath
import com.riege.scope.gradle.forms.FormRenderData
import com.riege.scope.gradle.forms.FormRenderDataCache
import com.riege.scope.gradle.forms.FormRenderDataFactory
import com.riege.scope.gradle.forms.PDFWithTextSupport
import com.riege.scope.gradle.forms.PdfCreator
import net.sf.jasperreports.engine.JasperReport
import org.gradle.api.DefaultTask
Expand Down Expand Up @@ -108,10 +109,19 @@ class RenderFormsTask extends DefaultTask {
rebuildSet.each { data ->
println "Rebuilding ${data.file}"
try {
byte[] pdf
pdf = LocalJasperService.instance().render(data.jasperServiceData)
pdf = PdfCreator.addTestOverlay(pdf)
writePdfToOutputDir(data.outputName, pdf)
byte[] renderedBytes
if (data.jasperServiceData != null) {
def renderData = data.jasperServiceData
if (data.textData != null) {
def generatedText = LocalJasperService.instance().render(data.textData)
renderData = PDFWithTextSupport.replaceEmbeddedText(data.jasperServiceData, new String(generatedText))
}
renderedBytes = LocalJasperService.instance().render(renderData)
renderedBytes = PdfCreator.addTestOverlay(renderedBytes)
} else {
renderedBytes = LocalJasperService.instance().render(data.textData)
}
writePdfToOutputDir(data.outputName, renderedBytes)
} catch (Exception e) {
handleRendererException(data.file, e)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ import akka.util.Timeout
import better.files.File
import com.riege.jasperservice.backend._
import com.riege.jasperservice.frontend.JasperServiceProtocol
import com.riege.jasperservice.model.{PDFDocument, PDFRawData}
import spray.json._
import com.riege.jasperservice.model.{PDFDocument, PDFRawData, TextDocument, TextRawData}

import spray.json._
import scala.concurrent.duration.SECONDS
import scala.concurrent.{Await, Future}

Expand Down Expand Up @@ -66,6 +66,7 @@ class LocalJasperService(val fileStore: String, val formsStore: String) extends
// )

val pdfProducer = actorOf(PDFProducer(formsStore, fileStore), "pdf-producer")
val textProducer = actorOf(TextProducer(formsStore), "text-producer")

// pageDimensionResolver = actorOf(PageDimensionResolver(formsStore), "page-dimension-resolver")
// textProducer = actorOf(TextProducer(formsStore), "text-producer")
Expand All @@ -83,6 +84,11 @@ class LocalJasperService(val fileStore: String, val formsStore: String) extends
pdfRawDataFormat.read(jsonWithDefaults).copy(encryptPDF = false)
}

def readText(dataFile: String): TextRawData = {
val json = File(dataFile).lines(UTF_8).mkString.parseJson
textRawDataFormat.read(json)
}

def render(data: PDFRawData): Array[Byte] = {
val pdfFuture: Future[Any] = pdfProducer ? data
val result = Await.result(pdfFuture, timeout.duration)
Expand All @@ -92,4 +98,11 @@ class LocalJasperService(val fileStore: String, val formsStore: String) extends
tmpFile.delete()
bytes
}

def render(data: TextRawData): Array[Byte] = {
val textFuture: Future[Any] = textProducer ? data
val result = Await.result(textFuture, timeout.duration)
val text = result.asInstanceOf[TextDocument]
text.content.getBytes(UTF_8)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/*
* Copyright (c) 2017 Riege Software International. All rights reserved.
* Use is subject to license terms.
*/

package com.riege.jasperservice.backend

import java.lang.StringBuilder
import java.util

import scala.util.control.NonFatal

import akka.actor.{Actor, ActorLogging, Props, Status}

import com.riege.jasperservice.backend.FormsLoader.PROPERTY_FORM_DIR
import com.riege.jasperservice.functions.JasperServiceFunctions
import com.riege.jasperservice.model.{TextDocument, TextRawData}

import net.sf.jasperreports.engine.data.JRMapCollectionDataSource
import net.sf.jasperreports.engine.export.JRTextExporter
import net.sf.jasperreports.engine.{JRParameter, JasperFillManager, JasperPrint, JasperReport}
import net.sf.jasperreports.export.{SimpleExporterInput, SimpleTextExporterConfiguration, SimpleTextReportConfiguration, SimpleWriterExporterOutput}

object TextProducer {

def apply(formsStore: String): Props =
Props(new TextProducer(formsStore))

}

/**
* @author <a href="mailto:golovnin@riege.com">Andrej Golovnin</a>
*/
class TextProducer(
formsStore: String
) extends Actor with ActorLogging {

override def receive: Receive = {
case data: TextRawData =>
try {
val document = createDocument(data)
sender() ! document
} catch {
case NonFatal(e) =>
import com.riege.jasperservice.frontend.JasperServiceProtocol._

log.error(e, "Failed to produce a text document for the data:\n{}\n",
textRawDataFormat.write(data).prettyPrint)
sender() ! Status.Failure(BackendException(e))
}
}

private def createDocument(data: TextRawData): TextDocument = {
val ctx = data.context
val formLoader = new FormsLoader(ctx, formsStore)
val form = formLoader.getForm(data.formName, Option(ctx.locale))
val exporter = getJRExporter(data)
val printable = createPrintable(data, formLoader, form)

val out = new StringBuilder()
exporter.setExporterInput(new SimpleExporterInput(printable))
exporter.setExporterOutput(new SimpleWriterExporterOutput(out))
exporter.exportReport()

if (ctx.production) {
TextDocument(out.toString)
} else {
TextDocument(out.toString, Some(form.getProperty(FormsLoader.PROPERTY_FORM_FILE)))
}
}

private def getJRExporter(data: TextRawData): JRTextExporter = {
val ec = new SimpleTextExporterConfiguration
ec.setLineSeparator(data.lineSeparator.getOrElse("\n"))
ec.setPageSeparator(data.pageSeparator.getOrElse("\n"))
val rc = new SimpleTextReportConfiguration
rc.setCharHeight(float2Float(data.charHeight.getOrElse(12.0f)))
rc.setPageWidthInChars(int2Integer(data.pageWidthInChars.getOrElse(74)))
rc.setPageHeightInChars(int2Integer(data.pageHeightInChars.getOrElse(64)))
val exporter = new JRTextExporter
exporter.setConfiguration(ec)
exporter.setConfiguration(rc)
exporter
}

private def createPrintable(
data: TextRawData,
formLoader: FormsLoader,
form: JasperReport
): JasperPrint = {
val locale = data.context.locale
val localeOpt = Option(locale)
val formDir = form.getProperty(PROPERTY_FORM_DIR)
val jasperData = formLoader.toJasperData(data.data)
val map: util.Map[String, Object] = jasperData.data
map.put(PROPERTY_FORM_DIR, formDir)
map.put(JRParameter.REPORT_LOCALE, locale)
JasperServiceFunctions.setLoadFormHandler(
formName => formLoader.getForm(formName, localeOpt)
)
try {
var dataSource: JRMapCollectionDataSource = null
val dataSourceData: util.Collection[util.Map[String, _]] =
map.get(data.dataSourceParameterName)
.asInstanceOf[util.Collection[util.Map[String, _]]]
if (dataSourceData != null) {
dataSource = new JRMapCollectionDataSource(dataSourceData)
}

val jasperPrint = JasperFillManager.fillReport(form, map, dataSource)

data.pageHeight.foreach(jasperPrint.setPageHeight)
data.pageWidth.foreach(jasperPrint.setPageWidth)

jasperPrint
} finally {
JasperServiceFunctions.remove()
}
}

}
Loading
Loading