Skip to content

Instantly share code, notes, and snippets.

package tika.example
import java.io.ByteArrayOutputStream
import java.nio.charset.Charset
import org.apache.tika.metadata.Metadata
import org.apache.tika.sax.BodyContentHandler
import scala.util.{Failure, Success, Using}
package tika.example
import java.io.InputStream
import org.apache.tika.config.TikaConfig
import org.apache.tika.metadata.Metadata
import org.apache.tika.parser.ocr.TesseractOCRConfig
import org.apache.tika.parser.pdf.PDFParserConfig
import org.apache.tika.parser.{AutoDetectParser, ParseContext, Parser}
import org.apache.tika.sax.BodyContentHandler
<dependency>
<groupId>org.apache.tika</groupId>
<artifactId>tika-core</artifactId>
<version>1.24</version>
</dependency>
<dependency>
<groupId>org.apache.tika</groupId>
<artifactId>tika-parsers</artifactId>
<version>1.24</version>
</dependency>
case class WeatherForecast(
humidity: Percentage,
windForecast: WindForecast,
sunshine: Percentage,
temperature: Temperature,
chanceOfRain: ChanceOfRain
)
case class Temperature(degrees: Int, temperatureScale: String)
case class Percentage(percent: Double)
case class WindForecast(windSpeed: WindSpeed, direction: String)
generateWeatherForecasts <- function(pathToMagicFile) {
# We're bringing the function contained in the file at the given location into scope
source(paste(pathToMagicFile))
# This returns a dataframe, a way for R to store large quantities of data in an ordered
# manner (kind of like a Database Table...)
weatherForecast <- magicHappensHere()
# We use the Scala Domain object provided through GraalVM bindings to get ourselves an
# instance of the Scala wrapper containing a List of WeatherForecast
// Remember to always put a call to R in a Try block, because
// R often resorts to throwing RuntimeExceptions.
Try(rMagicWithBindings(path)) match {
case Failure(f) => print(f)
case Success(weatherForecastList) =>
// We get back a WeatherForecastList, which is a wrapper for List[WeatherForecast].
// Now we can work with the results WITHOUT any parsing:
// simply take out the List and do your operations (here we print them one by one).
weatherForecastList.asScalaList.foreach(forecast => println(forecast))
}
// This function signature is a lot cleaner than the one that doesn't use bindings.
// It is also completely Scala, meaning we do not have to do ANY parsing.
val rMagicWithBindings: String => WeatherForecastList =
context.eval(sourceWithBindings).as(classOf[String => WeatherForecastList])
// This source will use the provided Domain instance to create objects as they have been
// defined in the Scala domain.
val sourceWithBindings: Source =
Source
.newBuilder("R", Main.getClass.getResource("fun_WithBindingsWeatherForecasts.R"))
.build()
/*
* Our Domain object functions as a factory for our domain-related classes.
* It has methods that create new instances of these classes, which can then safely be used from another Context.
*/
class Domain {
def weatherForecastList(): WeatherForecastList = WeatherForecastList(List())
def percentage(percent: Int): Percentage = Percentage(percent: Double)
def chanceOfRain(chance: Percentage): ChanceOfRain = ChanceOfRain(chance: Percentage)
def temperature(degrees: Int, temperatureScale: String): Temperature =
/*
* Exposing bindings is an interesting way to share functionality between languages.
* This command makes an instance of the Domain class available under the "Domain"
* accessor.
*/
context.getBindings("R").putMember("Domain", new Domain)