Re: [Lift] Re: fmapFunc and order of operations

2010-02-15 Thread Kris Nuttycombe
On Mon, Feb 15, 2010 at 4:31 PM, David Pollak
feeder.of.the.be...@gmail.com wrote:
 If all the SHtml stuff returned a NodeSeq (or Elem) with AnswerHolder and
 AnswerHolder[T] looked like:

 trait AnswerHolder[T] {
   def hasAnswer: Boolean
   def answer: Box[T]
   def map[S](f: T = S): Box[S]
   ...
 }

 Then we could get what you want (no explicit mutability) and keep APIs
 working the way they work now.  What do you think?

 We could even introduce alternative SHtml stuff like:

 def text(original: String): Elem with AnswerHolder[String]

 What do you think?

That looks good; I think it'd go a long way toward making the order of
operations a little more foolproof. The idea of 'Elem with
AnswerHolder' had never occurred to me; I guess I just always assumed
that Elem or Node was sealed, but it doesn't appear to be from the
scaladocs. That would certainly help on the backwards compatibility
front and would alleviate the need for the implicit conversion I'd
imagined from FormField[T] to NodeSeq.

What do you think about the notion of a ! method that does the
unsafe answer.open_! ? I would think that in the vast majority of
cases, the Box being Empty would represent either a coding error or a
framework error. In the case of a coding error (the answer attempting
to be extracted during the initial rendering of the form elements)
this would fail fast, and in the case where the response is actually
being processed it should probably never be empty anyway.

Kris


 On Mon, Jan 25, 2010 at 11:31 AM, Kris Nuttycombe
 kris.nuttyco...@gmail.com wrote:

 On Mon, Jan 25, 2010 at 12:16 PM, David Pollak
 feeder.of.the.be...@gmail.com wrote:
 
 
  On Mon, Jan 25, 2010 at 11:09 AM, Kris Nuttycombe
  kris.nuttyco...@gmail.com wrote:
 
  On Mon, Jan 25, 2010 at 11:51 AM, Kris Nuttycombe
  kris.nuttyco...@gmail.com wrote:
   On Mon, Jan 25, 2010 at 11:40 AM, David Pollak
   feeder.of.the.be...@gmail.com wrote:
  
  
   On Mon, Jan 25, 2010 at 10:19 AM, Kris Nuttycombe
   kris.nuttyco...@gmail.com wrote:
  
   On Mon, Jan 25, 2010 at 11:07 AM, Marius marius.dan...@gmail.com
   wrote:
S.formFuncName .. should guarantee proper ordering of functions
application respecting the ordering of functions creation (and
this
is
used by fmapFunc).
   
I'm a bit tired to follow code from this page so could you please
put
together a minimalistic application that I could just try?
   
Br's,
Marius
  
   Thanks, Marius, but I'm too time-crunched at the moment to boil
   this
   down. In any case, I found a solution. My frustration is primarily
   that ordering of function creation matters in the first place;
   making
   the ordering of function creation less relevant is the point of my
   proposal in the other thread. If the order that you do things in
   matters, it completely hoses you for the purposes of composition
   (as I
   painfully found out with this example.) Here, the composition is
   just
   two calls deep and explicit, and even with only that small amount
   of
   composition it was a pain to track down.
  
   Does this make my proposal in the other thread make any more sense
   to
   you?
  
   Ordering is well defined:
  
   The order in which the functions are mapped
   Skewed plus or minus based on value of S.formGroup
  
   There's no way to avoid ordering.  The functions have to be executed
   in
   some
   order.  By default, the stuff in SHtml does this in the order the
   elements
   were defined, but sets S.formGroup to 1 for the submit button (so
   it's
   always the last function executed.)
  
   They have to be executed in some order; I just wish that the
   execution
   could actually be performed by user code! That's the whole point of
   my
   suggestion from the other thread.
  
   More broadly, I think you might want to look at what I did with
   Screen
   and
   Wizard.  These are declarative mechanisms for defining forms,
   validations,
   and behaviors.  Where are these not working for you?
  
   I simply haven't had the time to port thousands of lines of form code
   I've already written over to stuff on SNAPSHOT. I was supposed to
   have
   this stuff released last Friday; my intention was to release on M8
   since I haven't had time to test SNAPSHOT adequately because I've
   been
   hunting down order of evaluation bugs.
  
   Kris
 
  More to the point, I think that with a slight modification in design,
  I wouldn't *have* to think about order of evaluation. The fact that
  it's exposed (and has been, for me, an infuriating source of bugs) is
  a design smell.
 
  But something's going to have to trigger the evaluation of the
  functions.
  If everything is passive, then how does your the form is submitted, now
  start pulling the rest of the form elements in stuff work?
 
  Since we moved to the S.formGroup stuff, other than this thread, there
  has
  not been an issue with form evaluation order, so tossing around design
  smell doesn't necessarily sit well

Re: [Lift] Re: Using Stateful Snippets

2010-01-29 Thread Kris Nuttycombe
On Fri, Jan 29, 2010 at 12:05 PM, Jay Cain cain@gmail.com wrote:
 It seems that you are correct. My user object is a JPA entity and when
 it enters the closure it has a different identityHash 10749831 vs.
 21737589.  This will probably be one of many issues that I will have
 to deal with if I'm going to continue with JPA?  It's like the
 entityManager loses reference to the entity object I persisted to the
 db.  That's no good.  I'm starting this project from scratch and have
 a java background is it easier to just pick up with Scala's persistent
 architecture then continue with these little bumps in the road.

Yes, JTA transactions and EntityManager instances are scoped to the
request by the container, so your entities will become detached and
will need to be merged before the closure can manipulate them.

I've been fighting this issue for over a year, and haven't really been
able to come up with a good solution. There's just a fundamental
mismatch between the models. This wouldn't be so bad if there were a
reattach to persistence context method on EntityManager in the EJB
spec, but merge is the closest thing and it comes with a huge host of
pitfalls, not the least of which is the fact that merge returns a
proxy which cannot *itself* be attached to a persistence context (if
detached) at all.

If you're on a fresh project, I would not recommend using JPA with
Lift. There are just too many sharp corners.

Kris

 On Jan 29, 11:06 am, Naftoli Gugenheim naftoli...@gmail.com wrote:
 And user is not a RequestVar, correct? So this is not a RequestVar problem 
 then?
 What is user? A JPA entity? Could this be a JPA issue?
 If you like you can use System.identityHashcode to demonstrate that the same 
 user instance is losing its data.

 -

 Jay Caincain@gmail.com wrote:

 User[ id=0 email=, username = , created on=Fri Jan 29 10:57:27 MST
 2010 role=Basic]

 This value I get

 On Jan 28, 10:44 pm, Naftoli Gugenheim naftoli...@gmail.com wrote:



  You didn't answer my question. At the time the closure passed to 
  redirectTo is executed, what is the value of 'user'?

  -

  Jay Caincain@gmail.com wrote:

  it appears that the user still creates a new User.  it is because I
  tell it to do that each time a new request is made.

  // Set up a requestVar to track the user object
  object userVar extends RequestVar(new User())

  So I guess my question is how prevent it from doing that and still
  pass a User object to the RequestVar I tried a RequestVar[User] but no
  bueno

  below is the snippet code for registering a user

   user.password = passwordHashed
   user.activationCode = activationCode
   user.userProfile.user = user
   user.userPreferences.user = user
   Model.mergeAndFlush(user)
   MailUtils.mailConfirmationLetter(user)
   S.redirectTo(thank_you, () = { println(user); userVar(user);}

  In the mean time I'm going to just extract the email and fullname from
  the user and pass it as a request param

  user.password = passwordHashed
  user.activationCode = activationCode
  user.userProfile.user = user
  user.userPreferences.user = user
  Model.mergeAndFlush(user)
  MailUtils.mailConfirmationLetter(user)
  val email = user.email
  val fullName = user.userProfile.fullName
  println(email  + email)
  S.redirectTo(thank_you, () = {S.set(email, email); S.set
  (fullName, fullName);})

  Thanks for helping out

  On Jan 27, 10:20 pm, Naftoli Gugenheim naftoli...@gmail.com wrote:

   Can you put a trace in that closure to see if 'user' has the correct 
   value?
   S.redirectTo(thank_you, () = {println(user); userVar(user);})
   etc.

   On Wed, Jan 27, 2010 at 11:51 PM, Jay Cain cain@gmail.com wrote:
I think that this would work

// Set up a requestVar to track the user object
object userVar extends RequestVar(new User())

S.redirectTo(thank_you, () = {userVar(user);})

but no bueno.

On Jan 27, 4:56 pm, Naftoli Gugenheim naftoli...@gmail.com wrote:
 When you redirect you start a new request, so RequestVars are fresh.
 redirectTo has an overload that take additionally a function to 
 execute
in the new request. Set the RequestVar there.

 -

 Jay Caincain@gmail.com wrote:

 I am a newbie to Lift and Scala.  I'm registering users and once they
 have entered the information in successfully.  I want to redirect to 
 a
 thank_you page that will display a snippet

 lift:UserOps.thanksMessage
         p
             entry:fullname/ thanks for joining Echo.  The
 confirmation
                 instructions for completing the signup process have 
 been
sent to
                 your email address, entry:email/
         /p
 /lift:UserOps.thanksMessage

 I assume that when I redirect it doesn't hold the state of the user
 information.

 On submit I invoke signup

 def 

Re: [Lift] Creating a path from a Loc

2010-01-26 Thread Kris Nuttycombe
For this you can use loc.link.createPath. I use something similar in
my codebase. This has a little cruft you may not be precisely
interested in, but if you look at the link and flink methods, you
should be able to get an idea of how to use the Loc.Link:

class Path(val elems: List[String])

object Path {
def apply(str: String) = new Path(str.split(/).toList)
def apply(elems: List[String]) = new Path(elems)
}

case class UULink[T : UUEntity](path: Path) extends
Loc.Link[T](path.elems, false) {
override def pathList(entity: T) = path.elems :::
entity.getUuid.toString :: Nil
}

class UULoc[T : UUEntity](override val params:
List[LocParam[T]])(implicit manifest: Manifest[T]) extends Loc[T] {
private val log = Logging.logger(UULoc)
private val typeName = manifest.erasure.getSimpleName
private val path = Path(typeName.toLowerCase + s :: show :: Nil)

override val name = typeName +   Details
override val link: UULink[T] = new UULink[T](path)
override val text = LinkText((t: T) = Text(typeName +   + t.getUuid))
override val defaultValue = Empty

private def isLegalPath(root: String, uuid: String): Boolean = {
//log.info(checking path root  + root +  against  +
typeName.toLowerCase +  and uuid  + uuid)
root == (typeName.toLowerCase + s) 
EM.findByUuid[T](uuid).isDefined
}

def link(entity: T, linkText: Box[NodeSeq], attrs: (String,
String)*): NodeSeq = {
a 
href={link.createPath(entity)}{linkText.openOr(title(entity))}/a
//% attrs
}

def flink(entity: T, linkText: Box[NodeSeq], attrs: (String,
String)*)(f: () = Any): NodeSeq = {
SHtml.link(link.createPath(entity), f,
linkText.openOr(text.text(entity)), attrs: _*)
}

override def rewrite = {
Full({
case RewriteRequest(ParsePath(root :: show ::
uuid :: Nil,_,_,_),_,_)
if isLegalPath(root, uuid) =
(RewriteResponse(path.elems,
Map(typeName.toLowerCase + Uuid - uuid)),
EM.findByUuid[T](uuid).get)
})
}
}

object UULoc {
def apply[T : UUEntity](params: LocParam[T]*)(implicit
manifest: Manifest[T]) : UULoc[T] = new UULoc[T](params.toList)
}

On Tue, Jan 26, 2010 at 3:29 AM, Adam Warski a...@warski.org wrote:
 Hello,

 I'm having some trouble generating a link basing on a Loc.
 My original use-case is to redirect the user to a  login page if the user is 
 not logged in. I found a wiki on this and it says there to simply redirect to 
 /user_mgt/login, however I think it would be much nicer if I could generate 
 the link basing on looking up the right Loc.

 However having the Loc I can only generate a NodeSeq, not a plain String.

 So the solution would be to add a method into the Loc trait parallel to this 
 one:

 def createDefaultLink: Option[NodeSeq] = currentValue.flatMap(p = 
 link.createLink(p)).toOption

 which would be:

 def createDefaultPath: Option[String] = currentValue.flatMap(p = 
 link.createPath(p)).toOption

 (btw., why is it Option here, not Box?)

 Then generating a link to the login page would simply be:

 SiteMap.findLoc(Login).open_!.createDefaultPath

 --
 Adam Warski
 http://www.warski.org
 http://www.softwaremill.eu




 --
 You received this message because you are subscribed to the Google Groups 
 Lift group.
 To post to this group, send email to lift...@googlegroups.com.
 To unsubscribe from this group, send email to 
 liftweb+unsubscr...@googlegroups.com.
 For more options, visit this group at 
 http://groups.google.com/group/liftweb?hl=en.



-- 
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.



Re: [Lift] Creating a path from a Loc

2010-01-26 Thread Kris Nuttycombe
On Tue, Jan 26, 2010 at 1:17 PM, Adam Warski a...@warski.org wrote:
 Hello,

 For this you can use loc.link.createPath. I use something similar in
 my codebase. This has a little cruft you may not be precisely
 interested in, but if you look at the link and flink methods, you
 should be able to get an idea of how to use the Loc.Link:


 I'm using Link in a similar way to, but here I can't use createPath, as 
 SiteMap.findLoc(...) returns a Loc[_], so the type parameter is unknown, so 
 without some casts I won't be able to pass the parameter.

 I tried:

 val loc = SiteMap.findLoc(Login).open_!
 val link = loc.link.createPath(loc.currentValue.open_!)

Instead of building your Loc inline in the SiteMap declaration and
using findLoc, simply declare the loc as a val (with the appropriate
type parameter) in Boot or a similar object of your choosing.

I have an object I call Site which I use to separate out the Loc stuff
from the SiteMap and Menu. Here's what it looks like:

object Site {
var locs: List[Loc[_]] = Nil

def loc(name: String, link: Link[Unit], text: LinkText[Unit],
params: AnyLocParam*): Loc[Unit] = {
val newLoc = Loc(name, link, text, params: _*)
locs = newLoc :: locs
newLoc
}

def uuloc[T : UUEntity](params: LocParam[T]*)(implicit
manifest: Manifest[T]) : UULoc[T] = {
val newLoc = new UULoc[T](params.toList)
locs = newLoc :: locs
newLoc
}

// Visible locs
val home =  loc(Home, index :: Nil , ?(Home))
val userSearch =loc(User Search, users :: search ::
Nil, ?(User Search))
val orderSearch =   loc(Order Search, orders :: search
:: Nil, ?(Order Search))
val orderForm = loc(New Order, orders :: new :: Nil,
?(New Order))
//...

// REST gettable object locs
val userDetail =uuloc[User](Hidden)
val orderDetail =   uuloc[Order](Hidden)
//...
}

Then, in Boot.scala I simply have this:

LiftRules.setSiteMap(SiteMap(Site.locs.reverse.map(Menu(_)): _*))

Don't throw away type information when you don't have to!

Kris


 but unfortunately the compiler doesn't seem to recognize the fact that the 
 type parameter for loc is the same as the one returned for loc.currentValue.

 --
 Adam Warski
 http://www.warski.org
 http://www.softwaremill.eu




 --
 You received this message because you are subscribed to the Google Groups 
 Lift group.
 To post to this group, send email to lift...@googlegroups.com.
 To unsubscribe from this group, send email to 
 liftweb+unsubscr...@googlegroups.com.
 For more options, visit this group at 
 http://groups.google.com/group/liftweb?hl=en.



-- 
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.



Re: [Lift] Re: A better approach to ajax forms?

2010-01-21 Thread Kris Nuttycombe
On Thu, Jan 21, 2010 at 12:23 PM, Marius marius.dan...@gmail.com wrote:
 Instead of

  submit - SHtml.submit(Parse, () = ())

 use:

  submit - SHtml.ajaxSubmit(Parse, () = ())

 you can also send normal forms via ajax like:

 SHtml.submitAjaxForm(formId, () = {

  /// Do your stuff here. This function will be called after form
 field functions are executed.
  Noop
 })


 Br's,
 Marius

Thanks, Marius. I've just updated from M1 to the snapshot to get
ajaxSubmit; however, it doesn't address my question as to why the
function passed to AjaxSubmit doesn't return a JsCmd that can be used
to refresh the page.

Also, any thoughts on my proposal?

