Skip to content

Commit

Permalink
First commit.
Browse files Browse the repository at this point in the history
  • Loading branch information
beniaminp committed Nov 16, 2016
0 parents commit f538b5c
Show file tree
Hide file tree
Showing 36 changed files with 8,144 additions and 0 deletions.
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
logs
target
/.idea
/.idea_modules
/.classpath
/.project
/.settings
/RUNNING_PID
8 changes: 8 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
This software is licensed under the Apache 2 license, quoted below.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this project 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.
49 changes: 49 additions & 0 deletions README
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
This is your new Play application
=================================

This file will be packaged with your application when using `activator dist`.

There are several demonstration files available in this template.

Controllers
===========

- HomeController.scala:

Shows how to handle simple HTTP requests.

- AsyncController.scala:

Shows how to do asynchronous programming when handling a request.

- CountController.scala:

Shows how to inject a component into a controller and use the component when
handling requests.

Components
==========

- Module.scala:

Shows how to use Guice to bind all the components needed by your application.

- Counter.scala:

An example of a component that contains state, in this case a simple counter.

- ApplicationTimer.scala:

An example of a component that starts when the application starts and stops
when the application stops.

Filters
=======

- Filters.scala:

Creates the list of HTTP filters used by your application.

- ExampleFilter.scala

A simple filter that adds a header to every response.
1 change: 1 addition & 0 deletions activatorStart.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
activator -Dhttp.proxyHost="192.168.16.1" -Dhttp.proxyPort="128" -Dhttps.proxyHost="192.168.16.1" -Dhttps.proxyPort="128" -Dhttp.nonProxyHosts="localhost|127.0.0.1" -Dhttps.nonProxyHosts="localhost|127.0.0.1" ~run
33 changes: 33 additions & 0 deletions app/Filters.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import javax.inject._
import play.api._
import play.api.http.HttpFilters
import play.api.mvc._

import filters.ExampleFilter

/**
* This class configures filters that run on every request. This
* class is queried by Play to get a list of filters.
*
* Play will automatically use filters from any class called
* `Filters` that is placed the root package. You can load filters
* from a different class by adding a `play.http.filters` setting to
* the `application.conf` configuration file.
*
* @param env Basic environment settings for the current application.
* @param exampleFilter A demonstration filter that adds a header to
* each response.
*/
@Singleton
class Filters @Inject() (
env: Environment,
exampleFilter: ExampleFilter) extends HttpFilters {

override val filters = {
// Use the example filter if we're running development mode. If
// we're running in production or test mode then don't use any
// filters at all.
if (env.mode == Mode.Dev) Seq(exampleFilter) else Seq.empty
}

}
28 changes: 28 additions & 0 deletions app/Module.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import com.google.inject.AbstractModule
import java.time.Clock

import services.{ApplicationTimer, AtomicCounter, Counter}

/**
* This class is a Guice module that tells Guice how to bind several
* different types. This Guice module is created when the Play
* application starts.
* Play will automatically use any class called `Module` that is in
* the root package. You can create modules in other locations by
* adding `play.modules.enabled` settings to the `application.conf`
* configuration file.
*/
class Module extends AbstractModule {

override def configure() = {
// Use the system clock as the default implementation of Clock
bind(classOf[Clock]).toInstance(Clock.systemDefaultZone)
// Ask Guice to create an instance of ApplicationTimer when the
// application starts.
bind(classOf[ApplicationTimer]).asEagerSingleton()
// Set AtomicCounter as the implementation for Counter.
bind(classOf[Counter]).to(classOf[AtomicCounter])
}

}
41 changes: 41 additions & 0 deletions app/controllers/AsyncController.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package controllers

import akka.actor.ActorSystem
import javax.inject._
import play.api._
import play.api.mvc._
import scala.concurrent.{ExecutionContext, Future, Promise}
import scala.concurrent.duration._

/**
* This controller creates an `Action` that demonstrates how to write
* simple asynchronous code in a controller. It uses a timer to
* asynchronously delay sending a response for 1 second.
*
* @param actorSystem We need the `ActorSystem`'s `Scheduler` to
* run code after a delay.
* @param exec We need an `ExecutionContext` to execute our
* asynchronous code.
*/
@Singleton
class AsyncController @Inject() (actorSystem: ActorSystem)(implicit exec: ExecutionContext) extends Controller {

/**
* Create an Action that returns a plain text message after a delay
* of 1 second.
*
* The configuration in the `routes` file means that this method
* will be called when the application receives a `GET` request with
* a path of `/message`.
*/
def message = Action.async {
getFutureMessage(1.second).map { msg => Ok(msg) }
}

private def getFutureMessage(delayTime: FiniteDuration): Future[String] = {
val promise: Promise[String] = Promise[String]()
actorSystem.scheduler.scheduleOnce(delayTime) { promise.success("Hi!") }
promise.future
}

}
39 changes: 39 additions & 0 deletions app/controllers/Barcodes.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package controllers

import javax.inject._
import play.api._
import play.api.mvc._
import play.api.i18n.{Messages, I18nSupport, MessagesApi}

