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

Scala version #38

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
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
64 changes: 64 additions & 0 deletions scala/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@

# Created by https://www.gitignore.io/api/sbt,scala,intellij

### Intellij ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839

# User-specific stuff:
.idea/

# CMake
cmake-build-debug/

# Mongo Explorer plugin:
.idea/**/mongoSettings.xml

## File-based project format:
*.iws

## Plugin-specific files:

# IntelliJ
/out/

# JIRA plugin
atlassian-ide-plugin.xml

# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties

### Intellij Patch ###
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721

# *.iml
# modules.xml
# .idea/misc.xml
# *.ipr

# Sonarlint plugin
.idea/sonarlint

### SBT ###
# Simple Build Tool
# http://www.scala-sbt.org/release/docs/Getting-Started/Directories.html#configuring-version-control

dist/*
target/
lib_managed/
src_managed/
project/boot/
project/plugins/project/
.history
.cache
.lib/

### Scala ###
*.class
*.log

# End of https://www.gitignore.io/api/sbt,scala,intellij

5 changes: 5 additions & 0 deletions scala/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Client requirement : scala 2.12 & sbt 0.13

To build and run : ''' sbt 'run ../data/0.json' '''
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should use backticks: ` for code examples in markdown.



9 changes: 9 additions & 0 deletions scala/build.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name := "scala"

version := "1.0"

scalaVersion := "2.12.2"

mainClass in (Compile,run) := Some("be.playing.withrojections.Main")

libraryDependencies += "org.scala-lang.modules" %% "scala-parser-combinators" % "1.0.4"
1 change: 1 addition & 0 deletions scala/project/build.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
sbt.version = 0.13.15
26 changes: 26 additions & 0 deletions scala/src/main/scala/be/playing/withrojections/Main.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package be.playing.withrojections

import be.playing.withrojections.utils.JsonElement

import scala.io.Source

object Main {
def main(args: Array[String]): Unit = {
if (args.length != 1) throw new Exception("Usage : Main 'path/to/file.json'")

val fileName = args(0)

if (!fileName.endsWith(".json")) throw new Exception("Usage : Main 'path/to/file.json'")

val content = Source.fromFile(fileName).mkString

// Lightweight library : https://gist.github.com/piotrga/5233317
val events = JsonElement.parse(content).get.asArray

println("Number of events " + CountEventProjection(events))
}
}

object CountEventProjection {
def apply(events: List[JsonElement]) = events.map(x => 1).sum
}
68 changes: 68 additions & 0 deletions scala/src/main/scala/be/playing/withrojections/utils/Json.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package be.playing.withrojections.utils

import scala.language.dynamics
import scala.util.parsing.json.JSON

trait JsonElement extends Dynamic{ self =>
def selectDynamic(field: String) : JsonElement = EmptyElement
def applyDynamic(field: String)(i: Int) : JsonElement = EmptyElement
def toList : List[String] = sys.error(s"$this is not a list.")
def asArray : List[JsonElement] = sys.error(s"$this is not a list.")
def asString: String = sys.error(s"$this has no string representation.")
def length$ : Int = sys.error(s"$this has no length")
}


object JsonElement{

def ^(s: String) = {
require(!s.isEmpty, "Element is empty")
s
}

implicit def toString(e: JsonElement) : String = e.asString
implicit def toBoolean(e: JsonElement) : Boolean = (^(e.asString)).toBoolean
implicit def toBigDecimal(e: JsonElement) : BigDecimal = BigDecimal(^(e.asString))
implicit def toDouble(e: JsonElement) : Double = ^(e.asString).toDouble
implicit def toFloat(e: JsonElement) : Float = ^(e.asString).toFloat
implicit def toByte(e: JsonElement) : Byte = ^(e.asString).stripSuffix(".0").toByte
implicit def toShort(e: JsonElement) : Short = ^(e.asString).stripSuffix(".0").toShort
implicit def toInt(e: JsonElement) : Int = ^(e.asString).stripSuffix(".0").toInt
implicit def toLong(e: JsonElement) : Long = ^(e.asString).stripSuffix(".0").toLong
implicit def toList(e: JsonElement) : List[String] = e.toList
implicit def asArray(e: JsonElement) : List[JsonElement] = e.asArray



def parse(json: String) = JSON.parseFull(json) map (JsonElement(_))

def apply(any : Any) : JsonElement = any match {
case x : Seq[Any] => new ArrayElement(x)
case x : Map[String, Any] => new ComplexElement(x)
case x => new PrimitiveElement(x)
}
}

case class PrimitiveElement(x: Any) extends JsonElement{
override def asString = x.toString
}

case object EmptyElement extends JsonElement{
override def asString = ""
override def toList = Nil
override def asArray = Nil
}

case class ArrayElement(private val x: Seq[Any]) extends JsonElement{
private lazy val elements = x.map((JsonElement(_))).toArray

override def applyDynamic(field: String)(i: Int) : JsonElement = elements.lift(i).getOrElse(EmptyElement)
override def toList : List[String] = elements map (_.asString) toList
override def asArray: List[JsonElement] = elements toList
override def length$ : Int = elements.length
}

case class ComplexElement(private val fields : Map[String, Any]) extends JsonElement{
override def selectDynamic(field: String) : JsonElement = fields.get(field) map(JsonElement(_)) getOrElse(EmptyElement)
}