Kris



 On Jan 21, 9:03 pm, Kris Nuttycombe kris.nuttyco...@gmail.com wrote:
 *thump* *thump* Hello, is this thing on? :)

 On Wed, Jan 20, 2010 at 10:20 AM, Kris Nuttycombe

 kris.nuttyco...@gmail.com wrote:
  On Wed, Jan 20, 2010 at 9:51 AM, Kris Nuttycombe
  kris.nuttyco...@gmail.com wrote:
  On Wed, Jan 20, 2010 at 9:39 AM, Kris Nuttycombe
  kris.nuttyco...@gmail.com wrote:
  Hi, all,

  I'm working on an AJAX form and feel like I'm missing something:
  namely, how to update the page based upon the result of the form
  submission.

  The three ajaxForm methods in SHtml have the following signatures:

  def ajaxForm(body : NodeSeq)
  def ajaxForm(body : NodeSeq, onSubmit : JsCmd)
  def ajaxForm(body : NodeSeq, onSubmit : JsCmd, postSubmit : JsCmd)

  In these signatures, onSubmit is called by the client prior to form
  submission, and postSubmit is called by the client after successful
  submission. My question is, why is there not a signature like this:

  def ajaxForm(body: NodeSeq, result: () = JsCmd)

  for which the specified result function will be called, and the JsCmd
  returned to the browser for evaluation after processing of the form
  contents on the server?

  Right now, I'm using the following to achieve this effect, but it
  seems really hacky:

         val (psId, psJs) = ajaxCall(JsRaw(dsl_text.value), text =
  After(20, SetHtml(results, parse(text

         ajaxForm(
             bind(plan, xhtml,
                  dsl - SHtml.textarea(, s = (), id -
  dsl_text, rows - 40, cols - 120),
                  submit - SHtml.submit(Parse, () = ())
             ),
             psJs.cmd
         )

  Here, JsCmd is actually doing the heavy lifting prior to form
  submission, with noop implementations for handling of the form
  elements. Seems really hacky.

  I feel like I've got to be missing something here, like there's got to
  be a better way to implement this such that the parsing of the
  textarea contents can be done by the closure passed to the
  SHtml.textarea call. How can I do this?

  Here's an idea I've been toying with for a while; it would be a
  somewhat significant change to Lift but I feel like there would be
  some benefits.

  Instead of SHtml.* having signatures like (String, () = Any, (String,
  String)*) = NodeSeq, imagine that there was a parameterized class
  (call it FormElement) that all of the SHtml methods returned, and then
  an implicit conversion from FormElement to NodeSeq. Might look
  something like this:

  trait FormElement[T] {
   def !: T
   def toNodeSeq: NodeSeq
  }

  An addendum: there's an obvious extension available here:

  trait FormElement[T] { self =
   def !: T

   def toNodeSeq: NodeSeq

   def map[U](f: T = U): FormElement[U] = new FormElement[U] {
     lazy val !: U = f(self!)
     lazy val toNodeSeq: NodeSeq = self.toNodeSeq
   }

   def flatMap[U](f: T = FormElement[U]): FormElement[U] = new
  FormElement[U] {
     private lazy val cache = f(self!)
     lazy val !: U = cache!
     lazy val toNodeSeq = self.toNodeSeq ++ cache.toNodeSeq
   }
  }

  On second thought, that FormElement implementation as a monad is wrong
  because toNodeSeq would cause strict evaluation of the closure when
  used in the SHtml.* case. Maybe FormElement just has to be a functor
  and not a monad.

  Kris

 --
 You received this message because you are subscribed to the Google Groups 
 Lift group.
 To post to this group, send email to lift...@googlegroups.com.
 To unsubscribe from this group, send email to 
 liftweb+unsubscr...@googlegroups.com.
 For more options, visit this group at 
 http://groups.google.com/group/liftweb?hl=en.




-- 
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.




Re: [Lift] Re: A better approach to ajax forms?

2010-01-21 Thread Kris Nuttycombe
On Thu, Jan 21, 2010 at 2:43 PM, Marius marius.dan...@gmail.com wrote:


 On Jan 21, 11:15 pm, Kris Nuttycombe kris.nuttyco...@gmail.com
 wrote:
 On Thu, Jan 21, 2010 at 12:23 PM, Marius marius.dan...@gmail.com wrote:
  Instead of

   submit - SHtml.submit(Parse, () = ())

  use:

   submit - SHtml.ajaxSubmit(Parse, () = ())

  you can also send normal forms via ajax like:

  SHtml.submitAjaxForm(formId, () = {

   /// Do your stuff here. This function will be called after form
  field functions are executed.
   Noop
  })

  Br's,
  Marius

 Thanks, Marius. I've just updated from M1 to the snapshot to get
 ajaxSubmit; however, it doesn't address my question as to why the
 function passed to AjaxSubmit doesn't return a JsCmd that can be used
 to refresh the page.

 The ajaxSubmit has the signature:

 def ajaxSubmit(value: String, func: () = Any, attrs: (String, String)
 *)

 returns an Any because Lift looks for the following:

 JsCmd,
 NodeSeq
 JsCommands
 LiftResponse

 however for consistency reasons I think I should change it to  func:
 () = JsCmd


 Also, any thoughts on my proposal?

 I don't really see the benefits in doing that.

The benefit is predictability; with the current functionality, as I
understand it, the order of evaluation of closures associated with
form elements is dependent upon the order in which those elements are
added to the form. What my proposal does is (1) eliminate the need to
close over local vars and (2) eliminate the dependence upon order of
declaration.

In essence, my proposal is to give the user the ability to, in
addition to having those closures invoked automatically on the
processing of a form, be able to explicitly invoke them during form
processing.

I really dislike the pattern:

def mySnippet(xhtml: NodeSeq) {
  var a: Option[String] = None

  bind(a, xhtml,
 value - text(. s = a = Some(s)),
 submit - submit(Submit, () = a.foreach(doSomething _)
  )
}

With my proposal, this would become:

def mySnippet(xhtml: NodeSeq) {
   val aField = text(s, s = s)

  bind(a, xhtml,
 value - aField,
 submit - submit(Submit, () = doSomething(a!))
  )
}

This becomes really advantageous, I think, when you're talking about
15 or 20 different form elements. The var solution in that case
becomes totally unwieldy because of the unwrapping of all of the
Options.

Kris



 Kris



  On Jan 21, 9:03 pm, Kris Nuttycombe kris.nuttyco...@gmail.com wrote:
  *thump* *thump* Hello, is this thing on? :)

  On Wed, Jan 20, 2010 at 10:20 AM, Kris Nuttycombe

  kris.nuttyco...@gmail.com wrote:
   On Wed, Jan 20, 2010 at 9:51 AM, Kris Nuttycombe
   kris.nuttyco...@gmail.com wrote:
   On Wed, Jan 20, 2010 at 9:39 AM, Kris Nuttycombe
   kris.nuttyco...@gmail.com wrote:
   Hi, all,

   I'm working on an AJAX form and feel like I'm missing something:
   namely, how to update the page based upon the result of the form
   submission.

   The three ajaxForm methods in SHtml have the following signatures:

   def ajaxForm(body : NodeSeq)
   def ajaxForm(body : NodeSeq, onSubmit : JsCmd)
   def ajaxForm(body : NodeSeq, onSubmit : JsCmd, postSubmit : JsCmd)

   In these signatures, onSubmit is called by the client prior to form
   submission, and postSubmit is called by the client after successful
   submission. My question is, why is there not a signature like this:

   def ajaxForm(body: NodeSeq, result: () = JsCmd)

   for which the specified result function will be called, and the JsCmd
   returned to the browser for evaluation after processing of the form
   contents on the server?

   Right now, I'm using the following to achieve this effect, but it
   seems really hacky:

          val (psId, psJs) = ajaxCall(JsRaw(dsl_text.value), text =
   After(20, SetHtml(results, parse(text

          ajaxForm(
              bind(plan, xhtml,
                   dsl - SHtml.textarea(, s = (), id -
   dsl_text, rows - 40, cols - 120),
                   submit - SHtml.submit(Parse, () = ())
              ),
              psJs.cmd
          )

   Here, JsCmd is actually doing the heavy lifting prior to form
   submission, with noop implementations for handling of the form
   elements. Seems really hacky.

   I feel like I've got to be missing something here, like there's got to
   be a better way to implement this such that the parsing of the
   textarea contents can be done by the closure passed to the
   SHtml.textarea call. How can I do this?

   Here's an idea I've been toying with for a while; it would be a
   somewhat significant change to Lift but I feel like there would be
   some benefits.

   Instead of SHtml.* having signatures like (String, () = Any, (String,
   String)*) = NodeSeq, imagine that there was a parameterized class
   (call it FormElement) that all of the SHtml methods returned, and then
   an implicit conversion from FormElement to NodeSeq. Might look
   something like this:

   trait FormElement[T] {
    def !: T
    def toNodeSeq: NodeSeq

Re: [Lift] Re: A better approach to ajax forms?

2010-01-21 Thread Kris Nuttycombe
On Thu, Jan 21, 2010 at 2:43 PM, Marius marius.dan...@gmail.com wrote:


 On Jan 21, 11:15 pm, Kris Nuttycombe kris.nuttyco...@gmail.com
 wrote:
 On Thu, Jan 21, 2010 at 12:23 PM, Marius marius.dan...@gmail.com wrote:
  Instead of

   submit - SHtml.submit(Parse, () = ())

  use:

   submit - SHtml.ajaxSubmit(Parse, () = ())

  you can also send normal forms via ajax like:

  SHtml.submitAjaxForm(formId, () = {

   /// Do your stuff here. This function will be called after form
  field functions are executed.
   Noop
  })

  Br's,
  Marius

 Thanks, Marius. I've just updated from M1 to the snapshot to get
 ajaxSubmit; however, it doesn't address my question as to why the
 function passed to AjaxSubmit doesn't return a JsCmd that can be used
 to refresh the page.

 The ajaxSubmit has the signature:

 def ajaxSubmit(value: String, func: () = Any, attrs: (String, String)
 *)

 returns an Any because Lift looks for the following:

 JsCmd,
 NodeSeq
 JsCommands
 LiftResponse

I think I must be misunderstanding something - should I expect the
following to work?

var text: Option[String] = None
ajaxForm(
bind(plan, xhtml,
 dsl - textarea(, s = text = Some(s), id -
dsl_text, rows - 40, cols - 120),
 submit - ajaxSubmit(Create Plan, () =
SetHtml(results, buildPlan(text.get)))
)
)

where there is div id=results/ in the rendered page? I don't seem
to get the expected results back, though it's clear from logging that
this is being processed correctly.

Kris

-- 
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.



Re: [Lift] Re: A better approach to ajax forms?

2010-01-21 Thread Kris Nuttycombe
On Thu, Jan 21, 2010 at 4:36 PM, Kris Nuttycombe
kris.nuttyco...@gmail.com wrote:
 On Thu, Jan 21, 2010 at 2:43 PM, Marius marius.dan...@gmail.com wrote:


 On Jan 21, 11:15 pm, Kris Nuttycombe kris.nuttyco...@gmail.com
 wrote:
 On Thu, Jan 21, 2010 at 12:23 PM, Marius marius.dan...@gmail.com wrote:
  Instead of

   submit - SHtml.submit(Parse, () = ())

  use:

   submit - SHtml.ajaxSubmit(Parse, () = ())

  you can also send normal forms via ajax like:

  SHtml.submitAjaxForm(formId, () = {

   /// Do your stuff here. This function will be called after form
  field functions are executed.
   Noop
  })

  Br's,
  Marius

 Thanks, Marius. I've just updated from M1 to the snapshot to get
 ajaxSubmit; however, it doesn't address my question as to why the
 function passed to AjaxSubmit doesn't return a JsCmd that can be used
 to refresh the page.

 The ajaxSubmit has the signature:

 def ajaxSubmit(value: String, func: () = Any, attrs: (String, String)
 *)

 returns an Any because Lift looks for the following:

 JsCmd,
 NodeSeq
 JsCommands
 LiftResponse

 I think I must be misunderstanding something - should I expect the
 following to work?

        var text: Option[String] = None
        ajaxForm(
            bind(plan, xhtml,
                 dsl - textarea(, s = text = Some(s), id -
 dsl_text, rows - 40, cols - 120),
                 submit - ajaxSubmit(Create Plan, () =
 SetHtml(results, buildPlan(text.get)))
            )
        )

 where there is div id=results/ in the rendered page? I don't seem
 to get the expected results back, though it's clear from logging that
 this is being processed correctly.

 Kris


A bit more, intriguing information: is SetHtml size-limited? It seems
to work fine if what I'm passing back is just a URL or something, but
if I pass back a 1.5k error message, the message never seems to
appear.

Kris

-- 
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.



Re: [Lift] Re: A better approach to ajax forms?

2010-01-21 Thread Kris Nuttycombe
Okay, I think I may have found a bug.

My returned content contains unescaped braces. In one failure case
(this is parsing a DSL) I was testing a parse of a missing end brace -
and part of the error message is the original text passed in (with
mismatched braces).

Figured it out by passing in content with a superfluous end brace -
that error returns fine. :)

Thought I was going nuts.

Kris

On Thu, Jan 21, 2010 at 5:08 PM, David Pollak
feeder.of.the.be...@gmail.com wrote:


 On Thu, Jan 21, 2010 at 4:04 PM, Kris Nuttycombe kris.nuttyco...@gmail.com
 wrote:

 On Thu, Jan 21, 2010 at 4:36 PM, Kris Nuttycombe
 kris.nuttyco...@gmail.com wrote:
  On Thu, Jan 21, 2010 at 2:43 PM, Marius marius.dan...@gmail.com wrote:
 
 
  On Jan 21, 11:15 pm, Kris Nuttycombe kris.nuttyco...@gmail.com
  wrote:
  On Thu, Jan 21, 2010 at 12:23 PM, Marius marius.dan...@gmail.com
  wrote:
   Instead of
 
    submit - SHtml.submit(Parse, () = ())
 
   use:
 
    submit - SHtml.ajaxSubmit(Parse, () = ())
 
   you can also send normal forms via ajax like:
 
   SHtml.submitAjaxForm(formId, () = {
 
    /// Do your stuff here. This function will be called after form
   field functions are executed.
    Noop
   })
 
   Br's,
   Marius
 
  Thanks, Marius. I've just updated from M1 to the snapshot to get
  ajaxSubmit; however, it doesn't address my question as to why the
  function passed to AjaxSubmit doesn't return a JsCmd that can be used
  to refresh the page.
 
  The ajaxSubmit has the signature:
 
  def ajaxSubmit(value: String, func: () = Any, attrs: (String, String)
  *)
 
  returns an Any because Lift looks for the following:
 
  JsCmd,
  NodeSeq
  JsCommands
  LiftResponse
 
  I think I must be misunderstanding something - should I expect the
  following to work?
 
         var text: Option[String] = None
         ajaxForm(
             bind(plan, xhtml,
                  dsl - textarea(, s = text = Some(s), id -
  dsl_text, rows - 40, cols - 120),
                  submit - ajaxSubmit(Create Plan, () =
  SetHtml(results, buildPlan(text.get)))
             )
         )
 
  where there is div id=results/ in the rendered page? I don't seem
  to get the expected results back, though it's clear from logging that
  this is being processed correctly.
 
  Kris
 

 A bit more, intriguing information: is SetHtml size-limited? It seems
 to work fine if what I'm passing back is just a URL or something, but
 if I pass back a 1.5k error message, the message never seems to
 appear.

 It's not size limited AFAIK.  Some browsers may have a limit on String
 length or the ability to parse super-long JavaScript, but you're probably
 looking at 16M (24 bits).


 Kris

 --
 You received this message because you are subscribed to the Google Groups
 Lift group.
 To post to this group, send email to lift...@googlegroups.com.
 To unsubscribe from this group, send email to
 liftweb+unsubscr...@googlegroups.com.
 For more options, visit this group at
 http://groups.google.com/group/liftweb?hl=en.




 --
 Lift, the simply functional web framework http://liftweb.net
 Beginning Scala http://www.apress.com/book/view/1430219890
 Follow me: http://twitter.com/dpp
 Surf the harmonics

 --
 You received this message because you are subscribed to the Google Groups
 Lift group.
 To post to this group, send email to lift...@googlegroups.com.
 To unsubscribe from this group, send email to
 liftweb+unsubscr...@googlegroups.com.
 For more options, visit this group at
 http://groups.google.com/group/liftweb?hl=en.


-- 
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.



[Lift] A better approach to ajax forms?

2010-01-20 Thread Kris Nuttycombe
Hi, all,

I'm working on an AJAX form and feel like I'm missing something:
namely, how to update the page based upon the result of the form
submission.

The three ajaxForm methods in SHtml have the following signatures:

def ajaxForm(body : NodeSeq)
def ajaxForm(body : NodeSeq, onSubmit : JsCmd)
def ajaxForm(body : NodeSeq, onSubmit : JsCmd, postSubmit : JsCmd)

In these signatures, onSubmit is called by the client prior to form
submission, and postSubmit is called by the client after successful
submission. My question is, why is there not a signature like this:

def ajaxForm(body: NodeSeq, result: () = JsCmd)

for which the specified result function will be called, and the JsCmd
returned to the browser for evaluation after processing of the form
contents on the server?

Right now, I'm using the following to achieve this effect, but it
seems really hacky:

val (psId, psJs) = ajaxCall(JsRaw(dsl_text.value), text =
After(20, SetHtml(results, parse(text

ajaxForm(
bind(plan, xhtml,
 dsl - SHtml.textarea(, s = (), id -
dsl_text, rows - 40, cols - 120),
 submit - SHtml.submit(Parse, () = ())
),
psJs.cmd
)

Here, JsCmd is actually doing the heavy lifting prior to form
submission, with noop implementations for handling of the form
elements. Seems really hacky.

I feel like I've got to be missing something here, like there's got to
be a better way to implement this such that the parsing of the
textarea contents can be done by the closure passed to the
SHtml.textarea call. How can I do this?

Here's an idea I've been toying with for a while; it would be a
somewhat significant change to Lift but I feel like there would be
some benefits.

Instead of SHtml.* having signatures like (String, () = Any, (String,
String)*) = NodeSeq, imagine that there was a parameterized class
(call it FormElement) that all of the SHtml methods returned, and then
an implicit conversion from FormElement to NodeSeq. Might look
something like this:

trait FormElement[T] {
  def !: T
  def toNodeSeq: NodeSeq
}

implicit def formElem2NodeSeq[T](e: FormElement[T]) = e.toNodeSeq

Then, the SHtml methods would have signatures like this instead:

def textarea[T](contents: String, onSubmit: (String) = T, attrs :
(String, String)*): FormElement[T]
def submit[T](label: String, onSubmit: () = T, attrs: (String,
String)*): FormElement[T]

With the implicit conversion in scope, these could be used exactly
like their current counterparts, but there's another way they could be
used as well. Here's what the problem I'm facing might look like with
this construction, along with the ability for ajaxForm to take a
closure as above:

val text: FormElement[NodeSeq] = SHtml.textArea(, s = parse(s),
rows - 40, cols - 120)
val submit: FormElement[JsCmd] = SHtml.submit(Parse, () =
SetHtml(results, text!))

ajaxForm(
  bind(plan, xhtml, dsl - text, submit - submit),
  () = submit!
)

What do you think?

Kris
-- 
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.




[Lift] Re: A better approach to ajax forms?

2010-01-20 Thread Kris Nuttycombe
On Wed, Jan 20, 2010 at 9:39 AM, Kris Nuttycombe
kris.nuttyco...@gmail.com wrote:
 Hi, all,

 I'm working on an AJAX form and feel like I'm missing something:
 namely, how to update the page based upon the result of the form
 submission.

 The three ajaxForm methods in SHtml have the following signatures:

 def ajaxForm(body : NodeSeq)
 def ajaxForm(body : NodeSeq, onSubmit : JsCmd)
 def ajaxForm(body : NodeSeq, onSubmit : JsCmd, postSubmit : JsCmd)

 In these signatures, onSubmit is called by the client prior to form
 submission, and postSubmit is called by the client after successful
 submission. My question is, why is there not a signature like this:

 def ajaxForm(body: NodeSeq, result: () = JsCmd)

 for which the specified result function will be called, and the JsCmd
 returned to the browser for evaluation after processing of the form
 contents on the server?

 Right now, I'm using the following to achieve this effect, but it
 seems really hacky:

        val (psId, psJs) = ajaxCall(JsRaw(dsl_text.value), text =
 After(20, SetHtml(results, parse(text

        ajaxForm(
            bind(plan, xhtml,
                 dsl - SHtml.textarea(, s = (), id -
 dsl_text, rows - 40, cols - 120),
                 submit - SHtml.submit(Parse, () = ())
            ),
            psJs.cmd
        )

 Here, JsCmd is actually doing the heavy lifting prior to form
 submission, with noop implementations for handling of the form
 elements. Seems really hacky.

 I feel like I've got to be missing something here, like there's got to
 be a better way to implement this such that the parsing of the
 textarea contents can be done by the closure passed to the
 SHtml.textarea call. How can I do this?

 Here's an idea I've been toying with for a while; it would be a
 somewhat significant change to Lift but I feel like there would be
 some benefits.

 Instead of SHtml.* having signatures like (String, () = Any, (String,
 String)*) = NodeSeq, imagine that there was a parameterized class
 (call it FormElement) that all of the SHtml methods returned, and then
 an implicit conversion from FormElement to NodeSeq. Might look
 something like this:

 trait FormElement[T] {
  def !: T
  def toNodeSeq: NodeSeq
 }

An addendum: there's an obvious extension available here:

trait FormElement[T] { self =
  def !: T

  def toNodeSeq: NodeSeq

  def map[U](f: T = U): FormElement[U] = new FormElement[U] {
lazy val !: U = f(self!)
lazy val toNodeSeq: NodeSeq = self.toNodeSeq
  }

  def flatMap[U](f: T = FormElement[U]): FormElement[U] = new
FormElement[U] {
private lazy val cache = f(self!)
lazy val !: U = cache!
lazy val toNodeSeq = self.toNodeSeq ++ cache.toNodeSeq
  }
}

Kris
-- 
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.




[Lift] Re: A better approach to ajax forms?

2010-01-20 Thread Kris Nuttycombe
On Wed, Jan 20, 2010 at 9:51 AM, Kris Nuttycombe
kris.nuttyco...@gmail.com wrote:
 On Wed, Jan 20, 2010 at 9:39 AM, Kris Nuttycombe
 kris.nuttyco...@gmail.com wrote:
 Hi, all,

 I'm working on an AJAX form and feel like I'm missing something:
 namely, how to update the page based upon the result of the form
 submission.

 The three ajaxForm methods in SHtml have the following signatures:

 def ajaxForm(body : NodeSeq)
 def ajaxForm(body : NodeSeq, onSubmit : JsCmd)
 def ajaxForm(body : NodeSeq, onSubmit : JsCmd, postSubmit : JsCmd)

 In these signatures, onSubmit is called by the client prior to form
 submission, and postSubmit is called by the client after successful
 submission. My question is, why is there not a signature like this:

 def ajaxForm(body: NodeSeq, result: () = JsCmd)

 for which the specified result function will be called, and the JsCmd
 returned to the browser for evaluation after processing of the form
 contents on the server?

 Right now, I'm using the following to achieve this effect, but it
 seems really hacky:

        val (psId, psJs) = ajaxCall(JsRaw(dsl_text.value), text =
 After(20, SetHtml(results, parse(text

        ajaxForm(
            bind(plan, xhtml,
                 dsl - SHtml.textarea(, s = (), id -
 dsl_text, rows - 40, cols - 120),
                 submit - SHtml.submit(Parse, () = ())
            ),
            psJs.cmd
        )

 Here, JsCmd is actually doing the heavy lifting prior to form
 submission, with noop implementations for handling of the form
 elements. Seems really hacky.

 I feel like I've got to be missing something here, like there's got to
 be a better way to implement this such that the parsing of the
 textarea contents can be done by the closure passed to the
 SHtml.textarea call. How can I do this?

 Here's an idea I've been toying with for a while; it would be a
 somewhat significant change to Lift but I feel like there would be
 some benefits.

 Instead of SHtml.* having signatures like (String, () = Any, (String,
 String)*) = NodeSeq, imagine that there was a parameterized class
 (call it FormElement) that all of the SHtml methods returned, and then
 an implicit conversion from FormElement to NodeSeq. Might look
 something like this:

 trait FormElement[T] {
  def !: T
  def toNodeSeq: NodeSeq
 }

 An addendum: there's an obvious extension available here:

 trait FormElement[T] { self =
  def !: T

  def toNodeSeq: NodeSeq

  def map[U](f: T = U): FormElement[U] = new FormElement[U] {
    lazy val !: U = f(self!)
    lazy val toNodeSeq: NodeSeq = self.toNodeSeq
  }

  def flatMap[U](f: T = FormElement[U]): FormElement[U] = new
 FormElement[U] {
    private lazy val cache = f(self!)
    lazy val !: U = cache!
    lazy val toNodeSeq = self.toNodeSeq ++ cache.toNodeSeq
  }
 }

On second thought, that FormElement implementation as a monad is wrong
because toNodeSeq would cause strict evaluation of the closure when
used in the SHtml.* case. Maybe FormElement just has to be a functor
and not a monad.

Kris
-- 
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.




Re: [Lift] Re: Minor breaking changes -- LiftRules.getResourceAsStream and LiftRules.finder

2010-01-04 Thread Kris Nuttycombe
On Mon, Jan 4, 2010 at 9:51 AM, David Pollak
feeder.of.the.be...@gmail.com wrote:


 On Sat, Jan 2, 2010 at 9:34 PM, Naftoli Gugenheim naftoli...@gmail.com
 wrote:

 I actually like StreamHandler better than StreamManager. StreamManager
 sounds like a something more complex.

 The implementation:

 trait Applier[T] {
   def apply[R](f: T = R): R
 }


 Has nothing to do with Streams.  It's a close cousin of a Function.


I believe that this is actually the type signature of the Thrush
combinator - it's a pretty generally useful type. I have the following
in my codebase:

implicit def any2Thrush[T](t: T): Thrush[T] = new Thrush[T](t)

class Thrush[T](t: T) {
  def -*[U](f: T = U): U = f(t)
}


 On Sat, Jan 2, 2010 at 7:58 AM, greekscala hellectro...@gmail.com wrote:

 Hello,

 I think applier is to general. applier for...? As Naftoli said, a name
 like StreamManager
 or StreamHandler is clearer for a newbie like me.

 best regards

 On 31 Dez. 2009, 21:48, David Pollak feeder.of.the.be...@gmail.com
 wrote:
  Folks,
 
  I've changed LiftRules.getResourceAsStream and LiftRules.finder to
  return
  Box[Applier[InputStream]] rather than Box[InputStream].
 
  Applier has a single method, apply[T] which takes an InputStream = T
  and
  insures the InputStream is closed.
 
  This change is unlikely to impact much code out there, but does make
  sure
  that InputStreams are closed.
 
  If any of the folks out there that name things better than I do (at
  least I
  didn't call it Apply_A_Tron), please feel free to suggest name changes,
  variance changes, etc.
 
  Thanks,
 
  David
 
  --
  Lift, the simply functional web frameworkhttp://liftweb.net
  Beginning Scalahttp://www.apress.com/book/view/1430219890
  Follow me:http://twitter.com/dpp
  Surf the harmonics

 --

 You received this message because you are subscribed to the Google Groups
 Lift group.
 To post to this group, send email to lift...@googlegroups.com.
 To unsubscribe from this group, send email to
 liftweb+unsubscr...@googlegroups.com.
 For more options, visit this group at
 http://groups.google.com/group/liftweb?hl=en.



 --

 You received this message because you are subscribed to the Google Groups
 Lift group.
 To post to this group, send email to lift...@googlegroups.com.
 To unsubscribe from this group, send email to
 liftweb+unsubscr...@googlegroups.com.
 For more options, visit this group at
 http://groups.google.com/group/liftweb?hl=en.



 --
 Lift, the simply functional web framework http://liftweb.net
 Beginning Scala http://www.apress.com/book/view/1430219890
 Follow me: http://twitter.com/dpp
 Surf the harmonics

 --

 You received this message because you are subscribed to the Google Groups
 Lift group.
 To post to this group, send email to lift...@googlegroups.com.
 To unsubscribe from this group, send email to
 liftweb+unsubscr...@googlegroups.com.
 For more options, visit this group at
 http://groups.google.com/group/liftweb?hl=en.


--

You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.




Re: [Lift] Lift based backend server subscribing via amqp

2010-01-04 Thread Kris Nuttycombe
On Mon, Jan 4, 2010 at 8:48 AM, Timothy Perrett timo...@getintheloop.eu wrote:
 Hi,

 No, the AMQP module hasnt had any work for some time... I think im the only 
 person actually using it.

 Check my article about it here: http://is.gd/5LZ34

 Cheers, Tim


Nope! We're using it in production as well. :)

Kris

 On 4 Jan 2010, at 15:34, vishnu wrote:

 Hi
   I'm trying to use lift to right a back end for a system that
 communicates via AMQP. The idea is to have a bunch of (threads?,
 processes? actors?) that subscribe to some queues on a queueing system
 and react to various messages by contacting various third party
 systems and persisting messages to a database.

 I was wondering firstly if it makes sense to use lift, or if it makes
 more sense to pull various parts out of lift and use them?

 Additionally, looking at the lift amqp code, it seems to be a little
 out of date, especially with regard to amqp. Does anyone know if there
 has been any active work on this segment?

 --

 You received this message because you are subscribed to the Google Groups 
 Lift group.
 To post to this group, send email to lift...@googlegroups.com.
 To unsubscribe from this group, send email to 
 liftweb+unsubscr...@googlegroups.com.
 For more options, visit this group at 
 http://groups.google.com/group/liftweb?hl=en.




 --

 You received this message because you are subscribed to the Google Groups 
 Lift group.
 To post to this group, send email to lift...@googlegroups.com.
 To unsubscribe from this group, send email to 
 liftweb+unsubscr...@googlegroups.com.
 For more options, visit this group at 
 http://groups.google.com/group/liftweb?hl=en.




--

You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.




Re: [Lift] Goals for type and method renaming for Lift 2.0 - was: Open discussion on Lift Name Calling practices

2009-12-14 Thread Kris Nuttycombe
On Mon, Dec 14, 2009 at 12:31 PM, David Pollak
feeder.of.the.be...@gmail.com wrote:
 Folks,

 Lift allows developers to create web sites that are:

 Reliable (which includes secure)
 Maintainable/concise
 Highly interactive
 Easy to build
 High Performance
 Easy to on-board (initial understanding of the APIs)

 Lift's APIs should reflect these rank-ordered goals.  Some of these goals
 are in tension with each other.  For example, easy on-boarding (e.g., longer
 method names, more traditional imperative style) is in tension with concise.

 There's also a very diverse Lift community.

 I use Emacs for a lot of my Lift coding.  I know folks who use TextMate for
 Lift coding.  Having long method names assumes the use of an IDE which has
 name completion.  Lift's APIs must serve both communities.
 People are coming to Lift from Java, Ruby, PHP, and other backgrounds.
 Assuming Scala conventions rather than a best choice for naming does a
 dis-service to the polygots.  Further, most of Scala's API conventions
 except for the collections stuff is not in my opinion that well thought out
 or consistent.
 Many of Lift's APIs have evolved correctly based on actual usage patterns.
 For example, the initially counter-intuitive use of apply to set fields and
 vars works far better than any other mechanism, especially when chaining
 calls.  I've tried many different mechanisms (e.g., update(), Pascal style
 :=, set(), etc.) for setting fields and the one that everybody gravitated to
 was apply().

 We also have to consider the existing code base.  I've personally got 150K
 lines of Lift-code under management.  If we start breaking APIs without a
 compelling reason, it costs me money and it costs my clients less of my
 time.  What's the impact to various different current users of Lift of
 breaking APIs without a compelling reason (and I like this name better than
 that name or this name is more consistent are not compelling reasons.)
 So, my criteria for any name changes (and this is not open to any type of
 negotiation and I've been 100% consistent about this since the discussion
 began) is:

 If the name change can be accomplished with a deprecation of the old name
 without breaking any existing APIs, then the name change can be the better
 name.
 If the name change is internal to Lift or is in a little-used feature (e.g.,
 Kris's API changes in Loc) such that very few projects will likely be
 impacted by a name change and those that are impacted are sufficiently savvy
 that they will understand the change and be able to make it in a matter of
 minutes.
 Any class name or object name change that does not meet the above criteria
 must be compelling.  For example, we changed from Scala Actors to Lift
 Actors.  This was a substantial amount of breakage, but there were no
 alternatives and the Scala Actor memory retention issues were materially
 impacting many different sites and we had worked on various attempted
 solutions over a 10 month period.  If we're going to break without
 deprecation and the breakage is going to impact a substantial part of the
 Lift community, there must be a compelling reason to make the breakage.

 On Sun, Dec 13, 2009 at 10:49 AM, Kris Nuttycombe
 kris.nuttyco...@gmail.com wrote:

 To this point, the only goals that have been recommended for this
 effort are those that I've noted below:

  1) Remove ambiguity wherever possible! There are a number of places
  where very similar names are used to refer to utterly different
  things.

  2) As an aide removing ambiguity, consider outlawing or eliminating
  extremely generic names, or else establish a single way in which a
  given name will be used across Lift. Examples are Field, Info, Holder,
  etc.

 In general, this is okay, but if there's a FooHolder that holds a Foo,
 what's wrong with that kind of naming?

Holder is probably the least problematic of these. The only issue I
have with it is that FooHolder doesn't say anything about why you
might want to have that particular kind of container (or indeed have a
container at all) for a Foo. In some sense, every object that contains
data is a holder - and I don't think StringHolder makes much sense;
why does FooHolder?


  3) Avoid making the name of the return type part of the name of the
  method. The types should tell the story as much as possible, except in
  the case where multiple methods varying only in return type would
  exist (illegal overloads)

 I'd be interested in understanding what the specific examples are, but I'm
 not sure I'm on board with this.  Sometimes getLiftResponse is a lot more
 meaningful than get.

There were a couple of examples of this in S that I thought were
suspect, but we can address those individually. In general I think
this suggestion boils down to DRY.


  4) Prefer Scala-style accessors and mutators.

 I disagree.  This is one where I have tried a lot of different accessors and
 mutators and the current crop is the best of breed.  Sure, it's a little

[Lift] Goals for type and method renaming for Lift 2.0 - was: Open discussion on Lift Name Calling practices

2009-12-13 Thread Kris Nuttycombe
To this point, the only goals that have been recommended for this
effort are those that I've noted below:

 1) Remove ambiguity wherever possible! There are a number of places
 where very similar names are used to refer to utterly different
 things.

 2) As an aide removing ambiguity, consider outlawing or eliminating
 extremely generic names, or else establish a single way in which a
 given name will be used across Lift. Examples are Field, Info, Holder,
 etc.

 3) Avoid making the name of the return type part of the name of the
 method. The types should tell the story as much as possible, except in
 the case where multiple methods varying only in return type would
 exist (illegal overloads)

 4) Prefer Scala-style accessors and mutators.

In general, the principle goal of this effort must be improving the
clarity of the Lift API for both new adopters and for maintainers. We
now have two days before the goal discussion closes. If anyone has
any additional objectives they'd like to voice before this window
closes, please do so now. I'd like to hold a vote on the proposals
above as well as any other objectives folks may have tomorrow, so that
any -1's can be ironed out before the 15th.

Kris

--

You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.




Re: [Lift] New Lift release process wiki page

2009-12-10 Thread Kris Nuttycombe
Maybe I missed it, but it's probably desirable to tag the actual
release point as well as create a branch, isn't it?

Kris

On Thu, Dec 10, 2009 at 7:47 AM, Heiko Seeberger
heiko.seeber...@googlemail.com wrote:
 2009/12/10 David Pollak feeder.of.the.be...@gmail.com

 On Wed, Dec 9, 2009 at 11:30 PM, Heiko Seeberger
 heiko.seeber...@googlemail.com wrote:

 David,
 I do not understand the naming convention Lift_x_version. Is this
 something like Lift_x_2.0 or Lift_2.0 or ...?

 git checkout -b Lift_x_version

 Maybe it is possible to find a better symbol, e.g.
 Lift_MAJOR.MINOR[.MICRO][-QUALIFIER] with QUALIFIER something like
 M8? Anyway, could you please write up some examples in the Wiki?

 Lift-1.1-M8

 Ah, OK. Thank you.


 You're welcome (encouraged) to update the process.

 Sure!
 Did it:
 create a new branch for the release:
 Name it Lift-VERSION with VERSION = MAJOR.MINOR[.MICRO][-QUALIFIER],
 e.g. Lift-2.0-M8 or Lift-2.0.1

 git checkout -b Lift-VERSION

 Heiko
 My job: weiglewilczek.com
 My blog: heikoseeberger.name
 Follow me: twitter.com/hseeberger
 OSGi on Scala: scalamodules.org
 Lift, the simply functional web framework: liftweb.net

 --

 You received this message because you are subscribed to the Google Groups
 Lift group.
 To post to this group, send email to lift...@googlegroups.com.
 To unsubscribe from this group, send email to
 liftweb+unsubscr...@googlegroups.com.
 For more options, visit this group at
 http://groups.google.com/group/liftweb?hl=en.


--

You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.




Re: [Lift] New Lift release process wiki page

2009-12-10 Thread Kris Nuttycombe
Right, but the moment another commit goes on the branch you no longer can
see exactly where the release was cut from. Thus it's best to both branch
and tag. In git a branch is a mutable reference to a commit whereas a tag is
immutable. That way you can do bugfixes on the release branch and diff
against the tag to see what has changed, and regularly merge down to master.


On Dec 10, 2009 4:51 PM, David Pollak feeder.of.the.be...@gmail.com
wrote:



On Thu, Dec 10, 2009 at 3:45 PM, Kris Nuttycombe kris.nuttyco...@gmail.com
wrote:   Maybe I miss...

In Git, it's the same thing.  The creation of the branch is a marker at a
particular commit... the same as a tag.

The advantage is that you don't have the step of setting all the pom.xml
files from M8 back to SNAPSHOT


   Kris   On Thu, Dec 10, 2009 at 7:47 AM, Heiko Seeberger  
heiko.seeber...@googlemail.com ...


-- Lift, the simply functional web framework http://liftweb.net Beginning
Scala http://www.apress
You received this message because you are subscribed to the Google Groups
Lift group.

To post to this group, send email to lift...@googlegroups.com. To
unsubscribe from this group, send...

--

You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.




Re: [Lift] New Lift release process wiki page

2009-12-10 Thread Kris Nuttycombe
On Thu, Dec 10, 2009 at 9:26 PM, Indrajit Raychaudhuri
indraj...@gmail.com wrote:


 On 11/12/09 9:48 AM, Kris Nuttycombe wrote:
 Right, but the moment another commit goes on the branch you no longer
 can see exactly where the release was cut from. Thus it's best to both
 branch and tag. In git a branch is a mutable reference to a commit
 whereas a tag is immutable. That way you can do bugfixes on the release
 branch and diff against the tag to see what has changed, and regularly
 merge down to master.

 +1

 However, David has a valid point. We can let this M8 proceed the way
 it's going and take this up for subsequent releases.

 With some luck we can let maven-release-plugin handle some of these for
 us automatically too.

It's also not a big deal to correctly tag the release commit after the
fact, so we can do that whenever.

I've yet to get maven-release-plugin working properly with git, but
it's been a year or more since i've spent much time on it so perhaps
things have improved since then.

In any case, I've added the tagging step to the wiki after the
verification that the release has proceeded correctly.

Kris

--

You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.




Re: [Lift] Open discussion on Lift Name Calling practices

2009-12-09 Thread Kris Nuttycombe
On Tue, Dec 1, 2009 at 1:43 PM, Jim Barrows jim.barr...@gmail.com wrote:
 Lift is getting very large.  We've got singular names as lists, and plural
 names that aren't lists.  We've got people calling roses red flowers, spades
 diamonds and other mass chaos.  Well, it's not that bad, but you get the
 idea.  This is an attempt to come up with a series of standard names to make
 working in lift easier, not only for the committers, but also (and more
 importantly) for you folks using it on a day to day basis.

 Achieving this means that there must be two things, a set of rules for
 naming conventions, and a process to make sure everyone is following those
 rules, and changing things when we mess it up.

 This thread is for discussing the process.  I'll be starting another thread
 to discuss the rules, as well as another thread to discuss current names
 that we want to change.
 As always, if you don't speak up, you're not dissenting, and we welcome your
 views and ideas on how to do this!

 1) Goal discussion (closes 8 Dec 09)
 2) Identify changes, and put the list on the wiki (closes 15 Jan 10)
 3) Convert the list to github tickets.  This includes discussing setting
 priorities etc, assessing impacts etc etc to go into the ticket. (closes 29
 Jan 10)
 4) Committers can then work the tickets into their own workflows, and
 everything would then follow the normal commit workflow from there.
 (committers work according to priority and impact etc)
 5) Naming becomes a part of the normal review board process.  However, if a
 committer thinks that the Name Caller needs to look at it earlier, or is
 having a hard time with naming something, by all means send an email.  (
 date we add this to the process 29 Jan 10)
 6) As we find things we missed, or better names, we work them through the
 github ticket and review system. ( date we add this to the process 29 Jan
 10)

 --
 James A Barrows

The timeline looks good to me, with the exception of the fact that
we've already passed the first milestone!

With respect to goals, I have a few general suggestions.

1) Remove ambiguity wherever possible! There are a number of places
where very similar names are used to refer to utterly different
things.
2) As an aide removing ambiguity, consider outlawing or eliminating
extremely generic names, or else establish a single way in which a
given name will be used across Lift. Examples are Field, Info, Holder,
etc.
3) Avoid making the name of the return type part of the name of the
method. The types should tell the story as much as possible, except in
the case where multiple methods varying only in return type would
exist (illegal overloads)
4) Prefer Scala-style accessors and mutators.

I also am attaching a start at some names I see as suboptimal from
S.scala, but since this thread isn't really for discussion of
individual naming issues (and such a thread doesn't yet exist) I
thought I'd go ahead and present my suggestions as a strawman for
format and what type of changes might be considered.

Kris

--

You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.


module: lift-util 
file: src/main/scala/net/liftweb/util/JsonCmd.scala
ResponseInfoHolder = ResponseMetadata

module: lift-webkit 
file: src/main/scala/net/liftweb/http/S.scala
RewriteHolder = NamedRewrite
DispatchHolder = NamedDispatch
CookieHolder = Cookies
(\w+)HighLevelSessionDispatcher = \1SessionDispatcher (No LowLevel???)
? = % or $ (printf, jsp - what's the inspiration for ? as 
localization/formatting?)
(\w+)_? = is\1 (underscore is used for enough things in Scala, let's not make 
method names harder to read)
getHeader = getResponseHeader
getDocType = docType (change return type from tuple to case class with 
sematically significant names?)
setDocType = docType_=
addCleanupFunc = onCleanup
functionLifespan_= parameter type Boolean = Lifespan (sealed trait Lifespan; 
case object Session extends Lifespan; case object Request extends Lifespan)
functionLifespan_? = functionLifespan
attrs = snippetAttrs; return type should be something more informative than 
List[(Either[String, (String, String)], String)] 
prefixedAttrsToMap = snippetAttrMap 
prefixedAttrsToMetadata = snippetAttrMetadata
mapToAttrs: Move to one of the util classes? No state dependencies in this 
one...

getSessionAttribute(s: String) = containerSessionAttribute (to avoid confusion 
with LiftSession) where containerSessionAttribute is a local object as defined 
below
setSessionAttribute(s: String, v: String) = containerSessionAttribute(s: 
String) = v; see below
object containerSessionAttribute {
  def apply(name: String) = containerSession.flatMap(_.attribute(name) match 
{case s: String = Full(s) case _ = Empty})
  def update(name: String, 

Re: [Lift] JRebel: implements new interfaces and could not be reloaded!

2009-11-19 Thread Kris Nuttycombe
Unfortunately, JRebel is sensitive to certain kinds of changes;
changes to the names of the generated classes for function literals is
one of them. In this case, since you've got two function literals in
the class, their names are something$1 and something$2 or equivalent.
After commenting out the line, the second one is now something$1,
which has a totally different interface.

You can work around it if you really want to, but it's probably easier
(or at least prettier code) to just restart the server.

Also, just stylistically, that commented line could be:

  //.sort(_.name.toString  _.name.toString)

Kris

On Thu, Nov 19, 2009 at 4:56 PM, Alex Black a...@alexblack.ca wrote:
 Anyone got any tips on working around this error?

 JRebel: Class 'com.blah.blah.explorer.snippet.Features$$anonfun$render
 $1' implements new interfaces and could not be reloaded!

 I've just tried JRebel for the first time, and I made what I thought
 was a minor change to my snippet and JRebel wasn't able to reload it.

 The change I made was to uncomment the sort line in this snippet:

 class Features {
  def render( xhtml: NodeSeq) : NodeSeq = {
    Server.store
      .classes
      //.sort( (c1,c2) = c1.name.toString  c2.name.toString)
      .flatMap( c =
      bind(feature, xhtml,
        name - c.name
      )
    )
  }
 }

 Thanks,

 - Alex

 --

 You received this message because you are subscribed to the Google Groups 
 Lift group.
 To post to this group, send email to lift...@googlegroups.com.
 To unsubscribe from this group, send email to 
 liftweb+unsubscr...@googlegroups.com.
 For more options, visit this group at 
 http://groups.google.com/group/liftweb?hl=.




--

You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=.




Re: [Lift] A sensible AJAX approach

2009-11-19 Thread Kris Nuttycombe
On Thu, Nov 19, 2009 at 2:52 PM, Chris Lewis burningodzi...@gmail.com wrote:
 Classic use case: a user chooses to view/edit and object by clicking on
 a link. This causes the app to fetch an edit view (form) and render it
 asynchronously, probably rendering it as a modal dialog. To specify the
 case a bit more, consider a table of like objects that allows you to
 edit them (orders or accounts). As far as the user experience, clicking
 edit for one would yield the same edit form as any other - only the
 contents (the target of the edit) would change.

 Normal ajax forms in lift are simple - just wrap the bind in an ajax
 form (http://is.gd/4Z61Z) and you get an async submit with essentially
 the same template code.

 But what about ajax forms delivered by ajax? What's the best way to
 implement this in lift? It seems like there are two routes: client and
 server-based.


 1) In the client-based approach, I can declare an invisible form in the
 template, as well as write some static javascript to do the heavy
 lifting (no pun intended). This JS would be responsible for receiving
 the data representing the object to edit from the server as json,
 unpacking it into the form for editing, rendering the form, handling the
 submit as ajax, and finally hiding the form.

 This means writing a good bit more JS by hand, but it keeps the
 (compiled) snippet code smaller. Ordinarily I'd see that as good, but
 more and more snippets seem like they are intended for such heavy view
 meddling.


 2) The server-based approach would require very little of the main
 template: basically just a containing element (w/ dom id) to host the
 delivered form. The snippet itself would yield a form on an ajax call
 via SetHtml. It would also have to set up the handlers and populate the
 form contents with the target object.

 This is the part that I'm not clear on. I know I can just inline the XML
 with bind points as if it were in a form, but that just feels strange.
 Would it make more sense to use an external template, similar to a rails
 partial? Is there a template loading facility for this?

 Thanks for any and all input.

 chris

I use the second style, to great effect, in Lift - except I use
net.liftweb.http.TemplateFinder.findAnyTemplate to get the NodeSeq
representing the template instead of inlining the XML, and then use a
normal call to bind. It works a treat.

There are a couple of utility traits that I use to make this even
cleaner; I don't have time to detail how they're used at the moment
but maybe you can get a little bit of an idea by looking at the types.
One of these days I'll clean these up into something truly reusable
(these rely on the bindings stuff I detailed on my blog at
http://logji.blogspot.com/2009/09/composable-bindings-in-lift.html
with a couple of extra things, tbind and the Templated trait.

def tbind(x: Binding with Templated): NodeSeq = x.bind(x.template)

trait Templated {
def template: List[String]
}

trait Form[T] {
def onSubmit: Unit = process
def process: T
}

trait FormSnippets {
this: StatefulSnippet =

var actionBinding: Binding with Templated = _
var editFormBinding: Binding with Templated = _

lazy val dispatch: DispatchIt = {
case actionSelect = actionBinding
case editForm = editFormBinding
}

def ajaxify(b: Binding with Templated with Form[_],
clientOnSubmit: JsCmd, serverRedirect: Option[String]) = new Binding
with Templated {
override val template = b.template
override def apply(xhtml: NodeSeq): NodeSeq = {
def serverOnSubmit: JsCmd = {
b.onSubmit

serverRedirect.map(where = RedirectTo(where)).
getOrElse(SetHtml(action_selector,
tbind(actionBinding))  SetHtml(edit_form, tbind(editFormBinding)))
}

ajaxForm(b.apply(xhtml) ++ hidden(serverOnSubmit _), clientOnSubmit)
}
}
}

Kris

--

You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=.




Re: [Lift] odd ajax issue (works every other time)

2009-11-18 Thread Kris Nuttycombe
I've got a few other things that I have to take care of today, but if
I can get those out of the way I will run a git bisect, compiling 
running with your test project to see if I can at least figure out the
commit that introduced the error. I've been wanting to learn about
bisect anyway. :)

Kris

On Wed, Nov 18, 2009 at 7:26 AM, David Pollak
feeder.of.the.be...@gmail.com wrote:


 On Tue, Nov 17, 2009 at 10:33 PM, David Pollak
 feeder.of.the.be...@gmail.com wrote:

 I am able to reproduce the problem with a simple Ajax control.

 It's very, very odd.  It seems to be an intermittent failure of the
 servlet container to find the HttpServletSession.  The client is presenting
 the cookie correctly, but Jetty is not recognizing it.

 For some reason, even though the browser sends the right cookies, Jetty is
 not recognizing them.  This is pretty easy to reproduce with Firefox, but I
 haven't seen it with Chrome.

 I'm enclosing a simple version of the project I used for testing... just
 keep pressing on the button and eventually the page will reload (indicating
 that the session was lost) or the counter will stop counting (same
 indication).

 I'm out of pocket for most of today (I might be on email just a little).

 This is a super ultra mega high priority in my book.  If Marius or Tim or
 Derek or any of the other Lift committers could shake loose time to look at
 this one, I'd really appreciate it... and Kris thanks for the time/effort
 you've put into this.  Please keep plugging.

 Thanks,

 David


 On Tue, Nov 17, 2009 at 4:10 PM, Kris Nuttycombe
 kris.nuttyco...@gmail.com wrote:

 I am able to duplicate this error. I was concerned that it might be
 the result of my Loc changes, so I just rebuilt Lift without the
 patches associated with that change and reproduced the problem again.

 Here are the conditions under which I'm able to reproduce the failure:

 1) load a page where the snippets are managed by a StatefulSnippet
 2) some page elements (in my case select boxes) have their values
 update by AJAX in response to user events. This appears to work
 normally.
 3) upon submission of the form on the page, the page is re-rendered.
 Logging in the submission function indicates that it is never called.
 4) if I fill in the form again and resubmit after the initial failure,
 the form submit behaves properly.
 5) I believe I've seen at least one instance (though I can't reliably
 reproduce this) where just a normal AJAX call (modifying one of the
 select boxes) caused the entire page to reload.

 Kris

 Kris

 On Tue, Nov 17, 2009 at 4:07 PM, O'Rorke Paul p...@ororke.com wrote:
  Not in a place where I can really debug this right now but I'm curious
  whether anybody else has seen this and knows the solution...
 
  since rebuilding a day or two ago with no recent code or other changes:
  every second time I go to click on an ajax checkbox or select widget,
  I get effectively no response.
  actually, it looks like there is a very quick spinning wheel (almost
  imperceptible) but the page doesn't  get  repainted and the database
  does not change.
  If  I use another operation that is non ajax (going in and editing an
  item and doing old fashioned get / posts) everything works fine after
  that (one time).
  Or if I reload the page then if I use an ajax widget after reloading
  ajax works (once).
 
  This is with 2.7.5 Scala and Lift 1.1-SNAPSHOT.
 
  Perhaps not coincidentally, I am getting Multiple versions of scala
  libraries detected! warnings and have not yet figured out how to get
  rid of them.
  I don't see another version of Scala in my pom or eclipse maven
  dependency graph and have been going around nuking old copies of scala
  but to no avail as yet.
 
  Another odd thing that is now happening is that when I shutdown with a
  control C in the terminal window, I get the following error:
 
  INFO - Service request (GET) /ajax_request/liftAjax.js took 2
  Milliseconds
  ^C2009-11-16 15:29:01.634::INFO:  Shutdown hook executing
  2009-11-16 15:29:02.249::INFO:  Shutdown hook complete
  [INFO] Jetty server exiting.
  [INFO]
 
  
  [INFO] BUILD SUCCESSFUL
  [INFO]
 
  
  [INFO] Total time: 33 minutes 4 seconds
  [INFO] Finished at: Mon Nov 16 15:29:02 PST 2009
  [INFO] Final Memory: 23M/257M
  [INFO]
 
  
  ERROR - Couldn't start SessionMaster ping
  net.liftweb.util.ActorPingException: net.liftweb.http.SessionMaster
  $checkandpur...@1cab4a5 could not be scheduled on
  net.liftweb.http.sessionmast...@119c2af
        at net.liftweb.util.ActorPing$.schedule(ActorPing.scala:54)
        at
  net.liftweb.http.SessionMaster$.net$liftweb$http$SessionMaster$
  $doPing(LiftSession.scala:187)
        at net.liftweb.http.SessionMaster$$anonfun$1.apply
  (LiftSession.scala:169

Re: [Lift] Re: Missing source files in 1.1-SNAPSHOT

2009-11-18 Thread Kris Nuttycombe
On Wed, Nov 18, 2009 at 12:31 PM, glenn gl...@exmbly.com wrote:
 Kris,

 Don't want to clone the GitHub repo, as I need a Maven repo.

 Glenn


Out of curiosity, is this because you have a Maven tool that helps
automate interaction with a debugger? If so I'd be interested in
learning about it - I've got a Lift bug I'm looking at now that would
probably benefit from using an actual debugger on.

Kris

 On Nov 18, 11:19 am, Indrajit Raychaudhuri indraj...@gmail.com
 wrote:
 Still, something looks wrong:

 http://scala-tools.org/repo-releases/net/liftweb/lift-webkit/1.1-M7/l...
 has the .scala sources

 buthttp://scala-tools.org/repo-snapshots/net/liftweb/lift-webkit/1.1-SNA...
 doesn't.

 - Indrajit

 On 19/11/09 12:32 AM, Kris Nuttycombe wrote:

  I recommend cloning dpp's github repository:http://github.com/dpp/liftweb

  Kris

  On Wed, Nov 18, 2009 at 11:41 AM, glenngl...@exmbly.com  wrote:
  Where are all the java source files in
 http://scala-tools.org/repo-snapshots/net/liftweb/lift-webkit/1.1-SNA...

  It's kind of hard to debug without them.

  Glenn

  --

  You received this message because you are subscribed to the Google Groups 
  Lift group.
  To post to this group, send email to lift...@googlegroups.com.
  To unsubscribe from this group, send email to 
  liftweb+unsubscr...@googlegroups.com.
  For more options, visit this group 
  athttp://groups.google.com/group/liftweb?hl=en.

  --

  You received this message because you are subscribed to the Google Groups 
  Lift group.
  To post to this group, send email to lift...@googlegroups.com.
  To unsubscribe from this group, send email to 
  liftweb+unsubscr...@googlegroups.com.
  For more options, visit this group 
  athttp://groups.google.com/group/liftweb?hl=en.

 --

 You received this message because you are subscribed to the Google Groups 
 Lift group.
 To post to this group, send email to lift...@googlegroups.com.
 To unsubscribe from this group, send email to 
 liftweb+unsubscr...@googlegroups.com.
 For more options, visit this group at 
 http://groups.google.com/group/liftweb?hl=en.




--

You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.




Re: [Lift] Re: Missing source files in 1.1-SNAPSHOT

2009-11-18 Thread Kris Nuttycombe
On Wed, Nov 18, 2009 at 1:51 PM, Jeppe Nejsum Madsen je...@ingolfs.dk wrote:
 Kris Nuttycombe kris.nuttyco...@gmail.com writes:

 On Wed, Nov 18, 2009 at 12:31 PM, glenn gl...@exmbly.com wrote:
 Kris,

 Don't want to clone the GitHub repo, as I need a Maven repo.

 Glenn


 Out of curiosity, is this because you have a Maven tool that helps
 automate interaction with a debugger? If so I'd be interested in
 learning about it - I've got a Lift bug I'm looking at now that would
 probably benefit from using an actual debugger on.

 If you use Eclipse, it can automatically get the sourc files from the
 sources jar. Open Type - Select e.g. Box - You get the Box.scala
 file. It is readonly though, so you can't easily try a quick hack

 /Jeppe

Eclipse required? println debugging it is then!

:)


 --

 You received this message because you are subscribed to the Google Groups 
 Lift group.
 To post to this group, send email to lift...@googlegroups.com.
 To unsubscribe from this group, send email to 
 liftweb+unsubscr...@googlegroups.com.
 For more options, visit this group at 
 http://groups.google.com/group/liftweb?hl=en.




