Permalink
Browse files

Initial commit

  • Loading branch information...
0 parents commit 276d06a94043c9c4de8b3adf765425083b152500 @aloiscochard committed Apr 14, 2012
@@ -0,0 +1,4 @@
+target
+boot
+lib_managed
+_build
@@ -0,0 +1,28 @@
+# Siona
+Siona is a layered application framework for the [Scala](http://www.scala-lang.org) programming language.
+
+## Contribution Policy
+
+Contributions via GitHub pull requests are gladly accepted from their original author.
+Along with any pull requests, please state that the contribution is your original work and
+that you license the work to the project under the project's open source license.
+Whether or not you state this explicitly, by submitting any copyrighted material via pull request,
+email, or other means you agree to license the material under the project's open source license and
+warrant that you have the legal authority to do so.
+
+## License
+
+ This software is licensed under the Apache 2 license, quoted below.
+
+ Copyright 2009-2012 Alois Cochard
+
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ use this file except in compliance with the License. You may obtain a copy of
+ the License at http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ License for the specific language governing permissions and limitations under
+ the License.
+
@@ -0,0 +1,49 @@
+import sbt._
+import Keys._
+
+abstract class PublishToSonatype(build: Build) {
+ import build._
+
+ val ossSnapshots = "Sonatype OSS Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots/"
+ val ossStaging = "Sonatype OSS Staging" at "https://oss.sonatype.org/service/local/staging/deploy/maven2/"
+
+ def projectUrl: String
+ def developerId: String
+ def developerName: String
+
+ def licenseName: String
+ def licenseUrl: String
+ def licenseDistribution = "repo"
+ def scmUrl = projectUrl
+ def scmConnection = "scm:git:" + scmUrl
+
+ def generatePomExtra(scalaVersion: String): xml.NodeSeq = {
+ <url>{ projectUrl }</url>
+ <licenses>
+ <license>
+ <name>{ licenseName }</name>
+ <url>{ licenseUrl }</url>
+ <distribution>{ licenseDistribution }</distribution>
+ </license>
+ </licenses>
+ <scm>
+ <url>{ scmUrl }</url>
+ <connection>{ scmConnection }</connection>
+ </scm>
+ <developers>
+ <developer>
+ <id>{ developerId }</id>
+ <name>{ developerName }</name>
+ </developer>
+ </developers>
+ }
+
+ def settings: Seq[Setting[_]] = Seq(
+ credentials += Credentials(Path.userHome / ".ivy2" / ".credentials"),
+ publishMavenStyle := true,
+ publishTo <<= version((v: String) => Some( if (v.trim endsWith "SNAPSHOT") ossSnapshots else ossStaging)),
+ publishArtifact in Test := false,
+ pomIncludeRepository := (_ => false),
+ pomExtra <<= (scalaVersion)(generatePomExtra)
+ )
+}
@@ -0,0 +1,67 @@
+// ____,__, ____, _, _, ____,
+// (-(__(-| (-/ \(-|\ | (-/_|
+// ____)_|_,_\__/,_| \|,_/ |,
+//
+
+import sbt._
+import Keys._
+
+object BuildSettings {
+ val buildSettings = Defaults.defaultSettings ++ Sonatype.settings ++ Seq(
+ organization := "com.github.aloiscochard.siona",
+ version := "0.1-SNAPSHOT",
+ scalaVersion := "2.9.1",
+ scalacOptions := Seq("-unchecked", "-deprecation", "-Ydependent-method-types"),
+ crossScalaVersions := Seq("2.9.1", "2.9.1-1", "2.9.2"),
+ resolvers ++= Seq(
+ "Sonatype OSS Releases" at "http://oss.sonatype.org/content/repositories/releases/",
+ "Sonatype OSS Snapshots" at "http://oss.sonatype.org/content/repositories/snapshots/"
+ )
+ )
+}
+
+object Dependencies {
+ val testDependencies = Seq(libraryDependencies += "org.specs2" %% "specs2" % "1.8.2" % "test")
+}
+
+object SionaBuild extends Build {
+ import Dependencies._
+ import BuildSettings._
+
+ lazy val sindi = Project (
+ "siona",
+ file ("."),
+ settings = buildSettings
+ ) aggregate (core, logging)
+
+ lazy val core = Project(
+ "siona-core",
+ file("siona-core"),
+ settings = buildSettings ++ testDependencies ++ Seq(
+ libraryDependencies ++= Seq(
+ "org.scalaz" %% "scalaz-core" % "7.0-SNAPSHOT",
+ "com.chuusai" %% "shapeless" % "1.2.0-SNAPSHOT"
+ )
+ )
+ )
+
+ lazy val logging = Project(
+ "siona-logging",
+ file("siona-logging"),
+ settings = buildSettings ++ testDependencies
+ ) dependsOn(core)
+
+ lazy val demo_petstore = Project(
+ "siona-demo-petstore",
+ file("siona-demo/petstore"),
+ settings = buildSettings ++ testDependencies
+ ) dependsOn(core, logging)
+}
+
+object Sonatype extends PublishToSonatype(SionaBuild) {
+ def projectUrl = "https://github.com/aloiscochard/siona"
+ def developerId = "alois.cochard"
+ def developerName = "Alois Cochard"
+ def licenseName = "Apache 2 License"
+ def licenseUrl = "http://www.apache.org/licenses/LICENSE-2.0.html"
+}
@@ -0,0 +1,15 @@
+// ____,__, ____, _, _, ____,
+// (-(__(-| (-/ \(-|\ | (-/_|
+// ____)_|_,_\__/,_| \|,_/ |,
+//
+package object siona {
+ import siona.core._
+ // core.uuid
+ type UUID = uuid.UUID
+ val UUID = uuid.UUID
+ implicit val uuidEqual = uuid.uuidEqual
+ // core.entity
+ val Key = entity.Key
+ type Entity[K, T] = entity.Entity[K, T]
+ implicit def entityOps[K, T](e: entity.Entity[K, T]) = entity.entityOps(e)
+}
@@ -0,0 +1,46 @@
+// ____,__, ____, _, _, ____,
+// (-(__(-| (-/ \(-|\ | (-/_|
+// ____)_|_,_\__/,_| \|,_/ |,
+//
+package siona.core
+
+import scalaz._
+import Scalaz._
+
+package object uuid {
+ type UUID = java.util.UUID
+
+ object UUID {
+ def random = java.util.UUID.randomUUID
+ }
+
+ implicit val uuidEqual = new Equal[UUID] {
+ def equal(id1: UUID, id2: UUID): Boolean = id1 == id2
+ }
+}
+
+package object entity {
+ object Key {
+ def apply[K, T](k: K): Entity[K, T]#Key = k.asInstanceOf[Entity[K, T]#Key]
+ }
+
+ object Entity {
+ implicit def equal[K, T](implicit eqK: Equal[K]): Equal[Entity[K, T]] = new Equal[Entity[K, T]] {
+ def equal(e1: Entity[K, T], e2: Entity[K, T]): Boolean = e1.id === e2.id
+ }
+ }
+
+ trait Entity[K, T] {
+ type Key = K @@ T
+ val key: Key
+ def id: K = key.asInstanceOf[K]
+ }
+
+ implicit def entityOps[K, T](e: Entity[K, T]) = EntityOps(e)
+
+ case class EntityOps[K, T](val entity: Entity[K,T]) {
+ def ===(other: Entity[K, T])(implicit e: Equal[Entity[K, T]]) = e.equal(entity, other)
+ }
+
+}
+
@@ -0,0 +1,76 @@
+// ____,__, ____, _, _, ____,
+// (-(__(-| (-/ \(-|\ | (-/_|
+// ____)_|_,_\__/,_| \|,_/ |,
+//
+package siona.data
+package mapping
+
+import siona.core.entity._
+
+import repository._
+import query._
+import model._
+
+trait Input[E <: Entity[_, _]] extends model.Input {
+ def key: E#Key
+}
+trait Output[E <: Entity[_, _]] extends model.Output
+
+trait Mapped[E <: Entity[_,_], T] extends model.Field[T] {
+ val lens: scalaz.Lens[E, T]
+ object Lens {
+ def apply(a: E => T, b: E => T => E) = scalaz.Lens.lensG[E, T](a, b)
+ }
+}
+
+trait Mapper[E <: Entity[_, _]] extends model.Model {
+ override type In = Input[E]
+ override type Out = Output[E]
+
+ type Mapped[T] = mapping.Mapped[E, T]
+
+ protected[this] def key[K, T](implicit in: In): Entity[K, T]#Key = in.key.asInstanceOf[Entity[K, T]#Key]
+
+ protected def in(implicit in: In): E
+ protected def out: List[Mapped[_]] // FIXME ... with HList? + Add key automatically
+
+ def read(i: In) = in(i)
+ def write(o: Out, e: E) = { // FIXME RETURN IO
+ //out.foreach(f => f.apply(f.lens.get(e), o)) // FIX WITH HLIST
+ e
+ }
+
+ implicit def fieldDefault2apply[T](f: model.Default[T])(implicit in: In) = f(in)
+ implicit def fieldOptional2apply[T](f: model.Optional[T])(implicit in: In) = f(in)
+}
+
+trait Mapping[M <: Mapper[E], E <: Entity[K, T], K, T] extends Repository[M] {
+ override type Key = E#Key
+
+ implicit def e2key(e: E): Key = e.key
+
+ implicit def e2ops(e: E) = EntityOps(e)
+
+ case class EntityOps(e: E) {
+ def save() = entity.set(e, e)
+ def update[T](m: Mapper[E]#Mapped[T])(f: T => T) = entity.update(e, m)(f)
+ }
+
+ object entity {
+ def get(k: Key) = Mapping.this.get(k, i => model.read(i))
+ def set(k: Key, e: E) = Mapping.this.set(k, o => model.write(o, e))
+ def update(k: Key, f: E => E) = Mapping.this.get(k, i => model.read(i)).flatMap(e => Mapping.this.set(k, o => model.write(o, e)))
+ def update[T](e: E, m: Mapper[E]#Mapped[T])(f: T => T) = None
+ def update[T0, T1](e: E)(ms: (Mapper[E]#Mapped[T0], Mapper[E]#Mapped[T1]))(ts: (T0, T1) => (T0, T1)) = None
+ def query[List[E]](xs: Predicate[_, Indexed]) = None
+ }
+}
+
+case class Entities[M <: Mapper[E], E <: Entity[K, T], K, T](override val model: M)
+ extends Repository[M] with Mapping[M, E, K, T] {
+ val key = new Field[K] {
+ val name = "key"
+ override type V = T
+ def apply(implicit in: siona.data.model.Input): V = throw new Error("Key field cannot be read.")
+ }
+}
@@ -0,0 +1,66 @@
+// ____,__, ____, _, _, ____,
+// (-(__(-| (-/ \(-|\ | (-/_|
+// ____)_|_,_\__/,_| \|,_/ |,
+//
+package siona.data
+
+import scalaz._
+
+import mapping._
+
+package object model {
+ type Validation[T] = T => ValidationNEL[String, T]
+}
+
+package model {
+ trait Input {
+ def apply[T](f: Field[T]) = f.apply(this)
+ def read[T](n: String): Option[T]
+ }
+ trait Output {
+ def write[T](n: String, x: T): T
+ }
+
+ trait Model {
+ type F[T] <: model.Field[T]
+ type In <: Input
+ type Out <: Output
+ }
+
+ trait Document extends Model {
+ override type F[T] = Indexed[T] with Validated[T]
+
+ abstract class Field[T](override val name: String)(implicit m: Monoid[T])
+ extends Default[T] with Indexed[T] with Validated[T] {
+ val default = m.zero
+ }
+ }
+
+ trait Field[T] {
+ type V
+ type Z[T] = Field[T]
+ val name: String
+ def apply(implicit in: Input): V
+ def apply(x: T)(out: Output) = out.write(name, x)
+ }
+
+ trait Optional[T] extends Field[T] {
+ override type V = Option[T]
+ def apply(implicit in: Input): V = in.read[T](name)
+ }
+
+ trait Default[T] extends Field[T] {
+ override type V = T
+ val default: T
+ def apply(implicit in: Input): V = in.read[T](name).getOrElse(default)
+ }
+
+ trait Indexed[T] extends Field[T]
+
+ trait Validated[T] extends Field[T] {
+ val validation: model.Validation[T]
+ object Validation {
+ def apply(v: model.Validation[T]) = v
+ }
+ }
+}
@@ -0,0 +1,27 @@
+// ____,__, ____, _, _, ____,
+// (-(__(-| (-/ \(-|\ | (-/_|
+// ____)_|_,_\__/,_| \|,_/ |,
+//
+package siona.data
+package query
+
+sealed trait Predicate[T, A[T]] {
+ val source: A[T]
+}
+case class Equal[T, A[T]](override val source: A[T], value: T) extends Predicate[T, A]
+case class Greater[T, A[T]](override val source: A[T], value: T) extends Predicate[T, A]
+
+case class Predictable[T, A[T]](source: A[T]) {
+ // > greaterThan
+ // < lessThan
+ //
+ // %== startsWith
+ // ==% endsWith
+ // =%= contains
+ //
+ // === equalTo
+ // =!= notEqualTo
+ def >(x: T) = Greater(source, x)
+
+ def ===(x: T) = Equal(source, x)
+}
Oops, something went wrong.

0 comments on commit 276d06a

Please sign in to comment.