class Barcodes @Inject() extends Controller {
val imageResolution = 144

def barcode(ean: Long) = Action{
import java.lang.IllegalArgumentException
val MimeType = "image/png"
try {
val imageData = ean13BarCode(ean, MimeType)
Ok(imageData).as(MimeType)
}
catch {
case e: IllegalArgumentException =>
BadRequest("Couldn’t generate bar code. Error: " + e.getMessage)
}
}
def ean13BarCode(ean: Long, mimeType: String): Array[Byte] = {
import java.io.ByteArrayOutputStream
import java.awt.image.BufferedImage
import org.krysalis.barcode4j.output.bitmap.BitmapCanvasProvider
import org.krysalis.barcode4j.impl.upcean.EAN13Bean

val output: ByteArrayOutputStream = new ByteArrayOutputStream
val canvas: BitmapCanvasProvider =
new BitmapCanvasProvider(output, mimeType, imageResolution,
BufferedImage.TYPE_BYTE_BINARY, false, 0)
val barcode = new EAN13Bean()
barcode.generateBarcode(canvas, String valueOf ean)
canvas.finish
output.toByteArray
}

}
25 changes: 25 additions & 0 deletions app/controllers/CountController.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package controllers

import javax.inject._
import play.api._
import play.api.mvc._

import services.Counter

/**
* This controller demonstrates how to use dependency injection to
* bind a component into a controller class. The class creates an
* `Action` that shows an incrementing count to users. The [[Counter]]
* object is injected by the Guice dependency injection system.
*/
@Singleton
class CountController @Inject() (counter: Counter) extends Controller {

/**
* Create an action that responds with the [[Counter]]'s current
* count. The result is plain text. This `Action` is mapped to
* `GET /count` requests by an entry in the `routes` config file.
*/
def count = Action { Ok(counter.nextCount().toString) }

}
24 changes: 24 additions & 0 deletions app/controllers/HomeController.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package controllers

import javax.inject._
import play.api._
import play.api.mvc._

/**
* This controller creates an `Action` to handle HTTP requests to the
* application's home page.
*/
@Singleton
class HomeController @Inject() extends Controller {

/**
* Create an Action to render an HTML page with a welcome message.
* The configuration in the `routes` file means that this method
* will be called when the application receives a `GET` request with
* a path of `/`.
*/
def index = Action {
Redirect(routes.Products.list)
}

}
57 changes: 57 additions & 0 deletions app/controllers/Products.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package controllers

import javax.inject._
import play.api._
import play.api.mvc._
import play.api.i18n.{Messages, I18nSupport, MessagesApi}
import play.api.data.Form
import play.api.data.Forms.{mapping, longNumber, nonEmptyText}
import models.Product

class Products @Inject()(val messagesApi: MessagesApi) extends Controller with I18nSupport{

def list = Action{ implicit request =>
val products = Product.findAll

Ok(views.html.products.list(products))
}

def show(ean: Long) = Action{ implicit request =>
Product.findByEan(ean).map{ product =>
Ok(views.html.products.details(product))
}.getOrElse(NotFound)
}

def newProduct = Action{ implicit request =>
val form = if(request.flash.get("error").isDefined)
productForm.bind(request.flash.data)
else
productForm
Ok(views.html.products.editProduct(form))
}

private val productForm: Form[Product] = Form(
mapping(
"ean" -> longNumber.verifying(
"validation.ean.duplicate", Product.findByEan(_).isEmpty),
"name" -> nonEmptyText,
"description" -> nonEmptyText
)(Product.apply)(Product.unapply)
)

def save = Action { implicit request =>
val newProductForm = productForm.bindFromRequest()

newProductForm.fold(
hasErrors = {form =>
Redirect(routes.Products.newProduct()).flashing(Flash(form.data) +
("error" -> Messages("validation.errors")))
},
success = {newProduct =>
Product.add(newProduct)
val message = Messages("products.new.success", newProduct.name)
Redirect.routes(routes.Products.show(newProduct.ean)).flashing("success" -> message)
}
)
}
}
33 changes: 33 additions & 0 deletions app/filters/ExampleFilter.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package filters

import akka.stream.Materializer
import javax.inject._
import play.api.mvc._
import scala.concurrent.{ExecutionContext, Future}

/**
* This is a simple filter that adds a header to all requests. It's
* added to the application's list of filters by the
* [[Filters]] class.
*
* @param mat This object is needed to handle streaming of requests
* and responses.
* @param exec This class is needed to execute code asynchronously.
* It is used below by the `map` method.
*/
@Singleton
class ExampleFilter @Inject()(
implicit override val mat: Materializer,
exec: ExecutionContext) extends Filter {

override def apply(nextFilter: RequestHeader => Future[Result])
(requestHeader: RequestHeader): Future[Result] = {
// Run the next filter in the chain. This will call other filters
// and eventually call the action. Take the result and modify it
// by adding a new header.
nextFilter(requestHeader).map { result =>
result.withHeaders("X-ExampleFilter" -> "foo")
}
}

}
31 changes: 31 additions & 0 deletions app/models/Product.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package models

case class Product(
ean: Long, name: String, description: String
)

object Product {
var products = Set(
Product(5010255079763L, "Paperclips Large",
"Large Plain Pack of 1000"),

Product(5018206244666L, "Giant Paperclips",
"Giant Plain 51mm 100 pack"),

Product(5018306332812L, "Paperclip Giant Plain",
"Giant Plain Pack of 10000"),

Product(5018306312913L, "No Tear Paper Clip",
"No Tear Extra Large Pack of 1000"),

Product(5018206244611L, "Zebra Paperclips",
"Zebra Length 28mm Assorted 150 Pack")
)
def findAll = products.toList.sortBy(_.ean)

def findByEan(ean: Long) = products.find(_.ean == ean)

def add(product: Product){
products = products + product
}
}
Loading

0 comments on commit f538b5c

Please sign in to comment.