--

You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.




Re: [Lift] Re: *** BREAKING CHANGES *** to Loc LocParam

2009-11-17 Thread Kris Nuttycombe
On Tue, Nov 17, 2009 at 7:37 AM, Jeppe Nejsum Madsen je...@ingolfs.dk wrote:
 On Nov 17, 12:11 am, David Pollak feeder.of.the.be...@gmail.com
 wrote:
 On Mon, Nov 16, 2009 at 3:10 PM, Kris Nuttycombe
 kris.nuttyco...@gmail.comwrote:





  On Mon, Nov 16, 2009 at 4:02 PM, David Pollak
  feeder.of.the.be...@gmail.com wrote:

   On Mon, Nov 16, 2009 at 2:20 PM, Kris Nuttycombe 
  kris.nuttyco...@gmail.com
   wrote:

   On Mon, Nov 16, 2009 at 3:13 PM, David Pollak
   feeder.of.the.be...@gmail.com wrote:

On Mon, Nov 16, 2009 at 2:12 PM, Kris Nuttycombe
kris.nuttyco...@gmail.com
wrote:

Hi, all,

I was just informed that my changes broke MetaMegaProtoUser
interaction. I've reverted the commit until I can get that sorted
  out.

How was it broken?

   It's something to do with how the login form is processed - at the
   moment I haven't figured out anything more with that. Essentially, the
   login fails silently and returns the user to the login form upon
   submission.

   That sounds like a deeper issue with MetaProtoUser.  I'd keep your
  changes
   and see why MegaProtoUser is failing.

  Absolutely; I just figured I didn't want to leave people with broken
  code while I figure it out since I'm not that familiar with
  MegaProtoUser and am not sure how long that will take.

 Please check the code back in and get me a test case and I'll debug it.

 I've got about 20 tickets I'm working on right now... one more ain't gonna
 kill me. ;-)

 Did this ever get resolved? I'm still seeing this after an update to
 latest. This is pretty major, so I looked into it and found this:

 1) The Template LocParam defined on loginMenuLoc is never called on
 form post, so the login method is never called during post. I assume
 this worked before?
 2) If I change the bind for login to include a function that calls
 login on submit, the login process works

 Not sure what the correct semantics are wrt 1) abovebut something
 definately seem to have changed...

 /Jeppe

I just noticed that David committed a fix. Thanks, David!

Kris

--

You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=.




Re: [Lift] Re: replay prevention tokens

2009-11-17 Thread Kris Nuttycombe
On Tue, Nov 17, 2009 at 7:25 AM, David Pollak
feeder.of.the.be...@gmail.com wrote:
 The problem was related to some of the recent changes to SiteMap... there
 was a lazy var that should have been a def... so particular user-supplied
 functions were called only once.

 I've checked in a fix to this issue and it's being built right now:
 http://hudson.scala-tools.org/job/Lift/1409/

 If you continue to have issue, I'll be back online at ~ 8:30am PST (gotta
 get the kids to school).  I can cycle with if there are any more failing use
 cases.

 Sorry for the inconvenience.

Yikes, I wasn't expecting the dependencies on that side effect. Okay,
lesson learned. :P

Thanks for sorting that out for me. I apologize for the inconvenience.

Kris

 On Tue, Nov 17, 2009 at 5:45 AM, opyate opy...@gmail.com wrote:

 Thanks Indrajit.

 It could have very well been a code change introduced in the past day
 or so, because I reverted my POM to 1.1-M7 (from 1.1-SNAPSHOT) and all
 is fine now.

 The only override I have in my User companion object is:

 --START--

 override def logUserIn(who: User) {
    super.logUserIn(who)
    loadcert(S.param(password).open_!)
  }

  private def loadcert(pw: String) = {
    import _root_.com.opyate.ken.util.crypto._

    User.currentUser.map({user =
      User.currentUser.open_!.securityModuleVar.is match {
        case Full(s) if s.isInitialised = {
          S.notice(Your private key was successfully initialised.)
        }
        case Empty = {
          try {
            val certPath = System.getProperty(certs)
            Log.debug(Loading certs from specified path  + certPath)
            // Since DBEntries need crypto functionality, it can be
 argued that the error
            // should occur here.
            if (certPath == null) {
              val err = Certs path not defined. Please define system
 property -Dcerts=/path/to/certs
              Log.error(err)
              S.error(err)
              S.redirectTo(/)
            } else {
              Log.debug(certs path is  + certPath)
            }

            val sec = new Security()
            sec.setCryptoUtil(new CryptoUtil())
            val keyUtil = new KeyUtil()
            keyUtil.setPrivateKeyFile(certPath + / +
 User.currentUser.open_!.email.toString);
            keyUtil.setPrivateKeyPassword(pw);
            keyUtil.setPublicKeyFile(certPath + /x509.key);
            sec.setKeyUtil(keyUtil)
            User.currentUser.open_!.securityModuleVar(Full(sec))

            // quick test
            {
              val sUnenc = unencrypted text
              val sEnc = sec.encrypt(sUnenc)
              val sDec = sec.decrypt(sEnc)
              assert(sDec == sUnenc)
            }

            S.notice(Your private key was successfully initialised.)
          } catch {
            case e = {

              S.warning(There was a problem initialising your private
 key:  + e.getMessage)
            }
          }
        }
        case _ = {
          S.warning(There was a problem initialising your private
 key.)
        }
      }
    }) openOr S.warning(There was a problem initialising your private
 key.)
  }

 --END--

 This code is a work in progress, and uses the password from the login
 form to initialise the user's private key (for decrypting sensitive
 stuff later on).

 I would love to help find the problem, but I have a showcase tomorrow
 (this is it!), so perhaps after.

 Thanks,
 Juan

 On Nov 17, 12:26 pm, Indrajit Raychaudhuri indraj...@gmail.com
 wrote:
  See formFuncName in net/liftweb/http/S.scala (lift-webkit).
 
  Cheers, Indrajit
 
  On 17/11/09 5:25 PM, opyate wrote:
 
 
 
   Hello Lifters,
 
   Could someone please point out which part of the Lift code takes care
   of generating unique names for form elements? (I'll delve in in the
   interim)
 
   I'm bleeding edge at the moment (1.1-SNAPSHOT and mvn -U clean
   always) and since about an hour ago my login form doesn't render with
   new tokens, and subsequent login attempts are ignored.
 
   I am overriding a few of the login methods in ProtoUser and want to
   investigate if I'm breaking anything.
 
   Thanks,
   Juan
 
   --
 
   You received this message because you are subscribed to the Google
   Groups Lift group.
   To post to this group, send email to lift...@googlegroups.com.
   To unsubscribe from this group, send email to
   liftweb+unsubscr...@googlegroups.com.
   For more options, visit this group
   athttp://groups.google.com/group/liftweb?hl=.

 --

 You received this message because you are subscribed to the Google Groups
 Lift group.
 To post to this group, send email to lift...@googlegroups.com.
 To unsubscribe from this group, send email to
 liftweb+unsubscr...@googlegroups.com.
 For more options, visit this group at
 http://groups.google.com/group/liftweb?hl=.





 --
 Lift, the simply functional web framework http://liftweb.net
 Beginning Scala http://www.apress.com/book/view/1430219890
 Follow me: http://twitter.com/dpp
 Surf the 

Re: [Lift] Re: Lots of compile-time cruft

2009-11-17 Thread Kris Nuttycombe
Very nice!

On Tue, Nov 17, 2009 at 10:16 AM, David Pollak
feeder.of.the.be...@gmail.com wrote:
 Okay, there's a simple answer that satisfies everyone:

 case class ParamCalcInfo(paramNames: List[String],
     params: Map[String, List[String]],
     uploadedFiles: List[FileParamHolder],
     body: Box[Array[Byte]])


   lazy val ParamCalcInfo(paramNames: List[String],
     params: Map[String, List[String]],
     uploadedFiles: List[FileParamHolder],
     body: Box[Array[Byte]]) = paramCalculator()

 No type erasure issues because the case class defines the types.  Optional
 (and in my opinion, necessary for at the very least documentation purposes)
 type declarations on the variables.  Better compiler enforcement than
 tuples.

 On Mon, Nov 16, 2009 at 10:30 PM, Kris Nuttycombe
 kris.nuttyco...@gmail.com wrote:

 On Mon, Nov 16, 2009 at 11:13 PM, David Pollak
 feeder.of.the.be...@gmail.com wrote:
 
 
  On Mon, Nov 16, 2009 at 5:01 PM, Alex Boisvert alex.boisv...@gmail.com
  wrote:
 
  On Mon, Nov 16, 2009 at 4:26 PM, David Pollak
  feeder.of.the.be...@gmail.com wrote:
 
  Speaking of warnings, which do you prefer (see patch below):
 
  1) Explicit types on val extractors (as it is today)
  2) One-liner with no types (proposed)
 
  We could save 4 warnings...
 
  Here's the cost of the 4 warnings:
 
  If you remove the type information and the lazy calculator thing
  changes
  how it does calculations, you'll silently get changed types (this has
  happened before) and that breaks things.  On the other hand, if we
  leave the
  code with explicit types, we'll get a match warning (with the type
  erasure
  stuff turned back off) if the type change.
 
  You get breakage if the types change in an incompatible manner in both
  cases.
 
  I don't see how you get any added safety by adding the types
  explicitly.
 
  You get type-safety in downstream code... the code that is accessing the
  variables.  You also avoid type inferencer problems.  The type
  inferencer
  doesn't always give you what you expect (it's not like Haskell).  Being
  explicit about what you expect is going to insure that the compiler does
  the
  right thing, even if it issues a spurious warning.
 
  So, why am I harping on this?

 The thing is, the compiler really *doesn't* do the right thing if you
 supply the types. In fact, it will do the wrong thing if you change
 the upstream code more frequently than it will do the right thing.

 Case in point: this compiles without complaint:

 object Test {
    class A
    class B extends A

    val (a: A, b: B) = (new A, new A);
 }

 It will fail at runtime with a MatchError or ClassCastException or
 something equally nasty. If the types were not annotated, then the
 downstream code would fail to compile.

 Kris

  (1) This code was stuff I worked on to get right back in 2007.  It's
  stable
  and despite the aesthetic displeasure of a spurious warning, it does not
  need to change.
  (2) This code reflects a lot of work getting it right with the Scala
  compiler back when the Scala compiler was less stable.  I know the code
  currently works and I don't remember what kind of weirdness other
  variations
  on the code caused, but I don't want to find out if there are latent
  issues
  with the Scala compiler.
  (3) From a priority standpoint, this is suboptimal.  It's suboptimal for
  me
  to have to sell you on why it should not be changed.  It is suboptimal
  because there are open tickets for some real issues that real users need
  addressed.  If your bent is more oriented to getting to know the code,
  there's plenty of ScalaDocs and higher level documentation to write.
  (4) from a readibility standpoint, I like the code the way it is and
  it's
  most likely that if there's a problem or enhancement in that part of the
  code, it's me or Marius that're going to be fixing it.
 
 
 
 
  In both cases, the compiler has the same information about the types
  and
  perform the same amount of type checking for you.
 
 
 
 
  alex
 
  --
 
  You received this message because you are subscribed to the Google
  Groups
  Lift group.
  To post to this group, send email to lift...@googlegroups.com.
  To unsubscribe from this group, send email to
  liftweb+unsubscr...@googlegroups.com.
  For more options, visit this group at
  http://groups.google.com/group/liftweb?hl=.
 
 
 
  --
  Lift, the simply functional web framework http://liftweb.net
  Beginning Scala http://www.apress.com/book/view/1430219890
  Follow me: http://twitter.com/dpp
  Surf the harmonics
 
  --
 
  You received this message because you are subscribed to the Google
  Groups
  Lift group.
  To post to this group, send email to lift...@googlegroups.com.
  To unsubscribe from this group, send email to
  liftweb+unsubscr...@googlegroups.com.
  For more options, visit this group at
  http://groups.google.com/group/liftweb?hl=.
 

 --

 You received this message because you are subscribed

Re: [Lift] odd ajax issue (works every other time)

2009-11-17 Thread Kris Nuttycombe
I am able to duplicate this error. I was concerned that it might be
the result of my Loc changes, so I just rebuilt Lift without the
patches associated with that change and reproduced the problem again.

Here are the conditions under which I'm able to reproduce the failure:

1) load a page where the snippets are managed by a StatefulSnippet
2) some page elements (in my case select boxes) have their values
update by AJAX in response to user events. This appears to work
normally.
3) upon submission of the form on the page, the page is re-rendered.
Logging in the submission function indicates that it is never called.
4) if I fill in the form again and resubmit after the initial failure,
the form submit behaves properly.
5) I believe I've seen at least one instance (though I can't reliably
reproduce this) where just a normal AJAX call (modifying one of the
select boxes) caused the entire page to reload.

Kris

Kris

On Tue, Nov 17, 2009 at 4:07 PM, O'Rorke Paul p...@ororke.com wrote:
 Not in a place where I can really debug this right now but I'm curious
 whether anybody else has seen this and knows the solution...

 since rebuilding a day or two ago with no recent code or other changes:
 every second time I go to click on an ajax checkbox or select widget,
 I get effectively no response.
 actually, it looks like there is a very quick spinning wheel (almost
 imperceptible) but the page doesn't  get  repainted and the database
 does not change.
 If  I use another operation that is non ajax (going in and editing an
 item and doing old fashioned get / posts) everything works fine after
 that (one time).
 Or if I reload the page then if I use an ajax widget after reloading
 ajax works (once).

 This is with 2.7.5 Scala and Lift 1.1-SNAPSHOT.

 Perhaps not coincidentally, I am getting Multiple versions of scala
 libraries detected! warnings and have not yet figured out how to get
 rid of them.
 I don't see another version of Scala in my pom or eclipse maven
 dependency graph and have been going around nuking old copies of scala
 but to no avail as yet.

 Another odd thing that is now happening is that when I shutdown with a
 control C in the terminal window, I get the following error:

 INFO - Service request (GET) /ajax_request/liftAjax.js took 2
 Milliseconds
 ^C2009-11-16 15:29:01.634::INFO:  Shutdown hook executing
 2009-11-16 15:29:02.249::INFO:  Shutdown hook complete
 [INFO] Jetty server exiting.
 [INFO]
 
 [INFO] BUILD SUCCESSFUL
 [INFO]
 
 [INFO] Total time: 33 minutes 4 seconds
 [INFO] Finished at: Mon Nov 16 15:29:02 PST 2009
 [INFO] Final Memory: 23M/257M
 [INFO]
 
 ERROR - Couldn't start SessionMaster ping
 net.liftweb.util.ActorPingException: net.liftweb.http.SessionMaster
 $checkandpur...@1cab4a5 could not be scheduled on
 net.liftweb.http.sessionmast...@119c2af
       at net.liftweb.util.ActorPing$.schedule(ActorPing.scala:54)
       at net.liftweb.http.SessionMaster$.net$liftweb$http$SessionMaster$
 $doPing(LiftSession.scala:187)
       at net.liftweb.http.SessionMaster$$anonfun$1.apply
 (LiftSession.scala:169)
       at net.liftweb.http.SessionMaster$$anonfun$1.apply
 (LiftSession.scala:135)
       at net.liftweb.actor.LiftActor$class.execTranslate(LiftActor.scala:
 247)
       at net.liftweb.http.SessionMaster$.execTranslate(LiftSession.scala:
 91)
       at net.liftweb.actor.SpecializedLiftActor$class.net$liftweb$actor
 $SpecializedLiftActor$$processMailbox(LiftActor.scala:142)
       at net.liftweb.actor.SpecializedLiftActor$$anonfun$3$$anonfun$apply
 $1.apply(LiftActor.scala:109)
       at net.liftweb.actor.SpecializedLiftActor$$anonfun$3$$anonfun$apply
 $1.apply(LiftActor.scala:109)
       at net.liftweb.actor.LAScheduler$$anonfun$1$$anon$1$$anon$2.run
 (LiftActor.scala:37)
       at java.util.concurrent.ThreadPoolExecutor$Worker.runTask
 (ThreadPoolExecutor.java:886)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run
 (ThreadPoolExecutor.java:908)
       at java.lang.Thread.run(Thread.java:637)
 Caused by: java.util.concurrent.RejectedExecutionException
       at java.util.concurrent.ThreadPoolExecutor
 $AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:1760)
       at java.util.concurrent.ThreadPoolExecutor.reject
 (ThreadPoolExecutor.java:767)
       at java.util.concurrent.ScheduledThreadPoolExecutor.delayedExecute
 (ScheduledThreadPoolExecutor.java:216)
       at java.util.concurrent.ScheduledThreadPoolExecutor.schedule
 (ScheduledThreadPoolExecutor.java:379)
       at java.util.concurrent.Executors
 $DelegatedScheduledExecutorService.schedule(Executors.java:654)
       at net.liftweb.util.ActorPing$.schedule(ActorPing.scala:52)
       ... 12 more


 Ideas / Suggestions for any of these issues (perhaps they are
 related?) most welcome!
 ---Paul O




 --

 You 

Re: [Lift] odd ajax issue (works every other time)

2009-11-17 Thread Kris Nuttycombe
Added as ticket #198

Kris

On Tue, Nov 17, 2009 at 5:10 PM, Kris Nuttycombe
kris.nuttyco...@gmail.com wrote:
 I am able to duplicate this error. I was concerned that it might be
 the result of my Loc changes, so I just rebuilt Lift without the
 patches associated with that change and reproduced the problem again.

 Here are the conditions under which I'm able to reproduce the failure:

 1) load a page where the snippets are managed by a StatefulSnippet
 2) some page elements (in my case select boxes) have their values
 update by AJAX in response to user events. This appears to work
 normally.
 3) upon submission of the form on the page, the page is re-rendered.
 Logging in the submission function indicates that it is never called.
 4) if I fill in the form again and resubmit after the initial failure,
 the form submit behaves properly.
 5) I believe I've seen at least one instance (though I can't reliably
 reproduce this) where just a normal AJAX call (modifying one of the
 select boxes) caused the entire page to reload.

 Kris

 Kris

 On Tue, Nov 17, 2009 at 4:07 PM, O'Rorke Paul p...@ororke.com wrote:
 Not in a place where I can really debug this right now but I'm curious
 whether anybody else has seen this and knows the solution...

 since rebuilding a day or two ago with no recent code or other changes:
 every second time I go to click on an ajax checkbox or select widget,
 I get effectively no response.
 actually, it looks like there is a very quick spinning wheel (almost
 imperceptible) but the page doesn't  get  repainted and the database
 does not change.
 If  I use another operation that is non ajax (going in and editing an
 item and doing old fashioned get / posts) everything works fine after
 that (one time).
 Or if I reload the page then if I use an ajax widget after reloading
 ajax works (once).

 This is with 2.7.5 Scala and Lift 1.1-SNAPSHOT.

 Perhaps not coincidentally, I am getting Multiple versions of scala
 libraries detected! warnings and have not yet figured out how to get
 rid of them.
 I don't see another version of Scala in my pom or eclipse maven
 dependency graph and have been going around nuking old copies of scala
 but to no avail as yet.

 Another odd thing that is now happening is that when I shutdown with a
 control C in the terminal window, I get the following error:

 INFO - Service request (GET) /ajax_request/liftAjax.js took 2
 Milliseconds
 ^C2009-11-16 15:29:01.634::INFO:  Shutdown hook executing
 2009-11-16 15:29:02.249::INFO:  Shutdown hook complete
 [INFO] Jetty server exiting.
 [INFO]
 
 [INFO] BUILD SUCCESSFUL
 [INFO]
 
 [INFO] Total time: 33 minutes 4 seconds
 [INFO] Finished at: Mon Nov 16 15:29:02 PST 2009
 [INFO] Final Memory: 23M/257M
 [INFO]
 
 ERROR - Couldn't start SessionMaster ping
 net.liftweb.util.ActorPingException: net.liftweb.http.SessionMaster
 $checkandpur...@1cab4a5 could not be scheduled on
 net.liftweb.http.sessionmast...@119c2af
       at net.liftweb.util.ActorPing$.schedule(ActorPing.scala:54)
       at net.liftweb.http.SessionMaster$.net$liftweb$http$SessionMaster$
 $doPing(LiftSession.scala:187)
       at net.liftweb.http.SessionMaster$$anonfun$1.apply
 (LiftSession.scala:169)
       at net.liftweb.http.SessionMaster$$anonfun$1.apply
 (LiftSession.scala:135)
       at net.liftweb.actor.LiftActor$class.execTranslate(LiftActor.scala:
 247)
       at net.liftweb.http.SessionMaster$.execTranslate(LiftSession.scala:
 91)
       at net.liftweb.actor.SpecializedLiftActor$class.net$liftweb$actor
 $SpecializedLiftActor$$processMailbox(LiftActor.scala:142)
       at net.liftweb.actor.SpecializedLiftActor$$anonfun$3$$anonfun$apply
 $1.apply(LiftActor.scala:109)
       at net.liftweb.actor.SpecializedLiftActor$$anonfun$3$$anonfun$apply
 $1.apply(LiftActor.scala:109)
       at net.liftweb.actor.LAScheduler$$anonfun$1$$anon$1$$anon$2.run
 (LiftActor.scala:37)
       at java.util.concurrent.ThreadPoolExecutor$Worker.runTask
 (ThreadPoolExecutor.java:886)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run
 (ThreadPoolExecutor.java:908)
       at java.lang.Thread.run(Thread.java:637)
 Caused by: java.util.concurrent.RejectedExecutionException
       at java.util.concurrent.ThreadPoolExecutor
 $AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:1760)
       at java.util.concurrent.ThreadPoolExecutor.reject
 (ThreadPoolExecutor.java:767)
       at java.util.concurrent.ScheduledThreadPoolExecutor.delayedExecute
 (ScheduledThreadPoolExecutor.java:216)
       at java.util.concurrent.ScheduledThreadPoolExecutor.schedule
 (ScheduledThreadPoolExecutor.java:379)
       at java.util.concurrent.Executors
 $DelegatedScheduledExecutorService.schedule(Executors.java:654)
       at net.liftweb.util.ActorPing$.schedule(ActorPing.scala:52

[Lift] *** BREAKING CHANGES *** to Loc LocParam

2009-11-16 Thread Kris Nuttycombe

Hi, all,

I have committed a number of enhancements to Loc  LocParam which
involves a number of breaking changes. The changes and their rationale
is listed below. Unless you have created your own subclasses of Loc or
LocParam, these changes should not have any repercussions for you. If
the effect of any of these changes on your particular codebase are
excessively disruptive, please contact me and I will work with you to
resolve the issue.

Breaking Changes:

1) LocParam

LocParam has been made a sealed trait to facilitate pattern matching
within the Lift codebase and has had a contravariant type parameter
added to its type to facilitate typesafe interactions with Loc[T]. The
new trait is hence LocParam[-T]. As LocParam is now a sealed trait, I
have added an extension point for user-specified LocParam subtypes as
UserLocParam[-T] extends LocParam[T]. Since the new type parameter is
contravariant, LocParam subclasses that are applicable for any Loc[T]
have the type LocParam[Any], and a type alias AnyLocParam has been
added for this type.

The Loc.checkProtected method now enforces type consistency between
the evaluated Link[T] and the list of LocParam[T] which are used to
evaluate whether the link is accessible given the specified
parameters.

2) Renames

Previously, the Param suffix was used for two unrelated purposes
within Loc: first, to refer to the type parameter of the Loc, and
secondly for the LocParam configuration. This overloading made the
code and the API somewhat difficult to read, so the first usage has
been removed resulting in the following renames:

ParamType = T
NullLocParams = //removed, Unit is sufficient!
Loc.defaultParams = Loc.defaultValue
Loc.forceParam = Loc.overrideValue
Loc.foundParam = Loc.requestValue
Loc.additionalKidParams = Loc.childValues

After this change, all instances of the param name within Loc should
refer to something having to do with LocParam instances.

Non-Breaking Additions:

case class IfValue[T](test: Box[T] = Boolean, failMsg: FailMsg)
extends LocParam[T]
case class UnlessValue[T](test: Box[T] = Boolean, failMsg: FailMsg)
extends LocParam[T]
case class TestValueAccess[T](func: Box[T] = Box[LiftResponse])
extends LocParam[T]

If you are using a non-Unit typed Loc, you can use these LocParam
instances to enforce access rules at the value level.

case class ValueTemplate[T](template: Box[T] = NodeSeq) extends
LocParam[T] //per-value template selection

DataLoc[T] subclass of Loc was added to facilitate the use of the new
more typeful LocParam subtypes.

A few changes to Link:

Since Link.createLink creates a Box[Text] (and not a clickable link) a
couple of methods were added to create the intermediate, unboxed
values in order that subclasses can more easily manipulate the resulting path:

Link.pathList(value: T): List[String] // added to facilitate creation
of value-aware paths by subclasses.
Link.createPath(value: T): String //creates the String representation
of the path that is subsequently turned into XML and boxed by
Link.createLink

Again, please let me know if any of these changes cause you headaches!
My hope is that much of the modified functionality has not been used
by very many people yet and that as a result it's a good time to make
these changes before typeful Locs get too widely used to make breaking
changes.

Thanks,

Kris

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Lift Scala style.

2009-11-16 Thread Kris Nuttycombe

Hi, all,

This is just a starting point for debate with a hope of eventual
consensus on something that's ultimately somewhat trivial matter.
Since style is currently a topic of discussion on the main scala-users
list, I thought it an appropriate time to bring it up.

Lift is one of the most prominent, perhaps the most prominent Scala
applications in current existence, and as such I think it has a
significant role to play in exemplifying good Scala style. At the same
time, Lift has also been developed over the course of its' developers
familiarization with the language, and so it displays some occasional
stylistic warts. At the same time, major changes coming with Scala
2.8, particularly named  default parameters, may be something we want
to take advantage of in ways that may have a substantial effect on
usability of our APIs.

I guess my general question is, how does the Lift community want to
deal with the stylistic warts and naming inconsistencies, and how do
we want to go about integrating some of these new features? In some
cases, we may be able to use a strategy of giving some operations new
names and deprecating the old, but in others this might lead to some
really hacky looking APIs since we've already got good names, and
changing their signatures might break a lot of code. Also, what are
the big warts on Lift that ought to be resolved by renames or
named/default parameters?

Two naming issues that have come up recently in Lift internal
discussions follow:

First, Alex Boisvert suggested that S.init be renamed to S.doWith to
have more consistency with Req and LiftSession. At least internally, I
think that the consensus was that this wasn't necessarily appropriate.

Second, I suggested the deprecation of the pattern of using apply() on
AnyVar to provide setter functionality, since to me using something
that looks like function application to do a mutation seems
ill-conceived. My initial suggestion was to piggyback our
functionality on the update() rewriting that is done by Scala, but on
further reflection and David's feedback I realized that this would be
even uglier since you'd have to use myRequestVar() = foo. So, what
would folks think about defining the symbolic method := on both
AnyVal and within the Mapper framework instead, with the goal of
eventual deprecation of the apply style?

Thirdly, I would like to propose that any marker traits (i.e. traits
that declare no methods) within Lift either be sealed, or have the
relevant methods tailored to the shared functionality they represent
added (or both.) Match errors can be nasty, and sealing the traits
(providing an extension point for users if need be) can help the
compiler help us to eliminate that class of errors.

