Latest Posts

Archives [+]

Categories [+]

Authors [+]

Entries filed under 'microsling'

    Posted by Kas Thomas JUL 09, 2010

    Posted in crx, crx gems, development, javascript, microsling, sling and tutorials Comment 1


    In prior blogs, I've given code for interacting via HTTP with Day's CRX repository from a Chrome/Greasemonkey script environment as well as from an OpenOffice macro. Such interactions are, as you know, made easy by CRX's (or should I say, Apache Sling's) REST API, which exposes a huge amount of functionality through plain old HTTP, obviating the need for such cumbersome things as RMI-over-IIOP, SOAP-RPC, complex content mappings on the back end, etc.

    It turns out that precisely because of the ease with which you can interact with a Sling repository over HTTP, it's quite straightforward to set up interactions between Adobe Acrobat (and/or Portable Document Format files) and CRX.
    There are two styles of what I'll call Acrobat-CRX integration, in terms of RESTful interactions. One style involves PDF forms. The other style involves the Adobe Acrobat runtime environment itself. In the former case, you'll typically write JavaScript snippets that attach to form fields and are triggered by form events. In the latter case, you write scripts for Acrobat itself, and from within those scripts you can hit the server in a variety of ways and do AJAX-like things behind the scenes. In this blog, we'll talk about the first case (which is easy); in a subsequent blog, we'll talk more about the second case (which is only slightly harder).

    The easiest way to read or write the repository from PDF is to use a PDF form. Acrobat Professional comes with decent form-creation tools, allowing you to create all the standard sorts of controls (text fields, radio buttons, etc.) and attach scripts to them. The default behavior of the Submit button, in a PDF form, is to trigger a POST in which all field data gets sent to the server, either as Adobe FDF (Forms Data Format), XFDF, or HTML (depending on what you specified in the Acrobat UI when you created the Submit button). So if all you want to do is hit the server with a form POST and (in so doing) push content into a new node in CRX, you simply need to create a PDF form with a Submit button and specify a Sling-legal target URL per the Sling cheat sheet. No JavaScript required.

    Most of the time, though, you'll probably want to exercise finer control over the form's behavior. You might want to issue a ":redirect" directive to the Sling servlet, for example, so that your user is taken to a particular page after the POST. Or you might want to use the ":nameHint" directive to force the repository to create a node with a specific name. Perhaps there are fields whose values you want to include or exclude at POST time. To handle these and other special situations, you'll want to write a bit of JavaScript.

    First, though, create the Submit button using Acrobat Professional's form-design tools. In the configuration dialog for the button, select the Actions tab, then use the Selection Actions picker to select "Run a JavaScript." (Normally, you'd choose "Submit a Form." Instead, we're going to do the Submit programmatically.) See the screenshot below.

    Use the "Add..." button to add a script to the button, then select "Run a JavaScript" in the Actions pane and you'll see an Edit button become enabled.

    Click the Edit button. In the dialog that appears, cut and paste the following code:

    var params = {};
    params.cURL = "http://localhost:7402/content/myapp/";
    params.cSubmitAs = "HTML";
    params.cCharset = "utf-8";
    params.bGet = false;
    this.submitForm( params );
     

    What's going on here is that we're simply creating a parameter block that tells Acrobat what we want done at POST time, then we're passing that parameter block as an argument to the Acrobat JavaScript API method submitForm().

    As you can see, we've specified in cURL the CRX target location (the node under which to create a new item). Note that the path ends with a forward-slash.

    In the cSubmitAs parameter, we tell Acrobat to submit the form as HTML, while in the cCharset parameter we specify UTF-8 encoding. (We could also specify UTF-16, Shift-JIS, BigFive, GBK, or UHC.) We set bGet to false to force a POST rather than GET. Acrobat's JavaScript API allows you to adjust a variety of other settings, as well, but this is all we really need to do in this example.

    A sample form that contains two text fields (one for an e-mail address and another for a Comment) and a Submit button with this script already attached to it is available via the download link at the end of this blog. Note that the form actually contains four text fields, two of which are hidden. We've created a hidden text field named ":redirect" with a value of "http://localhost:7402/content/acrobat/thankyou.pdf," which tells Sling to serve the specified file (thankyou.pdf, a small file containing just the words "Thank you for your feedback") after the POST finishes. If we don't do this (if we don't include ":redirect"), Acrobat will serve up a PDF representation of the Sling servlet's default response (i.e., a wire dump), which is probably not what you want your user to see.

    There is also a hidden field named ":nameHint," set to a default value of "myform." This tells Sling (or CRX) to create a new node named myform at the path given earlier. If myform already exists, a new node called myform_0 will be created. If that exists, myform_1 will be created. And so forth.

    That's really about all there is to creating new content in CRX with a PDF form POST.

    Next time, we'll look at what it takes to push and pull content to and from the repository asynchronously, which is to say in more of an AJAX-flavored manner, using Acrobat JavaScript. So stay tuned. It gets pretty interesting!

     

    * FormExample.pdf
    Example of a PDF form that will submit content to CRX.

    Posted by Michael Marth JAN 18, 2008

    Posted in jcr, microjax, microsling, rest, ria, ujax and usling Comments 7

    Ever since Gmail entered the Internet we have seen an ever increasing interest in the "client". Before Gmail (in the beginning of this century) the best practice for web applications was HTML pages that were dynamically generated on the server-side. The high level system architecture of such an application would usually consist of a data base, an application server of some kind that generates the HTML and the browser.

    Fast forward to 2008: the world has changed. Let me highlight some differences to 5 years ago.

    • The user experience of web applications is more of a concern and has been improved a lot. Consider Flickr’s drag-and-drop interface or iGoogle. While they were not technically impossible few considered to implement such an UI back then. In general, this means that more code is executed on the client (aka AJAX).
    • Servers routinely pump out pure data (rather than markup) in formats like RSS or JSON. This data can be integrated and displayed on the client (see the whole mash-ups phenomenon). From the point of view of the application developer all he does is write the client.

    These developments have an impact on the high level system architecture: the client actually does something (rather than just render documents). And more: the client consumes data from the server (rather than documents to render).

    So where does the "business logic" reside now? There is a continuum of possibilities: on one extreme it resides exclusively on the server (this is the "old style"). Then there is AJAX applications, where usually some logic resides on the server and some on the client. And by now, there is also the other extreme: all logic resides on the client (Bob Buffone has a nice slide on this continuum, see his presentation, slide 9).

    The clients are alright

    Let us look at the extreme case "all logic on the client". It might seem an unnatural thing to do (especially if you spent the last years coding server-executed JSPs or PHP scripts). But consider the technologies used for building Rich Internet Applications like Flex or Silverlight. If you use such a technology it is quite obvious that the client exchanges nothing but raw data with the server. Who in his right mind would let the server dynamically generate parts of a Flex application? Now, if you think about it, with an AJAX client the situation is not so different.

    So in summary, it has become a perfectly valid possibility for an application design to place all logic onto the client.

    The architectural change

    If a certain amount of business logic resides on the server writing an application invariably means server programming. The server is your application.

    However, in an architecture where the server just persists data and serves it to a client where the application logic resides this is necessarily the case anymore. If there is no application logic on the server then the server is just a piece of standard infrastructure much like a RDBMS is today (most people do not code business logic into their data base. Oh well, yes, some do). It just sits there, but there is no coding to be done on it.

    Meet microjax

    This type of application architecture is what David Nuescheler is aiming at with microjax. Let the client do the UI (because the client-side technologies are so much better at that) and let the server serve the data.

    In microjax you have a (JCR) content repository and a very thin layer on top that reads and writes JSON. This means that the server-side is not split into the classical database/application server combo. Your data is your web server. The mapping between data and JSON output is implicit and does not need any explicit coding. The access rights are in your JCR (on "row level" in db lingo).

    Let me highlight some implications of this:

    • There is no need for server-side scripts.
    • There is no need for db drivers. A REST interface is the "driver".
    • There is less need for server-side CPUs. The clients bring their own.
    • Web application development requires only HTML and Javascript skills (no PHP, JSP, ASP, …) which is around in abundance and the artificial boundary between web designers and server developers that translate their work into server code is gone.

    See here to get started with microjax.

    In the blogosphere

    Who else is on this case? Peter Svensson has been exploring similar ideas (see his blog post The End of Web Frameworks and the follow-up Alternatives to Server-side Web Frameworks.

    Even more, for his project Mashupstation Peter has come up with these interesting rules for application development:

    1. All functionality that possibly can be implemented on the client side shall be implemented on the client side.
    2. All communication with the server middleware shall be constrained to service-interfaces; For instance REST.
    3. No part of the client shall be evoked, generated or templated from the server-side. This rules out in-line conditional HTML in JSP, ASP, PHP, etc.
    4. The logic making up the server middleware will be implementing only the following functionality:
    a. Security
    b. Database access
    c. Cross-domain proxying for remote resources implementing only a) and b).

    These rules could have been taken from the microjax textbook it seems to me.

    Back to the continuum

    As I described above, the "all logic on the client" case is an extreme case of a continuum. But this extreme case might not be the right choice for each and every application. Luckily, microjax is part of microsling. Microsling allows application developers to execute server-side scripts that are implemented e.g. in Javascript. As such, the application developer can freely decide how much logic shall reside on the server and how much shall be on the client. Since both environments are coded in the same programming language moving logic back and forth is rather seamless (to get started with microsling see here).

    IBM "gets it"

    From the high level architecture view microjax and CouchDB are very similar. Both combine persistence (without prior structure) and a web server. Now, IBM has recently bought CouchDB.

    IBM’s employee Patrick Mueller blogged about this purchase:

    It's a web server and a database. And to me, this is the most interesting point. Just as we've seen client programs start to embed web browsing technology (like iTunes), there's really no reason why server programs like a database shouldn't be able to embed a web server.

    Apparently, Big Blue considers the architectural change described above to be relevant.

    As a side-note: while microjax and CouchDB are similar in ideas, but they differ in maturity. JCR implementations like Apache Jackrabbit (upon which microjax is based) have been in production use for years. Plus, there are tools for using them efficiently.

    And another note: the "without prior structure" bracket above is further explored here.

    Posted by Michael Marth JAN 09, 2008

    Posted in dev.day.com, microsling, sling and usling Add comment

    Lately, I have been a bit quiet about Sling (apologies to the readers that wait for part 2 of "How this blog is built"). The reason is that there has been quite some discussions (and changes) regarding

    One architectural bit that has been ironed out is the separation of Sling and microsling. It has been decided that they get merged again.

    Sling developer Betrand Delacretaz has nicely summed up this merge in the corresponding ticket description (on Sling's bug tracker). Unlike most tickets it is definitely worth a read.

    Especially useful is that Bertrand clearly defines the design goals of microsling (2.0):

    µsling 2.0 is a preconfigured instance of Sling, meant to allow web developers to test drive Sling by building scripted web and REST applications backed by a JCR repository.

    The µsling 2.0 distribution only requires a Java 5 VM to run, no installation is needed. Fifteen minutes should be enough to start µsling and understand the basic concepts, based on self-guiding examples. µsling should ideally be delivered as a single runnable jar file.

    Java programming is not required to build web and REST applications with µsling 2.0: both server-side and client-side javascript code and presentation templates can be used to process HTTP requests. Other scripting and templating languages (JSP and BSF-supported ones) can be plugged in easily.

    Posted by David Nuescheler DEC 14, 2007

    Posted in javapolis, microsling, ujax and usling Comment 1

    Posted by Michael Marth DEC 14, 2007

    Posted in crx, davids model, microsling, sling and tutorial Comments 2

    If you followed the previous parts of this little microsling tutorial (here, here and here) you should now have microsling up and running. It’s time to move on and create a real web application with microsling. In this post I will explain how this blog system that you are currently reading has been built.

    Content model

    There is not too much information about structuring JCR content available (I hope to address this issue in the future). But one thing that is available is "David’s Model". I took it as the basis for structuring the blog.

    Let’s see, there are blog posts, a blog entity to hold the posts, comments posted by readers and file attachments to blog posts. Now for the rules:

    Rule #1: Data First, Structure Later. Maybe.

    OK, that’s easy. I will store everything as nt:unstructured. Sounds good, did not want to think about node types anyway.

    Rule #2: Drive the content hierarchy, don't let it happen.

    This is a really good rule IMO. Especially, if one has done some relational DB modeling it is a bit hard to get into. But in our case it is easy and natural enough: blog posts will be children of the blog they belong to. Comments and attachments will be children of the post they belong to.

    Rule #3: Workspaces are for clone(), merge() and update().

    Actually, workspaces would be really useful for a staging area. However, I will not use them here in order to keep things simple.

    Rule #4: Beware of Same Name Siblings.

    This is no problem for the posts (I can just name them any way I like and there should not be too many), but I will come back to this regarding the user generated comments.

    Rule #5: References considered harmful.

    OK, I do not think I need them here.

    Rule #6: Files are Files are Files.

    I will use nt:file for attachments. Attachments are files after all.

    Rule #7: ID's are evil.

    I do not want to be evil. Hence, I do not use IDs (and I have not needed them so far).

    Right, so the model looks something like this:

    blog [nt:unstructured]
    |  +sling:resourceType[string]
    |--post [nt:unstructured]
    |    +title[string]
    |    +body[string]
    |    +sling:resourceType[string]
    |----comment [nt:unstructured]
    |      +body[string]
    |      +sling:resourceType[string]
    |----attachment [nt:file]

    Most of the properties should be self-explanatory (well, a blog post needs a title), but not the "sling:resourceType" properties. Since all nodes are unstructured (apart from the files) this additional property is needed for script resolution (see the post about microsling’s request processing). Microsling determines the resource type through this property (and indirectly the script to execute).

    Display a blog post

    Let’s now display a blog post. First, you need to create a post using CRX’s Content Explorer (see the last part of this tutorial if you are not sure how to do this). Create a blog node named "myblog". It shall contain a post node named "firstpost". Add a title and a body property.

    The property "sling:resourceType" of the post shall have the value "blogPost". For the blog node the value shall be "blog".

    You should get something like this:

    Next, you need to put a script to display this node into the repository. The script must be placed in the directory "/sling/scripts/blogPost" and called "html.esp" (the server-side JavaScript processor will be used). The file shall contain:

    <html>
      <body>
        <h1><%=resource.node.title%></h1>
        <%=resource.node.body%>
      </body>
    </html>

    To see the output of the script point your browser to http://localhost:7402/microsling/myblog/firstpost.html. As you already know, the bit between the <%= %> brackets is executed on the server and the result is inserted into the output. The resource object has a property node which represents the JCR node that was requested. This node has the two properties "title" and "body" which are accessed using JavaScript’s dot notation.

    Display the whole blog

    For displaying the whole blog you need to put a script called "html.esp" into "/sling/scripts/blog". The file shall contain:

    <html>
      <body>
      <%
      for (var prop in resource.node) {
        if (resource.node[prop]["sling:resourceType"] == "blogPost") {
      %>
          <h1><%= resource.node[prop].title%></h1>
          <p><%= resource.node[prop].body%>
          </p>
      <%
        }
      }
      %>
      </body>
    </html>

    The parts between <% %>, (without the equals sign as opposed to above) denote JavaScript that is executed on the server without having the results being written into the output stream (that is just like JSPs again).

    In the line

    for (var prop in resource.node) {

    the script iterates over the children of the blog node and looks for children of (Sling) resource type "blogPost" in this line:

    if (resource.node[prop]["sling:resourceType"] == "blogPost") {

    The square-bracket syntax for accessing a property (in this case ["sling:resourceType"]) is an alternative to the dot notation used above for title and body.

    To see the output of the script point your browser to http://localhost:7402/microsling/myblog.html

    An RSS feed and includes

    Now that you have the list of posts it is really easy to add an additional feature: an RSS feed. For this, create a new script called xml.esp (i.e. it shall respond to requests ending in ".xml") and place it in "/sling/scripts/blog". The logic is almost the same as above, just the markup is different. Simply iterate over the blog posts and produce xml instead of html. So the file should contain:

    <?xml version="1.0"?>
    <rss version="2.0">
    <channel>
    <title>My blog </title>
    <description>My blog</description>
    <link>http://mydomain.com/microsling<%= resource %>.html"</link>
    <%
      for (var prop in resource.node) {
        if (resource.node[prop]["sling:resourceType"] == "blogPost") {
          %><%=sling.include("/microsling"+\\
          resource.node[prop]+".rssitem.xml")%><%
        }
      }
    %>
    </channel>
    </rss>

    (The \\ characters shall denote that the line continues. Delete them from your code.)

    The first new bit in this code is the expression <%= resource %>. This evaluates to the node name including the full path. It is useful e.g. for generating links as above.

    The second new bit is the line

    %><%=sling.include("/microsling"+\\
    resource.node[prop]+".rssitem.xml")%><%

    The include method generates a new request on the server-side. The result of this request is included into the output stream. This includes an alternative "view" of a blog post. "resource.node[prop]" is the node that contains the post. "rssitem" is a selector on this node. With a selector you can render a certain resource type in alternative ways. In this case you need to render a blog post as an rss feed item. Thus, create a script at "sling/scripts/blogPost/rssitem/xml.esp" that contains:

    <item>
    <title><%= resource.node.title %></title>
    <description><%= resource.node.body%></description>
    <link>http://mydomain.com/microsling<%= resource%>.html</link>
    </item>

    Now point your browser at http://localhost:7402/microsling/myblog.xml to see the resulting RSS feed.

    OK, that’s all for today. In the next part, we will look at user-generated comments and attachments.

    (For your convenience all the scripts have been added as an attachment to this post.)