Latest Posts

Archives [+]

Archive for 'September 2010'

    Posted by Federico Paparoni SEP 28, 2010

    Posted in graph and sling Add comment

    This post is cross-posted here.

    Yesterday I was looking an interesting javascript library, JIT (JavaScript InfoVis Toolkit), that is really useful to create some cool representation of your data with graphs, trees, charts and so on.

    This toolkit creates different data representation using JSON as input, so I thought it could be funny to integrate with Apache Sling to have a new representation of my repository.

    Unfortunately JSON translation in Apache Sling is a bit different from the one used in JIT, because it needs children node represented as an array (not in every demo contained in JIT but in the one I want so integrate with Sling).

    So I modified org.apache.sling.commons.json.jcr.JsonItemWriter, to encapsulate the nodes in a JSON array

    Iterator children = resource.listChildren();
    if (children.hasNext()) {
    w.key("children");
    w.array();
    while (children.hasNext()){
    Resource n = children.next();
    log.info("Giro "+n.getName());
    dump(n);
    }
    w.endArray();
    }


    Now I have to load some data on my instance of Apache Sling, so I create a simple JSON.

    {
    "id": "node01",
    "name": "0.2",
    "data":"",
    "jcr:primaryType":"sling:Folder",
    "node11": {
    "id": "node13",
    "name": "1.3",
    "data": "",
    "jcr:primaryType":"sling:Folder",
    "node111":{
    ...
    ...


    Finally I have to load this data into JIT, so I modified an example to load JSON data from an external source
    So I got a very cool representation of my data stored with JCR

    file

    Posted by Kas Thomas SEP 23, 2010

    Posted in crx, crx gems and everything is content Add comment

    From time to time, people ask what the easiest way is to upload a binary file (such as a JPEG image) straight to CRX. Actually, few things could be simpler. The following HTML form will do the trick:

    <html>
    <body>

    <form action="http://localhost:7402/content/test/image"
    enctype="multipart/form-data" method="post">
    <p>
    Type some text (if you wish):<br>
    <input type="text" name="textline" size="30">
    </p>
    <p>
    Please specify a file, or a set of files:<br>
    <input type="file" name="datafile" size="40">
    </p>
    <div>
    <input type="submit" value="Send">
    </div>
    </form>

    </body>
    </html>
     

     

    Note that the form's action attribute is set to the path in CRX where the image is to be saved. The actual name of the node as stored in CRX will (in this case) be "datafile" in accordance with the name attribute of the second <input> element.

    In a browser, this form will look something like this:

    file

     

     

     

     

     

    When you click the Browse button, you'll be allowed to navigate to the image (or other binary) file that you want to upload. Hitting Send causes the upload to occur. If the chosen file was a JPEG image, the resulting node in CRX will have a jcr:mimeType attribute with value "image/jpeg".

    Once the image is uploaded, you can see it in your browser by navigating to

    http://localhost:7402/content/test/image/datafile

    If you need programmatic access to the stored image, that's easy enough too. Assuming that 'p' is the property containing the binary data you'd like to download (p being of type javax.jcr.Property), you can do something like this:

      java.io.InputStream stream = p.getStream();
      try {
       // write the stream to a java.io.FileOutputStream
      } finally {
          stream.close();
      }

    For more tips on uploading content, be sure to see Michael Marth's "File Uploads in Sling."

    Posted by Jean-Christophe Kautzmann SEP 13, 2010

    Posted in java content repository, jcr, jsr-283, sling and tutorial Comment 1

    When you develop an application on top of a JCR repository, you eventually need to access the following basic objects: the repository, a workspace, a session, a node, a property and some managers to perform operations like versioning, querying or controlling the access to the repository.
    I've put together here some code samples to let you do that.

    Getting the repository

    One way to access the repository is to use the JcrUtils.getRepository(Map) utility method of the jackrabbit-jcr-commons library:

    Map parameters = new HashMap();
    parameters.put(..., ...);
    Repository repository = JcrUtils.getRepository(parameters);

    Other ways to access the repository are described here.

    If you are using Sling, you can reference an existing service, called SlingRepository, by using the @scr.reference annotation as follows in your class:

    /** @scr.reference */
    private SlingRepository repository;


    Getting a session and a workspace

    Once you have accessed the repository, you can define a session:

    SimpleCredentials credentials = new SimpleCredentials(userID, password);
    Session session = repository.login(credentials);

    You can also define an administrative session by using the loginAdministrative() method of the SlingRepository interface:

    Session adminSession = repository.loginAdministrative(null);

    When using Sling, to get the user session within a servlet, you can use the following code (e.g. within the doGet() method):

    Session session = req.getResourceResolver().adaptTo(Session.class);
    // req is the SlingHttpServletRequest object passed to the servlet

    Note: all opened sessions should be properly closed when they are no longer needed. The recommended pattern is:

    Session session = repository.login(...);
    try {
      // use the session
    } finally {
      session.logout();
    }

    The only time you don't need this is when you're adapting the SlingHttpServletRequest instance to a Session, as Sling will automatically close that session once the request has been fully processed.

    To get a workspace:

    Workspace workspace = session.getWorkspace();        


    Getting a node, a property and a value

    To get a node:

    Node node = session.getNode(pathToNode);

    To get a property:

    Property property = session.getProperty(pathToProperty);

    To get the value of a single value property:

    if (!property.isMultiple()) {
        Value value = property.getValue();
        String myStringValue = value.getString();
    }

    To get the values of a multiple value property:

    if (property.isMultiple()) {
        Value[] values = property.getValues();
        for (int i = 0; i < values.length; i++) {
            Value value = values[i];
            // assuming the values are strings
            String myStringValue = value.getString();
        }
    }

    Getting managers

    To get managers for the features introduced by the JCR 2.0 specifications like locking, node type management, observation, querying, versioning, access control or retention:

    LockManager lockManager = workspace.getLockManager();
    NodeTypeManager nodeTypeManager = workspace.getNodeTypeManager();
    ObservationManager observationManager = workspace.getObservationManager();
    QueryManager queryManager = workspace.getQueryManager();
    VersionManager versionManager = workspace.getVersionManager();
    AccessControlManager accessControlManager = session.getAccessControlManager();
    RetentionManager retentionManager = session.getRetentionManager();

    For more details please refer to the JCR 2.0 API javadocs or to the JSR-283 specifications that define the JCR API.

    Posted by Kas Thomas SEP 08, 2010

    Posted in cq, crx, crx gems and sling Add comment

    Being able to modularize pages (build them up from individual pieces) using some sort of "include" mechanism is fundamental to web design. That's no less true in the Sling world than in any other environment. As it turns out, there are several techniques you can use for achieving componentized pages in Sling.

    In Java Server Pages, one of the handiest techniques for pulling together disparate page elements is the @include directive:

    <%@ include file="myScript.jsp" %>

    This line of code will tell the JSP compiler to include a complete file (namely, myScript.jsp) into the current file at compilation time, just as if the contents of the included file were pasted directly into the original file.

    In the Day Communiqué runtime environment, it's also possible to achieve this using a syntax of:

    <cq:include script="myScript.jsp" />

    The difference in this case is that the included file gets pulled in at runtime, rather than at servlet compile time.

    In the Sling environment (which of course also means the CRX environment), there's yet another possible technique for achieving inclusion, and that's one in which you do something like this:

    <% sling.include("/content/mypath/mynode") %>

    This line of code relies on the sling convenience object, which has an include() method. What's happening here is that you're essentially telling Sling to render the node "mynode" using whatever script Sling can find for that node based on the node's sling:resourceType. The rendered version of the node's content is what gets inserted into the original file.

    Let's take an example. Suppose we have a node at /content/test/mycontent which has a "content" property containing the string "This is some content." Furthermore, suppose there's a node at /content/test/myhead that has a "content" property containing the string value "This is a headline." Let's assume that both of these nodes have a sling:resourceType of "test," which means Sling will look under /apps/test/ to find any applicable scripts for rendering the nodes.

    Let's say we have a script designed to render content as an H1 head. We'll call it /apps/test/h1.jsp:

    <%@taglib prefix="sling" uri="http://sling.apache.org/taglibs/sling/1.0" %>
    <sling:defineObjects/>
    <h1>
    <%= currentNode.getProperty("content").getString() %>
    </h1>

    Suppose we have CRX running on port 7402. If we were now to aim our browser at http://localhost:7402/content/test/myhead.h1, the following content would be streamed out to the browser:

    <h1>This is a headline</h1>

    But suppose we want to include that line into an HTML file that also includes the (plain text) line "This is some content." We could do it with a JSP page that looks like this:

    <%@taglib prefix="sling" uri="http://sling.apache.org/taglibs/sling/1.0" %>
    <sling:defineObjects/>
    <html>
    <%
           sling.include("/content/test/myhead.h1");
    %>
    <%= currentNode.getProperty("content").getString() %>
    </html>

    All we have to do is give this script a name like html.jsp and put it under /apps/test/, then point the browser to http://localhost:7402/content/test/mycontent.html. The ".html" on the end of mycontent tells Sling to use html.jsp to render the page. The fully rendered page contains markup of:

    <html>
    <h1>This is a headline</h1>
    This is some content.
    </html>

    The sling.include() technique is very powerful. It not only lets you include programmatically rendered content into a file at runtime, but because it's scriptable, you can use sling.include() to conditionally pull content into a page (which is not true of the other inclusion techniques described above). For example, suppose you wanted to pull an iframe containing SVG (Scalable Vector Graphics) into a page, but only for page requests coming from Firefox. You could have code that looks something like:

     <%
        if ( sling.getRequest().getHeader("User-agent").indexOf("Firefox") != -1 )
            sling.include("/content/test/myhead.iframe");
        else
            sling.include("/content/test/myhead.h1");
    %>

    This assumes you've got a script, iframe.jsp, that contains something like:

    <iframe src="/content/test/myhead.svg" width="300" height="50" style="border:none" > </iframe>

    In this way, you can dynamically assemble a page that renders content one way for one type of browser and another way for another type of browser.