Fourth, in compiling the Lift source I see far more warnings related
to type erasure in match statements than I'm strictly comfortable
with. My personal plan is to start working through these and
eliminating them where possible, but in general I think that we as a
community should start running all of our builds with all warnings
enabled, and strive to eliminate them. The Scala type system can be
complicated, but in my experience it is virtually always possible to
avoid such warnings (and type unsafety!) with a bit of extra thought.
The less we subvert the type system, the less likely we are to have
unexpected errors.

Kris

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: Lift Scala style.

2009-11-16 Thread Kris Nuttycombe

On Mon, Nov 16, 2009 at 1:22 PM, David Pollak
feeder.of.the.be...@gmail.com wrote:
 Kris,

 Thanks for starting this thread.

 I am all for getting the Lift APIs more normalized.  It'd also be great if
 we could do a lot of it during the next month or so (prior to M8) because
 I'd really like M8 to be stable and the M8 phase be a bug-fix and 2.8 port
 phase.

 On Mon, Nov 16, 2009 at 11:59 AM, Kris Nuttycombe
 kris.nuttyco...@gmail.com wrote:

 Hi, all,

 This is just a starting point for debate with a hope of eventual
 consensus on something that's ultimately somewhat trivial matter.
 Since style is currently a topic of discussion on the main scala-users
 list, I thought it an appropriate time to bring it up.

 Lift is one of the most prominent, perhaps the most prominent Scala
 applications in current existence, and as such I think it has a
 significant role to play in exemplifying good Scala style. At the same
 time, Lift has also been developed over the course of its' developers
 familiarization with the language, and so it displays some occasional
 stylistic warts. At the same time, major changes coming with Scala
 2.8, particularly named  default parameters, may be something we want
 to take advantage of in ways that may have a substantial effect on
 usability of our APIs.

 I guess my general question is, how does the Lift community want to
 deal with the stylistic warts and naming inconsistencies, and how do
 we want to go about integrating some of these new features? In some
 cases, we may be able to use a strategy of giving some operations new
 names and deprecating the old, but in others this might lead to some
 really hacky looking APIs since we've already got good names, and
 changing their signatures might break a lot of code. Also, what are
 the big warts on Lift that ought to be resolved by renames or
 named/default parameters?

 Two naming issues that have come up recently in Lift internal
 discussions follow:

 First, Alex Boisvert suggested that S.init be renamed to S.doWith to
 have more consistency with Req and LiftSession. At least internally, I
 think that the consensus was that this wasn't necessarily appropriate.

 Second, I suggested the deprecation of the pattern of using apply() on
 AnyVar to provide setter functionality, since to me using something
 that looks like function application to do a mutation seems
 ill-conceived. My initial suggestion was to piggyback our
 functionality on the update() rewriting that is done by Scala, but on
 further reflection and David's feedback I realized that this would be
 even uglier since you'd have to use myRequestVar() = foo. So, what
 would folks think about defining the symbolic method := on both
 AnyVal and within the Mapper framework instead, with the goal of
 eventual deprecation of the apply style?

 I am firmly opposed to deprecation of the apply style of setting entities in
 Lift.

 Mapper (and Record) use the apply style very successfully.  The apply style
 allows chaining of the setting of fields and that leads to much more
 readable code.

 Mapper initially used the update() and Pascal (:=) styles for assignment.
 Neither of these proved popular and are generally disused (I may have taken
 them out at some point).

 So, I'm all for Pascal style assignment to entities in addition to the
 apply() style, but the apply() style keeps things consistent with
 persistence libraries in Lift.


They're not there now. I'll open a ticket to add the Pascal style
assignment method where appropriate and provide a patch - I figure
that the update() syntax is so ugly that people probably aren't keen
to use that one so I'll leave it out unless someone is interested.


 Thirdly, I would like to propose that any marker traits (i.e. traits
 that declare no methods) within Lift either be sealed, or have the
 relevant methods tailored to the shared functionality they represent
 added (or both.) Match errors can be nasty, and sealing the traits
 (providing an extension point for users if need be) can help the
 compiler help us to eliminate that class of errors.

 I'm cool with this... but I don't know how many of these exist.  I think
 only 1 or 2.

Yeah, it's not a huge problem. Will ticket  patch, and check back if
I have any questions.



 Fourth, in compiling the Lift source I see far more warnings related
 to type erasure in match statements than I'm strictly comfortable
 with. My personal plan is to start working through these and
 eliminating them where possible,

 I agree and I've done a lot over the years to try to reduce them.
 Unfortunately, Seq and List (the places where the issue is most prevalent),
 are type-erased.  I tried to get Martin to include Manfest on List for 2.8,
 but failed.


 but in general I think that we as a
 community should start running all of our builds with all warnings
 enabled, and strive to eliminate them. The Scala type system can be
 complicated, but in my experience it is virtually always possible to
 avoid

[Lift] Re: *** BREAKING CHANGES *** to Loc LocParam

2009-11-16 Thread Kris Nuttycombe

Hi, all,

I was just informed that my changes broke MetaMegaProtoUser
interaction. I've reverted the commit until I can get that sorted out.

Sorry,

Kris

On Mon, Nov 16, 2009 at 11:27 AM, Kris Nuttycombe
kris.nuttyco...@gmail.com wrote:
 Hi, all,

 I have committed a number of enhancements to Loc  LocParam which
 involves a number of breaking changes. The changes and their rationale
 is listed below. Unless you have created your own subclasses of Loc or
 LocParam, these changes should not have any repercussions for you. If
 the effect of any of these changes on your particular codebase are
 excessively disruptive, please contact me and I will work with you to
 resolve the issue.

 Breaking Changes:

 1) LocParam

 LocParam has been made a sealed trait to facilitate pattern matching
 within the Lift codebase and has had a contravariant type parameter
 added to its type to facilitate typesafe interactions with Loc[T]. The
 new trait is hence LocParam[-T]. As LocParam is now a sealed trait, I
 have added an extension point for user-specified LocParam subtypes as
 UserLocParam[-T] extends LocParam[T]. Since the new type parameter is
 contravariant, LocParam subclasses that are applicable for any Loc[T]
 have the type LocParam[Any], and a type alias AnyLocParam has been
 added for this type.

 The Loc.checkProtected method now enforces type consistency between
 the evaluated Link[T] and the list of LocParam[T] which are used to
 evaluate whether the link is accessible given the specified
 parameters.

 2) Renames

 Previously, the Param suffix was used for two unrelated purposes
 within Loc: first, to refer to the type parameter of the Loc, and
 secondly for the LocParam configuration. This overloading made the
 code and the API somewhat difficult to read, so the first usage has
 been removed resulting in the following renames:

 ParamType = T
 NullLocParams = //removed, Unit is sufficient!
 Loc.defaultParams = Loc.defaultValue
 Loc.forceParam = Loc.overrideValue
 Loc.foundParam = Loc.requestValue
 Loc.additionalKidParams = Loc.childValues

 After this change, all instances of the param name within Loc should
 refer to something having to do with LocParam instances.

 Non-Breaking Additions:

 case class IfValue[T](test: Box[T] = Boolean, failMsg: FailMsg)
 extends LocParam[T]
 case class UnlessValue[T](test: Box[T] = Boolean, failMsg: FailMsg)
 extends LocParam[T]
 case class TestValueAccess[T](func: Box[T] = Box[LiftResponse])
 extends LocParam[T]

 If you are using a non-Unit typed Loc, you can use these LocParam
 instances to enforce access rules at the value level.

 case class ValueTemplate[T](template: Box[T] = NodeSeq) extends
 LocParam[T] //per-value template selection

 DataLoc[T] subclass of Loc was added to facilitate the use of the new
 more typeful LocParam subtypes.

 A few changes to Link:

 Since Link.createLink creates a Box[Text] (and not a clickable link) a
 couple of methods were added to create the intermediate, unboxed
 values in order that subclasses can more easily manipulate the resulting path:

 Link.pathList(value: T): List[String] // added to facilitate creation
 of value-aware paths by subclasses.
 Link.createPath(value: T): String //creates the String representation
 of the path that is subsequently turned into XML and boxed by
 Link.createLink

 Again, please let me know if any of these changes cause you headaches!
 My hope is that much of the modified functionality has not been used
 by very many people yet and that as a result it's a good time to make
 these changes before typeful Locs get too widely used to make breaking
 changes.

 Thanks,

 Kris


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: *** BREAKING CHANGES *** to Loc LocParam

2009-11-16 Thread Kris Nuttycombe

On Mon, Nov 16, 2009 at 3:13 PM, David Pollak
feeder.of.the.be...@gmail.com wrote:


 On Mon, Nov 16, 2009 at 2:12 PM, Kris Nuttycombe kris.nuttyco...@gmail.com
 wrote:

 Hi, all,

 I was just informed that my changes broke MetaMegaProtoUser
 interaction. I've reverted the commit until I can get that sorted out.

 How was it broken?

It's something to do with how the login form is processed - at the
moment I haven't figured out anything more with that. Essentially, the
login fails silently and returns the user to the login form upon
submission.

Kris



 Sorry,

 Kris

 On Mon, Nov 16, 2009 at 11:27 AM, Kris Nuttycombe
 kris.nuttyco...@gmail.com wrote:
  Hi, all,
 
  I have committed a number of enhancements to Loc  LocParam which
  involves a number of breaking changes. The changes and their rationale
  is listed below. Unless you have created your own subclasses of Loc or
  LocParam, these changes should not have any repercussions for you. If
  the effect of any of these changes on your particular codebase are
  excessively disruptive, please contact me and I will work with you to
  resolve the issue.
 
  Breaking Changes:
 
  1) LocParam
 
  LocParam has been made a sealed trait to facilitate pattern matching
  within the Lift codebase and has had a contravariant type parameter
  added to its type to facilitate typesafe interactions with Loc[T]. The
  new trait is hence LocParam[-T]. As LocParam is now a sealed trait, I
  have added an extension point for user-specified LocParam subtypes as
  UserLocParam[-T] extends LocParam[T]. Since the new type parameter is
  contravariant, LocParam subclasses that are applicable for any Loc[T]
  have the type LocParam[Any], and a type alias AnyLocParam has been
  added for this type.
 
  The Loc.checkProtected method now enforces type consistency between
  the evaluated Link[T] and the list of LocParam[T] which are used to
  evaluate whether the link is accessible given the specified
  parameters.
 
  2) Renames
 
  Previously, the Param suffix was used for two unrelated purposes
  within Loc: first, to refer to the type parameter of the Loc, and
  secondly for the LocParam configuration. This overloading made the
  code and the API somewhat difficult to read, so the first usage has
  been removed resulting in the following renames:
 
  ParamType = T
  NullLocParams = //removed, Unit is sufficient!
  Loc.defaultParams = Loc.defaultValue
  Loc.forceParam = Loc.overrideValue
  Loc.foundParam = Loc.requestValue
  Loc.additionalKidParams = Loc.childValues
 
  After this change, all instances of the param name within Loc should
  refer to something having to do with LocParam instances.
 
  Non-Breaking Additions:
 
  case class IfValue[T](test: Box[T] = Boolean, failMsg: FailMsg)
  extends LocParam[T]
  case class UnlessValue[T](test: Box[T] = Boolean, failMsg: FailMsg)
  extends LocParam[T]
  case class TestValueAccess[T](func: Box[T] = Box[LiftResponse])
  extends LocParam[T]
 
  If you are using a non-Unit typed Loc, you can use these LocParam
  instances to enforce access rules at the value level.
 
  case class ValueTemplate[T](template: Box[T] = NodeSeq) extends
  LocParam[T] //per-value template selection
 
  DataLoc[T] subclass of Loc was added to facilitate the use of the new
  more typeful LocParam subtypes.
 
  A few changes to Link:
 
  Since Link.createLink creates a Box[Text] (and not a clickable link) a
  couple of methods were added to create the intermediate, unboxed
  values in order that subclasses can more easily manipulate the resulting
  path:
 
  Link.pathList(value: T): List[String] // added to facilitate creation
  of value-aware paths by subclasses.
  Link.createPath(value: T): String //creates the String representation
  of the path that is subsequently turned into XML and boxed by
  Link.createLink
 
  Again, please let me know if any of these changes cause you headaches!
  My hope is that much of the modified functionality has not been used
  by very many people yet and that as a result it's a good time to make
  these changes before typeful Locs get too widely used to make breaking
  changes.
 
  Thanks,
 
  Kris
 





 --
 Lift, the simply functional web framework http://liftweb.net
 Beginning Scala http://www.apress.com/book/view/1430219890
 Follow me: http://twitter.com/dpp
 Surf the harmonics

 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: *** BREAKING CHANGES *** to Loc LocParam

2009-11-16 Thread Kris Nuttycombe

On Mon, Nov 16, 2009 at 4:02 PM, David Pollak
feeder.of.the.be...@gmail.com wrote:


 On Mon, Nov 16, 2009 at 2:20 PM, Kris Nuttycombe kris.nuttyco...@gmail.com
 wrote:

 On Mon, Nov 16, 2009 at 3:13 PM, David Pollak
 feeder.of.the.be...@gmail.com wrote:
 
 
  On Mon, Nov 16, 2009 at 2:12 PM, Kris Nuttycombe
  kris.nuttyco...@gmail.com
  wrote:
 
  Hi, all,
 
  I was just informed that my changes broke MetaMegaProtoUser
  interaction. I've reverted the commit until I can get that sorted out.
 
  How was it broken?

 It's something to do with how the login form is processed - at the
 moment I haven't figured out anything more with that. Essentially, the
 login fails silently and returns the user to the login form upon
 submission.

 That sounds like a deeper issue with MetaProtoUser.  I'd keep your changes
 and see why MegaProtoUser is failing.

Absolutely; I just figured I didn't want to leave people with broken
code while I figure it out since I'm not that familiar with
MegaProtoUser and am not sure how long that will take.

 Also, it's best that people discuss these kinds of things on list rather
 than contacting you privately so we can all see what's going on.


Totally agree. I should have made that more clear in the initial email.

Kriis


 Kris

 
 
  Sorry,
 
  Kris
 
  On Mon, Nov 16, 2009 at 11:27 AM, Kris Nuttycombe
  kris.nuttyco...@gmail.com wrote:
   Hi, all,
  
   I have committed a number of enhancements to Loc  LocParam which
   involves a number of breaking changes. The changes and their
   rationale
   is listed below. Unless you have created your own subclasses of Loc
   or
   LocParam, these changes should not have any repercussions for you. If
   the effect of any of these changes on your particular codebase are
   excessively disruptive, please contact me and I will work with you to
   resolve the issue.
  
   Breaking Changes:
  
   1) LocParam
  
   LocParam has been made a sealed trait to facilitate pattern matching
   within the Lift codebase and has had a contravariant type parameter
   added to its type to facilitate typesafe interactions with Loc[T].
   The
   new trait is hence LocParam[-T]. As LocParam is now a sealed trait, I
   have added an extension point for user-specified LocParam subtypes as
   UserLocParam[-T] extends LocParam[T]. Since the new type parameter is
   contravariant, LocParam subclasses that are applicable for any Loc[T]
   have the type LocParam[Any], and a type alias AnyLocParam has been
   added for this type.
  
   The Loc.checkProtected method now enforces type consistency between
   the evaluated Link[T] and the list of LocParam[T] which are used to
   evaluate whether the link is accessible given the specified
   parameters.
  
   2) Renames
  
   Previously, the Param suffix was used for two unrelated purposes
   within Loc: first, to refer to the type parameter of the Loc, and
   secondly for the LocParam configuration. This overloading made the
   code and the API somewhat difficult to read, so the first usage has
   been removed resulting in the following renames:
  
   ParamType = T
   NullLocParams = //removed, Unit is sufficient!
   Loc.defaultParams = Loc.defaultValue
   Loc.forceParam = Loc.overrideValue
   Loc.foundParam = Loc.requestValue
   Loc.additionalKidParams = Loc.childValues
  
   After this change, all instances of the param name within Loc
   should
   refer to something having to do with LocParam instances.
  
   Non-Breaking Additions:
  
   case class IfValue[T](test: Box[T] = Boolean, failMsg: FailMsg)
   extends LocParam[T]
   case class UnlessValue[T](test: Box[T] = Boolean, failMsg: FailMsg)
   extends LocParam[T]
   case class TestValueAccess[T](func: Box[T] = Box[LiftResponse])
   extends LocParam[T]
  
   If you are using a non-Unit typed Loc, you can use these LocParam
   instances to enforce access rules at the value level.
  
   case class ValueTemplate[T](template: Box[T] = NodeSeq) extends
   LocParam[T] //per-value template selection
  
   DataLoc[T] subclass of Loc was added to facilitate the use of the new
   more typeful LocParam subtypes.
  
   A few changes to Link:
  
   Since Link.createLink creates a Box[Text] (and not a clickable link)
   a
   couple of methods were added to create the intermediate, unboxed
   values in order that subclasses can more easily manipulate the
   resulting
   path:
  
   Link.pathList(value: T): List[String] // added to facilitate creation
   of value-aware paths by subclasses.
   Link.createPath(value: T): String //creates the String representation
   of the path that is subsequently turned into XML and boxed by
   Link.createLink
  
   Again, please let me know if any of these changes cause you
   headaches!
   My hope is that much of the modified functionality has not been used
   by very many people yet and that as a result it's a good time to make
   these changes before typeful Locs get too widely used to make
   breaking
   changes.
  
   Thanks,
  
   Kris

[Lift] Re: *** BREAKING CHANGES *** to Loc LocParam

2009-11-16 Thread Kris Nuttycombe

On Mon, Nov 16, 2009 at 4:11 PM, David Pollak
feeder.of.the.be...@gmail.com wrote:


 On Mon, Nov 16, 2009 at 3:10 PM, Kris Nuttycombe kris.nuttyco...@gmail.com
 wrote:

 On Mon, Nov 16, 2009 at 4:02 PM, David Pollak
 feeder.of.the.be...@gmail.com wrote:
 
 
  On Mon, Nov 16, 2009 at 2:20 PM, Kris Nuttycombe
  kris.nuttyco...@gmail.com
  wrote:
 
  On Mon, Nov 16, 2009 at 3:13 PM, David Pollak
  feeder.of.the.be...@gmail.com wrote:
  
  
   On Mon, Nov 16, 2009 at 2:12 PM, Kris Nuttycombe
   kris.nuttyco...@gmail.com
   wrote:
  
   Hi, all,
  
   I was just informed that my changes broke MetaMegaProtoUser
   interaction. I've reverted the commit until I can get that sorted
   out.
  
   How was it broken?
 
  It's something to do with how the login form is processed - at the
  moment I haven't figured out anything more with that. Essentially, the
  login fails silently and returns the user to the login form upon
  submission.
 
  That sounds like a deeper issue with MetaProtoUser.  I'd keep your
  changes
  and see why MegaProtoUser is failing.

 Absolutely; I just figured I didn't want to leave people with broken
 code while I figure it out since I'm not that familiar with
 MegaProtoUser and am not sure how long that will take.

 Please check the code back in and get me a test case and I'll debug it.

 I've got about 20 tickets I'm working on right now... one more ain't gonna
 kill me. ;-)

Reverted my reversion. The test case is an easy one: login in
hellolift displays the pathology.

Thanks for your help,

Kris


  Also, it's best that people discuss these kinds of things on list rather
  than contacting you privately so we can all see what's going on.
 

 Totally agree. I should have made that more clear in the initial email.

 Kriis

 
  Kris
 
  
  
   Sorry,
  
   Kris
  
   On Mon, Nov 16, 2009 at 11:27 AM, Kris Nuttycombe
   kris.nuttyco...@gmail.com wrote:
Hi, all,
   
I have committed a number of enhancements to Loc  LocParam which
involves a number of breaking changes. The changes and their
rationale
is listed below. Unless you have created your own subclasses of
Loc
or
LocParam, these changes should not have any repercussions for you.
If
the effect of any of these changes on your particular codebase are
excessively disruptive, please contact me and I will work with you
to
resolve the issue.
   
Breaking Changes:
   
1) LocParam
   
LocParam has been made a sealed trait to facilitate pattern
matching
within the Lift codebase and has had a contravariant type
parameter
added to its type to facilitate typesafe interactions with Loc[T].
The
new trait is hence LocParam[-T]. As LocParam is now a sealed
trait, I
have added an extension point for user-specified LocParam subtypes
as
UserLocParam[-T] extends LocParam[T]. Since the new type parameter
is
contravariant, LocParam subclasses that are applicable for any
Loc[T]
have the type LocParam[Any], and a type alias AnyLocParam has been
added for this type.
   
The Loc.checkProtected method now enforces type consistency
between
the evaluated Link[T] and the list of LocParam[T] which are used
to
evaluate whether the link is accessible given the specified
parameters.
   
2) Renames
   
Previously, the Param suffix was used for two unrelated purposes
within Loc: first, to refer to the type parameter of the Loc, and
secondly for the LocParam configuration. This overloading made the
code and the API somewhat difficult to read, so the first usage
has
been removed resulting in the following renames:
   
ParamType = T
NullLocParams = //removed, Unit is sufficient!
Loc.defaultParams = Loc.defaultValue
Loc.forceParam = Loc.overrideValue
Loc.foundParam = Loc.requestValue
Loc.additionalKidParams = Loc.childValues
   
After this change, all instances of the param name within Loc
should
refer to something having to do with LocParam instances.
   
Non-Breaking Additions:
   
case class IfValue[T](test: Box[T] = Boolean, failMsg: FailMsg)
extends LocParam[T]
case class UnlessValue[T](test: Box[T] = Boolean, failMsg:
FailMsg)
extends LocParam[T]
case class TestValueAccess[T](func: Box[T] = Box[LiftResponse])
extends LocParam[T]
   
If you are using a non-Unit typed Loc, you can use these LocParam
instances to enforce access rules at the value level.
   
case class ValueTemplate[T](template: Box[T] = NodeSeq) extends
LocParam[T] //per-value template selection
   
DataLoc[T] subclass of Loc was added to facilitate the use of the
new
more typeful LocParam subtypes.
   
A few changes to Link:
   
Since Link.createLink creates a Box[Text] (and not a clickable
link)
a
couple of methods were added to create the intermediate, unboxed
values in order that subclasses can more easily

[Lift] Re: Lots of compile-time cruft

2009-11-16 Thread Kris Nuttycombe

On Mon, Nov 16, 2009 at 4:28 PM, David Pollak
feeder.of.the.be...@gmail.com wrote:
 Folks,

 I'm seeing a lot of:
 [INFO] Unable to find resource 'javax.script:script-js:pom:1.0' in
 repository specs-repository (http://specs.googlecode.com/svn/maven2/)

 Also, I know Kris turned on type erasure warnings because he wants to debug
 them but there's just a pile that can't be fixed and these unfixable
 warnings get in the way of real warnings... any compromise we can find on
 this situation?

Oops... I didn't realize I'd committed the pom with that in! I've no
problem putting the extra warnings into a profile. Does Scala have an
equivalent of or support the @SuppressWarnings annotation that you
have in Java?

Kris

 Thanks,

 David

 --
 Lift, the simply functional web framework http://liftweb.net
 Beginning Scala http://www.apress.com/book/view/1430219890
 Follow me: http://twitter.com/dpp
 Surf the harmonics

 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: Lots of compile-time cruft

2009-11-16 Thread Kris Nuttycombe

On Mon, Nov 16, 2009 at 4:33 PM, Kris Nuttycombe
kris.nuttyco...@gmail.com wrote:
 On Mon, Nov 16, 2009 at 4:28 PM, David Pollak
 feeder.of.the.be...@gmail.com wrote:
 Folks,

 I'm seeing a lot of:
 [INFO] Unable to find resource 'javax.script:script-js:pom:1.0' in
 repository specs-repository (http://specs.googlecode.com/svn/maven2/)

 Also, I know Kris turned on type erasure warnings because he wants to debug
 them but there's just a pile that can't be fixed and these unfixable
 warnings get in the way of real warnings... any compromise we can find on
 this situation?

 Oops... I didn't realize I'd committed the pom with that in! I've no
 problem putting the extra warnings into a profile. Does Scala have an
 equivalent of or support the @SuppressWarnings annotation that you
 have in Java?

 Kris

Actually, on further examination I claim innocence! git blame shows
the real culprit! :)

I've moved the flags to a profile.

mvn -Pdetail clean compile

will give you all the warnings; basic usage does not.

Kris

 Thanks,

 David

 --
 Lift, the simply functional web framework http://liftweb.net
 Beginning Scala http://www.apress.com/book/view/1430219890
 Follow me: http://twitter.com/dpp
 Surf the harmonics

 



--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



Re: [Lift] Re: Lots of compile-time cruft

2009-11-16 Thread Kris Nuttycombe
On Mon, Nov 16, 2009 at 11:13 PM, David Pollak
feeder.of.the.be...@gmail.com wrote:


 On Mon, Nov 16, 2009 at 5:01 PM, Alex Boisvert alex.boisv...@gmail.com
 wrote:

 On Mon, Nov 16, 2009 at 4:26 PM, David Pollak
 feeder.of.the.be...@gmail.com wrote:

 Speaking of warnings, which do you prefer (see patch below):

 1) Explicit types on val extractors (as it is today)
 2) One-liner with no types (proposed)

 We could save 4 warnings...

 Here's the cost of the 4 warnings:

 If you remove the type information and the lazy calculator thing changes
 how it does calculations, you'll silently get changed types (this has
 happened before) and that breaks things.  On the other hand, if we leave the
 code with explicit types, we'll get a match warning (with the type erasure
 stuff turned back off) if the type change.

 You get breakage if the types change in an incompatible manner in both
 cases.

 I don't see how you get any added safety by adding the types explicitly.

 You get type-safety in downstream code... the code that is accessing the
 variables.  You also avoid type inferencer problems.  The type inferencer
 doesn't always give you what you expect (it's not like Haskell).  Being
 explicit about what you expect is going to insure that the compiler does the
 right thing, even if it issues a spurious warning.

 So, why am I harping on this?

The thing is, the compiler really *doesn't* do the right thing if you
supply the types. In fact, it will do the wrong thing if you change
the upstream code more frequently than it will do the right thing.

Case in point: this compiles without complaint:

object Test {
class A
class B extends A

val (a: A, b: B) = (new A, new A);
}

It will fail at runtime with a MatchError or ClassCastException or
something equally nasty. If the types were not annotated, then the
downstream code would fail to compile.

Kris

 (1) This code was stuff I worked on to get right back in 2007.  It's stable
 and despite the aesthetic displeasure of a spurious warning, it does not
 need to change.
 (2) This code reflects a lot of work getting it right with the Scala
 compiler back when the Scala compiler was less stable.  I know the code
 currently works and I don't remember what kind of weirdness other variations
 on the code caused, but I don't want to find out if there are latent issues
 with the Scala compiler.
 (3) From a priority standpoint, this is suboptimal.  It's suboptimal for me
 to have to sell you on why it should not be changed.  It is suboptimal
 because there are open tickets for some real issues that real users need
 addressed.  If your bent is more oriented to getting to know the code,
 there's plenty of ScalaDocs and higher level documentation to write.
 (4) from a readibility standpoint, I like the code the way it is and it's
 most likely that if there's a problem or enhancement in that part of the
 code, it's me or Marius that're going to be fixing it.




 In both cases, the compiler has the same information about the types and
 perform the same amount of type checking for you.




 alex

 --

 You received this message because you are subscribed to the Google Groups
 Lift group.
 To post to this group, send email to lift...@googlegroups.com.
 To unsubscribe from this group, send email to
 liftweb+unsubscr...@googlegroups.com.
 For more options, visit this group at
 http://groups.google.com/group/liftweb?hl=.



 --
 Lift, the simply functional web framework http://liftweb.net
 Beginning Scala http://www.apress.com/book/view/1430219890
 Follow me: http://twitter.com/dpp
 Surf the harmonics

 --

 You received this message because you are subscribed to the Google Groups
 Lift group.
 To post to this group, send email to lift...@googlegroups.com.
 To unsubscribe from this group, send email to
 liftweb+unsubscr...@googlegroups.com.
 For more options, visit this group at
 http://groups.google.com/group/liftweb?hl=.


--

You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=.




[Lift] Re: Changes to transaction handling since M6?

2009-11-13 Thread Kris Nuttycombe

On Thu, Nov 12, 2009 at 5:57 PM, David Pollak
feeder.of.the.be...@gmail.com wrote:
 Kris,

 There was a bunch of changes in the net.liftweb.mapper.DB code for
 transaction management, but I don't think that would impact JPA.

 Also, in M7, there were changes in how RequestVars are handled during Ajax
 requests... basically, state is snapshotted when the Ajax request is created
 and then that snapshot state is restored during the servicing of the Ajax
 request.  If the RequestVarEM stuff is being snapshotted, that could cause
 issues.

 Thanks,

 David

That sounds like it could very likely be the culprit, but I'm going to
have to dig a bit more to know for certain.

the RequestVarEM trait uses the following RequestVar:

  object emVar extends RequestVar[EntityManager](openEM()) {
this.registerGlobalCleanupFunc(ignore = closeEM(this.is))

override def __nameSalt = net.liftweb.util.Helpers.randomString(10)
  }

openEM() is supplied in my case by JndiEMF. If this would not be
called during handling of an AJAX request, that's definitely the
issue.

This brings to mind an issue I'd worried about a long time ago, back
when I had my own implementation of a JNDI resource acquisition trait
for persistence. We can tie into the cleanup phase of the RequestVar's
lifecycle with a cleanup func, but if the RequestVar is going to be
persisted across actual HTTP requests in the AJAX case, we will also
need additional lifecycle hooks. I'm actually kind of concerned about
this decision; it seems like it could really complicate usage of
RequestVar in cases where the container has additional stuff it does
related to the lifecycle of the HTTP request (like JTA).

Maybe there should be a separate AnyVar subclass that is intended for
this sort of persist-for-ajax situation?

Kris


 On Thu, Nov 12, 2009 at 4:49 PM, Kris Nuttycombe kris.nuttyco...@gmail.com
 wrote:

 Hi, all (Derek! :),

 Have there been significant changes in how transactions are handled by
 lift-jpa since M6? Due to the rearrangement of the repository, I'm
 having a hard time figuring out if the code has changed.

 I have a repeatable issue that shows up when changing between M6 and
 SNAPSHOT wherein I now get
 javax.persistence.TransactionRequiredExceptions when doing a merge
 using a JndiEMF with RequestVarEM in an AJAX callback.

 Has anything major changed in this timeframe?

 Kris





 --
 Lift, the simply functional web framework http://liftweb.net
 Beginning Scala http://www.apress.com/book/view/1430219890
 Follow me: http://twitter.com/dpp
 Surf the harmonics

 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: Changes to transaction handling since M6?

2009-11-13 Thread Kris Nuttycombe

Hmmm is this now TransientRequestVar? It's private[http], but
could it be protected instead?

Kris

On Fri, Nov 13, 2009 at 11:22 AM, Kris Nuttycombe
kris.nuttyco...@gmail.com wrote:
 Let me just try it out since I've got a test case, and if need be I'll
 file the ticket  commit.

 Kris

 On Fri, Nov 13, 2009 at 10:45 AM, Derek Chen-Becker
 dchenbec...@gmail.com wrote:
 Looking at 81f1715f671e8b5ee4f6d3ce242cc9da272611d1, maybe the RequestVar
 needs to be changed to an UnboundRequestVar. It's not clear from the
 scaladocs on UnboundRequestVar, though, that this is the intent. It looks
 like those scaladocs were just copied and pasted from RequestVar. If this
 sounds like the right change to make I can fix RequestVarEM and update the
 scaladocs for UnboundRequestVar.

 Derek

 On Fri, Nov 13, 2009 at 11:24 AM, Kris Nuttycombe
 kris.nuttyco...@gmail.com wrote:

 On Thu, Nov 12, 2009 at 5:57 PM, David Pollak
 feeder.of.the.be...@gmail.com wrote:
  Kris,
 
  There was a bunch of changes in the net.liftweb.mapper.DB code for
  transaction management, but I don't think that would impact JPA.
 
  Also, in M7, there were changes in how RequestVars are handled during
  Ajax
  requests... basically, state is snapshotted when the Ajax request is
  created
  and then that snapshot state is restored during the servicing of the
  Ajax
  request.  If the RequestVarEM stuff is being snapshotted, that could
  cause
  issues.
 
  Thanks,
 
  David

 That sounds like it could very likely be the culprit, but I'm going to
 have to dig a bit more to know for certain.

 the RequestVarEM trait uses the following RequestVar:

  object emVar extends RequestVar[EntityManager](openEM()) {
    this.registerGlobalCleanupFunc(ignore = closeEM(this.is))

    override def __nameSalt = net.liftweb.util.Helpers.randomString(10)
  }

 openEM() is supplied in my case by JndiEMF. If this would not be
 called during handling of an AJAX request, that's definitely the
 issue.

 This brings to mind an issue I'd worried about a long time ago, back
 when I had my own implementation of a JNDI resource acquisition trait
 for persistence. We can tie into the cleanup phase of the RequestVar's
 lifecycle with a cleanup func, but if the RequestVar is going to be
 persisted across actual HTTP requests in the AJAX case, we will also
 need additional lifecycle hooks. I'm actually kind of concerned about
 this decision; it seems like it could really complicate usage of
 RequestVar in cases where the container has additional stuff it does
 related to the lifecycle of the HTTP request (like JTA).

 Maybe there should be a separate AnyVar subclass that is intended for
 this sort of persist-for-ajax situation?

 Kris

 
  On Thu, Nov 12, 2009 at 4:49 PM, Kris Nuttycombe
  kris.nuttyco...@gmail.com
  wrote:
 
  Hi, all (Derek! :),
 
  Have there been significant changes in how transactions are handled by
  lift-jpa since M6? Due to the rearrangement of the repository, I'm
  having a hard time figuring out if the code has changed.
 
  I have a repeatable issue that shows up when changing between M6 and
  SNAPSHOT wherein I now get
  javax.persistence.TransactionRequiredExceptions when doing a merge
  using a JndiEMF with RequestVarEM in an AJAX callback.
 
  Has anything major changed in this timeframe?
 
  Kris
 
 
 
 
 
  --
  Lift, the simply functional web framework http://liftweb.net
  Beginning Scala http://www.apress.com/book/view/1430219890
  Follow me: http://twitter.com/dpp
  Surf the harmonics
 
  
 




 



