Skip to content
This repository has been archived by the owner on Apr 12, 2018. It is now read-only.

Commit

Permalink
Initial demo work for discussion
Browse files Browse the repository at this point in the history
  • Loading branch information
dchenbecker committed Nov 17, 2010
1 parent cf92a9c commit fb8f1fa
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 2 deletions.
Expand Up @@ -507,6 +507,21 @@ trait MappedField[FieldType <: Any,OwnerType <: Mapper[OwnerType]] extends Typed
*/
def setFromAny(value: Any): FieldType

/**
* This defines a per-field method that can be used to parse the field
* value from a String. You can set global parsing for a given type
* using the MapperParsers trait and the MapperRules.parsers variable.
*/
val parseValue : Box[String => FieldType] = Empty

/**
* This defines a per-field parse error handler. If you want
* to override a specific field's parse error handling, provide
* a function here. You can set a global parse error handler
* using the MapperParsers trait and the MapperRules.parsers variable.
*/
val parseErrorHandler : Box[String => FieldType] = Empty

def toFormAppendedAttributes: MetaData =
if (Props.mode == Props.RunModes.Test)
new PrefixedAttribute("lift", "field_name", Text(calcFieldName), Null)
Expand Down
Expand Up @@ -248,9 +248,9 @@ abstract class MappedInt[T<:Mapper[T]](val fieldOwner: T) extends MappedField[In
case Some(n: Number) => this.set(n.intValue)
case Full(n: Number) => this.set(n.intValue)
case None | Empty | Failure(_, _, _) => this.set(0)
case (s: String) :: _ => this.set(toInt(s))
case (s: String) :: _ => MapperRules.parsers.parseInt(s, this.set, this)
case null => this.set(0)
case s: String => this.set(toInt(s))
case s: String => MapperRules.parsers.parseInt(s, this.set, this)
case o => this.set(toInt(o))
}
}
Expand Down
@@ -0,0 +1,75 @@
/*
* Copyright 2010 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 mapper {

import common.{Box,Full}
import http.S
import util.BasicTypesHelpers

/**
* This trait provides configuration points for global parse handling. The default
* implementations of all parsers conforms to pre-MapperParsers behavior.
*
* TODO: More docs
*/
trait MapperParsers {
def parseInt(value : String, setter : Int => Int, field: MappedField[Int, _]) : Int = {
setter(BasicTypesHelpers.toInt(value))
}

def parseLong(value : String, setter : Long => Long, field: MappedField[Long, _]) : Long = {
setter(BasicTypesHelpers.toLong(value))
}

/**
* Override this method to set your own global error handling. The default
* is to do nothing on a parse failure.
*/
def parseErrorHandler[T](value : String, field : MappedField[T,_]) : T =
field.is

protected def dispatchErrorHandling[T](value : String, field : MappedField[T,_]) : T =
field.parseErrorHandler match {
case Full(handler) => handler(value)
case _ => parseErrorHandler(value,field)
}
}

object DefaultMapperParsers extends MapperParsers

object NewMapperParsers extends MapperParsers {

This comment has been minimized.

Copy link
@nafg

nafg Nov 18, 2010

Perhaps in two years the "New" in the name won't look like the best choice... ;)

This comment has been minimized.

Copy link
@dchenbecker

dchenbecker Nov 21, 2010

Author Member

How about "Different" ;)

This comment has been minimized.

Copy link
@indrajitr

indrajitr Nov 21, 2010

Member

Or maybe, AltMapperParsers/AlternateMapperParsers :)

This comment has been minimized.

Copy link
@nafg

nafg Nov 22, 2010

Hi, those are exciting names ;) but you have to put yourself in your consumers' shoes. Names are a form of documentation, etc...
How about something like ErrorHandlingParsers? ErrorReportingParsers? NondestructiveParsers (there's got to be a good synonym for non-destructive...)?

This comment has been minimized.

Copy link
@dchenbecker

dchenbecker Nov 24, 2010

Author Member

I like ErrorHandlingParsers :)

def tryParse[T](value : String, field : MappedField[T,_], setter : T => T, default : String => T) : T =
try {
setter((field.parseValue openOr default)(value))
} catch {
case _ => dispatchErrorHandling(value, field)
}

override def parseInt(value : String, setter : Int => Int, field: MappedField[Int, _]) : Int =
tryParse(value, field, setter, java.lang.Integer.parseInt)

override def parseLong(value : String, setter : Long => Long, field: MappedField[Long, _]) : Long =
tryParse(value, field, setter, java.lang.Long.parseLong)

override def parseErrorHandler[T](value : String, field: MappedField[T,_]) : T = {
S.error("Invalid value \"%s\" for %s".format(value, field.displayName))
field.is
}
}

}} // Close nested packages
Expand Up @@ -133,6 +133,12 @@ object MapperRules extends Factory {
* MapperRules.columnName = (_,name) => StringHelpers.snakify(name)
*/
var tableName: (ConnectionIdentifier,String) => String = (_,name) => name.toLowerCase

/**
* Define the set of functions that will be used to parse Strings
* into their proper field types.
*/
var parsers : MapperParsers = DefaultMapperParsers
}

trait MetaMapper[A<:Mapper[A]] extends BaseMetaMapper with Mapper[A] {
Expand Down

0 comments on commit fb8f1fa

Please sign in to comment.