|
Lift Framework example source code file (Maker.scala)
The Lift Framework Maker.scala source code/* * Copyright 2009-2011 WorldWide Conferencing, LLC * * 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. */ package net.liftweb package util import java.util.concurrent.{ConcurrentHashMap => CHash, Callable} import java.lang.ThreadLocal import scala.reflect.Manifest import common._ import xml.NodeSeq /** * A trait that does basic dependency injection. */ trait Injector { implicit def inject[T](implicit man: Manifest[T]): Box[T] } /** * An implementation of Injector that has an implementation */ trait SimpleInjector extends Injector { private val diHash: CHash[String, Function0[_]] = new CHash /** * Perform the injection for the given type. You can call: * inject[Date] or inject[List[Map[String, PaymentThing]]]. The * appropriate Manifest will be */ implicit def inject[T](implicit man: Manifest[T]): Box[T] = (Box !! diHash.get(man.toString)).flatMap(f => Helpers.tryo(f.apply())).asInstanceOf[Box[T]] /** * Register a function that will inject for the given Manifest */ def registerInjection[T](f: () => T)(implicit man: Manifest[T]) { diHash.put(man.toString, f) } /** * Create an object or val that is a subclass of the FactoryMaker to * generate factory for a particular class as well as define session and * request specific vendors and use doWith to define the vendor just for * the scope of the call. */ abstract class Inject[T](_default: Vendor[T]) (implicit man: Manifest[T]) extends StackableMaker[T] with Vendor[T] { registerInjection(this)(man) /** * The default function for vending an instance */ object default extends PSettableValueHolder[Vendor[T]] { private var value = _default def get = value def is = get def set(v: Vendor[T]): Vendor[T] = { value = v v } } /** * Vend an instance */ implicit def vend: T = make openOr default.is.apply() /** * Make a Box of the instance. */ override implicit def make: Box[T] = super.make or Full(default.is.apply()) } } /** * In addition to an Injector, you can have a Maker which will make a given * type. The important thing about a Maker is that it's intended to be used * as part of a factory that can vend an instance without the vaguaries of * whether the given class has registered a with the injector. */ trait Maker[T] { implicit def make: Box[T] } object Maker { def apply[T](value: T): Maker[T] = new Maker[T]{implicit def make: Box[T] = Full(value)} def apply[T](func:() => T): Maker[T] = new Maker[T]{implicit def make: Box[T] = Full(func())} def apply[T](func: Box[() => T]): Maker[T] = new Maker[T]{implicit def make: Box[T] = func.map(_.apply())} def apply1[T](box: Box[T]): Maker[T] = new Maker[T]{implicit def make: Box[T] = box} def apply2[T](func: Box[() => Box[T]]): Maker[T] = new Maker[T]{implicit def make: Box[T] = func.flatMap(_.apply())} def apply3[T](func: () => Box[T]): Maker[T] = new Maker[T]{implicit def make: Box[T] = func.apply()} implicit def vToMake[T](v: T): Maker[T] = this.apply(v) implicit def vToMake[T](v: () => T): Maker[T] = this.apply(v) implicit def vToMakeB1[T](v: Box[T]): Maker[T] = this.apply1(v) implicit def vToMakeB2[T](v: Box[() => T]): Maker[T] = this.apply(v) implicit def vToMakeB3[T](v: Box[() => Box[T]]): Maker[T] = this.apply2(v) implicit def vToMakeB4[T](v: () => Box[T]): Maker[T] = this.apply3(v) } /** * A StackableMaker allows DynamicVar functionality by supply a Maker or function * that will vend an instance during any sub-call on the stack and then * restore the implementation. This is value for testing. */ trait StackableMaker[T] extends Maker[T] { private val _stack: ThreadLocal[List[PValueHolder[Maker[T]]]] = new ThreadLocal private def stack: List[PValueHolder[Maker[T]]] = _stack.get() match { case null => Nil case x => x } def doWith[F](value: T)(f: => F): F = doWith(PValueHolder(Maker(value)))(f) def doWith[F](vFunc: () => T)(f: => F): F = doWith(PValueHolder(Maker(vFunc)))(f) def doWith[F](addl: PValueHolder[Maker[T]])(f: => F): F = { val old = _stack.get() _stack.set(addl :: stack) try { f } finally { _stack.set(old) } } protected final def find(in: List[PValueHolder[Maker[T]]]): Box[T] = in match { case Nil => Empty case x :: rest => x.get.make match { case Full(v) => Full(v) case _ => find(rest) } } implicit def make: Box[T] = find(stack) } /** * An implementation where you can define the stack of makers. */ class MakerStack[T](subMakers: PValueHolder[Maker[T]]*) extends StackableMaker[T] { private val _sub: List[PValueHolder[Maker[T]]] = subMakers.toList override implicit def make: Box[T] = super.make or find(_sub) } /** * A Vendor is a Maker that also guarantees that it will return a value */ trait Vendor[T] extends Maker[T] with Function0[T] { implicit def vend: T def apply() = vend } /** * A bridge from Java to Scala */ class VendorJBridge { /** * Create a Vendor from a Func0 */ def vendor[T](f: Func0[T]): Vendor[T] = Vendor(Func.lift(f)) /** * Create a Vendor from a Callable */ def vendor[T](f: Callable[T]): Vendor[T] = Vendor(Func.lift(f)) /** * Create a Vendor from a value */ def vendor[T](v: T): Vendor[T] = Vendor(v) } /** * A companion to the Vendor trait */ object Vendor { def apply[T](f: () => T): Vendor[T] = new Vendor[T] { implicit def vend: T = f() implicit def make: Box[T] = Full(f()) } def apply[T](f: T): Vendor[T] = new Vendor[T] { implicit def vend: T = f implicit def make: Box[T] = Full(f) } implicit def valToVender[T](value: T): Vendor[T] = apply(value) implicit def funcToVender[T](f: () => T): Vendor[T] = apply(f) } case class FormBuilderLocator[T](func: (T, T => Unit) => NodeSeq)(implicit val manifest: Manifest[T]) Other Lift Framework examples (source code examples)Here is a short list of links related to this Lift Framework Maker.scala source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.