--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: Changes to transaction handling since M6?

2009-11-13 Thread Kris Nuttycombe

Let me just try it out since I've got a test case, and if need be I'll
file the ticket  commit.

Kris

On Fri, Nov 13, 2009 at 10:45 AM, Derek Chen-Becker
dchenbec...@gmail.com wrote:
 Looking at 81f1715f671e8b5ee4f6d3ce242cc9da272611d1, maybe the RequestVar
 needs to be changed to an UnboundRequestVar. It's not clear from the
 scaladocs on UnboundRequestVar, though, that this is the intent. It looks
 like those scaladocs were just copied and pasted from RequestVar. If this
 sounds like the right change to make I can fix RequestVarEM and update the
 scaladocs for UnboundRequestVar.

 Derek

 On Fri, Nov 13, 2009 at 11:24 AM, Kris Nuttycombe
 kris.nuttyco...@gmail.com wrote:

 On Thu, Nov 12, 2009 at 5:57 PM, David Pollak
 feeder.of.the.be...@gmail.com wrote:
  Kris,
 
  There was a bunch of changes in the net.liftweb.mapper.DB code for
  transaction management, but I don't think that would impact JPA.
 
  Also, in M7, there were changes in how RequestVars are handled during
  Ajax
  requests... basically, state is snapshotted when the Ajax request is
  created
  and then that snapshot state is restored during the servicing of the
  Ajax
  request.  If the RequestVarEM stuff is being snapshotted, that could
  cause
  issues.
 
  Thanks,
 
  David

 That sounds like it could very likely be the culprit, but I'm going to
 have to dig a bit more to know for certain.

 the RequestVarEM trait uses the following RequestVar:

  object emVar extends RequestVar[EntityManager](openEM()) {
    this.registerGlobalCleanupFunc(ignore = closeEM(this.is))

    override def __nameSalt = net.liftweb.util.Helpers.randomString(10)
  }

 openEM() is supplied in my case by JndiEMF. If this would not be
 called during handling of an AJAX request, that's definitely the
 issue.

 This brings to mind an issue I'd worried about a long time ago, back
 when I had my own implementation of a JNDI resource acquisition trait
 for persistence. We can tie into the cleanup phase of the RequestVar's
 lifecycle with a cleanup func, but if the RequestVar is going to be
 persisted across actual HTTP requests in the AJAX case, we will also
 need additional lifecycle hooks. I'm actually kind of concerned about
 this decision; it seems like it could really complicate usage of
 RequestVar in cases where the container has additional stuff it does
 related to the lifecycle of the HTTP request (like JTA).

 Maybe there should be a separate AnyVar subclass that is intended for
 this sort of persist-for-ajax situation?

 Kris

 
  On Thu, Nov 12, 2009 at 4:49 PM, Kris Nuttycombe
  kris.nuttyco...@gmail.com
  wrote:
 
  Hi, all (Derek! :),
 
  Have there been significant changes in how transactions are handled by
  lift-jpa since M6? Due to the rearrangement of the repository, I'm
  having a hard time figuring out if the code has changed.
 
  I have a repeatable issue that shows up when changing between M6 and
  SNAPSHOT wherein I now get
  javax.persistence.TransactionRequiredExceptions when doing a merge
  using a JndiEMF with RequestVarEM in an AJAX callback.
 
  Has anything major changed in this timeframe?
 
  Kris
 
 
 
 
 
  --
  Lift, the simply functional web framework http://liftweb.net
  Beginning Scala http://www.apress.com/book/view/1430219890
  Follow me: http://twitter.com/dpp
  Surf the harmonics
 
  
 




 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: Changes to transaction handling since M6?

2009-11-13 Thread Kris Nuttycombe

On Fri, Nov 13, 2009 at 11:46 AM, Derek Chen-Becker
dchenbec...@gmail.com wrote:
 Looks like it. Probably private[liftweb] would work, too. In any case, the
 scaladocs need to be updated to reflect what it's for.

 On Fri, Nov 13, 2009 at 12:26 PM, Kris Nuttycombe
 kris.nuttyco...@gmail.com wrote:

 Hmmm is this now TransientRequestVar? It's private[http], but
 could it be protected instead?

 Kris

David, do you have an opinion? Is there any reason to keep this
private to lift, or is it something that 3rd-party libraries could
make use of (as in this case?)

Kris

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: Changes to transaction handling since M6?

2009-11-13 Thread Kris Nuttycombe

On Fri, Nov 13, 2009 at 3:42 PM, David Pollak
feeder.of.the.be...@gmail.com wrote:


 On Fri, Nov 13, 2009 at 12:12 PM, Kris Nuttycombe
 kris.nuttyco...@gmail.com wrote:

 On Fri, Nov 13, 2009 at 11:46 AM, Derek Chen-Becker
 dchenbec...@gmail.com wrote:
  Looks like it. Probably private[liftweb] would work, too. In any case,
  the
  scaladocs need to be updated to reflect what it's for.
 
  On Fri, Nov 13, 2009 at 12:26 PM, Kris Nuttycombe
  kris.nuttyco...@gmail.com wrote:
 
  Hmmm is this now TransientRequestVar? It's private[http], but
  could it be protected instead?
 
  Kris

 David, do you have an opinion? Is there any reason to keep this
 private to lift, or is it something that 3rd-party libraries could
 make use of (as in this case?)

 I wanted to keep it as narrow as possible while we saw how it worked and got
 better naming.  Making it private[liftweb] is fine and we'll open it up
 later.


Okay, done and on ReviewBoard.

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Changes to transaction handling since M6?

2009-11-12 Thread Kris Nuttycombe

Hi, all (Derek! :),

Have there been significant changes in how transactions are handled by
lift-jpa since M6? Due to the rearrangement of the repository, I'm
having a hard time figuring out if the code has changed.

I have a repeatable issue that shows up when changing between M6 and
SNAPSHOT wherein I now get
javax.persistence.TransactionRequiredExceptions when doing a merge
using a JndiEMF with RequestVarEM in an AJAX callback.

Has anything major changed in this timeframe?

Kris

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: Loc questions

2009-10-29 Thread Kris Nuttycombe

Okay. I might add a createPath method that returns List[String] or
Box[List[String]].

Kris

On Tue, Oct 27, 2009 at 9:14 PM, David Pollak
feeder.of.the.be...@gmail.com wrote:
 createLink returns an Option[NodeSeq].
 The reason for it is that the Scala XML literals do very well with
 Option[NodeSeq]:
 a href={Some(Text(/foo/bar))}/ // a href=/foo/bar/
 a href={None}/ // a/
 I'm cool with a helper method that returns a Box[String] or something that
 would otherwise be more flexible elsewhere.

 On Tue, Oct 27, 2009 at 4:43 PM, Kris Nuttycombe kris.nuttyco...@gmail.com
 wrote:

 I'm somewhat puzzled by the signature of Loc.Link.createLink -
 principally by the fact that it returns Box[NodeSeq] instead of some
 more path-like object. Due to having this signature, you can't simply
 override createLink to create an actual link (the way it's used by
 SiteMap inhibits this). Instead, it returns a path-like string wrapped
 in a Text in its default implementation. This seems like a
 not-very-useful thing to return; you can't use it in an SHtml.a or
 SHtml.link call without unwrapping it and the type system doesn't help
 you at all (Box[NodeSeq] is definitely *not* the meaning of those
 bytes).

 Is there any better path-like construct that a Link could be
 constructed around? Do people have their own Link implementations, or
 is the Link class mostly used internally (such that its api could be
 change to represent something path-link instead of xml-like?)

 Kris





 --
 Lift, the simply functional web framework http://liftweb.net
 Beginning Scala http://www.apress.com/book/view/1430219890
 Follow me: http://twitter.com/dpp
 Surf the harmonics

 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: Loc questions

2009-10-29 Thread Kris Nuttycombe

In this case, yes. Both createLink (and the new createPath on my
branch) take a parameter of type T where T is the parameterized type
of the Loc. If the path varies by instance, this is useful.

Kris

On Thu, Oct 29, 2009 at 8:47 AM, Naftoli Gugenheim naftoli...@gmail.com wrote:

 Should it start with create? I'm not too familiar with Loc, but is it 
 building something or calculating/returning something?

 -
 Kris Nuttycombekris.nuttyco...@gmail.com wrote:


 Okay. I might add a createPath method that returns List[String] or
 Box[List[String]].

 Kris

 On Tue, Oct 27, 2009 at 9:14 PM, David Pollak
 feeder.of.the.be...@gmail.com wrote:
 createLink returns an Option[NodeSeq].
 The reason for it is that the Scala XML literals do very well with
 Option[NodeSeq]:
 a href={Some(Text(/foo/bar))}/ // a href=/foo/bar/
 a href={None}/ // a/
 I'm cool with a helper method that returns a Box[String] or something that
 would otherwise be more flexible elsewhere.

 On Tue, Oct 27, 2009 at 4:43 PM, Kris Nuttycombe kris.nuttyco...@gmail.com
 wrote:

 I'm somewhat puzzled by the signature of Loc.Link.createLink -
 principally by the fact that it returns Box[NodeSeq] instead of some
 more path-like object. Due to having this signature, you can't simply
 override createLink to create an actual link (the way it's used by
 SiteMap inhibits this). Instead, it returns a path-like string wrapped
 in a Text in its default implementation. This seems like a
 not-very-useful thing to return; you can't use it in an SHtml.a or
 SHtml.link call without unwrapping it and the type system doesn't help
 you at all (Box[NodeSeq] is definitely *not* the meaning of those
 bytes).

 Is there any better path-like construct that a Link could be
 constructed around? Do people have their own Link implementations, or
 is the Link class mostly used internally (such that its api could be
 change to represent something path-link instead of xml-like?)

 Kris





 --
 Lift, the simply functional web framework http://liftweb.net
 Beginning Scala http://www.apress.com/book/view/1430219890
 Follow me: http://twitter.com/dpp
 Surf the harmonics

 




 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Loc questions

2009-10-27 Thread Kris Nuttycombe

I'm somewhat puzzled by the signature of Loc.Link.createLink -
principally by the fact that it returns Box[NodeSeq] instead of some
more path-like object. Due to having this signature, you can't simply
override createLink to create an actual link (the way it's used by
SiteMap inhibits this). Instead, it returns a path-like string wrapped
in a Text in its default implementation. This seems like a
not-very-useful thing to return; you can't use it in an SHtml.a or
SHtml.link call without unwrapping it and the type system doesn't help
you at all (Box[NodeSeq] is definitely *not* the meaning of those
bytes).

Is there any better path-like construct that a Link could be
constructed around? Do people have their own Link implementations, or
is the Link class mostly used internally (such that its api could be
change to represent something path-link instead of xml-like?)

Kris

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Proposal: Lift-unstable branch (was Are we willing to make a breaking change for Joda Time?)

2009-10-24 Thread Kris Nuttycombe

This brings to mind something I've been thinking about for a while -
what would folks think about the possibility of creating a
lift-unstable branch? Lift is only a couple of years old, and it
seems to me like it would be unfortunate to start stagnating
development due to concerns about backwards compatibility.

So, my proposal is this: that we create a branch of Lift that makes no
guarantees about source compatibility from release to release or
indeed day-to-day. This could be a proving ground for new ideas that
could then either be migrated into the main trunk with changes for
backwards compatibility, or could be source of new major version
releases.

If we don't have the freedom to make breaking changes at even such a
small level as Derek proposed with the Joda-Time situation, I think
it's a problem. Lift is too young to calcify just yet.

Kris

On Sat, Oct 24, 2009 at 12:03 PM, David Pollak
feeder.of.the.be...@gmail.com wrote:


 On Sat, Oct 24, 2009 at 3:05 AM, Jeppe Nejsum Madsen je...@ingolfs.dk
 wrote:

 Derek Chen-Becker dchenbec...@gmail.com writes:


 [...]

   It's entirely subjective, but I just strongly dislike the idea of
  using method names like jtNow, etc.

 I couldn't agree morecode just doesn't read nice anymore.

 I'm cool with other names, but, and this is a huge *BUT*...

 having two methods that have different return signatures is a huge source of
 bugs.  We saw this when we changed some of the S methods to return
 Box[String] rather than String.  There were hundreds of subtle errors.

 I'm happy to deprecate now and have goodNow (returns JodaTime) and evilNow
 (returns java.util.Date), but I am 100% against changing a return signature.

 I am sorry that my position is making folks unhappy, especially Derek who
 works hard and does a great job.

 Thanks,

 David


 /Jeppe





 --
 Lift, the simply functional web framework http://liftweb.net
 Beginning Scala http://www.apress.com/book/view/1430219890
 Follow me: http://twitter.com/dpp
 Surf the harmonics

 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: Playing around with Loc

2009-10-24 Thread Kris Nuttycombe

My motivation was twofold: first, I wanted to be able to control
access to a Loc based upon the data in the Loc itself (hence the new
IfValue and UnlessValue) and in the process I realized that there was
a disconnect in type safety between for example the Title LocParam and
the Loc itself because there was no enforcement that a LocParam added
to the Loc would respect the Loc's type. Secondly, I have found it
useful to have a construct like the following:

object Site {
   var locs: List[Loc[_]] = Nil
   def add[T](l: Loc[T]): Loc[T] = {
  locs = l :: locs
  l
   }

   val userLoc = add(new DataLoc[User](...))
   val orderLoc = add(new DataLoc[Order](...))
}

Then, in my Boot.scala I create the SiteMap like this:

LiftRules.setSiteMap(SiteMap(Site.locs.map(Menu(_)): _*))

The advantage of this construction is that I can refer to userLoc or
orderLoc from anywhere in my application and can use the Locs to
create links to display pages for various objects in a typesafe
fashion.

The main breaking change is a rename of defaultParams to defaultValue,
which I did mostly in the process of trying to understand the code
better, since it took me a few minutes at first to figure out the dual
use of the Param.

It also occurred to me that instead of adding the type parameter
directly to LocParam and adding the AnyLocParam name for
LocParam[Nothing], it would be just as easy to add a new parameterized
supertrait of LocParam which would break less code.

As far as sealing the trait goes, I've been bitten twice recently by
production bugs due to an incomplete match, so I figure that sealing
could be helpful so long as there's a well-known extension point for
user additions.

Kris

On Sat, Oct 24, 2009 at 5:18 PM, David Pollak
feeder.of.the.be...@gmail.com wrote:
 In general, it all sounds very good to me.
 What was your motivation (other than pure aesthetics)?
 If there are breaking changes to code, will they be super-obvious
 (compilation failures)?

 On Fri, Oct 23, 2009 at 5:04 PM, Kris Nuttycombe kris.nuttyco...@gmail.com
 wrote:

 Hi, all,

 I've been messing around with Loc a bit to try to tighten up the type
 safety of the parameterized type and add authentication LocParams that
 can be aware of the current value encapsulated by the Loc. I've put up
 some changes on the kjn-loc-wip branch and would really like some
 feedback.

 Some of the major changes:

 * gave LocParam a covariant type parameter to go with Loc's type
 parameter and made it a sealed trait, with UserLocParam[T] as the main
 extension point for user-defined traits. Added AnyLocParam as base
 trait of LocParam instances that are not dependent upon T
 * Added IfValue  UnlessValue LocParams
 * Made default Loc parameterized by Unit instead of NullLocParams
 * Some minor renaming to distinguish between uses of the Param name-
 - now all Param usages refer to LocParams
 * Removed need for a bunch of asInstanceOf casts

 What do you all think? Is this something that you'd like to see
 cleaned up  committed to master?

 Thanks,





 --
 Lift, the simply functional web framework http://liftweb.net
 Beginning Scala http://www.apress.com/book/view/1430219890
 Follow me: http://twitter.com/dpp
 Surf the harmonics

 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: confusing error on missing bind

2009-10-24 Thread Kris Nuttycombe

You'll notice if you look at the page source that the error you saw is
actually generously provided by Firefox, not by Lift. There is an
overload of bind that you could use that allow you to provide a
default for any unbound value, although of course this can obscure
errors. For a while there was also some code that gave more
informative error messages if you were running the app in development
mode, but for some reason I don't think I've seen those recently.

Hmm. Perhaps I need to make sure I'm not doing development in
production mode myself. :)

Kris

On Sat, Oct 24, 2009 at 5:39 PM, bob rbpas...@gmail.com wrote:

 the following error was the result of a bug in my app: i had an
 element (queries:service/) in the template which I had forgotten to
 bind in the snippet

This page contains the following errors:
error on line 18 at column 48: Namespace prefix queries on service is not 
defined

 in a big red box

 first, there is no line 18 in the template, and line 18 in my
 source code is a blank line, so I couldn't tell which line (let alone
 which column column) it was referring to. and since the error appeared
 in the webpage (rather than, say Console), i expected it referred to
 line 18 in the template, but in fact my error was in the code.

 second, the error would be more informative if it said something along
 the lines of:

. : Namespace prefix 'queries' on 'service'  in template index.html was 
not bound
 or even

. : queries:service in template index.html' was not bound


 thanks, bob

 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: Playing around with Loc

2009-10-24 Thread Kris Nuttycombe

On Sat, Oct 24, 2009 at 5:18 PM, David Pollak
feeder.of.the.be...@gmail.com wrote:
 In general, it all sounds very good to me.
 What was your motivation (other than pure aesthetics)?
 If there are breaking changes to code, will they be super-obvious
 (compilation failures)?


Oh... and yeah, replacing NullLocParams with Unit was purely aesthetic. :)

Kris

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Playing around with Loc

2009-10-23 Thread Kris Nuttycombe

Hi, all,

I've been messing around with Loc a bit to try to tighten up the type
safety of the parameterized type and add authentication LocParams that
can be aware of the current value encapsulated by the Loc. I've put up
some changes on the kjn-loc-wip branch and would really like some
feedback.

Some of the major changes:

* gave LocParam a covariant type parameter to go with Loc's type
parameter and made it a sealed trait, with UserLocParam[T] as the main
extension point for user-defined traits. Added AnyLocParam as base
trait of LocParam instances that are not dependent upon T
* Added IfValue  UnlessValue LocParams
* Made default Loc parameterized by Unit instead of NullLocParams
* Some minor renaming to distinguish between uses of the Param name-
- now all Param usages refer to LocParams
* Removed need for a bunch of asInstanceOf casts

What do you all think? Is this something that you'd like to see
cleaned up  committed to master?

Thanks,

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: NetBeans is barfing on the new pom.xml structure

2009-10-23 Thread Kris Nuttycombe

I ran into that -it's a missing version number in the root pom. Fixed
in my kjn-loc-wip branch if you just want to grab it from there.

On Fri, Oct 23, 2009 at 3:41 PM, David Pollak
feeder.of.the.be...@gmail.com wrote:
 Folks,

 Any idea why NetBeans doesn't like the new Lift pom structure?

 Thanks,

 David

 --
 Lift, the simply functional web framework http://liftweb.net
 Beginning Scala http://www.apress.com/book/view/1430219890
 Follow me: http://twitter.com/dpp
 Surf the harmonics

 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: Why fields are declared as 'object' with Mapper/Record?

2009-10-06 Thread Kris Nuttycombe

One major reason for the inner object pattern is that when you have
a singleton object extending a trait, it is possible for the trait to
reflect upon that object's class to obtain information like the name
of the field. You'll see this pattern used throughout Lift (AnyVar
subclasses RequestVar and SessionVar *must* be instantiated as objects
- if you do something like this:

class StringRequestVar(x: = String) extends RequestVar[String](x)

object MyState {
   val v1 = new StringRequestVar(foo)
   val v2 = new StringRequestVar(bar)
}

then v2 will actually stomp on v1 at instantiation, and any assignment
to v1 will stomp on v2 and vice versa.

(I don't really care for this pattern either, but understand the
justification for it.)

Kris


On Tue, Oct 6, 2009 at 12:38 AM, Oleg G. ojo...@gmail.com wrote:

 Sorry if its a stupid question, but why?

 I like the idea very much and trying to understand all the aspects.
 Fields declared as 'objects' can't be overridden. Is it intended? If
 so why?

 Consider following oversimplified example:
  trait Field
  trait Prop1
  trait Prop2
  trait Prop3

  class Person {
    val name = new Field with Prop1 with Prop2
  }

  class CustomPerson extends Person {
    override val name = new Field with Prop1 with Prop2 with Prop3
  }

 Is there something wrong?

 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: Lift compiled against 2.7.7.RC1

2009-10-02 Thread Kris Nuttycombe

Hi, David,

Is the RC available from a public Maven repo, or did you have to
install it locally?

Kris

On Fri, Oct 2, 2009 at 4:27 PM, David Pollak
feeder.of.the.be...@gmail.com wrote:
 Folks,
 I have pushed a branch of Lift that compiles against Scala 2.7.7.RC1 to the
 Lift repository (dpp_wip_277).
 Indrajit, please do Hudson magic such that there are Maven artifacts that
 people can test against and send out changes that people will need to make
 to their pom.xml file to test against the 2.7.7.RC1 build of Lift.
 I found no source incompatibilities, so your code should 'just work.'  But,
 please report any unexpected (i.e., different than Lift running against
 Scala 2.7.5) behaviors to this list.  We'll reproduce and determine if the
 issue is in Lift (we'll update Lift) or in 2.7.7.RC1 (we'll post to the
 Scala list/trac).
 Thanks,
 David

 --
 Lift, the simply functional web framework http://liftweb.net
 Beginning Scala http://www.apress.com/book/view/1430219890
 Follow me: http://twitter.com/dpp
 Surf the harmonics

 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: RequestVar not Persisting

2009-09-04 Thread Kris Nuttycombe

While your updated list will be modified by the loadUsers closure,
the for comprehension will only be executed on the initial rendering
of the snippet, not as part of the execution of your loadUsers or
processUsers callbacks. So the state of the RequestVar will never be
reset.

Kris



On Fri, Sep 4, 2009 at 2:01 PM, Peter Robinettpe...@bubblefoundry.com wrote:

 I'm trying to use a RequestVar to keep the Mapper model that I'm
 editing throughout the lifetime of a simple form. Specifically, I'm
 adding Users to a Role. The problem is, the RequestVar seems to get
 recreated at every step and, I must admit, it's driving me crazy and
 I'd appreciate some help.

 Here's my snippet code:
  object currentRole extends RequestVar[Role](new Role)

  def addUsers(xhtml: NodeSeq): NodeSeq = {
    val possible = User.findAll().map(user = (user.id.toString,
 user.name))
    val current = role.users.map(user = user.id.toString)
    var updated: List[Long] = Nil

    for {
      id - S.param(id)
      num - Full(id.toLong)
      e - Role.find(By(Role.id, num))
    } {
      println(currentRole)
      currentRole(e)
      println(currentRole)
    }

    def loadUsers(ids: List[String]) = {
      updated = ids.map(_.toLong)
    }

    def processUsers() = {
      println(updated)
      println(currentRole)
    }

    bind(entry, xhtml,
      users - SHtml.multiSelect(possible, current, loadUsers(_)),
      submit - SHtml.submit(Update, processUsers)
    )
  }

 And the template:
 lift:surround with=default at=content
  lift:ManageRoles.addUsers form=POST
    entry:users /
    entry:submit /
  /lift:ManageRoles.addUsers
 /lift:surround

 And my STDOUT:
 com.equalnetworks.model.Role={Parent
 Role:=NULL,datacenter=NULL,Name:=,id=-1,Delete:=false,Update:=false,Create:=false,Read:=false}
 com.equalnetworks.model.Role={Parent
 Role:=NULL,datacenter=NULL,Name:=Customers,id=2,Delete:=false,Update:=false,Create:=false,Read:=false}
 INFO - Service request (GET) /roles/memberships/ took 87 Milliseconds
 INFO - Service request (GET) /classpath/jquery.js took 7 Milliseconds
 INFO - Service request (GET) /images/ajax-loader.gif took 6
 Milliseconds
 List(1, 2)
 com.equalnetworks.model.Role={Parent
 Role:=NULL,datacenter=NULL,Name:=,id=-1,Delete:=false,Update:=false,Create:=false,Read:=false}

 As you can see, I'm using a for comprehension to take a request
 parameter (e.g. /roles/memerships/?id=2) and get a Role, which I then
 successfully assign to my currentRole RequestVar (see how id is first
 -1 and then 2). Unfortunately once I submit the form processUsers is
 called and currentRole again has an id of -1. Why is this?

 Thanks in advance,
 Peter Robinett
 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: Dependency Injection in Lift

2009-09-03 Thread Kris Nuttycombe

On Wed, Sep 2, 2009 at 11:05 PM, Chris Lewisburningodzi...@gmail.com wrote:

 DPP's explanation of how to mock infrastructure code (bound to S, etc)
 made since, but it still feels a bit sketchy. Again, this may be my
 misunderstanding, but he's saying to do something like replace the value
 of the function S.redirectTo, so I can test as needed. So here we go:

 S.redirectTo = () = { println(redirect received); }

 Now that value is overwritten. What if I was unit testing a bunch of
 snippets, some of those snippets call the same global function, but I
 need to do per-snippet recordings/inspections of those calls? Must I
 reconfigure the values under S each time? What if I forget one?

 I've seen Bill Venner's specs - haven't used it but it looks cool. I've
 not heard of mokkito (and didn't see a relevant link on google), so I
 don't know how these tools might help here. Do share :-)

It's mockito - http://mockito.org/ which looks like EasyMock (what
I've used most) except that the interfaces are a bit more fluent and
mockito allows mocking of concrete classes, not just interfaces.

Kris

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: Dependency Injection in Lift

2009-09-03 Thread Kris Nuttycombe

This is a great analysis, Chris, thank you. I'll be saving this one
away for my next discussion of DI and IOC - the Law of Demeter point
is a particularly salient one that had been implicit in my thinking
but really needs to be discussed.

As usual, when people have different axioms communication is difficult
because such axioms tend to be assumed common when they really
probably are not.
Kris

On Thu, Sep 3, 2009 at 10:02 AM, Chris Shorrockchris.shorr...@gmail.com wrote:
 Let me prefix this by saying this has been a brilliant conversation with
 some obviously smart people and has been enjoyable to follow over the past
 little bit.
 I'll argue (briefly as possible, although I'm notoriously wordy) that one of
 the biggest deltas between the two sides of the conversation is the concept
 of IoC and how it's being applied within the context of Lift. If we define
 dependency injection as the ability to retrieve a reference to a depended
 upon object it's been shown that we can achieve this through the various
 patterns which have proven themselves viable due to how the language has
 constructed itself.
 it sounds like the bigger stumbling point is the concept of IoC, that is,
 how we retrieve a reference to these objects. While dependency injection and
 IoC may be synonyms in some contexts I want to define them differently here,
 and I would say then define IoC different from DI in that it changes how
 things are referenced within the execution graph of an application. DI
 can obviously thus be used to achieve IoC.
 In a previous message David questions::

 How is:

 class Foo(snippetConstructors: XX) extends Snippet {}

 Any more abstract than:

 class Foo with MyProjectState {}

 where:

 trait MyProjectState { def snippetConstructor: XX}

 And in this case I would say the difference is IoC. When testing Foo in the
 first instance, it's explicitly clear what you need to mock out to Test
 Foo, where in the later example what you require is a little less clear. Of
 course this is a pretty trivial example so if we example further the
 differences between:
 def foo(state:S) = { ... }
 vs
 def state = S
 def foo() = {  /* uses state */ }
 Again, pretty similar. But the difference is is that foo in the first case
 has declared precisely what it requires to perform it's operation. It's
 contract is very clear. Foo in the later case looks like it can be called
 without any parameter, but it implicitly needs a reference to S via the
 state() method, thus you need an explicit understanding of how things are
 used within a method to be able to test, or use it.  Again simple example,
 but as the complexity of a method grows this problem exacerbates itself
 until the point where testing has becomes very difficult.
 Is this a huge deal, maybe not, but when this type of thing is repeated over
 the course of time, with many developers on a project I think it could get
 hard to manage. Finally, the other thing that I don't believe anybody has
 mentioned is how this all relates to LoD. In the example above, if we need
 to do something like:
 def state = S
 def foo() = { state.servletRequest.getCookies() }
 In order to test not only do we need to understand foo(), how it's using S
 via the state method but we also need to understand that S is calling
 servletRequest, which is calling cookies, further complicating testing.
 def foo(cookies:Array[Cookie]) = { ... }
 Would be a much preferable method signature. Anyways, I'll wrap up my
 thoughts there, most of my opinions here come from having lead development
 on a large SOA system where we made TONS of architectural mistakes, which
 really made testing a pain in the ass. In the past 6 or so we've started  to
 employ some of the techniques discussed here and it's really made things
 much easier, and cleaner. With that said, this was all Java based, and while
 I've been using Scala at personal projects for some time now, only recently
 did we start to roll it out within the company, so it's possible my opinions
 may be deprecated due to lack of hands on unit-testing experience using some
 of the patterns mentioned above :)
 (love the framework by the way)

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: Dependency Injection in Lift

2009-09-02 Thread Kris Nuttycombe

I think that the following really misses the point of dependency injection:

On Wed, Sep 2, 2009 at 11:39 AM, David
Pollakfeeder.of.the.be...@gmail.com wrote:

 Let's say we're running in test mode, in Boot.scala:
 if (Props.testMode) {
   MyAppRules.paymentGateway = () = MockPaymentGateway
 }

In order to test in isolation, production code should never have to
have any idea that mock classes might exist. In most cases, they don't
- the mock is a dynamic proxy that has expectations configured on it
*in the test case*.

Dependency injection can be used to do configuration at any level of
granularity, not just at the global config level that is Boot.scala.
This is the whole reason the enterprise world has rejected singletons,
because any code that uses such a singleton cannot be tested in
isolation without messing with a class that may be largely irrelevant
to the functionality being tested. If the only dependencies that an
object has are provided through constructor parameters, any and all
external state that the object depends upon can be trivially mocked
simply by passing in different parameters.

With respect to Tim's comment, with Guice you usually don't use a
configuration file; your configuration is in code. In a test case, you
create an Injector using a set of modules that have the rules for
object creation (specifications for what type or instance of object is
to be injected in any given position) and then you use this Injector
as your factory. In a production system, the process is exactly the
same - but you create the Injector with a different set of modules.

In reading this thread, I can't help but to wonder... how extensively
have those of you who are purporting traits and partial functions to
be a replacement for DI actually used a modern dependency injection
framework?

Kris

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



Fwd: [Lift] Re: Dependency Injection in Lift

2009-09-02 Thread Kris Nuttycombe

On Wed, Sep 2, 2009 at 4:30 PM, David
Pollakfeeder.of.the.be...@gmail.com wrote:


 On Wed, Sep 2, 2009 at 1:27 PM, Kris Nuttycombe kris.nuttyco...@gmail.com
 wrote:

 I think that the following really misses the point of dependency
 injection:

 On Wed, Sep 2, 2009 at 11:39 AM, David
 Pollakfeeder.of.the.be...@gmail.com wrote:
 
  Let's say we're running in test mode, in Boot.scala:
  if (Props.testMode) {
    MyAppRules.paymentGateway = () = MockPaymentGateway
  }

 In order to test in isolation, production code should never have to
 have any idea that mock classes might exist. In most cases, they don't
 - the mock is a dynamic proxy that has expectations configured on it
 *in the test case*.

 At some point, the concrete implementation has to be specified, DI or no.
 At some point there needs to be a definition (in a config file, in an
 annotation, in Boot, in the current session, on the current call stack) of
 the concrete class.  Having a factory function that can be changed means
 that you can define how an instance is created, that's all.

My point is that Boot is part of the production codebase, and as such
it should be entirely ignorant of the test harness.

 Dependency injection can be used to do configuration at any level of
 granularity, not just at the global config level that is Boot.scala.

 And my example above allowed for configuration at any level (well... the
 example didn't include 'current request' but that's a change from SessionVar
 to RequestVar)

But can you test a snippet in the absence of references to RequestVar,
SessionVar, S, and the rest of Lift if the snippet makes calls to such
objects? I don't want to have to set up the state of a Req having been
processed through a RewriteRequest and so on to create an environment
for my snippet to run in.

 This is the whole reason the enterprise world has rejected singletons,
 because any code that uses such a singleton cannot be tested in
 isolation without messing with a class that may be largely irrelevant
 to the functionality being tested.

 I guess this is where our philosophies diverge.  I believe in integration
 tests and unit tests of things that deal with untyped data (Strings).  Most
 other forms of testing tend in my experience to be pointless: they take lots
 of time to write and run and yield very few delta defects.

I guess I'm just not that good; I miss boundary cases in my algorithms
on a not-too infrequent basis, particularly when there's a large state
space that the configurations of my persistent data can occupy. I find
unit tests to be extremely helpful, particularly with how often the
requirements I'm trying to satisfy grow and force me to refactor.

