Latest Posts

Archives [+]

Categories [+]

Authors [+]

Archive for March 2008

    Posted by Greg Klebus MAR 26, 2008

    Posted in announcements, jcr and sling Add comment

    The Day JCR Cup 2008 programming contest has been launched today! David Nuescheler's presentation, Kickstarting JCR: TheServerSide.com as a Content Application, at The Server Side Symposium in Las Vegas has a lot of information useful for the ones of you who are interested in the contest.

    We are going to launch the contest website very soon, with the freely downloadable CRX "Special Cup" Edition (prepare yourself for a nice surprise on how quickly you can get from download to the first lines of code!) and all the necessary contest infrastructure. In the meantime, be sure to leave your email address in contest banner at the top of this page and we're going to notify you when the contest website is up and running. And learn more about the Day JCR Cup 2008 below.

    The Challenge

    Design and develop a content-centric application using Day CRX,a fully JCR compliant content repository based on Apache Jackrabbit and CRX Launchpad, an easy to use rapid application development framework, based on Apache Sling, and included in the Day CRX package.

    The JCR vision is that content-centric applications can be built
    quickly and in elegant ways, focusing on the user and content.
    It is developers like you who will shape the vision by building these
    great content applications.

    The Prize

    A fully-loaded MacBook Pro with a 17-inch widescreen. And an all-in-one printer.

    The Application

    The application you submit should:

    • allow the entry of content, formatted in any appropriate format (wiki, blog, simple markup)
    • offer user authentication for content creation
    • have two kinds of taxonomies for each content piece: a "vertical" taxonomy to classify the "section" of the content, and a "horizontal" taxonomy to provide more detail for each content piece
      • Example: vertical taxonomy - sections of the website like "news", "reviews", etc, and the horizontal taxonomy - tags or categories for individual content pieces like, e.g., Spring and JCR
    • allow any given content article to have multiple horizontal and vertical taxonomies (this isn't a strict requirement, though)
    • allow search facilities to be restricted by taxonomies as well as content
    • leverage a web browser environment

    Optional requirements:

    • Preview before publication of content
    • Workflow process for publication
    • Discussion thread for content

    We believe that using the JCR repository features and the rapid application development framework based on Apache Sling framework such an application can be built quickly and in an elegant way.

    Understanding of Java and JCR API concepts, and practical knowledge of web development standards (Javascript, HTML/CSS) are the prerequisites for participation. The contest is also a great way to learn more about JCR if you did not have a chance to try it out yet.

    The Rules in Short

    • Contest is worldwide, submissions from individuals only, one entry per person
    • Submission in a form of a content package (everything in English) through Day JCR Cup website on dev.day.com
    • Entries will be accepted through 12am Pacific Coast Time, July 31, 2008
    • Submissions will be judged by a panel of technology experts
      • David Nuescheler, Day's CTO and the spec lead for JSR 170 and JSR 283
      • Joseph B. Ottinger, Editor, TheServerSide
      • Michael Marth, industry expert on Java and Open Source technologies and editor of dev.day.com
    • Judging criteria
      • Originality of the application (30%)
      • Content and application design (20%)
      • Quality of delivered code (20%)
      • Appropriate use of JCR API features (20%)
      • Other outstanding features (10%)
    • The Winner will be announced within 28 days of the contest close

    Posted by Michael Marth MAR 14, 2008

    Posted in announcements, day and jackrabbit Add comment

    There will be a JCR community gathering as a sidetrack of ApacheCon EU in Amsterdam next month. See http://wiki.apache.org/jackrabbit/JcrMeetupApril2008 for the details. For Day the Sling and Jackrabbit committers Jukka Zitting, David Nuescheler, and Felix Meschberger will take part. See you there?

    Posted by Lars Trieloff MAR 12, 2008

    Posted in cms, crx, sling, standards and ujax Add comment

    This month has been full of presentations for me. Aside from some internal and some customer presentations, the two that are available online are my slides from Web Monday Stockholm, where I presented JCR, Sling and microjax. Peter Svensson invited me, so I also demonstrated the Dojo integration for µjax that allowed me to write a basic repository browser for a content repository in less than 50 lines of code.

    Later that week I presented Content Fragmentation vs. Social Computing at the CeBIT Content Management Arena. The main idea of the talk is that social computing lives by its network effects, and that these network effects apply to people and to content. So the more content you have accessible and the more content and people can be connected to each other, the higher the value of your social application is. While mechanisms like OpenSocial, OpenID and DataPortability can help to a certain degree achieving higher content connectability at the application level, Day's CRX with its connector products allow integration at the content level with a proven and standardized API, namely JCR.



    Posted by Michael Marth MAR 05, 2008

    Posted in cms and link of the day Add comment

    CMSWatch has published a CMS subway map. Day is placed in the city center and on the ECM, WCM and DAM lines. I guess this is more fun than serious, but I feel the need to argue anyway: the Day station should have been moved further north, closer to the Open Source CMSs (after all, we sponsor Jackrabbit and Sling as well as other OSS, see the bottom of the right sidebar on the front page of this blog).

    CMS Watch Vendor Subway Map, 2008

    Posted by Michael Duerig MAR 05, 2008

    Posted in dynamic languages, jcr, rad and tutorial Add comment

    In two earlier posts (1, 2) I showed how to define a Scala operator in a way such that building a JCR tree structure results in code which - when properly indented - resembles an ASCII art drawing of the tree. Up to now this only works for nodes. In this post I show how to define an operator for adding properties. A full working example is available from my personal blog.

    Basically adding properties is no different to adding nodes: just define an operator and overload it for every type of property. At this point it is tempting to not even define a new operator but to further overload the ¦- (add node) operator. But there is a problem. Consider the signature for adding a string typed property:

    def ¦-(name: String, value: String) 

    This happens to be exactly the same as the signature for adding a node of a given type

    def ¦-(relPath: String, tyqe: String)

    We could fix this by adding a dummy parameter for disambiguation. But I consider this a hack rather than a solution. Furthermore overloading ¦- for adding properties contradicts the principle of separation of concerns.

    Using ¦= as operator for adding properties to a node, the following definitions could be added to NodeExtender effectively overloading ¦= for every property type.

    def ¦=(name: String, value: long) =                        node.setProperty(name, value)def ¦=(name: String, value: String) =                        node.setProperty(name, value)...

    With these definitions in place adding properties works as expected. The following code adds a title and a length property to the movie node.

    movie ¦= ("title", "Night on Earth")movie ¦= ("length", 123L)

    However, how should we handle multi-value properties? Of course, we could add another overload of ¦= like this:

    def ¦=(name: String, value: Array[Value]) =                       node.setProperty(name, value)

    This is a simple solution and works well, but it doesn't really seem to fit into the existing framework: the array of Values has to be constructed in advance before it can be passed to the ¦= operator. It would be much nicer if we could use Scala's List constructors and write

    movie ¦= ("ratings", 9L::8L::5L::Nil) movie ¦= ("languages", "en"::"it"::"fi"::"fr"::Nil) 

    instead.

    So let's try to add corresponding overloads for ¦=

    def ¦=(name: String, value: List[long]) = ...def ¦=(name: String, value: List[String]) = ......

    This seems all too easy, but unfortunately it does not work. When compiling, Scala complains about the overloaded methods having the same type erasure:

    double definition:method ¦=:(String,List[String]) andmethod ¦=:(String,List[long]) have same type after erasure.

    What is going on? Scala - as Java - implements generics by erasure. In a nutshell this means that at compile time the compiler removes the type information from generic types. When such types are referenced, it automatically infers the correct type and adds a casts if necessary. Removing the type arguments from above methods leaves us with the same signature for both: the erasure of the type of the value argument is always the type List.

    Of course we could chicken out of this dilemma by using a generic method for multi-valued properties like this:

    def ¦=[T](name: String, value: List[T]) = ... 

    An implementation would query the actual type of the list elements at runtime and then call the right overload of setProperty. However, such an approach is not type safe: if T is of a type for which there is no overload of setProperty, the implementation would have to throw an exception.

    As it turns out, we can do better. There is a way to define the ¦= operator without abandoning type safety. Basically we want to define a method

    def ¦=[T](name: String, value: T) = ...

    applicable to every type T for which either an overload of the setProperty method exists or for which a setProperty method taking an array of Values of type T exists. We can achieve this by employing Scala's view bounds and implicits:

     

    def ¦=[T <% Extensions.Val[T]](name: String,       value: T) =value.setOnNode(node, name, valueFactory)

    This signature basically says that ¦= is applicable to every type T which is convertible to the type Extensions.Val[T]. All we have to do now is to provide conversion methods to Extensions.Val[T] for the right types of T.

    object Extensions {   import javax.jcr.{Value, ValueFactory}  implicit def extendNode(node: Node) =     new NodeExtender(node)       abstract class Val[-T](value: T) {    def setOnNode(node: Node, name: String,      factory: ValueFactory)    def toValue(factory: ValueFactory): Value  }      implicit def longToVal(l: long) = new Val(l) {    def setOnNode(node: Node, name: String,      factory: ValueFactory) =       node.setProperty(name, factory.createValue(l))                def toValue(factory: ValueFactory) =       factory.createValue(l)  }  implicit def stringToVal(s: String) = new Val(s) {    def setOnNode(node: Node, name: String,      factory: ValueFactory) =       node.setProperty(name, factory.createValue(s))            def toValue(factory: ValueFactory) =        factory.createValue(s)  }      implicit def listToVal[T](seq: Seq[T])    (implicit toVal: T => Val[T]) = new Val(seq) {    def setOnNode(node: Node, name: String,      factory: ValueFactory) = {      val values = seq.map(toVal(_).toValue(factory))      .toArray        node.setProperty(name, values)    }            def toValue(factory: ValueFactory) =       error("not applicable")  }}

    Each Extensions.Val[T] has a setOnNode method, which is eventually responsible for calling setProperty passing along a Value of type T. It uses the valueFactory supplied by the caller to construct this Value. The toValue method converts the individual elements of a multi-valued property to the corresponding Value objects. It is called once for each element of such a property from the setOnNode method of an Extensions.Val[Seq[T]] instance.

    The implicit method listToValue is responsible for converting a sequence of Ts into an Extensions.Val[Seq[T]] instance. Note that the parameter toVal of listToValue is implicit itself. This parameter is a converter for the elements of the sequence. (i.e. we can convert a sequence if we have a converter for it's elements). The conversion of the list uses my implicit double dispatch pattern: the setOnNode method passes each element of the sequence (by means of map) to the converter toVal obtaining a Val object whose toValue method is used in turn to obtain a Value object. These Values are then collected into an array by toArray and finally passed to the setProperty method.

    At first this technique might seem awfully convoluted. However, it turns out to be an instance of a more general pattern, which allows for effectively overcoming a limitation of the type system: overloading of methods with arguments having the same type erasure. While Java has the same limitation, there is no such solution in Java. For more details see Implicit double dispatch and Implicit double dispatch revisited on my personal blog.

    Reality check: after finally having overcome all these difficulties, we are now in the position to add properties - both single and multi-valued - using ASCII-Art syntax:

    n ¦- "movies" -+ { n: Node =>             n ¦- "cast" -+ { n: Node =>                          n ¦= ("Gena Rowlands",                                "Victoria Snelling")                           n ¦= ("Winona Ryder",                                 "Corky")                           n ¦= ("Roberto Benigni",                                 "Taxi Driver")                             }             n ¦= ("title", "Night on Earth")               n ¦= ("length", 123L)               n ¦= ("ratings", 9L::8L::5L::Nil)               n ¦= ("languages",              "en"::"it"::"fi"::"fr"::Nil)                }n ¦- "movies" -+ { n: Node =>             n ¦- "cast" -+ { n: Node =>                          n ¦= ("James Stewart",                                 "Det. Ferguson")                           n ¦= ("Tom Helmore",                                 "Gavin Elster")                           n ¦= ("Henry Jones",                                 "Coroner")                             }             n ¦= ("title", "Vertigo")               n ¦= ("length", 124L)               n ¦= ("ratings", 10L::8L::7L::Nil)               n ¦= ("languages", "en"::Nil)                  }