Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
tuhlmann committed Oct 4, 2011
2 parents c6ec24f + 7805a44 commit 05d43e4
Show file tree
Hide file tree
Showing 9 changed files with 198 additions and 84 deletions.
70 changes: 39 additions & 31 deletions core/util/src/main/scala/net/liftweb/util/Props.scala
Expand Up @@ -209,49 +209,57 @@ object Props extends Logger {
* The map of key/value pairs retrieved from the property file.
*/
lazy val props: Map[String, String] = {
import java.io.{ByteArrayInputStream}
import java.util.InvalidPropertiesFormatException
import java.util.{Map => JMap}
import java.io.{ByteArrayInputStream}
import java.util.InvalidPropertiesFormatException
import java.util.{Map => JMap}

var tried: List[String] = Nil
var tried: List[String] = Nil

def vendStreams: List[(String, () => Box[InputStream])] = whereToLook() :::
trace("Loading properties. Active run.mode is %s".format(if (modeName=="") "(Development)" else modeName))

def vendStreams: List[(String, () => Box[InputStream])] = whereToLook() :::
toTry.map{
f => {
val name = f() + "props"
name -> (() => tryo{getClass.getResourceAsStream(name)}.filter(_ ne null))
name -> {() =>
val res = tryo{getClass.getResourceAsStream(name)}.filter(_ ne null)
trace("Trying to open resource %s. Result=%s".format(name, res))
res
}
}
}

// find the first property file that is available
first(vendStreams){
case (str, streamBox) =>
tried ::= str
for {
stream <- streamBox()
} yield {
val ret = new Properties
val ba = Helpers.readWholeStream(stream)
try {
ret.loadFromXML(new ByteArrayInputStream(ba))
} catch {
case _: InvalidPropertiesFormatException =>
ret.load(new ByteArrayInputStream(ba))
}
ret
}
} match {
// if we've got a propety file, create name/value pairs and turn them into a Map
case Full(prop) =>
Map(prop.entrySet.toArray.flatMap{
// find the first property file that is available
first(vendStreams){
case (str, streamBox) =>
tried ::= str
for {
stream <- streamBox()
} yield {
val ret = new Properties
val ba = Helpers.readWholeStream(stream)
try {
ret.loadFromXML(new ByteArrayInputStream(ba))
debug("Loaded XML properties from resource %s".format(str))
} catch {
case _: InvalidPropertiesFormatException =>
ret.load(new ByteArrayInputStream(ba))
debug("Loaded key/value properties from resource %s".format(str))
}
ret
}
} match {
// if we've got a propety file, create name/value pairs and turn them into a Map
case Full(prop) =>
Map(prop.entrySet.toArray.flatMap{
case s: JMap.Entry[_, _] => List((s.getKey.toString, s.getValue.toString))
case _ => Nil
} :_*)

case _ =>
error("Failed to find a properties file (but properties were accessed). Searched: "+tried.reverse.mkString(", "))
Map()
case _ =>
error("Failed to find a properties file (but properties were accessed). Searched: "+tried.reverse.mkString(", "))
Map()
}
}
}
}

Expand Up @@ -222,13 +222,15 @@ trait MongoMetaRecord[BaseRecord <: MongoRecord[BaseRecord]]
/**
* Find all documents with the given ids
*/
def findAll(ids: List[ObjectId]): List[BaseRecord] = if (ids.isEmpty) Nil else {
val list = new java.util.ArrayList[ObjectId]()
def findAllByList[T](ids: List[T]): List[BaseRecord] = if (ids.isEmpty) Nil else {
val list = new java.util.ArrayList[T]()
for (id <- ids.distinct) list.add(id)
val query = QueryBuilder.start("_id").in(list).get()
findAll(query)
}

def findAll(ids: List[ObjectId]): List[BaseRecord] = findAllByList[ObjectId](ids)

protected def saveOp(inst: BaseRecord)(f: => Unit): Boolean = {
foreachCallback(inst, _.beforeSave)
f
Expand Down
Expand Up @@ -76,7 +76,7 @@ class BsonRecordField[OwnerType <: BsonRecord[OwnerType], SubRecordType <: BsonR
* List of BsonRecords
*/
class BsonRecordListField[OwnerType <: BsonRecord[OwnerType], SubRecordType <: BsonRecord[SubRecordType]]
(rec: OwnerType, valueMeta: BsonMetaRecord[SubRecordType])
(rec: OwnerType, valueMeta: BsonMetaRecord[SubRecordType])(implicit mf: Manifest[SubRecordType])
extends MongoListField[OwnerType, SubRecordType](rec: OwnerType) {

import scala.collection.JavaConversions._
Expand Down
Expand Up @@ -27,9 +27,10 @@ import scala.xml.NodeSeq
import common.{Box, Empty, Failure, Full}
import json.JsonAST._
import json.JsonParser
import http.SHtml
import http.js.JE.{JsNull, JsRaw}
import net.liftweb.record.{Field, FieldHelpers, MandatoryTypedField, Record}
import util.Helpers.tryo
import util.Helpers._

import com.mongodb._
import org.bson.types.ObjectId
Expand All @@ -38,24 +39,27 @@ import org.bson.types.ObjectId
* List field. Compatible with most object types,
* including Pattern, ObjectId, Date, and UUID.
*/
class MongoListField[OwnerType <: BsonRecord[OwnerType], ListType](rec: OwnerType)
class MongoListField[OwnerType <: BsonRecord[OwnerType], ListType: Manifest](rec: OwnerType)
extends Field[List[ListType], OwnerType]
with MandatoryTypedField[List[ListType]]
with MongoFieldFlavor[List[ListType]]
{

import Meta.Reflection._

lazy val mf = manifest[ListType]

override type MyType = List[ListType]

def owner = rec

def defaultValue = List[ListType]()

def setFromAny(in: Any): Box[List[ListType]] = {
def setFromAny(in: Any): Box[MyType] = {
in match {
case dbo: DBObject => setFromDBObject(dbo)
case list: List[ListType] => setBox(Full(list))
case Some(list: List[ListType]) => setBox(Full(list))
case Full(list: List[ListType]) => setBox(Full(list))
case list@c::xs if mf.erasure.isInstance(c) => setBox(Full(list.asInstanceOf[MyType]))
case Some(list@c::xs) if mf.erasure.isInstance(c) => setBox(Full(list.asInstanceOf[MyType]))
case Full(list@c::xs) if mf.erasure.isInstance(c) => setBox(Full(list.asInstanceOf[MyType]))
case s: String => setFromString(s)
case Some(s: String) => setFromString(s)
case Full(s: String) => setFromString(s)
Expand All @@ -78,7 +82,28 @@ class MongoListField[OwnerType <: BsonRecord[OwnerType], ListType](rec: OwnerTyp
case other => setBox(Failure("Error parsing String into a JValue: "+in))
}

def toForm: Box[NodeSeq] = Empty
/*
* MongoListField is built on MandatoryField, so optional_? is always false. It would be nice to use optional to differentiate
* between a list that requires at least one item and a list that can be empty.
*/

/** Options for select list **/
def options: List[(ListType, String)] = Nil

private def elem = SHtml.multiSelectObj[ListType](
options,
value,
set(_)
) % ("tabindex" -> tabIndex.toString)

def toForm: Box[NodeSeq] =
if (options.length > 0)
uniqueFieldId match {
case Full(id) => Full(elem % ("id" -> id))
case _ => Full(elem)
}
else
Empty

def asJValue = JArray(value.map(li => li.asInstanceOf[AnyRef] match {
case x if primitive_?(x.getClass) => primitive2jvalue(x)
Expand All @@ -105,8 +130,8 @@ class MongoListField[OwnerType <: BsonRecord[OwnerType], ListType](rec: OwnerTyp
}

// set this field's value using a DBObject returned from Mongo.
def setFromDBObject(dbo: DBObject): Box[List[ListType]] =
setBox(Full(dbo.asInstanceOf[BasicDBList].toList.asInstanceOf[List[ListType]]))
def setFromDBObject(dbo: DBObject): Box[MyType] =
setBox(Full(dbo.asInstanceOf[BasicDBList].toList.asInstanceOf[MyType]))
}

/*
Expand All @@ -121,7 +146,7 @@ class MongoDateListField[OwnerType <: BsonRecord[OwnerType]](rec: OwnerType)
* List of JsonObject case classes
*/
class MongoJsonObjectListField[OwnerType <: BsonRecord[OwnerType], JObjectType <: JsonObject[JObjectType]]
(rec: OwnerType, valueMeta: JsonObjectMeta[JObjectType])
(rec: OwnerType, valueMeta: JsonObjectMeta[JObjectType])(implicit mf: Manifest[JObjectType])
extends MongoListField[OwnerType, JObjectType](rec: OwnerType) {

override def asDBObject: DBObject = {
Expand Down
Expand Up @@ -90,46 +90,21 @@ trait MongoRefField[RefType <: MongoRecord[RefType], MyType] extends TypedField[
}

class ObjectIdRefField[OwnerType <: BsonRecord[OwnerType], RefType <: MongoRecord[RefType]](
rec: OwnerType, rm: MongoMetaRecord[RefType]
)
extends ObjectIdField[OwnerType](rec)
with MongoRefField[RefType, ObjectId]
{
def refMeta = rm
}
rec: OwnerType, val refMeta: MongoMetaRecord[RefType]
) extends ObjectIdField[OwnerType](rec) with MongoRefField[RefType, ObjectId] {}

class UUIDRefField[OwnerType <: BsonRecord[OwnerType], RefType <: MongoRecord[RefType]](
rec: OwnerType, rm: MongoMetaRecord[RefType]
)
extends UUIDField[OwnerType](rec)
with MongoRefField[RefType, UUID]
{
def refMeta = rm
}
rec: OwnerType, val refMeta: MongoMetaRecord[RefType]
) extends UUIDField[OwnerType](rec) with MongoRefField[RefType, UUID] {}

class StringRefField[OwnerType <: BsonRecord[OwnerType], RefType <: MongoRecord[RefType]](
rec: OwnerType, rm: MongoMetaRecord[RefType], maxLen: Int
)
extends StringField[OwnerType](rec, maxLen)
with MongoRefField[RefType, String]
{
def refMeta = rm
}
rec: OwnerType, val refMeta: MongoMetaRecord[RefType], maxLen: Int
) extends StringField[OwnerType](rec, maxLen) with MongoRefField[RefType, String] {}

class IntRefField[OwnerType <: BsonRecord[OwnerType], RefType <: MongoRecord[RefType]](
rec: OwnerType, rm: MongoMetaRecord[RefType]
)
extends IntField[OwnerType](rec)
with MongoRefField[RefType, Int]
{
def refMeta = rm
}
rec: OwnerType, val refMeta: MongoMetaRecord[RefType]
) extends IntField[OwnerType](rec) with MongoRefField[RefType, Int] {}

class LongRefField[OwnerType <: BsonRecord[OwnerType], RefType <: MongoRecord[RefType]](
rec: OwnerType, rm: MongoMetaRecord[RefType]
)
extends LongField[OwnerType](rec)
with MongoRefField[RefType, Long]
{
def refMeta = rm
}
rec: OwnerType, val refMeta: MongoMetaRecord[RefType]
) extends LongField[OwnerType](rec) with MongoRefField[RefType, Long] {}
@@ -0,0 +1,84 @@
/*
* Copyright 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 mongodb
package record
package field

import common._
import http.{S, SHtml}
import net.liftweb.record.{Field, MandatoryTypedField, TypedField}

import java.util.UUID

import org.bson.types.ObjectId

/*
* Trait for creating a Field for storing a list of "foreign keys". Caches the
* items after fetching. Implementations are available for ObjectId, UUID, String,
* Int, and Long, but you can extend this.
*
* toForm produces a multi-select form element. You just need to supply the
* options by overriding the options method.
*/
abstract class MongoRefListField[OwnerType <: BsonRecord[OwnerType], RefType <: MongoRecord[RefType], MyType]
(rec: OwnerType)(implicit mf: Manifest[MyType]) extends MongoListField[OwnerType, MyType](rec) {

/** The MongoMetaRecord of the referenced object **/
def refMeta: MongoMetaRecord[RefType]

/*
* get the referenced objects
*/
def objs = synchronized {
if (!_calcedObjs) {
_calcedObjs = true
this._objs = refMeta.findAllByList(this.value)
}
_objs
}

def cached_? : Boolean = synchronized { _calcedObjs }

def primeObjs(objs: List[RefType]) = synchronized {
_objs = objs
_calcedObjs = true
}

private var _objs: List[RefType] = Nil
private var _calcedObjs = false
}

class ObjectIdRefListField[OwnerType <: BsonRecord[OwnerType], RefType <: MongoRecord[RefType]](
rec: OwnerType, val refMeta: MongoMetaRecord[RefType]
) extends MongoRefListField[OwnerType, RefType, ObjectId](rec) {}

class UUIDRefListField[OwnerType <: BsonRecord[OwnerType], RefType <: MongoRecord[RefType]](
rec: OwnerType, val refMeta: MongoMetaRecord[RefType]
) extends MongoRefListField[OwnerType, RefType, UUID](rec) {}

class StringRefListField[OwnerType <: BsonRecord[OwnerType], RefType <: MongoRecord[RefType]](
rec: OwnerType, val refMeta: MongoMetaRecord[RefType]
) extends MongoRefListField[OwnerType, RefType, String](rec) {}

class IntRefListField[OwnerType <: BsonRecord[OwnerType], RefType <: MongoRecord[RefType]](
rec: OwnerType, val refMeta: MongoMetaRecord[RefType]
) extends MongoRefListField[OwnerType, RefType, Int](rec) {}

class LongRefListField[OwnerType <: BsonRecord[OwnerType], RefType <: MongoRecord[RefType]](
rec: OwnerType, val refMeta: MongoMetaRecord[RefType]
) extends MongoRefListField[OwnerType, RefType, Long](rec) {}

0 comments on commit 05d43e4

Please sign in to comment.