What's strange to me is that in my experience, unit tests are quick to
write and run, while integration tests are the ones that are a
nightmare to set up for.

 Additionally, the S pattern looks like a global, but is in fact a front end
 to thread-specific state.  Scala's DynamicVar (S sits on top of a DynamicVar
 style pattern) gives you a lot of latitude to have a concrete symbol for
 something with a dynamic meaning for that symbol.

I understand this, but to me thread-local state is little better than
global state, because when you come down to it RequestVar and
SessionVar instances behave like globals within the context of the
request or the session, respectively. If I have multiple snippets on a
page that both happen to mutate the state of a RequestVar without
checking it, code that's ignorant of the order of snippet calls cannot
reliably  make any assumptions about said state. This has caused me
bugs that took serious time to track down and in some cases still
aren't fully resolved.

 If the only dependencies that an
 object has are provided through constructor parameters, any and all
 external state that the object depends upon can be trivially mocked
 simply by passing in different parameters.

 I don't understand the difference between having a parameter magically
 passed because on an annotation and making a method call to get a parameter
 that satisfies an interface other than the call is explicit and the
 annotation based mechanism is something that happens by magic where I regard
 magic to be bad.

I guess I feel like dependency injection is a declarative approach,
which I prefer to the imperative method call. Ultimately, the
significant question is what is allowed to configure how that method
call responds; if there are several layers of framework (Boot, S,
RequestVar, etc.) between the configurer and the configuree I don't
have confidence that the state I'm trying to establish wont get mucked
up along the way. DI is hardly magic; it's just a matter of having a
piece of code that will calculate a dependency graph for you then find
the correct objects to plug in from a flat scope to establish the
state of the object you request.

 With respect to Tim's comment, with Guice you usually don't use a
 configuration file; your configuration is in code

[Lift] Re: todo app., Oracle: Invalid column type

2009-08-11 Thread Kris Nuttycombe

ROWID is indeed a pseudo-column that isn't even stable, to my
knowledge. I've always know it as a 0-based index over the rows
returned from a query.

As of 9i, at least, Oracle insisted that you implement
auto-incrementing columns manually using a sequence and an associated
trigger. I presume that they have a good reason for this, perhaps
related to replication or something. It's a hassle.

Kris

On Mon, Aug 10, 2009 at 4:26 PM, Derek Chen-Beckerdchenbec...@gmail.com wrote:
 OK, I think that I've at least figured out the cause of the exception. The
 Oracle driver is set to use ROWID for primary keys and long indices. As far
 as I can tell from the Oracle docs, ROWID is a pseudo-column and shouldn't
 really be used as a column type in table creation DDL. The Boolean
 conversion appears to be working correctly, so now I just need to figure out
 the best way to abstract auto-increment column creation.

 Derek

 On Mon, Aug 10, 2009 at 1:51 AM, Jon Kleiser jon.klei...@usit.uio.no
 wrote:

 Hi,

 Here's the contents of my default.props file:

 db.driver = oracle.jdbc.OracleDriver
 db.url = jdbc:oracle:thin:@myserver.site.no:1540:mydatabase
 db.user = myuser
 db.password = xxx

 The file is located in todo/src/main/webapp/WEB-INF/classes/props/

 /Jon


 On 8/10/09 5:01 AM, Derek Chen-Becker wrote:

 Or at least the JDBC connection URL that you're using (no passwords or
 username needed).

 On Sun, Aug 9, 2009 at 8:25 AM, Derek Chen-Becker dchenbec...@gmail.com
 mailto:dchenbec...@gmail.com wrote:

    Please send me the props file. I want to duplicate exactly (as much
    as possible) what you're doing.

    Derek


    On Sat, Aug 8, 2009 at 2:14 PM, Jon Kleiser jon.klei...@usit.uio.no
    mailto:jon.klei...@usit.uio.no wrote:

        Hi Derek,

        The attached file should be identical to the project I use for
        the Oracle
        testing, except that the file specifying the Oracle connection
        (was it
        default.props?) is missing. I have it on my PPC Mac, not here. I
        guess you
        know how to create that file and where to put it. If you're not
        sure, let
        me know, and I'll send you the info early Monday (or later).

        /Jon


 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: Rational Behind One Callback per Form Field

2009-07-25 Thread Kris Nuttycombe

On Sat, Jul 25, 2009 at 3:18 PM, Devon Tuckerdevonrtuc...@gmail.com wrote:

 Hi all,

 I've been working with Lift for about a little while now; there are
 still plenty of aspects of Lift I haven't touched yet. One thing I am
 curious about at this point though is the rationale behind having one
 callback per field when generating forms. Each SHtml form element
 needs to be handed its own call back function. This strikes me as a
 kind of cumbersome, for instance the form examples on the Wiki and in
 the Exploring Lift book all follow this pattern:

 someSnippet(xml: NodeSeq) = {
    var fieldOne = 
    var fieldTwo = 
    def sumbitHandler() = { ... }

    bind(prefix, xml,
        fieldOne - SHtml.text(fieldOne, fieldOne = _),
        fieldTwo - SHtml.text(fieldTwo, fieldTwo = _),
        formSubmit - SHtml.submit(Submit, submitHandler))
 }

 I've seen several examples of this exact pattern at this point and it
 makes the whole fieldOne = _ callback seem like needless boiler-plate.
 Why not allow for just one callback function that works over some
 object encapsulating an entire form? Am I missing something?

This is a pretty interesting question; I've sometimes wondered whether
the use of bare closures for this purpose isn't a bit too close to the
metal. It would be possible to do something like what you describe,
but the binding of each form element would still have to have some
reference to the variable being set. Now this could conceivably be
achieved in a few different ways:

You could have each bound variable, instead of being a regular Scala
variable, be an object extending some trait that the SHtml field
builders know about. This would mean that you'd just pass references
to those objects to the field builders, and they'd be automatically
mutated with the form field value on submit. The amount of boilerplate
-- maybe something like object fieldOne extends StringField -- would
be similar to what you get from the current situation. The one thing I
like about this is that the state of such a field could be tracked a
bit better; in the past I've found myself with a lot of code like the
following:

var fieldOne: Option[MyObject] = None
val options: Seq[(MyObject, String)] = ...

bind(prefix, xml,
   myselect - SHtml.selectObj(options, Empty, a = fieldOne = Some(a))

just to avoid mucking about with nulls, and this definitely gets laden
with boilerplate when you have a bunch of fields, particularly in the
handler function.

You could have the SHtml field builders return some sort of object
apart from an XML node, store that in a local val, and then have your
form-level callback refer to that value. This seems like an attractive
possibility to me because it could eliminate the need for mutable
variables entirely; the resulting objects could dynamically obtain
their submitted values from the Req when referenced by the callback
function.

Neither of these approaches exist yet, but you could build either one
of them atop the current framework, which I think is sort of one of
the main points of Lift at this stage in its development - it gives
you the most powerful tools it can, and one can build higher-level
abstractions atop what it provides.

Kris

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: How to test/TDD lift apps?

2009-07-03 Thread Kris Nuttycombe

Hi, David,

Thanks for taking some time to look at this problem. I'm a little
concerned about the approach, though - should Lift really behave
significantly differently in test mode than it does in production
mode? This seems like it would lend to the possibility of subtle bugs
that don't show up until one is in production.

With respect to unit testing, Lift's singletons depend upon underlying
thread-local variables (via ThreadGlobal) to maintain state. I'm just
musing here, but do you think it might be possible to inject a layer
of indirection between Lift's singletons and the underlying state
mechanism so that the state maintenance layer could be mocked out for
tests?

This brings some other issues I've been wrangling with lately to mind.
Please forgive me for rambling, but I think that the issue of testing
is intimately tied to how Lift deals with state maintenance.

State is sort of becoming a bugbear for me as my Lift app becomes more
complex. I'm not sure whether I'm just doing things wrong or what, but
I'm finding that using RequestVars and StatefulSnippets to maintain
state makes it difficult to build composable editing components. As an
example, I've got a StatefulSnippet that I use to build an object of
type EventTrigger. There are a few possible subclasses of EventTrigger
that can be produced through the workflow managed by the
StatefulSnippet, and switching between the type options and such works
well.

The problem is that an EventTrigger may be associated with some number
of Products, of which there are also a number of subclasses. So, I
also have a similar StatefulSnippet that manages the flow of creating
Products. But how do I pass the state of a newly created (or selected
existing) EventTrigger from one StatefulSnippet to the next? As far as
I can tell, there is no way to hand off control between
StatefulSnippet instances - instead I must populate a RequestVar and
use a redirect in the transition. Both sides of this state transaction
have expectations of the state of the intermediate RequestVar, but
there is no way to enforce that it be populated before the second
snippet attempts to use it. This feels very Model 1 to me. It's the
same case wherever I use RequestVar - some component (say a link) sets
a value, then some other component reads it, and while the ReqestVar
provides type safety for the value type, there is no associated type
safety available for the call, as both links and redirects simply use
strings to define behavior.

This all seems to fall out of the fact that the processing of a
template at a Loc results in reflective invocation of snippet
functions. The template itself, which is outside the type system,
defines the behavior at a Loc. As such, every snippet must be written
to operate correctly in the absence of any piece of the state it
expects. At least in my app, this ends up as an obnoxiously large
amount of boilerplate.

I think that I must be doing something wrong, because the feel of my
app is that it is held together by snot and string, threaded through
RequestVars that I hope will be populated with the correct values at
the correct times and redirects that I hope are pointing to the right
locations. At the same time, I can't figure out how else Lift will
permit me to handle my state. With each new feature I add, I become a
little more dismayed.

Please, how can I handle these problems better?

Thanks,

Kris




On Fri, Jul 3, 2009 at 10:43 AM, David
Pollakfeeder.of.the.be...@gmail.com wrote:
 Jeppe,

 Once I check in some code (in about 20 minutes), if you run Lift in Test
 mode (-Drun.mode=test), forms, etc. will have stable names which makes
 testing easier.

 Thanks,

 David

 On Thu, Jul 2, 2009 at 1:13 PM, Jeppe Nejsum Madsen je...@ingolfs.dk
 wrote:

 Hi,

 Having taken the first baby steps and gotten a Lift app running, it's
 time to bring back some of the old engineering practices to make sure
 things keep running when new features are added at a rapid pace :-)

 I'm interested in how people are testing their Lift apps, both at the
 unit test level (ie. specs/scalatest with no container) and at the
 integration test level (running in servlet container). Also, how are you
 doing TDD with Lift (if at all).

 Specifically, I've run into the following issues:

 1) Testing model classes. Many require access to S (ie to read
 resources) or other static Lift constructs. How can you mock these?

 2) Testing snippets. Same issue with S, but more related to the actual
 request, eg. S.param

 For in-container testing it seems the practice of generating unique
 names for form fields, makes it difficult to use tools like Selenium to
 do browser based testing? How do you handle this?

 Any input is appreciated

 /Jeppe





 --
 Lift, the simply functional web framework http://liftweb.net
 Beginning Scala http://www.apress.com/book/view/1430219890
 Follow me: http://twitter.com/dpp
 Git some: http://github.com/dpp

 



[Lift] Re: Changes to ajax handling?

2009-07-02 Thread Kris Nuttycombe

Marius, that fix appears to work fine, thank you!

Bloody nulls. :)

Kris

On Thu, Jul 2, 2009 at 7:17 AM, marius d.marius.dan...@gmail.com wrote:

 Corrected and pushed. Please do an update and give it a try.

 Br's,
 Marius

 On Jul 2, 8:56 am, marius d. marius.dan...@gmail.com wrote:
 On Jul 2, 12:40 am, Kris Nuttycombe kris.nuttyco...@gmail.com wrote:



  To answer my own question, looking over the commit log 28595307 looks
  extremely suspicious. I can revert it locally but would prefer a
  mainline fix, and don't want to attempt it myself. Marius?

  Kris

  On Wed, Jul 1, 2009 at 3:33 PM, Kris

  Nuttycombekris.nuttyco...@gmail.com wrote:
   Hi, all,

   Have there been recent changes made to liftAjax.js? I am encountering
   new errors from an ajaxSelect() today that were not present yesterday.
   Firebug complains:

   Use of getBoxObjectFor() is deprecated. Try to use
   element.getBoundingClientRect() if possible.
   [Break on this error] undefined
   liftAjax.js (line 111)
   aboutToSend.responseType is null
   lift_doAjaxCycle()()liftAjax.js (line 111)
   lift_ajaxHandler()()liftAjax.js (line 21)
   onchange(change )add_trig...Gyw%3D%3D (line 2)
   [Break on this error] if (aboutToSend.responseType.toLowerCase() === 
   json)

 That is my commt but right now I don,t see how it affects other
 things ... But I,ll definitely look on it today. Note that there is no
 intent for ajax behavior changes .. Just an augmentation ...

   Thanks,

   Kris
 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Changes to ajax handling?

2009-07-01 Thread Kris Nuttycombe

Hi, all,

Have there been recent changes made to liftAjax.js? I am encountering
new errors from an ajaxSelect() today that were not present yesterday.
Firebug complains:

