[Lift] **BREAKING CHANGES** in lift-record
As I mentioned before, I was planning to make some breaking changes to lift-record, and since I got no additional feedback, I've now pushed to master. These changes make some cleanups to method naming and functionality in lift-record, and all code using 2.0-SNAPSHOT will need some changes: - Each MetaRecord implementation must define createRecord. To migrate, add this method to your MetaRecord: def createRecord: MyRecord = new MyRecord - If you previously used Record#fromJSON, you will need to use Record#setFieldsFromJSON instead. - If you previously used MetaRecord#createRecord(json: String), you will need to use MetaRecord#fromJSON instead. - If you previously used MetaRecord#fromJSON(inst, json), you will need to use MetaRecord#setFieldsFromJSON instead. In addition, lift-couchdb has been updated to track these changes: - If you previously used JSONRecord#fromJValue, you will need to use JSONRecord#setFieldsFromJValue instead. - If you previously used JSONMetaRecord#fromJValue(rec, jvalue), you will need to use JSONMetaRecord#setFieldsFromJValue instead. - CouchMetaRecord#create and CouchMetaRecord#createFromJValue have been removed. Use MetaRecord#createRecord and JSONMetaRecord#fromJValue instead. Let me know if anyone has any problems. -Ross On Feb 27, 2010, at 11:53 AM, Ross Mellgren wrote: Hey all, So as a result of an infelicity in the way records are initialized that tripped up Tim a week or two ago, I'm planning on doing some cleanup to lift-record. It is a breaking change, and it was noted that it'd be good to get opinions on this, so here we are! The original problem was that if you used new MyRecord then you'd get a record that was basically functional but some of the extended metadata (notably field.name) would not be initialized correctly. This is because the correct way to create a record was MyRecordMeta.createRecord. I fixed it so that new MyRecord is equivalent to MyRecordMeta.createRecord, but Marius pointed out there was more cleaning to do. Here are the changes: - I made the createRecord method on MetaRecord abstract, so that MyRecordMeta must now implement it. If you are porting over old code, then just do: def createRecord = new MyRecord This change is so that record creation must be explicitly specified in case it is different from new MyRecord (the default implementation) - MetaRecord.fromJSON(inst, json) has been renamed to setFieldsFromJSON(inst, json) - a new method MetaRecord.setFieldsFromReq(inst, req) has been created to parallel the new name of fromJSON - MetaRecord.createRecord(json) has been renamed to fromJSON(json) - Record.fromJSON has been renamed to setFieldsFromJSON - Record.setFieldsFromReq has been added -- they just call the meta methods of the same name. These changes at the end make it so that fromSomething(something) are consistently factory methods that create records from some source (JSON or Req), and that setFieldsFromSomething(inst, something) is consistently there for setting the fields from the source. Let me know what you think. -Ross -- 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] Breaking changes in lift-record 2.0-SNAPSHOT - Optional fields
I just committed a change to lift-record in 2.0-SNAPSHOT that will possibly (probably?) break your build if you use it. This change makes it possible to have any record field be optional -- that is, Box[MyType]. You use it like this: object MyRecord extends Record[MyRecord] { object myNormalField extends StringField(this, 100) object myOptionalField extends StringField(this, 100) { override def optional_? = true override def defaultValueBox = Empty override def defaultValue = nothin } } val r: MyRecord r.myNormalField.set(Hello) // as before the change r.myOptionalField.setBox(Empty) r.myNormalField.value == Hello // as before r.myNormalField.valueBox == Full(Hello) r.myOptionalField.valueBox == Empty r.myOptionalField.value == nothin // because defaultValue was used to give back something As part of this change, the semantics for field errors has changed somewhat -- hopefully, to be more consistent. Previously if you tried to set a field and checkCanWrite_? returned false then an internal flag valueCouldNotBeSet on the field will be raised which makes that field generate a validation error when validate is called on the record. In addition, some fields (but not all) would raise the same flag and return Failure or Empty from setFromString or setFromAny upon being given an invalid value. With this change, all types of failure to set now result in the field value becoming a Failure. setFromAny, setFromString, and setBox all return that Failure, while set will return defaultValue (due to its return type.) validators and set filters have had their types changed to Boxed equivalents. And finally, I made consistent the setFromAny methods of all the built-in field types so that they all follow the same contract. For setFromAny it's essentially accept one of MyType, Box[MyType], Option[MyType], or List[MyType] as well as null, with a default to convert an unknown input to string and use setFromString. For setFromString, it is as before, except if the field is optional_? and the empty string is passed in, that's treated as Empty. As I'll mention in another message, I also pushed lift-couchdb to master. I ran the unit tests that I wrote for that, but that doesn't give me full confidence that all the fields are entirely bug free. Similarly I did not test the form generation. If anybody runs into any issues please let me know and I'll fix it as soon as I can. And of course if it causes too much breakage we can revert it back out. -Ross -- 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] **BREAKING CHANGES**: Use mvn archetype:generate to generate 1.1-SNAPSHOT archetypes
Friends, Following the recent refactoring that the Lift archetypes went though, we have moved forward to the new archetype metadata format [1] for all the archetypes. So far, the JPA related archetypes were using the new metadata format while the others (esp. lift-archetype-blank and lift-archetype-basic) were still on the old format. Moving to the new metadata format helps us keep things consistent, comply with Maven's recommendation and open the archetypes up for additional future enhancements. From now on, the recommended Maven goal to generate projects from archetype is to use archetype:generate [2]. The currently deprecated Maven goal archetype:create [3] would not work to give expected result and thus is not recommended anymore. Therefore, to generate project from the archetypes in the master you would use a command of the form: mvn archetype:generate \ -DarchetypeRepository=http://scala-tools.org/repo-snapshots \ -DremoteRepositories=http://scala-tools.org/repo-snapshots \ -DarchetypeGroupId=net.liftweb \ -DarchetypeArtifactId=lift-archetype-blank \ -DarchetypeVersion=1.1-SNAPSHOT \ -DgroupId=com.mypackage \ -DartifactId=myproject \ -Dversion=1.0-SNAPSHOT Currently, the possible archetypeArtifactId are: - lift-archetype-blank - lift-archetype-basic - lift-archetype-jpa-blank-single - lift-archetype-jpa-blank - lift-archetype-jpa-basic If you create project interactively (default behavior), -DgroupId, - DartifactId, -Dversion are optional. Maven would prompt for these values (and some more) interactively. On the other hand, if you are using a batch/shell script to generate project non-interactively, you would need to add at least -DgroupId, - DartifactId and additionally set -DinteractiveMode=false. Cheers, Indrajit References: [1] http://maven.apache.org/plugins/maven-archetype-plugin/specification/archetype-metadata.html [2] http://maven.apache.org/plugins/maven-archetype-plugin/generate-mojo.html [3] http://maven.apache.org/plugins/maven-archetype-plugin/create-mojo.html -- 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] *** BREAKING CHANGES *** to Loc LocParam
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] Breaking changes in CometActor code vs. continuing instabilities in Scala Actors
Guys, The Scala Actor issue has raised its head again. From November 2008 - June 2009, I did an epic battle with Scala actors and their memory retention issues. I finally wrote a Lift Actor library that made all the Scala Actor-related issues go away for the short-lived Actors that Lift uses as listeners for comet long-polling. It seems that the Actor issue is not gone. I'm not sure it will be gone in Scala 2.8. I can make a change in Lift to move to Lift Actors in CometActor code. It means that if you're using Scala Actors beyond !, !! and !? methods, you will have to change your code, otherwise it will just be a recompile. What do people think? 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] *** BREAKING CHANGES COMING UP SOON ***
Folks, I spent a few days decoupling Lift from JEE web container dependencies: javax.servlet._ The code is currently in wip-marius-http- abstractions. I still need to nail down a few things but the idea is: 1. Lift will work with its own traits that abstracts HTTP request, response, HTTP sessions etc. 2. By default there will be the servlet implementation and it'll work as currently. 3. Certain function names will slightly change. 4. If your application explicitly wants to use HttpServletRequest obtained from S some explicit casts would be needed. Generally Lift application should probably not explicitly use javax.servlet._ references. I will post the details of the changes when I'll merge it to master (hopefully this week). Br's, Marius --~--~-~--~~~---~--~~ 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] *breaking changes* Gravatar widget
Hey guys, I've updated the Gravatar widget that was origionally created by Ty. The implementation now is actually very different. No longer is the Gravatar class an instansiable class, its an object with overloaded apply methods. So, now, rather than: val g = new Gravatar() g.render([EMAIL PROTECTED]) You need to do: Gravatar([EMAIL PROTECTED]) Or, if you want an image with a set size, you do: Gravatar([EMAIL PROTECTED], 50) Or, if you want to produce one thats for a set rating (other than the default G) do: Gravatar([EMAIL PROTECTED], 50, R) Hope thats all ok for everyone Cheers, Tim --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/liftweb?hl=en -~--~~~~--~~--~--~---