Use of getBoxObjectFor() is deprecated. Try to use
element.getBoundingClientRect() if possible.
[Break on this error] undefined
liftAjax.js (line 111)
aboutToSend.responseType is null
lift_doAjaxCycle()()liftAjax.js (line 111)
lift_ajaxHandler()()liftAjax.js (line 21)
onchange(change )add_trig...Gyw%3D%3D (line 2)
[Break on this error] if (aboutToSend.responseType.toLowerCase() === json) {


Thanks,

Kris

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: Changes to ajax handling?

2009-07-01 Thread Kris Nuttycombe

To answer my own question, looking over the commit log 28595307 looks
extremely suspicious. I can revert it locally but would prefer a
mainline fix, and don't want to attempt it myself. Marius?

Kris

On Wed, Jul 1, 2009 at 3:33 PM, Kris
Nuttycombekris.nuttyco...@gmail.com wrote:
 Hi, all,

 Have there been recent changes made to liftAjax.js? I am encountering
 new errors from an ajaxSelect() today that were not present yesterday.
 Firebug complains:

 Use of getBoxObjectFor() is deprecated. Try to use
 element.getBoundingClientRect() if possible.
 [Break on this error] undefined
 liftAjax.js (line 111)
 aboutToSend.responseType is null
 lift_doAjaxCycle()()liftAjax.js (line 111)
 lift_ajaxHandler()()liftAjax.js (line 21)
 onchange(change )add_trig...Gyw%3D%3D (line 2)
 [Break on this error] if (aboutToSend.responseType.toLowerCase() === json) {


 Thanks,

 Kris


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Examples of ajaxForm(...)

2009-06-30 Thread Kris Nuttycombe

Hi, all,

I'm looking for some examples of uses of ajaxForm in cases where
multiple form elements are included and processed on submit. Can
someone point me in the right direction? The only examples I found in
the example apps on github were related to Comet.

Thanks,

Kris

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: Examples of ajaxForm(...)

2009-06-30 Thread Kris Nuttycombe

Thanks, Marius, you answered my unspoken question as to whether the
callbacks registered with regular old form elements from SHtml are
called in the AJAX processing lifecycle. The hidden field piece
(instead of / in addition to a submit button) is what I was missing.

Kris

On Tue, Jun 30, 2009 at 2:09 PM, marius d.marius.dan...@gmail.com wrote:

 Imagine that your snippet has a bunch of form elements ... such as:


 lift:Ajax.form

  f:inputFirstName/
  f:inputLastName/

 /lift:Ajax.form

 and your snippet function:

 def form(xml: NodeSeq): NodeSeq = {

  ajxForm(bind(
   f, xml,
   inputFirstName -SHtml.text(, (s) = {//do something here})
   inputLastName -SHtml.text(, (s) = {//do something here})
  ) ++ SHtml.hidden(() = {
  // Do processing
 }))
 }

 So to the snippet child nodes we append a hidden element where we have
 our processing function. Note that Lift automatically serializes the
 form elements as key/value pairs forming a HTTP query string. Hence in
 your anonymous function fir the hidden element you can just do
 whatever action you want. I actually added the hidden so that when
 it's called all functions bound to you form lements were executed.


 The other way of working with ajax forms is to actually use jsonForm.

 Br's,
 Marius

 On Jun 30, 8:39 pm, Kris Nuttycombe kris.nuttyco...@gmail.com wrote:
 Hi, all,

 I'm looking for some examples of uses of ajaxForm in cases where
 multiple form elements are included and processed on submit. Can
 someone point me in the right direction? The only examples I found in
 the example apps on github were related to Comet.

 Thanks,

 Kris
 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: Pagination in lift?

2009-06-28 Thread Kris Nuttycombe

If you're using JPA, pagination is pretty trivial. Here's what I use
in my app to provide it; the links stuff is primitive and needs
improvement but works.

import net.liftweb.util.Helpers._
import net.liftweb.http.SHtml._
import scala.xml._

class Paginator[A](val queryBase : String, val ordering :
Option[String], val params : Pair[String,Any]*) extends Paging[A] {
def count() : Long = {
val query = EM.createQuery[Long](SELECT COUNT (o)  + queryBase)
for (p - params) query.setParameter(p._1, p._2)
query.getSingleResult
}

/** 0 based page index. */
def getPage(page : Int, pageSize : Int) : Collection[A] = {
val query = EM.createQuery[A](SELECT o  + queryBase +
ordering.getOrElse())
for (p - params) query.setParameter(p._1, p._2)
query.setFirstResult(page * pageSize)
query.setMaxResults(pageSize)
query.getResultList
}

/**
 * Display a pagination list for the order search.
 */
def pageLinks(maxRecords: Int, pageSetter: Int = Unit, loc:
String, xhtml : NodeSeq) : NodeSeq = {
val pageCount = (count / maxRecords).intValue + 1

(0 until pageCount).flatMap(i = bind(page, xhtml, link -
link(loc, () = pageSetter(i), Text(i.toString
}
}

object Paginator {

def emptyPaginator[A]  = new Paging[A]() {
def count = 0
def getPage(page : Int, pageSize: Int) : Collection[A] = Nil
}
}


On Sun, Jun 28, 2009 at 1:44 PM, Naftoli Gugenhemnaftoli...@gmail.com wrote:

 Does lift have built in support for pagination -- breaking up a query and 
 continuing it across multiple pages, and clicking the headers to sort?
 If not how hard is it?

 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: [scala] implementation hiding

2009-06-26 Thread Kris Nuttycombe

This does not hide the type of MSequitor, but:

trait MBrace[C[X] : MBrace[C,X],A] {
  def nest( a : A ) : C[A]
  def flatten[T : C[C[A]]]( bsq : T ) : C[A]
}

// a monad that is a Seq
trait MBraceSeq[C[X] : MBrace[C,X] with Seq[X],A] extends MBrace[C,A]

trait MSequitor[A] extends Seq[A] with MBrace[MSequitor,A]

object MBraceSequitor {
  // one of the simplest witnesses of monad i can find
  private case class MSequitorImpl[A]( a_ : A* ) extends MSequitor[A] {
override def nest( a : A ) = new MSequitorImpl[A]( a )
override def flatten[T : MSequitor[MSequitor[A]]]( bsq : T ) :
MSequitor[A] = {
  (new MSequitorImpl[A]( ) /: bsq)( {
( acc : MSequitor[A], e : MSequitor[A] ) = new
MSequitorImpl[A]( acc ++ e : _* )
  } )
}
override def length = a_.length
override def elements = a_.elements
override def apply( n : Int ) = a_.apply( n )
  }
}

// a statement of the instance relation
class MBraceSequitor[A] extends MBraceSeq[MSequitor,A] {
  import MBraceSequitor._
  val empty : MSequitor[A] = new MSequitorImpl[A]( )
  override def nest( a : A ) = empty.nest( a )
  override def flatten[T : MSequitor[MSequitor[A]]]( bsq : T )
  : MSequitor[A] = empty.flatten( bsq )
}

Kris

On Fri, Jun 26, 2009 at 12:47 PM, Meredith
Gregorylgreg.mered...@gmail.com wrote:
 All,

 Am i being stupid or is it impossible in the code below to construct a
 natural way to hide the concrete case class?

 Best wishes,

 --greg

 trait MBrace[C[X] : MBrace[C,X],A] {
   def nest( a : A ) : C[A]
   def flatten[T : C[C[A]]]( bsq : T ) : C[A]
 }

 // a monad that is a Seq
 trait MBraceSeq[C[X] : MBrace[C,X] with Seq[X],A] extends MBrace[C,A]

 // one of the simplest witnesses of monad i can find
 case class MSequitor[A]( a_ : A* ) extends Seq[A] with MBrace[MSequitor,A] {
   override def nest( a : A ) = new MSequitor[A]( a )
   override def flatten[T : MSequitor[MSequitor[A]]]( bsq : T ) :
 MSequitor[A] = {
     (new MSequitor[A]( ) /: bsq)( {
   ( acc : MSequitor[A], e : MSequitor[A] ) = ( acc ++ e
 ).asInstanceOf[MSequitor[A]]
     } )
   }
   override def length = a_.length
   override def elements = a_.elements
   override def apply( n : Int ) = a_.apply( n )
 }

 // a statement of the instance relation
 class MBraceSequitor[A] extends MBraceSeq[MSequitor,A] {
   val empty : MSequitor[A] = new MSequitor[A]( )
   override def nest( a : A ) = empty.nest( a )
   override def flatten[T : MSequitor[MSequitor[A]]]( bsq : T )
   : MSequitor[A] = empty.flatten( bsq )
 }

 --
 L.G. Meredith
 Managing Partner
 Biosimilarity LLC
 1219 NW 83rd St
 Seattle, WA 98117

 +1 206.650.3740

 http://biosimilarity.blogspot.com


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: Can't embed a snippet

2009-06-24 Thread Kris Nuttycombe

The error was occurring if you had more than a single root element. Thus:

div
   h2/
   p/
/div

works whereas

h2/
p/

caused the template not found erroneous exception before David fixed
it. Thanks David!

Kris

On Wed, Jun 24, 2009 at 8:40 AM, Derek Chen-Beckerdchenbec...@gmail.com wrote:
 Wait a second. I have plenty of templates that have multiple elements in
 them. What exactly is the problem you're seeing here?

 Derek

 On Tue, Jun 23, 2009 at 10:09 PM, Nolan Darilek no...@thewordnerd.info
 wrote:

 Cool deal, mvn test showed me the issue.

 Apparently, templates can only have a single element, I had an h2/ and
 a p/. The book called it a fragment, so this wasn't entirely clear. In
 any case, I put a div#welcome around it and now it works fine. Thanks
 for the pointer.





 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: Deployment questions and little Java web dev experience

2009-06-24 Thread Kris Nuttycombe

I hadn't seen openejb before, thanks for the reference!

Kris

On Wed, Jun 24, 2009 at 8:35 AM, Derek Chen-Beckerdchenbec...@gmail.com wrote:
 The line is blurring. With EJB 3.1 (Java EE 6) there is talk of using
 various profiles so that you can essentially deploy a WAR file that
 bootstraps a subset of an application server feature set within a servlet
 container. OpenEJB already does something like this:

 http://openejb.apache.org/

 Derek

 On Tue, Jun 23, 2009 at 1:54 PM, Jeppe Nejsum Madsen je...@ingolfs.dk
 wrote:

 On 23 Jun 2009, Naftoli Gugenhem wrote:


  What's the difference between an application server and a servlet
  container?

 Depends on who you ask :-) Application server usually means a J2EE
 implementation which support things such as EJBs, message services,
 transaction monitors, database pools (and a servlet container).

 A servlet container, as the name implies, is a service that can be used
 to host servlets.

 So while applications can run using only a servlet container, an
 application server typically means a servlet container and a lot of
 extra services which you may or (most likely) may not need.

 /Jeppe




 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: Can't embed a snippet

2009-06-24 Thread Kris Nuttycombe

Perhaps something a touch more intuitive like lift:template/? It
would feel odd to have to tell lift not to ignore stuff.

Kris

On Wed, Jun 24, 2009 at 9:49 AM, David
Pollakfeeder.of.the.be...@gmail.com wrote:
 We should probably have a lift:dont_ignore/ tag to surround stuff like
 this and to complement the lift:ignore/ tag.  Anyone want to add that
 snippet?

 On Wed, Jun 24, 2009 at 8:36 AM, Derek Chen-Becker dchenbec...@gmail.com
 wrote:

 Yes. Since it's a full template and not a fragment (using lift:surround
 /) it has to conform to normal XML rules. In particular, XML can only have
 one root element.

 Derek

 On Wed, Jun 24, 2009 at 9:08 AM, Nolan Darilek no...@thewordnerd.info
 wrote:

 On 06/24/2009 09:40 AM, Derek Chen-Becker wrote:
  Wait a second. I have plenty of templates that have multiple elements
  in them. What exactly is the problem you're seeing here?
 
 Using 1.1, I have the following in templates-hidden/welcome.html:

 h2Welcome/h2

 pPut welcome details here./p

 Running mvn test gives me the following failure report:


 ---
 Test set: info.thewordnerd.therascribe.AppTest

 ---
 Tests run: 2, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 1.8 sec
  FAILURE!
 testXml(info.thewordnerd.therascribe.AppTest)  Time elapsed: 1.474 sec
  FAILURE!
 junit.framework.AssertionFailedError: Malformed XML in 1 file:
 src/main/webapp/templates-hidden/welcome.html
     at junit.framework.Assert.fail(Assert.java:47)
     at info.thewordnerd.therascribe.AppTest.testXml(AppTest.scala:72)
 ..

  From the surefire report:

 system-outMalformed XML in 1 file:
 src/main/webapp/templates-hidden/welcome.html
 /system-out
 system-err:3:70: document must contain exactly one element
                                                                      ^
 /system-err

 Surrounding it in a div fixes that. Must be a new addition in 1.1?









 --
 Lift, the simply functional web framework http://liftweb.net
 Beginning Scala http://www.apress.com/book/view/1430219890
 Follow me: http://twitter.com/dpp
 Git some: http://github.com/dpp

 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: [scala] JPA question

2009-06-23 Thread Kris Nuttycombe
,

 --greg

 On Mon, Jun 22, 2009 at 3:52 PM, Derek Chen-Becker
 dchenbec...@gmail.com wrote:

 Something I just want to throw out into the discussion: Since you're
 using table-per-class, having a @Table annotation on AbstractContainer
 doesn't do anything since abstract classes can't have instances. Tables 
 are
 only generated for abstract classes if you're using a JOINED inheritance
 strategy. You might want to look at using the MappedSuperclass annotation
 for the abstract base class instead. If I change the AbstractContainer 
 def
 to:

 @MappedSuperclass
 public abstract class AbstractContainer implements java.io.Serializable
 {

 and then modify MySampleFuContainer to:

 public class MySampleFuContainer extends AbstractContainer {

 then I seem to get the proper schema:

     create table lingo_production.MySampleFuContainer_table (
     id varchar(255) not null,
     uuid varchar(255),
     mysamplingmumble__idSuper varchar(255),
     primary key (id),
     unique (uuid)
     );


 Having said that, I think that the behavior you're currently seeing
 appears to be a bug.

 Derek

 On Mon, Jun 22, 2009 at 3:43 PM, Meredith Gregory
 lgreg.mered...@gmail.com wrote:

 Kris,

 Here is a link to the self-contained example that now uses just Java.
 i included the target dir in the repo to speed up investigation, but 
 you can
 just blow that away and build from scratch. The example is currently 
 written
 to Java1.6, but also exhibits the same behavior under Java1.5. To run 
 the
 example

  svn co
  http://svn.biosimilarity.com/src/open/codesamples/trunk/hibernate
 ...
  env PATH=path-to-java1.6:$PATH JAVA_HOME=path-to-java1.6 mvn
  clean compile process-classes

 If you switch comment and decl at line 22 in
 src/main/java/maxb/hbex2/MySampleFuContainer.java then you see the 
 error.
 The schema goes from

 create table lingo_production.MySampleFuContainer_table (
     id_AbstractContainer varchar(255) not null,
     varchar(255) not null,
     uuid varchar(255),
     mysamplingmumble__idSuper varchar(255),
     primary key (id),
     unique (uuid)
     );

 to

 create table lingo_production.MySampleFuContainer_table (
     id_AbstractContainer varchar(255) not null,
     id varchar(255),
     mysamplingmumble_ tinyblob,
     uuid varchar(255),
     primary key (id_AbstractContainer),
     unique (id_AbstractContainer)
     );

 Best wishes,

 --greg

 On Mon, Jun 22, 2009 at 1:38 PM, Meredith Gregory
 lgreg.mered...@gmail.com wrote:

 Kris,

 Thanks for the suggestion. i've now got a tiny little example that
 compiles on its own that illustrates the problem. Changing the 
 inheritance
 strategy to JOINED makes no difference. Hibernate still does the wrong
 thing.

 Best wishes,

 --greg

 On Mon, Jun 22, 2009 at 8:55 AM, Kris Nuttycombe
 kris.nuttyco...@gmail.com wrote:

 This may be off the mark, but I'm wondering if the reason that
 you're
 having difficulty with the parallel inheritance hierarchy problem is
 not your use of TABLE_PER_CLASS inheritance. In my application, I
 have
 a similar construct, but I am using JOINED_TABLE inheritance. This
 allows for a normal foreign key relationship to be created in the
 database between C2_table and the base table for CThing, with the
 result that Hibernate will generate the query for CThing member as a
 union. Using table per class inheritance, I would expect Hibernate
 to
 need to synthesize an additional dtype field in C2_table along with
 the key column in order to enforce the uniqueness of the keys to the
 joined entities, and I don't believe that it does this.

 I'm not sure how the fact that the code is generated is particularly
 relevant; surely if it's possible to hand-write a successful
 solution,
 then your code generator could be made aware of how to construct a
 viable solution?

 Kris

 On Fri, Jun 19, 2009 at 8:47 PM, Meredith
 Gregorylgreg.mered...@gmail.com wrote:
  All,
 
  i had a similar problem and found the source of the issues. Spse
  you have a
  container hierarchy (CTop - C2) side-by-side with a contained
  hierarchy
  (CThing - CThing1). The inheritance at the top of the container
  hierarchy,
  CTop, causes hibernate to bail on tracking the relations and punt
  to
  embedded values instead. Rewriting the top to be a
  @MappedSuperClass fixes
  the problem in this specific case. However, if your hierarchy is
  deep,
  you're screwed.
 
  If anybody has a suggestion for a workaround, i'm all ears. The
  problem is
  that it would appear that both Mr Crowley and i are generating
  Java + JPA
  code. So, the solution needs to be algorithmic and not 1-off.
 
  Perhaps the best solution is to find an alternative to hibernate
  as this is
  a particularly irritating bug.
 
  Best wishes,
 
  --greg
 
  @Entity
  @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
  abstract class CTop {
     ...
     @Id
      @GeneratedValue(generator = system-uuid

[Lift] Re: [scala] JPA question

2009-06-23 Thread Kris Nuttycombe
 the MappedSuperclass annotation
 for the abstract base class instead. If I change the AbstractContainer def
 to:

 @MappedSuperclass
 public abstract class AbstractContainer implements java.io.Serializable
 {

 and then modify MySampleFuContainer to:

 public class MySampleFuContainer extends AbstractContainer {

 then I seem to get the proper schema:

     create table lingo_production.MySampleFuContainer_table (
     id varchar(255) not null,
     uuid varchar(255),
     mysamplingmumble__idSuper varchar(255),
     primary key (id),
     unique (uuid)
     );


 Having said that, I think that the behavior you're currently seeing
 appears to be a bug.

 Derek

 On Mon, Jun 22, 2009 at 3:43 PM, Meredith Gregory
 lgreg.mered...@gmail.com wrote:

 Kris,

 Here is a link to the self-contained example that now uses just Java.
 i included the target dir in the repo to speed up investigation, but you 
 can
 just blow that away and build from scratch. The example is currently 
 written
 to Java1.6, but also exhibits the same behavior under Java1.5. To run the
 example

  svn co
  http://svn.biosimilarity.com/src/open/codesamples/trunk/hibernate
 ...
  env PATH=path-to-java1.6:$PATH JAVA_HOME=path-to-java1.6 mvn
  clean compile process-classes

 If you switch comment and decl at line 22 in
 src/main/java/maxb/hbex2/MySampleFuContainer.java then you see the error.
 The schema goes from

 create table lingo_production.MySampleFuContainer_table (
     id_AbstractContainer varchar(255) not null,
     varchar(255) not null,
     uuid varchar(255),
     mysamplingmumble__idSuper varchar(255),
     primary key (id),
     unique (uuid)
     );

 to

 create table lingo_production.MySampleFuContainer_table (
     id_AbstractContainer varchar(255) not null,
     id varchar(255),
     mysamplingmumble_ tinyblob,
     uuid varchar(255),
     primary key (id_AbstractContainer),
     unique (id_AbstractContainer)
     );

 Best wishes,

 --greg

 On Mon, Jun 22, 2009 at 1:38 PM, Meredith Gregory
 lgreg.mered...@gmail.com wrote:

 Kris,

 Thanks for the suggestion. i've now got a tiny little example that
 compiles on its own that illustrates the problem. Changing the 
 inheritance
 strategy to JOINED makes no difference. Hibernate still does the wrong
 thing.

 Best wishes,

 --greg

 On Mon, Jun 22, 2009 at 8:55 AM, Kris Nuttycombe
 kris.nuttyco...@gmail.com wrote:

 This may be off the mark, but I'm wondering if the reason that
 you're
 having difficulty with the parallel inheritance hierarchy problem is
 not your use of TABLE_PER_CLASS inheritance. In my application, I
 have
 a similar construct, but I am using JOINED_TABLE inheritance. This
 allows for a normal foreign key relationship to be created in the
 database between C2_table and the base table for CThing, with the
 result that Hibernate will generate the query for CThing member as a
 union. Using table per class inheritance, I would expect Hibernate
 to
 need to synthesize an additional dtype field in C2_table along with
 the key column in order to enforce the uniqueness of the keys to the
 joined entities, and I don't believe that it does this.

 I'm not sure how the fact that the code is generated is particularly
 relevant; surely if it's possible to hand-write a successful
 solution,
 then your code generator could be made aware of how to construct a
 viable solution?

 Kris

 On Fri, Jun 19, 2009 at 8:47 PM, Meredith
 Gregorylgreg.mered...@gmail.com wrote:
  All,
 
  i had a similar problem and found the source of the issues. Spse
  you have a
  container hierarchy (CTop - C2) side-by-side with a contained
  hierarchy
  (CThing - CThing1). The inheritance at the top of the container
  hierarchy,
  CTop, causes hibernate to bail on tracking the relations and punt
  to
  embedded values instead. Rewriting the top to be a
  @MappedSuperClass fixes
  the problem in this specific case. However, if your hierarchy is
  deep,
  you're screwed.
 
  If anybody has a suggestion for a workaround, i'm all ears. The
  problem is
  that it would appear that both Mr Crowley and i are generating
  Java + JPA
  code. So, the solution needs to be algorithmic and not 1-off.
 
  Perhaps the best solution is to find an alternative to hibernate
  as this is
  a particularly irritating bug.
 
  Best wishes,
 
  --greg
 
  @Entity
  @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
  abstract class CTop {
     ...
     @Id
      @GeneratedValue(generator = system-uuid)
      @GenericGenerator(name = system-uuid, strategy = uuid)
      private String id_CTop;
  }
 
  @Entity
  @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
  abstract class CThing {
     ...
     @Id
      @GeneratedValue(generator = system-uuid)
      @GenericGenerator(name = system-uuid, strategy = uuid)
      private String id_CThing;
  }
 
  @Entity
  @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
  @Table(name = C2_table, catalog

[Lift] Re: is there a name for this pattern?

2009-06-19 Thread Kris Nuttycombe

I've always called this recursive type parameterization. It's useful
when the base class needs to know the type that it's eventually
instantiated as, usually so that it can provide implementations of
methods where dispatch is based upon the instantiated type. I've found
myself using the pattern mostly in cases where I wanted to have
parallel class hierarchies, say of model objects and rendering
strategies for those models. In this case, the model base class would
have a recursive type parameter, and the rendering strategy would be
parameterized with respect to the model type.

ex:

class Model[T : Model[T]] {
   self: T =
   def render(r: Renderer[T]) {
  r.render(this)
   }
}

class ConcreteModel extends Model[ConcreteModel]

class Renderer[T : Model[T]] {
   abstract def render(model: T)
}

class ConcreteModelRenderer extends Renderer[ConcreteModel] {
   def render(model: ConcreteModel) { ... }
}

In Java, you have a little more boilerplate because you don't have an
explicit self-type, so you have to define an abstract method self: T
which you implement trivially in each subclass.

Recursive self-types can be really useful but they're definitely a
double-edged sword because they're sort of viral; you have to add a
bunch of boilerplate type information everywhere that you refer to the
base type, and if you ever discard the more specific type information
(in the example above, say by putting a bunch of different subclasses
of Model into a List[Model[_]]) then you can never get it back without
reflection, and any use of the members of that list in a contravariant
position (say as an argument to another method call) becomes
impossible.

Kris

On Fri, Jun 19, 2009 at 12:18 AM, Eric Bowmanebow...@boboco.ie wrote:

 The basic trick where a superclass has its subclass as a type parameter,
 e.g.

 class User extends MegaProtoUser[User]

 I've run into this before, I remember struggling to get it, then
 getting it, but I can't recall the epiphany.  But obviously this is a
 relatively common technique, so something to google is much appreciated.

 Thanks,
 Eric

 --
 Eric Bowman
 Boboco Ltd
 ebow...@boboco.ie
 http://www.boboco.ie/ebowman/pubkey.pgp
 +35318394189/+353872801532


 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: Thoughts on separation of display from logic

2009-06-18 Thread Kris Nuttycombe

Though that's undeniably a bit of a rabbit hole, it would also be the
fully general solution and could have really interesting applications
in terms of being able to bind not just full NodeSeqs but individual
attributes, and even attributes in multiple nodes. Sounds like an
exciting feature to me!

onward and xbindward,

Kris

On Wed, Jun 17, 2009 at 5:29 PM, David
Pollakfeeder.of.the.be...@gmail.com wrote:
 Crud... adding xpathisms to bind... where will it end? :-)



 On Wed, Jun 17, 2009 at 3:41 PM, Kevin Wright
 kev.lee.wri...@googlemail.com wrote:

 One possibility I already considered is something like:
 bind(nodeseq, prefix,
     suffix - Text(matched an element),
     @suffix - Text(matched an attribute),
     @suffix=value - Text(matched an attribute with specified value));
 the bindings here would respectively match the elements:
 prefix:suffixcontent/prefix:suffix
 span prefix:suffix=placeholdercontent/span
 span prefix:suffix=valuecontent/span

 Use of the span elements above was an arbitrary choice
 What's missing is an intuitive way to access the node that has been bound,
 especially if you only want to change the contents

 On Wed, Jun 17, 2009 at 10:19 PM, David Pollak
 feeder.of.the.be...@gmail.com wrote:


 On Wed, Jun 17, 2009 at 2:07 PM, Kris Nuttycombe
 kris.nuttyco...@gmail.com wrote:

 We'd still need some attribute to disambiguate in the case of multiple
 textarea tags, wouldn't we?

 I don't think so. The only NodeSeq being passed to the function is the
 NodeSeq inside the tag that's getting bound to.


 Kris

 On Wed, Jun 17, 2009 at 2:51 PM, David
 Pollakfeeder.of.the.be...@gmail.com wrote:
  I can see a set of methods that look like:
  textarea(f: String = Unit)(n: NodeSeq) that will slurp the values and
  attributes out of the NodeSeq... so you'd bind like:
  biography - textarea(s = setBio(s)) _
 
  On Wed, Jun 17, 2009 at 10:22 AM, Matt Williams m...@makeable.co.uk
  wrote:
 
  I wholeheartedly agree with the philosophy of separating the display
  from the program logic, and am currently getting to grips with the
  generators, but am finding that now I end up with a degree of markup
  within my code.
 
  Can you think of any caveats to infering the node type passed, and
  dynamically using the relevant generators to construct the returned
  node.
 
  I am thinking something along the lines of:
 
  person:biography
  textarea style=myStyle cols=20 rows=5
  This is a sample of some biography text
  /textarea
  /person:biography
 
  Where it would automatically infer that it is a textarea, pass
  through
  the relevant attributes, and insert whatever function, values, etc I
  have specified in my snippet.
 
  What are your thoughts on this?
 
  Brgds,
 
  Matt
 
 
 
 
 
 
  --
  Lift, the simply functional web framework http://liftweb.net
  Beginning Scala http://www.apress.com/book/view/1430219890
  Follow me: http://twitter.com/dpp
  Git some: http://github.com/dpp
 
  
 





 --
 Lift, the simply functional web framework http://liftweb.net
 Beginning Scala http://www.apress.com/book/view/1430219890
 Follow me: http://twitter.com/dpp
 Git some: http://github.com/dpp








 --
 Lift, the simply functional web framework http://liftweb.net
 Beginning Scala http://www.apress.com/book/view/1430219890
 Follow me: http://twitter.com/dpp
 Git some: http://github.com/dpp

 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: Very basic questions

2009-06-18 Thread Kris Nuttycombe

Hi, and welcome to Lift!

On Thu, Jun 18, 2009 at 10:46 AM, DFectuososantiago1...@gmail.com wrote:

 Hi! I'm starting to use lift/scala(I don't know either) and already I
 have a couple of (very very basic) questions.
 I'm reading The definitive guide to lift and even tho it's been
 enough to actually understand some of the key elements of a lift
 application I am having some problems understanding some of the code
 and how you people work with Lift.

 1.- What tools do you use to program, debug and run the website? At
 this moment I'm using text mate to program and the terminal to run
 yetti; It's very slow to run yetti every time and its hard to
 understand the errors so i tried eclipse but I had trouble installing
 the maven plug-in so... what is your toolbox?

I tend to like Netbeans 6.7 (currently in rc3 status) with the Scala
plugin. Others use Eclipse, IDEA, Vim, and Emacs with varying degrees
of success. I'm not familiar with yetti (jetty?) but a lot of folks in
the Lift community use JavaRebel speed things up and avoid container
restarts. I run my app on Glassfish (with JavaRebel in development),
but any servlet container will work and jetty is probably be the best
for getting started.

 2.- What is _ and Full in different places?
 I see that  in a binding name - SHtml.text(name, name = _)  or when
 checking for cases there's a case for Full(_) and for _ ; what does _
 means and what does Full mean; and whats the difference between Full
 (_) and _.

_ is the great wildcard in Scala. In the binding example, name = _
is equivalent to the anonymous function (s: String) = name = s. A
case matching on Full(_) will match any Full box, ignoring the type of
its contents. A case matching on _ will match any value not matched by
previous clauses.

 3.-Reading about the flow from request to response; i cant avoid to
 ask: How many times does the Boot(or bootloader) run? Once when i run
 the app(or web server; yetti in my case) or once every time there's a
 request?

Boot is run on startup, and not re-run subsequently. This can cause
some trickiness when using JavaRebel; you will need to restart the
application if you make changes to Boot.

Kris

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: interaction with hibernate crowd?

2009-06-18 Thread Kris Nuttycombe

Ah, this makes sense to me. Final fields in Hibernate-manage objects
will almost certainly cause problems in my experience (at least using
field-based access; I've no experience with property-based mappings.)

Kris.

On Thu, Jun 18, 2009 at 3:09 PM, Meredith
Gregorylgreg.mered...@gmail.com wrote:
 Viktor,

 i finally got someone on the hibernate IRC channel to take a look at the
 problem. He claims that if he removes the final declarator from a field for
 which i have only a getter and then adds a setter hibernate works as
 advertised. i will test this out. If no joy i might take you up on your kind
 offer.

 Best wishes,

 --greg

 On Thu, Jun 18, 2009 at 1:10 PM, Viktor Klang viktor.kl...@gmail.com
 wrote:

 Gregory, send the available debug info regarding the suspected defect and
 I'll see what I can do.

 Viktor,
 Rogue Software Architect
 18 jun 2009 kl. 21.24 Meredith Gregory lgreg.mered...@gmail.com skrev:

 Lifted and Scalata,

 Has anyone had any joy engaging the hibernate crowd? i've been trying
 every channel i can to get someone in the hibernate know to take a look at
 what i believe is a bug and no one even responds at all.

 Best wishes,

 --greg

 --
 L.G. Meredith
 Managing Partner
 Biosimilarity LLC
 1219 NW 83rd St
 Seattle, WA 98117

 +1 206.650.3740

 http://biosimilarity.blogspot.com







 --
 L.G. Meredith
 Managing Partner
 Biosimilarity LLC
 1219 NW 83rd St
 Seattle, WA 98117

 +1 206.650.3740

 http://biosimilarity.blogspot.com

 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: Thoughts on separation of display from logic

2009-06-17 Thread Kris Nuttycombe

This reminds me somewhat of the Wicket approach, which would use a
namespaced attribute of the textarea tag to inform the binding
logic. I've been wanting to keep the styling of my lift-generated tags
in the markup as well, so maybe I'll toy a bit with creating a version
of bind() and the form generator functions that would allow this.

Kris

On Wed, Jun 17, 2009 at 11:22 AM, Matt Williamsm...@makeable.co.uk wrote:

 I wholeheartedly agree with the philosophy of separating the display
 from the program logic, and am currently getting to grips with the
 generators, but am finding that now I end up with a degree of markup
 within my code.

 Can you think of any caveats to infering the node type passed, and
 dynamically using the relevant generators to construct the returned
 node.

 I am thinking something along the lines of:

 person:biography
 textarea style=myStyle cols=20 rows=5
 This is a sample of some biography text
 /textarea
 /person:biography

 Where it would automatically infer that it is a textarea, pass through
 the relevant attributes, and insert whatever function, values, etc I
 have specified in my snippet.

 What are your thoughts on this?

 Brgds,

 Matt


 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: Thoughts on separation of display from logic

2009-06-17 Thread Kris Nuttycombe

We'd still need some attribute to disambiguate in the case of multiple
textarea tags, wouldn't we?

Kris

On Wed, Jun 17, 2009 at 2:51 PM, David
Pollakfeeder.of.the.be...@gmail.com wrote:
 I can see a set of methods that look like:
 textarea(f: String = Unit)(n: NodeSeq) that will slurp the values and
 attributes out of the NodeSeq... so you'd bind like:
 biography - textarea(s = setBio(s)) _

 On Wed, Jun 17, 2009 at 10:22 AM, Matt Williams m...@makeable.co.uk wrote:

 I wholeheartedly agree with the philosophy of separating the display
 from the program logic, and am currently getting to grips with the
 generators, but am finding that now I end up with a degree of markup
 within my code.

 Can you think of any caveats to infering the node type passed, and
 dynamically using the relevant generators to construct the returned
 node.

 I am thinking something along the lines of:

 person:biography
 textarea style=myStyle cols=20 rows=5
 This is a sample of some biography text
 /textarea
 /person:biography

 Where it would automatically infer that it is a textarea, pass through
 the relevant attributes, and insert whatever function, values, etc I
 have specified in my snippet.

 What are your thoughts on this?

 Brgds,

 Matt






 --
 Lift, the simply functional web framework http://liftweb.net
 Beginning Scala http://www.apress.com/book/view/1430219890
 Follow me: http://twitter.com/dpp
 Git some: http://github.com/dpp

 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: Wolfram Alpha integration for Lift

2009-06-11 Thread Kris Nuttycombe

I sort of see Wolfram Alpha as simply an incredibly sophisticated
calculator instead of an information discovery tool. What were you
trying to compute about polyadic pi-calculus?

Alpha seems to be trying to put all sorts of different kinds of data
into a common, hugely high-dimensional space so that you can perform
computations on it, where your computations are expressed in a mix of
mathematical and natural language. There are certainly a lot of things
that it's not useful for yet, but it's a tremendously interesting
problem.

Kris

On Thu, Jun 11, 2009 at 12:42 PM, Meredith
Gregorylgreg.mered...@gmail.com wrote:
 Tim,

 Thanks for the response. i'll have to noodle on that one. Off the top of my
 head, i'm usually in this loop

 Initially, usually badly formulated question
 Get information sources
 Reformulate question
 Loop

 So, i don't really see much difference between the two, except by use. i
 will think about it, though.

 Best wishes,

 --greg


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: maven question

2009-06-11 Thread Kris Nuttycombe

There may well be another way to do this that I'm unaware of, but I
would put the configuration for each of these executions in a separate
profile, with the activation based upon some property.

Kris

On Thu, Jun 11, 2009 at 12:49 PM, Meredith
Gregorylgreg.mered...@gmail.com wrote:
 Lifted,

 Spse you've got a maven plugin configured with multiple executions in the
 same life-cycle phase, distinguished by id. How do you invoke one of them by
 id? For example, suppose i've got the maven-exec-plugin configured with two
 executions in the package phase, with ids, 'one' and 'two', respectivelys.
 What's the maven command line invocation that allows me to execute one
 without the other?

 Best wishes,

 --greg

 --
 L.G. Meredith
 Managing Partner
 Biosimilarity LLC
 1219 NW 83rd St
 Seattle, WA 98117

 +1 206.650.3740

 http://biosimilarity.blogspot.com

 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: PhET Website

2009-04-05 Thread Kris Nuttycombe

Hi, Sam,

I'm a Java/Scala developer living in Boulder, so if you'd like to meet
some time and talk about your project just let me know. I'm fully
bogged down with work at the moment so I'm not really looking for
work, but I'm always glad to hear about other locals who are using
these tools.

Kris

On Fri, Apr 3, 2009 at 11:05 PM, samreid samrr...@gmail.com wrote:

 Lift community,

 My name is Sam Reid, I'm a Java + Scala developer for PhET Interactive
 Simulations at http://phet.colorado.edu/.  We produce free, open
 source educational science simulations for college and high school-
 level students.  We are considering porting our website to Lift and
 adding some functionality such as internationalization.  I was
 wondering if there are any Lift developers who would be interested in
 this work.  If you're interested, please look through our existing
 website at http://phet.colorado.edu/ and provide a time/price estimate
 to me at reids at colorado dot edu.  We have some existing databases
 that would need to be supported, and the existing code is PHP+HTML
 +JavaScript.  We currently average about 200,000 pageviews/day, and
 we'll need to make sure that Lift is capable of this and more.  Please
 let me know if you have questions or comments.

 Thanks,
 Sam Reid

 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: class hierarchy with models

2009-04-01 Thread Kris Nuttycombe

Hi, David,

I can give you a good example of a class hierarchy that I use in my
application (via JPA). In fact, it is a pair of coupled model
hierarchies.

The primary hierarchy is based in a class PaymentSource which has
subclasses such as CreditCard, CheckingAcct, and PayPalAcct. This is
then related to a class hierarchy PaymentSourceTransaction[T :
PaymentSource]. There is an appropriate subclass
(CreditCardTransaction extends PaymentSourceTransaction[CreditCard])
for each type of payment source, and then interfaces AuthTransaction,
CaptureTransaction, CreditTransaction, and VoidTransaction with
subclass implementations for each type of payment source.

The model hierarchy ends up looking like this:

PaymentSource
 - CreditCard
 - CheckingAcct
 - PayPalAcct

PaymentSourceTransaction[T : PaymentSource]
- CreditCardTransaction extends PaymentSourceTransaction[CreditCard]
- CCAuthTransaction extends CreditCardTransaction with AuthTransaction
...
- CheckingAcctTransaction extends PaymentSourceTransaction[CheckingAcct]
- CheckingAuthTransaction extends CheckingAcctTransaction
with AuthTransaction

and so forth.

Kris


On Wed, Apr 1, 2009 at 8:17 AM, David Pollak
feeder.of.the.be...@gmail.com wrote:
 Wow.  Awesome answer!
 A couple of things.  Some of the Mapper code is my earliest Scala attempts
 and other code is desperate attempts on my part to work around Scala's type
 system.  Some of it is instructive, but other parts are just wrong and ugly.
  I'd suggest running in horror from any code that has asInstanceOf in it.
 I think there's also a lurking pattern in there someplace for a lazy val on
 the model instances that vends the manipulator  logic instance that can
 be one of many subclasses of a base class (or trait) and that implements
 logic based on the contents of the model.
 I'd like to see some examples of class hierarchies for model objects... that
 might help me understand how to build such a pattern into Lift.
 Thanks,
 David
 On Wed, Apr 1, 2009 at 6:18 AM, Giuseppe Fogliazza g.foglia...@mcmspa.it
 wrote:

 Hi Tobias.
 I am a newbie too, Hence wait for more solid support. Nevertheless I
 made some investigate on how to describe a complex object model using
 Mapper.
 The short answer is that Mapper does not support inheritance and hence
 you cannot specilized the ToDo class. Period.
 Moreover in some topics in this group there were indication on
 limiting the use of Mapper for simple object models, preferring JPA
 integration for more complex structures or waiting for Record (Lift
 1.1) to get the best from both world.
 After running throuh some examples I became addicted to some of
 Mapper's functionalities such as CRUDify and .toForm that at the
 beginning I was a little bit suspicious about (you know MVC purity and
 all this stuff).
 If limitations on relationship management could be easily overcome by
 manually developed helper functions, inheritance is definitely a
 different beast. But using traits it seems possible (even if a little
 bit tricky at the beginning) to build hierarchies (and with multiple
 inheritance too!). I suggest you to have a look to how the trait IdPK
 is implemented in Mapper.scala (and in general look at the scala code
 lift is made of, it is very insightful to both scala and lift).
 The only limitation is that when you arrive to concretize a class
 (and the related metaclass singleton) you cannot procede further with
 inheritance (it should be a leaf in your hierarchy tree). I posted an
 example some weeks ago you can have a look at just to understand what
 I am talking about (tht topic was : Using Traits in complex domain
 models )ards

 Regards
 beppe

 On Apr 1, 11:21 am, Tobias Daub hannes.flo...@gmx.li wrote:
  Hi There,
 
  I'm new to Scala and Lift and still feeling a little bit lost.
 
  In case of the ToDo example from the Getting started guide: Would it be
  possible to make a more specialized version of a ToDo item that inherits
  from the existing one?
 
  This is more a general question about inheritance from Lift models,
  because I've to design some more complex class hierarchy, where its
  really necessary to have stupid classes that can be specialized later
  on.
 
  Apply the same rules about inheritance, traits, etc. to Lift models,
  too. Can I do all the stuff that I can do with normal classes?
 
  Thanks alot!
  Tobias





 --
 Lift, the simply functional web framework http://liftweb.net
 Beginning Scala http://www.apress.com/book/view/1430219890
 Follow me: http://twitter.com/dpp
 Git some: http://github.com/dpp

 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en

[Lift] Re: lift-core jar in repo-releases does not contain classes

2009-04-01 Thread Kris Nuttycombe

If lift-core doesn't contain any classes, could it be changed to a pom
artifact type instead?

Kris

On Wed, Apr 1, 2009 at 8:09 AM, David Pollak
feeder.of.the.be...@gmail.com wrote:
 That's right.  The lift-core.jar file has never contained any classes.  It's
 a marker for Maven.  lift-core depends on all the other Lift packages (e.g.,
 lift-util, lift-webket, etc.) so these other packages are included in your
 project and they have classes in their jar files.

 On Wed, Apr 1, 2009 at 6:58 AM, Rosh jacknjill...@gmail.com wrote:

 I just started the learning scala and lift and was trying out the ToDo
 example. It seems that the lift-core artifact jar in the maven repo,
 http://scala-tools.org/repo-releases, is empty. I used the lift-basic-
 archetype which uses lift-core-0.8 jar. But the jar only contains the
 META-INF folder. No classes. Same with the 1.0 jar as well. The 0.6
 jar contains

 Does not contain any classes:
 http://scala-tools.org/repo-releases/net/liftweb/lift-core/0.8/
 lift-core-0.8.jar       2008-Nov-24 23:39:51    1.4K
  application/java-archive

 http://scala-tools.org/repo-releases/net/liftweb/lift-core/1.0/
 lift-core-1.0.jar       2009-Feb-26 18:09:39    1.5K
  application/java-archive

 Contains classes:
 Under http://scala-tools.org/repo-releases/net/liftweb/lift-core/0.6:
 lift-core-0.6.jar       2008-Nov-24 23:40:15    3.6M
  application/java-archive

 Am I missing something? I know I haven't had my morning coffee yet.

 Thanks,
 Rosh
 http://blogs.plexibus.com
 http://www.twitter.com/ras_shadow





 --
 Lift, the simply functional web framework http://liftweb.net
 Beginning Scala http://www.apress.com/book/view/1430219890
 Follow me: http://twitter.com/dpp
 Git some: http://github.com/dpp

 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: Newbie Scala syntax question re: parameterized types with bounds

2009-04-01 Thread Kris Nuttycombe

Something that occurred to me recently along these lines - perhaps
someone can disabuse me of this notion. In Java, such recursive types
are necessary because you don't have abstract types. To refer to the
implementation type in the declaring class you have to use the
self-type.

But in Scala, what application would not be satisfied by:

trait Mapper {
   type T : Mapper
}

class User extends Mapper {
   type T = User
}

Is it just that the restriction on T is not sufficiently narrow?

Kris

On Fri, Mar 27, 2009 at 5:26 PM, Alex Boisvert boisv...@intalio.com wrote:
 Or said another way,

 MappedTextarea[ T : Mapper[T] ]

 declares a type parameter T and fixes the upper bound of the MappedTextarea
 type parameter to Mapper[T], which means that the type passed to
 MappedTextArea must be a subtype of Mapper.

 I, too, found this notation confusing at first and wished I could write
 MappedTextarea[ : Mapper[T] ] directly but declaring the T before its use
 is necessary to disambiguate it from existing class names.

 alex



 On Fri, Mar 27, 2009 at 1:52 PM, Stefan Scott stefanscottal...@gmail.com
 wrote:

 Hi -

 Sorry to be asking a Scala syntax question here in the Lift group, but
 I figured somebody here would know, since this Scala syntax occurs
 quite a bit in the Lift source code.

 When reading some of the Lift source I come across a particular Scala
 idiom involving parameterized types with bounds, whose semantics I'm
 unsure of.

 For example:

 class MappedTextarea[ T : Mapper[ T ] ] ( owner : T, maxLen: Int )
 extends
      MappedString[ T ]( owner, maxLen ) { ... }

 What I'm unsure about here is the part where it says:

 T : Mapper[ T ]

 At first, this made no sense to me - how could a type T be a subtype
 of type Mapper[ T ] ?

 Then I guessed that maybe the two occurrences of T are unrelated to
 each other - ie, class MappedTextarea is parameterized over a type T,
 which must be a subtype of a type Mapper[ T ] -- where the second T is
 actually in a separate scope so that it has nothing to do with the
 first T.

 Is that what this really means?

 And, if that's really the case, then I guess the other occurrences of
 T later in the text:

 owner : T
 MappedString[ T ]

 are also referring to the first occurrence of T -- the type T which is
 upper-bounded by type Mapper[ T ].

 Finally, does this mean that the above code could also have been
 written equivalently as follows:

 class MappedTextarea[ T : Mapper[ U ] ] ( owner : T, maxLen: Int )
 extends
      MappedString[ T ]( owner, maxLen ) { ... }

 using U instead of T for the type parameter that's in a separate
 scope?

 Thanks for any help.

 - Stefan Scott








 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: MappedDateTime - Do we have a Date? Or is it a timestamp?

2009-03-31 Thread Kris Nuttycombe

I'm also using joda-time, and very pleased with it. In fact, I use it
in my Lift project - via JPA with the provided Hibernate extensions
for mapping of DateTime, Period, etc.

Kris

On Tue, Mar 31, 2009 at 1:54 PM, TylerWeir tyler.w...@gmail.com wrote:

 For an internal project I used JodaTime, twas a dream.

 I have switched to using MappedLong along with Unix time for dates
 now.

 ( hooray for ancedotes! )

 On Mar 31, 3:21 pm, Jorge Ortiz jorge.or...@gmail.com wrote:
 I was on IRC trying to help Clemens with this. The name (MappedDateTime),
 targetSQLType (java.sql.Types.TIMESTAMP), and type (extends
 MappedField[java.util.Date, _]) of this class suggests millisecond precision
 (java.sql.Timestamp and java.util.Date have millisecond precision). However,
 methods jdbcFriendly and real_convertToJDBCFriendly use java.sql.Date, which
 has only day precision.

 If the intent is day precision, then calling the class DateTime is probably
 misleading. If the intent is millisecond precision, then we have a bug.

 rant

 Which brings up the larger issue of the brokennes of the Java Date/Time API.
 Java 7 will hopefully be getting a newer/better one, but for those of us
 stuck on Java 5/6, Joda Time is much preferable to the native Date/Time API.
 It more clearly represents foundational concepts like instants (March 31,
 2009 at 12:15.000pm UTC), partials (March 3 or 7:15pm), intervals (the space
 between two instants), durations (1000 milliseconds), periods (1 month), and
 chronologies (calendar systems). It's also completely immutable (oh, you
 didn't know java.util.Calendar isn't thread-safe? you're lucky to have never
 had to track down that bug).

 /rant

 Sigh... it's probably too big of a breaking change to rip out Java Date/Time
 from Mapper and Helpers and replace it with Joda Time, but one can dream...

 --j

 On Tue, Mar 31, 2009 at 11:58 AM, Clemens Oertel
 clemens.oer...@gmail.comwrote:





  While trying to figure out why my MappedDateTime fields get stored in
  the DB with all the time info set to 0, I noticed the following:

  MappedDateTime (v. 1.0) claims to be a TimeStamp: def targetSQLType
  = Types.TIMESTAMP. However, it uses java.sql.Date for its JDBC-
  friendly converted version, not java.sql.TimeStamp. If I read the
  java.sql.Date documentation correctly, java.sql.Date does set all time
  information to 0, since the SQL DATE type only stores dates, by no
  times.

  Any comment whether this might have something to do with me losing my
  time would be appreciated.

  Best,
  Clemens
 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: Objections to merging jpa archetype?

2009-03-13 Thread Kris Nuttycombe

What version of Maven are you using? I'm getting the following errors:

knuttyco...@knuttycombe-ubuntu:~/tmp$ mvn -DarchetypeCatalog=local
archetype:generate
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'archetype'.
[INFO] 
[INFO] Building Maven Default Project
[INFO]task-segment: [archetype:generate] (aggregator-style)
[INFO] 
[INFO] Preparing archetype:generate
[INFO] No goals needed for project - skipping
[INFO] Setting property: classpath.resource.loader.class =
'org.codehaus.plexus.velocity.ContextClassLoaderResourceLoader'.
[INFO] Setting property: velocimacro.messages.on = 'false'.
[INFO] Setting property: resource.loader = 'classpath'.
[INFO] Setting property: resource.manager.logwhenfound = 'false'.
[INFO] [archetype:generate]
[INFO] Generating project in Interactive mode
[INFO] No archetype defined. Using maven-archetype-quickstart
(org.apache.maven.archetypes:maven-archetype-quickstart:1.0)
Choose archetype:
1: local - lift-jpa-archetype (lift-jpa-archetype)
Choose a number:  (1):
Choose archetype:
1: local - lift-jpa-archetype (lift-jpa-archetype)
Choose a number:  (1): 1
Define value for groupId: : com.gaiam.gcsi
Define value for artifactId: : jpa-lift
Define value for version:  1.0-SNAPSHOT: :
Define value for package: : com.gaiam.gcsi
Confirm properties configuration:
groupId: com.gaiam.gcsi
artifactId: jpa-lift
version: 1.0-SNAPSHOT
package: com.gaiam.gcsi
 Y: : Y
[INFO] 

[INFO] Using following parameters for creating OldArchetype:
lift-jpa-archetype:0.11-SNAPSHOT
[INFO] 

[INFO] Parameter: groupId, Value: com.gaiam.gcsi
[INFO] Parameter: packageName, Value: com.gaiam.gcsi
[INFO] Parameter: package, Value: com.gaiam.gcsi
[INFO] Parameter: artifactId, Value: jpa-lift
[INFO] Parameter: basedir, Value: /home/knuttycombe/tmp
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] * End of debug info from resources from
generated POM ***
[ERROR] ResourceManager : unable to find resource
'archetype-resources/webapp/src/main/webapp/templates-hidden/default.html'
in any resource loader.
[ERROR] Failed to generate project from the old archetype
org.apache.maven.archetype.exception.ArchetypeGenerationFailure:
Failed to generate project from the old archetype
at 
org.apache.maven.archetype.generator.DefaultArchetypeGenerator.processOldArchetype(DefaultArchetypeGenerator.java:272)
at 
org.apache.maven.archetype.generator.DefaultArchetypeGenerator.generateArchetype(DefaultArchetypeGenerator.java:145)
at 
org.apache.maven.archetype.generator.DefaultArchetypeGenerator.generateArchetype(DefaultArchetypeGenerator.java:290)
at 
org.apache.maven.archetype.DefaultArchetype.generateProjectFromArchetype(DefaultArchetype.java:75)
at 
org.apache.maven.archetype.mojos.CreateProjectFromArchetypeMojo.execute(CreateProjectFromArchetypeMojo.java:185)
at 
org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:451)
at 
org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:558)
at 
org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeStandaloneGoal(DefaultLifecycleExecutor.java:512)
at 
org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:482)
at 
org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:330)
at 
org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:227)
at 
org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:142)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:336)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:129)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:287)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at 
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315)
at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430)
at org.codehaus.classworlds.Launcher.main(Launcher.java:375)
Caused by: org.apache.maven.archetype.old.ArchetypeTemplateProcessingException:
Error merging velocity templates
at 

[Lift] Re: Objections to merging jpa archetype?

2009-03-13 Thread Kris Nuttycombe

How are you installing the archetype as a plugin? After clearing out
the repo and running an install of the plugin project, I'm not seeing
it in my local archetype repository.

I had to add this to the lift-archetype-jpa-basic pom.xml to get it to install:

diff --git a/lift-archetype-jpa-basic/pom.xml b/lift-archetype-jpa-basic/pom.xml
index 453e2b3..fc0cf8c 100644
--- a/lift-archetype-jpa-basic/pom.xml
+++ b/lift-archetype-jpa-basic/pom.xml
@@ -7,6 +7,7 @@
 relativePath../pom.xml/relativePath
   /parent
   artifactIdlift-archetype-jpa-basic/artifactId
+  packagingmaven-archetype/packaging
   name${project.artifactId}/name
   descriptionArchetype - blank JPA project for Lift/description
   properties
@@ -14,10 +15,18 @@
 maven.test.skiptrue/maven.test.skip
   /properties
   build
+extensions
+  extension
+groupIdorg.apache.maven.archetype/groupId
+artifactIdarchetype-packaging/artifactId
+version2.0-alpha-4/version
+  /extension
+/extensions
 plugins
   plugin
 artifactIdmaven-archetype-plugin/artifactId
 version2.0-alpha-4/version
+extensionstrue/extensions
 configuration
   archetypeArtifactId${project.artifactId}/archetypeArtifactId
   archetypeGroupId${project.groupId}/archetypeGroupId

After that, the archetype installed and I was able to generate it
correctly. I have not yet tested the resulting application, though.

Kris


On Fri, Mar 13, 2009 at 9:46 AM, Derek Chen-Becker
dchenbec...@gmail.com wrote:
 de...@rocky:/home/software/liftbook$ mvn -v
 Maven version: 2.0.9
 Java version: 1.6.0_11
 OS name: linux version: 2.6.27-11-generic arch: amd64 Family: unix

 This line in your output concerns me:

 [INFO] Using following parameters for creating
 OldArchetype:lift-jpa-archetype:0.11-SNAPSHOT

 The version in my archetype is 1.1-SNAPSHOT, so I wonder if you're getting
 an older version in your repo. Could you try nuking your .m2/repo and see if
 you still get the same error?

 Derek


 On Fri, Mar 13, 2009 at 9:38 AM, Kris Nuttycombe kris.nuttyco...@gmail.com
 wrote:

 What version of Maven are you using? I'm getting the following errors:

 knuttyco...@knuttycombe-ubuntu:~/tmp$ mvn -DarchetypeCatalog=local
 archetype:generate
 [INFO] Scanning for projects...
 [INFO] Searching repository for plugin with prefix: 'archetype'.
 [INFO]
 
 [INFO] Building Maven Default Project
 [INFO]    task-segment: [archetype:generate] (aggregator-style)
 [INFO]
 
 [INFO] Preparing archetype:generate
 [INFO] No goals needed for project - skipping
 [INFO] Setting property: classpath.resource.loader.class =
 'org.codehaus.plexus.velocity.ContextClassLoaderResourceLoader'.
 [INFO] Setting property: velocimacro.messages.on = 'false'.
 [INFO] Setting property: resource.loader = 'classpath'.
 [INFO] Setting property: resource.manager.logwhenfound = 'false'.
 [INFO] [archetype:generate]
 [INFO] Generating project in Interactive mode
 [INFO] No archetype defined. Using maven-archetype-quickstart
 (org.apache.maven.archetypes:maven-archetype-quickstart:1.0)
 Choose archetype:
 1: local - lift-jpa-archetype (lift-jpa-archetype)
 Choose a number:  (1):
 Choose archetype:
 1: local - lift-jpa-archetype (lift-jpa-archetype)
 Choose a number:  (1): 1
 Define value for groupId: : com.gaiam.gcsi
 Define value for artifactId: : jpa-lift
 Define value for version:  1.0-SNAPSHOT: :
 Define value for package: : com.gaiam.gcsi
 Confirm properties configuration:
 groupId: com.gaiam.gcsi
 artifactId: jpa-lift
 version: 1.0-SNAPSHOT
 package: com.gaiam.gcsi
  Y: : Y
 [INFO]
 
 [INFO] Using following parameters for creating OldArchetype:
 lift-jpa-archetype:0.11-SNAPSHOT
 [INFO]
 
 [INFO] Parameter: groupId, Value: com.gaiam.gcsi
 [INFO] Parameter: packageName, Value: com.gaiam.gcsi
 [INFO] Parameter: package, Value: com.gaiam.gcsi
 [INFO] Parameter: artifactId, Value: jpa-lift
 [INFO] Parameter: basedir, Value: /home/knuttycombe/tmp
 [INFO] Parameter: version, Value: 1.0-SNAPSHOT
 [INFO] * End of debug info from resources from
 generated POM ***
 [ERROR] ResourceManager : unable to find resource
 'archetype-resources/webapp/src/main/webapp/templates-hidden/default.html'
 in any resource loader.
 [ERROR] Failed to generate project from the old archetype
 org.apache.maven.archetype.exception.ArchetypeGenerationFailure:
 Failed to generate project from the old archetype
        at
 org.apache.maven.archetype.generator.DefaultArchetypeGenerator.processOldArchetype(DefaultArchetypeGenerator.java:272)
        at
 org.apache.maven.archetype.generator.DefaultArchetypeGenerator.generateArchetype

[Lift] Re: Objections to merging jpa archetype?

2009-03-13 Thread Kris Nuttycombe

Done.


On Fri, Mar 13, 2009 at 10:41 AM, Derek Chen-Becker
dchenbec...@gmail.com wrote:
 Actually, I see that you did that against git. Can you commit your changes?

 Thanks,

 Derek

 On Fri, Mar 13, 2009 at 11:40 AM, Derek Chen-Becker dchenbec...@gmail.com
 wrote:

 Ah, I think I missed that part of the POM. Let me fix that and commit the
 changes and then we can re-test.

 Thanks!

 Derek

 On Fri, Mar 13, 2009 at 11:11 AM, Kris Nuttycombe
 kris.nuttyco...@gmail.com wrote:

 How are you installing the archetype as a plugin? After clearing out
 the repo and running an install of the plugin project, I'm not seeing
 it in my local archetype repository.

 I had to add this to the lift-archetype-jpa-basic pom.xml to get it to
 install:

 diff --git a/lift-archetype-jpa-basic/pom.xml
 b/lift-archetype-jpa-basic/pom.xml
 index 453e2b3..fc0cf8c 100644
 --- a/lift-archetype-jpa-basic/pom.xml
 +++ b/lift-archetype-jpa-basic/pom.xml
 @@ -7,6 +7,7 @@
     relativePath../pom.xml/relativePath
   /parent
   artifactIdlift-archetype-jpa-basic/artifactId
 +  packagingmaven-archetype/packaging
   name${project.artifactId}/name
   descriptionArchetype - blank JPA project for Lift/description
   properties
 @@ -14,10 +15,18 @@
     maven.test.skiptrue/maven.test.skip
   /properties
   build
 +    extensions
 +      extension
 +        groupIdorg.apache.maven.archetype/groupId
 +        artifactIdarchetype-packaging/artifactId
 +        version2.0-alpha-4/version
 +      /extension
 +    /extensions
     plugins
       plugin
         artifactIdmaven-archetype-plugin/artifactId
         version2.0-alpha-4/version
 +        extensionstrue/extensions
         configuration

 archetypeArtifactId${project.artifactId}/archetypeArtifactId
           archetypeGroupId${project.groupId}/archetypeGroupId

 After that, the archetype installed and I was able to generate it
 correctly. I have not yet tested the resulting application, though.

 Kris


 On Fri, Mar 13, 2009 at 9:46 AM, Derek Chen-Becker
 dchenbec...@gmail.com wrote:
  de...@rocky:/home/software/liftbook$ mvn -v
  Maven version: 2.0.9
  Java version: 1.6.0_11
  OS name: linux version: 2.6.27-11-generic arch: amd64 Family:
  unix
 
  This line in your output concerns me:
 
  [INFO] Using following parameters for creating
  OldArchetype:lift-jpa-archetype:0.11-SNAPSHOT
 
  The version in my archetype is 1.1-SNAPSHOT, so I wonder if you're
  getting
  an older version in your repo. Could you try nuking your .m2/repo and
  see if
  you still get the same error?
 
  Derek
 
 
  On Fri, Mar 13, 2009 at 9:38 AM, Kris Nuttycombe
  kris.nuttyco...@gmail.com
  wrote:
 
  What version of Maven are you using? I'm getting the following errors:
 
  knuttyco...@knuttycombe-ubuntu:~/tmp$ mvn -DarchetypeCatalog=local
  archetype:generate
  [INFO] Scanning for projects...
  [INFO] Searching repository for plugin with prefix: 'archetype'.
  [INFO]
 
  
  [INFO] Building Maven Default Project
  [INFO]    task-segment: [archetype:generate] (aggregator-style)
  [INFO]
 
  
  [INFO] Preparing archetype:generate
  [INFO] No goals needed for project - skipping
  [INFO] Setting property: classpath.resource.loader.class =
  'org.codehaus.plexus.velocity.ContextClassLoaderResourceLoader'.
  [INFO] Setting property: velocimacro.messages.on = 'false'.
  [INFO] Setting property: resource.loader = 'classpath'.
  [INFO] Setting property: resource.manager.logwhenfound = 'false'.
  [INFO] [archetype:generate]
  [INFO] Generating project in Interactive mode
  [INFO] No archetype defined. Using maven-archetype-quickstart
  (org.apache.maven.archetypes:maven-archetype-quickstart:1.0)
  Choose archetype:
  1: local - lift-jpa-archetype (lift-jpa-archetype)
  Choose a number:  (1):
  Choose archetype:
  1: local - lift-jpa-archetype (lift-jpa-archetype)
  Choose a number:  (1): 1
  Define value for groupId: : com.gaiam.gcsi
  Define value for artifactId: : jpa-lift
  Define value for version:  1.0-SNAPSHOT: :
  Define value for package: : com.gaiam.gcsi
  Confirm properties configuration:
  groupId: com.gaiam.gcsi
  artifactId: jpa-lift
  version: 1.0-SNAPSHOT
  package: com.gaiam.gcsi
   Y: : Y
  [INFO]
 
  
  [INFO] Using following parameters for creating OldArchetype:
  lift-jpa-archetype:0.11-SNAPSHOT
  [INFO]
 
  
  [INFO] Parameter: groupId, Value: com.gaiam.gcsi
  [INFO] Parameter: packageName, Value: com.gaiam.gcsi
  [INFO] Parameter: package, Value: com.gaiam.gcsi
  [INFO] Parameter: artifactId, Value: jpa-lift
  [INFO] Parameter: basedir, Value: /home/knuttycombe/tmp
  [INFO] Parameter: version, Value: 1.0-SNAPSHOT
  [INFO] * End of debug info from resources from
  generated POM

[Lift] Re: Objections to merging jpa archetype?

2009-03-13 Thread Kris Nuttycombe

I actually haven't deployed an archetype onto a remote repository
before, but it sounds right.

Has ScalaJPA become publicly available on scala-tools yet?

Kris

On Fri, Mar 13, 2009 at 11:28 AM, Derek Chen-Becker
dchenbec...@gmail.com wrote:
 OK, I'll go ahead and merge with master. If I understand this whole process
 correctly, Hudson should build the new project and deploy it under snapshots
 on scala-tools.org. At that point we should be able to use the
 archetype:generate -DremoteRepository=http://scala-tools.org/repo-snapshots
 to generate, correct?

 Derek

 On Fri, Mar 13, 2009 at 12:01 PM, Kris Nuttycombe
 kris.nuttyco...@gmail.com wrote:

 Done.


 On Fri, Mar 13, 2009 at 10:41 AM, Derek Chen-Becker
 dchenbec...@gmail.com wrote:
  Actually, I see that you did that against git. Can you commit your
  changes?
 
  Thanks,
 
  Derek
 
  On Fri, Mar 13, 2009 at 11:40 AM, Derek Chen-Becker
  dchenbec...@gmail.com
  wrote:
 
  Ah, I think I missed that part of the POM. Let me fix that and commit
  the
  changes and then we can re-test.
 
  Thanks!
 
  Derek
 
  On Fri, Mar 13, 2009 at 11:11 AM, Kris Nuttycombe
  kris.nuttyco...@gmail.com wrote:
 
  How are you installing the archetype as a plugin? After clearing out
  the repo and running an install of the plugin project, I'm not seeing
  it in my local archetype repository.
 
  I had to add this to the lift-archetype-jpa-basic pom.xml to get it to
  install:
 
  diff --git a/lift-archetype-jpa-basic/pom.xml
  b/lift-archetype-jpa-basic/pom.xml
  index 453e2b3..fc0cf8c 100644
  --- a/lift-archetype-jpa-basic/pom.xml
  +++ b/lift-archetype-jpa-basic/pom.xml
  @@ -7,6 +7,7 @@
      relativePath../pom.xml/relativePath
    /parent
    artifactIdlift-archetype-jpa-basic/artifactId
  +  packagingmaven-archetype/packaging
    name${project.artifactId}/name
    descriptionArchetype - blank JPA project for Lift/description
    properties
  @@ -14,10 +15,18 @@
      maven.test.skiptrue/maven.test.skip
    /properties
    build
  +    extensions
  +      extension
  +        groupIdorg.apache.maven.archetype/groupId
  +        artifactIdarchetype-packaging/artifactId
  +        version2.0-alpha-4/version
  +      /extension
  +    /extensions
      plugins
        plugin
          artifactIdmaven-archetype-plugin/artifactId
          version2.0-alpha-4/version
  +        extensionstrue/extensions
          configuration
 
  archetypeArtifactId${project.artifactId}/archetypeArtifactId
            archetypeGroupId${project.groupId}/archetypeGroupId
 
  After that, the archetype installed and I was able to generate it
  correctly. I have not yet tested the resulting application, though.
 
  Kris
 
 
  On Fri, Mar 13, 2009 at 9:46 AM, Derek Chen-Becker
  dchenbec...@gmail.com wrote:
   de...@rocky:/home/software/liftbook$ mvn -v
   Maven version: 2.0.9
   Java version: 1.6.0_11
   OS name: linux version: 2.6.27-11-generic arch: amd64 Family:
   unix
  
   This line in your output concerns me:
  
   [INFO] Using following parameters for creating
   OldArchetype:lift-jpa-archetype:0.11-SNAPSHOT
  
   The version in my archetype is 1.1-SNAPSHOT, so I wonder if you're
   getting
   an older version in your repo. Could you try nuking your .m2/repo
   and
   see if
   you still get the same error?
  
   Derek
  
  
   On Fri, Mar 13, 2009 at 9:38 AM, Kris Nuttycombe
   kris.nuttyco...@gmail.com
   wrote:
  
   What version of Maven are you using? I'm getting the following
   errors:
  
   knuttyco...@knuttycombe-ubuntu:~/tmp$ mvn -DarchetypeCatalog=local
   archetype:generate
   [INFO] Scanning for projects...
   [INFO] Searching repository for plugin with prefix: 'archetype'.
   [INFO]
  
  
   
   [INFO] Building Maven Default Project
   [INFO]    task-segment: [archetype:generate] (aggregator-style)
   [INFO]
  
  
   
   [INFO] Preparing archetype:generate
   [INFO] No goals needed for project - skipping
   [INFO] Setting property: classpath.resource.loader.class =
   'org.codehaus.plexus.velocity.ContextClassLoaderResourceLoader'.
   [INFO] Setting property: velocimacro.messages.on = 'false'.
   [INFO] Setting property: resource.loader = 'classpath'.
   [INFO] Setting property: resource.manager.logwhenfound = 'false'.
   [INFO] [archetype:generate]
   [INFO] Generating project in Interactive mode
   [INFO] No archetype defined. Using maven-archetype-quickstart
   (org.apache.maven.archetypes:maven-archetype-quickstart:1.0)
   Choose archetype:
   1: local - lift-jpa-archetype (lift-jpa-archetype)
   Choose a number:  (1):
   Choose archetype:
   1: local - lift-jpa-archetype (lift-jpa-archetype)
   Choose a number:  (1): 1
   Define value for groupId: : com.gaiam.gcsi
   Define value for artifactId: : jpa-lift
   Define value for version:  1.0-SNAPSHOT: :
   Define value for package: : com.gaiam.gcsi
   Confirm properties

[Lift] Re: Objections to merging jpa archetype?

2009-03-13 Thread Kris Nuttycombe

Excellent!

On Fri, Mar 13, 2009 at 12:55 PM, Derek Chen-Becker
dchenbec...@gmail.com wrote:
 OK, it built and deployed. I just confirmed that you can create it with:

 mvn archetype:generate \
    -DarchetypeRepository=http://scala-tools.org/repo-snapshots \
    -DarchetypeGroupId=net.liftweb \
    -DarchetypeArtifactId=lift-archetype-jpa-basic \
    -DarchetypeVersion=1.1-SNAPSHOT

 Derek

 On Fri, Mar 13, 2009 at 12:54 PM, Derek Chen-Becker dchenbec...@gmail.com
 wrote:

 Darnit. It helps if I make the jpa archetype a module of the master lift
 project. Fixing now.

 Derek

 On Fri, Mar 13, 2009 at 12:52 PM, Derek Chen-Becker
 dchenbec...@gmail.com wrote:

 1.0, baby!

 http://scala-tools.org/mvnsites/scalajpa/

 I've been too busy to put up a nice blog entry on it, but it's on my todo
 list :(

 Derek

 On Fri, Mar 13, 2009 at 12:47 PM, Kris Nuttycombe
 kris.nuttyco...@gmail.com wrote:

 I actually haven't deployed an archetype onto a remote repository
 before, but it sounds right.

 Has ScalaJPA become publicly available on scala-tools yet?

 Kris

 On Fri, Mar 13, 2009 at 11:28 AM, Derek Chen-Becker
 dchenbec...@gmail.com wrote:
  OK, I'll go ahead and merge with master. If I understand this whole
  process
  correctly, Hudson should build the new project and deploy it under
  snapshots
  on scala-tools.org. At that point we should be able to use the
  archetype:generate
  -DremoteRepository=http://scala-tools.org/repo-snapshots
  to generate, correct?
 
  Derek
 
  On Fri, Mar 13, 2009 at 12:01 PM, Kris Nuttycombe
  kris.nuttyco...@gmail.com wrote:
 
  Done.
 
 
  On Fri, Mar 13, 2009 at 10:41 AM, Derek Chen-Becker
  dchenbec...@gmail.com wrote:
   Actually, I see that you did that against git. Can you commit your
   changes?
  
   Thanks,
  
   Derek
  
   On Fri, Mar 13, 2009 at 11:40 AM, Derek Chen-Becker
   dchenbec...@gmail.com
   wrote:
  
   Ah, I think I missed that part of the POM. Let me fix that and
   commit
   the
   changes and then we can re-test.
  
   Thanks!
  
   Derek
  
   On Fri, Mar 13, 2009 at 11:11 AM, Kris Nuttycombe
   kris.nuttyco...@gmail.com wrote:
  
   How are you installing the archetype as a plugin? After clearing
   out
   the repo and running an install of the plugin project, I'm not
   seeing
   it in my local archetype repository.
  
   I had to add this to the lift-archetype-jpa-basic pom.xml to get
   it to
   install:
  
   diff --git a/lift-archetype-jpa-basic/pom.xml
   b/lift-archetype-jpa-basic/pom.xml
   index 453e2b3..fc0cf8c 100644
   --- a/lift-archetype-jpa-basic/pom.xml
   +++ b/lift-archetype-jpa-basic/pom.xml
   @@ -7,6 +7,7 @@
       relativePath../pom.xml/relativePath
     /parent
     artifactIdlift-archetype-jpa-basic/artifactId
   +  packagingmaven-archetype/packaging
     name${project.artifactId}/name
     descriptionArchetype - blank JPA project for
   Lift/description
     properties
   @@ -14,10 +15,18 @@
       maven.test.skiptrue/maven.test.skip
     /properties
     build
   +    extensions
   +      extension
   +        groupIdorg.apache.maven.archetype/groupId
   +        artifactIdarchetype-packaging/artifactId
   +        version2.0-alpha-4/version
   +      /extension
   +    /extensions
       plugins
         plugin
           artifactIdmaven-archetype-plugin/artifactId
           version2.0-alpha-4/version
   +        extensionstrue/extensions
           configuration
  
   archetypeArtifactId${project.artifactId}/archetypeArtifactId
             archetypeGroupId${project.groupId}/archetypeGroupId
  
   After that, the archetype installed and I was able to generate it
   correctly. I have not yet tested the resulting application,
   though.
  
   Kris
  
  
   On Fri, Mar 13, 2009 at 9:46 AM, Derek Chen-Becker
   dchenbec...@gmail.com wrote:
de...@rocky:/home/software/liftbook$ mvn -v
Maven version: 2.0.9
Java version: 1.6.0_11
OS name: linux version: 2.6.27-11-generic arch: amd64
Family:
unix
   
This line in your output concerns me:
   
[INFO] Using following parameters for creating
OldArchetype:lift-jpa-archetype:0.11-SNAPSHOT
   
The version in my archetype is 1.1-SNAPSHOT, so I wonder if
you're
getting
an older version in your repo. Could you try nuking your
.m2/repo
and
see if
you still get the same error?
   
Derek
   
   
On Fri, Mar 13, 2009 at 9:38 AM, Kris Nuttycombe
kris.nuttyco...@gmail.com
wrote:
   
What version of Maven are you using? I'm getting the following
errors:
   
knuttyco...@knuttycombe-ubuntu:~/tmp$ mvn
-DarchetypeCatalog=local
archetype:generate
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix:
'archetype'.
[INFO]
   
   
   

[INFO] Building Maven Default Project
[INFO]    task-segment: [archetype:generate]
(aggregator-style)
[INFO

[Lift] Re: Objections to merging jpa archetype?

2009-03-13 Thread Kris Nuttycombe

Yeah... the minor things that made it work at all. :)
And ScalaJPA
And the whole exploration of Scala's interaction with JPA that you so
thoroughly documented on the wiki, which gave me the confidence to use
Lift in a major project in my company in the first place...

Thank you Derek. You do rock.

Kris

On Fri, Mar 13, 2009 at 4:55 PM, Derek Chen-Becker
dchenbec...@gmail.com wrote:
 Well, to give proper credit, Tyler and Kris both did a lot of initial work
 on the archetype and I just fixed a few minor things.

 Derek

 On Fri, Mar 13, 2009 at 5:49 PM, Charles F. Munat c...@munat.com wrote:

 OH HELL YEAH! THANKYOUTHANKYOUTHANKYOU. You rock.

 Chas.

 Derek Chen-Becker wrote:
  OK, it built and deployed. I just confirmed that you can create it with:
 
  mvn archetype:generate \
     -DarchetypeRepository=http://scala-tools.org/repo-snapshots \
     -DarchetypeGroupId=net.liftweb \
     -DarchetypeArtifactId=lift-archetype-jpa-basic \
     -DarchetypeVersion=1.1-SNAPSHOT
 
  Derek
 
  On Fri, Mar 13, 2009 at 12:54 PM, Derek Chen-Becker
  dchenbec...@gmail.com mailto:dchenbec...@gmail.com wrote:
 
      Darnit. It helps if I make the jpa archetype a module of the master
      lift project. Fixing now.
 
      Derek
 
 
      On Fri, Mar 13, 2009 at 12:52 PM, Derek Chen-Becker
      dchenbec...@gmail.com mailto:dchenbec...@gmail.com wrote:
 
          1.0, baby!
 
          http://scala-tools.org/mvnsites/scalajpa/
 
          I've been too busy to put up a nice blog entry on it, but it's
          on my todo list :(
 
          Derek
 
 
          On Fri, Mar 13, 2009 at 12:47 PM, Kris Nuttycombe
          kris.nuttyco...@gmail.com mailto:kris.nuttyco...@gmail.com
          wrote:
 
 
              I actually haven't deployed an archetype onto a remote
              repository
              before, but it sounds right.
 
              Has ScalaJPA become publicly available on scala-tools yet?
 
              Kris
 
              On Fri, Mar 13, 2009 at 11:28 AM, Derek Chen-Becker
              dchenbec...@gmail.com mailto:dchenbec...@gmail.com
  wrote:
                OK, I'll go ahead and merge with master. If I understand
              this whole process
                correctly, Hudson should build the new project and deploy
              it under snapshots
                on scala-tools.org http://scala-tools.org. At that
              point we should be able to use the
                archetype:generate
              -DremoteRepository=http://scala-tools.org/repo-snapshots
                to generate, correct?
               
                Derek
               
                On Fri, Mar 13, 2009 at 12:01 PM, Kris Nuttycombe
                kris.nuttyco...@gmail.com
              mailto:kris.nuttyco...@gmail.com wrote:
               
                Done.
               
               
                On Fri, Mar 13, 2009 at 10:41 AM, Derek Chen-Becker
                dchenbec...@gmail.com mailto:dchenbec...@gmail.com
              wrote:
                 Actually, I see that you did that against git. Can you
              commit your
                 changes?
                
                 Thanks,
                
                 Derek
                
                 On Fri, Mar 13, 2009 at 11:40 AM, Derek Chen-Becker
                 dchenbec...@gmail.com mailto:dchenbec...@gmail.com
                 wrote:
                
                 Ah, I think I missed that part of the POM. Let me fix
              that and commit
                 the
                 changes and then we can re-test.
                
                 Thanks!
                
                 Derek
                
                 On Fri, Mar 13, 2009 at 11:11 AM, Kris Nuttycombe
                 kris.nuttyco...@gmail.com
              mailto:kris.nuttyco...@gmail.com wrote:
                
                 How are you installing the archetype as a plugin?
              After clearing out
                 the repo and running an install of the plugin
              project, I'm not seeing
                 it in my local archetype repository.
                
                 I had to add this to the lift-archetype-jpa-basic
              pom.xml to get it to
                 install:
                
                 diff --git a/lift-archetype-jpa-basic/pom.xml
                 b/lift-archetype-jpa-basic/pom.xml
                 index 453e2b3..fc0cf8c 100644
                 --- a/lift-archetype-jpa-basic/pom.xml
                 +++ b/lift-archetype-jpa-basic/pom.xml
                 @@ -7,6 +7,7 @@
                     relativePath../pom.xml/relativePath
                   /parent
                   artifactIdlift-archetype-jpa-basic/artifactId
                 +  packagingmaven-archetype/packaging
                   name${project.artifactId}/name
                   descriptionArchetype - blank JPA project for
              Lift/description
                   properties
                 @@ -14,10 +15,18

[Lift] Re: IDE

2009-03-04 Thread Kris Nuttycombe
NetBeans works well for me. I've always found that NetBeans's Maven
integration is superior to that for Eclipse, and the fact that the Scala
plugin interoperates smoothly with the Maven integration is a big plus for
me. The Scala autocomplete functionality and automatic syntax checking in
NetBeans has recently improved significantly, as well.

Kris

On Wed, Mar 4, 2009 at 9:21 AM, Timothy Perrett timo...@getintheloop.euwrote:


 Paulo,

 Lots of people use netbeans and eclipse. Im sure if you have issues
 with the eclipse plugin its maintainers would love bug reports :-)
 Otherwise, I know a lot of use (myself included) just use TextMate
 with a compiler open in a terminal window which works great.

 Hope that helps

 Tim
 - Show quoted text -

 On Mar 4, 4:14 pm, Paulo Cheque pauloche...@gmail.com wrote:
  What IDE do you use to develop lift applications? Eclipse? NetBeans?
  I want to use Scala regurlarly, but Eclipse plugin is too bugged...
 
  Thanks in advance..
  []s
  Paulo
 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: IDE

2009-03-04 Thread Kris Nuttycombe
Oh, and one more thing about NetBeans - if you, like me, have vi hardwired
into your nervous system, the jvi plugin (http://jvi.sourceforge.net) for
NetBeans is a HUGE win. A fully featured vi in the editor window + NetBeans
autocomplete, refactoring support, etc is bliss.

Kris

On Wed, Mar 4, 2009 at 9:27 AM, Kris Nuttycombe
kris.nuttyco...@gmail.comwrote:

 NetBeans works well for me. I've always found that NetBeans's Maven
 integration is superior to that for Eclipse, and the fact that the Scala
 plugin interoperates smoothly with the Maven integration is a big plus for
 me. The Scala autocomplete functionality and automatic syntax checking in
 NetBeans has recently improved significantly, as well.

 Kris

 On Wed, Mar 4, 2009 at 9:21 AM, Timothy Perrett 
 timo...@getintheloop.euwrote:


 Paulo,

 Lots of people use netbeans and eclipse. Im sure if you have issues
 with the eclipse plugin its maintainers would love bug reports :-)
 Otherwise, I know a lot of use (myself included) just use TextMate
 with a compiler open in a terminal window which works great.

 Hope that helps

 Tim
 - Show quoted text -

 On Mar 4, 4:14 pm, Paulo Cheque pauloche...@gmail.com wrote:
  What IDE do you use to develop lift applications? Eclipse? NetBeans?
  I want to use Scala regurlarly, but Eclipse plugin is too bugged...
 
  Thanks in advance..
  []s
  Paulo
 



--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: Code Freeze

2009-02-12 Thread Kris Nuttycombe
I presume that I'm still okay to commit all of the scaladoc updates I've
been working on? I'll probably have all of  lift-utils (with the exception
of the parser combinator stuff which I don't understand) fully documented
either tonight or tomorrow morning, with lift-webkit soon to follow.

Kris

On Thu, Feb 12, 2009 at 8:12 PM, David Pollak feeder.of.the.be...@gmail.com
 wrote:

 Folks,
 The code for Lift 0.11-SNAPSHOT (aka, Lift 1.0 RC) is frozen.

 The only changes to the Lift codebase between now and 2/26, the 1.0 release
 date, will be bug fixes.

 Please test, test, test, test, test the 0.11-SNAPSHOT release.

 I checked in some browser compatibility fixes today (making IE8 work,
 fixing the XHTML rendering for XHTML such that tags that are not EMPTY are
 rendered as open/close tags per the W3C spec).

 Thanks,

 David

 --
 Lift, the simply functional web framework http://liftweb.net
 Beginning Scala http://www.apress.com/book/view/1430219890
 Follow me: http://twitter.com/dpp
 Git some: http://github.com/dpp

 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Lift group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: Need access to session variables when about to shut down a session.

2009-02-05 Thread Kris Nuttycombe
David, I'm a little confused by how to use registerCleanupFunc after your
most recent set of changes. It now appears to be package-private, so what is
the recommended way to register a cleanup func for a RequestVar? Previously,
I'd implemented my JNDIResource class for use with the JPA stuff like this:

object JNDIResource {
  val context = new InitialContext()
}

abstract class JNDIResource[T](val name: String) extends
RequestVar[T](context.lookup(name).asInstanceOf[T]) {

  // This is way too dependent upon an implementation detail of the
superclass.
  override def cleanupFunc : Box[() = Unit] = {
Log.debug(Initializing JNDI resource  + name + ( + this.is + ))
initialize(this.is) //this will result in a recursive call, but the the
order of operations is such that it will take the other branch.

Full(() = {
Log.debug(Releasing JNDI resource  + name + ( + this.is + ))
dispose(this.is)
  })
  }

  /**
   * Subclasses should override this method to provide initialization
   */
  protected def initialize(resource : T) {
  }

  /**
   * Subclasses should override this method to provide initialization
   */
  protected def dispose(resource: T) {
  }
}

Using the cleanupFunc like this was of course a complete hack to add the
ability to do additional delgated initialization to the variable retrieved
from the JNDI context. I can handle the initialization part by overriding
setFunc in my new implementation, but how can I set up the delegation to
dispose?

Thanks,

Kris


 On Feb 4, 11:56 pm, David Pollak feeder.of.the.be...@gmail.com
 wrote:
  I've just realized that I'm a complete idiot.
  I need to totally re-do the clean-up mechanism.
 
  Please give me an hour.
 
  On Wed, Feb 4, 2009 at 3:06 PM, Kris Nuttycombe
  kris.nuttyco...@gmail.comwrote:
 
 
 
   Heh, this one just bit me too. I can't say I didn't warn myself,
 though:
 
 // This is way too dependent upon an implementation detail of the
   superclass.
 override def cleanupFunc : Box[() = Unit] = {
...
 }
 
   Kris
 
   On Wed, Feb 4, 2009 at 1:47 PM, David Pollak 
   feeder.of.the.be...@gmail.com wrote:
 
   That's because cleanUpFunc is gone.
 
   You must do:
 
   object sessDirHash extends SessionVar[String]() {
 registerCleanupFunc(session = println(Got hash:  + this.is))
 
   }
 
   On Wed, Feb 4, 2009 at 12:43 PM, Alli allilis...@gmail.com wrote:
 
   Hey David,
 
   Two questions this time:
 
   I've been playing with your commit earlier today and cleaning up
   SessionVar's.
   I got:
 
   object sessDirHash extends SessionVar[String]() {
def cleanUpFunc(sess: LiftSession) = {
 println(Got hash:  + this.is)
   }
 
   In my test snippet I got:
   sessDirHash(this is a test)
   println(Got var:  + ResizeMyPics.sessDirHash.is)
 
   I can see it printed out correctly after setting it but it's empty in
   the cleanup function.
 
   2)
   Second question, I submit a form and my flash component starts e.g. 3
   new sessions and POST's to /resize
 
   /resize sets a SessionVar variable but it's like it's only being set
   the first time. I'm printing out right before I register
   the clean up handler in the SessionVar, from my jetty logs:
 
   INFO - Service request (GET) /images/cancelbutton.gif took 9
   Milliseconds
   Rez Gots: 127.0.0.1
   Registering cleanup for: 1uvl5176sdy9r
   Rez Rep Gots: 127.0.0.1
   INFO - Service request (POST) /resize took 270 Milliseconds
   Rez Gots: 127.0.0.1
   Rez Rep Gots: 127.0.0.1
   INFO - Service request (POST) /resize took 91 Milliseconds
   Rez Gots: 127.0.0.1
   Rez Rep Gots: 127.0.0.1
   INFO - Service request (POST) /resize took 481 Milliseconds
 
   I would think it should print out Registering cleanup handler ...
   after each /resize request since they are different sessions.
 
   Then the sessions all timeout and I can see there are 4 sessions
   expiring but there is only message printed out once
   from the clean up handler.
 
   What are your thoughts on this?
 
   Cheers,
   Alfred
 
   On Feb 4, 1:19 am, Alli allilis...@gmail.com wrote:
Thanks David, I'll get it tomorrow from scala-tools.org and finish
 up
the app.
URL will behttp://www.resizemypics.netafree service for people to
resize their pictures
and view them online. Just a simple, yet convenient service. Gives
 me
a chance to learn
more about lift as well. Been following lift for a while but this
 is
the first site I finish, have a
half finished blog site in lift. Doing all this stuff outside of
 work
so it's easy to get distracted.
 
Will let you know once the site is in production.
 
Again thanks for your help.
 
Cheers,
Alli
 
On Feb 4, 1:12 am, David Pollak feeder.of.the.be...@gmail.com
 wrote:
 
 0.11-SNAPSHOT is 0.10 with bug fixes.  It's very stable and will
 be
   1.0 on
 2/26.
 I'll commit up a fix to this problem in a few minutes.
 
 Also, what's the URL of the site? :-)
 
 On Tue, Feb 3

  1   2   >