Latest Posts

Archives [+]

Entries filed under 'graph'

    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 Michael Marth APR 18, 2008

    Posted in crx quickstart, data first, davids model, everything is content, graph, jcr, open, rest, sling, social and tutorial Comments 4

    In case you follow emerging Internet standards you will have come across OpenSocial, the Google-led spec for social network applications. Major supporters are MySpace, LinkedIn, XING, Google's own Orkut, Hi5 and others. The Apache Software Foundation's implementation of this spec is called Apache Shindig. It is a container (runtime) for OpenSocial applications (which are called gadgets).

    In my opinion OpenSocial and Apache Sling are a good technical fit for at least two reasons:

    1. On a raw technology level both use the same technology building blocks, e.g. JavaScript: in Sling JS is used on the server-side for .esp templates and on the client-side in the case of JST templates. OpenSocial gadgets are coded in JS as well. Moreover, associated technologies like JSON, feeds and REST are supported by both.
    2. On a more conceptional level: As a spec that must work across a number of different social networks the majority of information that is accessible through the OpenSocial API is optional, i.e. it is up to the container if data is returned or not. This situation is a good fit to the unstructured, "Data First" approach that is enabled by Sling (respectively the underlying JCR).

    I would like to show Apache Shindig (Apache's OpenSocial container implementation) and CRX Quickstart (a bundle of Apache Sling and Day's JCR-compliant repository) working together in this blog post.

    Installation

    In this screencast I have shown how to install CRX Quickstart: double-click on its icon (CRX Quickstart is not available, yet, but it will be very soon). Strictly speaking, you do not need CRX Quickstart for the examples below. It all works with "plain" Sling as well.

    Installing Shindig is a tad more complicated and described on Shindig's web site. You need to check out, do a Maven build (I used revision 648157 for this example) and start Shindig's Jetty server on port 8080 with:

    mvn jetty:run-war

    Once you started Shindig hit /gadgets/files/samplecontainer/samplecontainer.html on http://localhost:8080. You should get a kind of gadget console that looks like this (click to enlarge):

     

    Shindig comes with an example implementation of a social network. By default it runs the "Hello World" example gadget located at:/gadgets/files/samplecontainer/examples/SocialHelloWorld.xml on http://localhost:8080.(btw Shindig comes with some example data so don't worry, if you have no friends - Shindig has some imaginary ones for you).

    Friends are Content

    What I would like do is: grab the gadget's viewer's friends and all the available data about them and store this data in the repository. For this purpose I have written a little gadget (see below) and saved it in my JCR repository at /apps/friends/friendsaver.html. By default the repository is running on port 7402, so when I point the gadget console to http://localhost:7402/apps/friends/friendsaver.html I get (click to enlarge):

     

    The gadget retrieves the viewer's friends and displays them in HTML. Moreover, in the background the viewer's data and the available friend data is posted to my repository. In the Content Explorer this looks like (click to enlarge):

     

    Hey, remember the "Everything is Content" mantra? Well, your imaginary friends are content, too.

    Please note that this works without setting up any schema or any other configuration of the repository. I ran it on an out-of-the-box CRX Quickstart (see also this screencast and this post about Data First). Only for the fields that are actually sent node properties are created.

    The Gadget Code

    The gadget is completely standard OpenSocial code, no surprises here. In onLoadFriends() the viewer's friends (variable viewerFriends) are iterated and displayed in HTML. For each opensocial.Person object the function createFriendNode() is called. In this function an HTTP POST request is sent to the repository that persists the person. Available opensocial.Person.Field data is sent as POST parameters (in the code only gender and first phone number are implemented) and thus persisted as node properties. I want to leverage the repository's hierarchy and store the friends as child nodes below the viewer (see David's model, rule 2). Here's the relevant snippet:

     /**  * Request for friend information.  */function getData() {      var req = opensocial.newDataRequest();  req.add(req.newFetchPersonRequest(opensocial.    DataRequest.PersonId.VIEWER), 'viewer');  req.add(req.newFetchPeopleRequest(opensocial.    DataRequest.Group.VIEWER_FRIENDS),    'viewerFriends');  req.send(onLoadFriends);}; /**  * Parses the response to the friend request  * @param {Object} dataResponse Friend      information that was requested.  */function onLoadFriends(dataResponse) {  var viewer = dataResponse.get('viewer').    getData();  var html = 'Friends of ' + viewer.    getDisplayName();   html += ':<br><ul>';  createFriendNode(viewer);  var viewerFriends = dataResponse.    get('viewerFriends').getData();  viewerFriends.each(function(person) {    html += '<li>'      + person.getDisplayName()      + '</li>';    createFriendNode(person, viewer);  });  html += '</ul>';  document.getElementById('message').    innerHTML = html;};  function createFriendNode(person, parent) {     var url = "http://localhost:7402/content/friends/";  if(parent) {    url += sanitizeId(parent.getId())+"/*";     } else {     url += "*";    }        var params = {};    params[gadgets.io.    RequestParameters.CONTENT_TYPE] =    gadgets.io.ContentType.TEXT;    params[gadgets.io.    RequestParameters.METHOD] =    gadgets.io.MethodType.POST;    var postParams = "";  postParams += 'name=' +    sanitizeId(person.getId()) + '&fullname=' +    person.getDisplayName();  if(person.getField(opensocial.Person.Field.    PHONE_NUMBERS)) postParams +=    ('&phone=' +    person.getField(opensocial.Person.Field.    PHONE_NUMBERS)[0].    getField(opensocial.Phone.Field.NUMBER))  if(person.getField(opensocial.Person.Field.    GENDER)) postParams += ('&gender=' +    person.getField(opensocial.Person.Field.    GENDER).getKey())  // I could add more fields here...        params[gadgets.io.RequestParameters.    POST_DATA] = postParams  gadgets.io.makeRequest(url, null, params);};    function sanitizeId(id) {  return id.replace(".", "_");   }gadgets.util.registerOnLoadHandler(getData);  

    Round-Tripping

    Now that the friends are stored in the repository each one has a URL. Displaying a friend in a simple HTML page can be done with e.g. server-side Javascript. Storing this file in the repository in /apps/friends/html.esp

    <html>  <body>    <h1><%= currentNode["fullname"] %></h1><ul><li>gender: <%= currentNode["gender"] %></li><li>phone: <%= currentNode["phone"] %></li></ul>  </body></html>

    will yield for the URL http://localhost:7402/content/friends/john_doe/jane_doe.html

    But this is only half the fun. It is much more interesting to retrieve the friends data in another OpenSocial gadget. This can easily be done without any repository-side code as Sling natively supports the json format. For example the URL http://localhost:7402/content/friends/john_doe/jane_doe.json will return this node in json format. Like that, we can easily access the friends nodes through a gadget containing this snippet:

    function makeCRXRequest() {    var params = {};    params[gadgets.io.RequestParameters.    CONTENT_TYPE] =    gadgets.io.ContentType.JSON;    var url =    "http://localhost:7402/content/friends/john_doe/"+    document.getElementById("person_name").value+    ".json";    gadgets.io.makeRequest(url, response, params);};function response(person) {    var html = "";  html += "name: " + person.data.fullname +    "<br/>";  html += "phone: " + person.data.phone +     "<br/>";  html += "gender: " + person.data.gender +    "<br/>";    document.getElementById('content_div').     innerHTML = html;};

    The gadget in action looks like this (click to enlarge)

     

    This little hack could be the starting point for a cross-social network phone book application.

    Final remarks

    I hope I could show that Sling and Shindig go really well together. Especially, being able to utilize the JCR repository as a backend without any coding on the repository side looks tempting to me. Maybe at one point Sling will even be able to run OpenSocial gadgets natively.

    In this post I concentrated on frontend intergration technologies. But OpenSocial will soon add a REST API next to its JS API. For Shindig the implementation of this REST API is likely to be Apache Abdera which uses JCR as an optional persistence storage. So there will be additional points of contact.

    Posted by Lars Trieloff JAN 09, 2008

    Posted in graph, news, open and social Comment 1

    The in the last two days we have seen two exciting news: Google and Facebook joining Dataportability.org and Google, IBM and Verisign agree to support OpenID. Together with Apache's Shindig, an open source implementation of Google's OpenSocial engine (see this Youtube Video for an interview with Brian McCallister who explains what Shindig and OpenSocial are) we are witnessing what will evolve to true social network portability.

    • With OpenID you are able to transfer your identity from one network to another. No need to enter the same information about yourself over and over again. You are even free to create multiple identities if you would like to separate some aspects of your digital life.
    • With DataPortability.org you are able to transfer the social graph from one network to another. This means you do not have to find your friends on each new network again and again.
    • And with OpenSocial have application portability. If there is a nice widget in one network that you would like to embed into another network - no problem with OpenSocial.

    As a consequence, the costs of joining yet another social network will shrink dramatically. As you have portability of identity, social graph and applications, you can start cherry-picking by joining many specialized networks, selecting the parts of the application that are most useful and aggregate them in your main OpenSocial container. But this also changes the rules of the game for social network vendors. You do not have to build up your user community from scratch, you do not have to convince your users to jump the high sign-up-and give-away-your-private-information barrier anymore, no you can create a highly specialized niche social network that serves only a small fraction of the population or that has only few, highly specific use-cases. This will lead to the generation of thousands of nice social networks, some standalone, some embedded into larger websites, but all will be able to interchange users, social graph and widgets with each other.

    As for the big players Google and Facebook: They will have to compete for the best platform for running these widgets. Facebook can benefit from the large number of existing Facebook applications and the really neat integration into the site from a usability point of view, but Google's hold on the desktop with Google Toolbar and the ability to display desktop widgets in the web and vice versa could lead to a completely new way to see the web.

    Posted by Lars Trieloff NOV 28, 2007

    Posted in cms, everything is content and graph Add comment

    Tim Berners Lee recently coined the term "The Graph". The idea here is that computer networks undergo a conceptual evolution. The starting point, the Net (internet) connects computers, abstracting from the cables between computers allowing the creation of networked applications. The most successful networked application became known as the Web (world wide web) and provided another abstraction. It is not the computers we care about, it is the documents (resources) and links between them (hyperlinks). This web is what most content management systems and content repositories care about - they manage documents after all.

    The Graph is nothing else than the realization that we actually do not care about documents (or even the computers where these documents are stored), but about the things that are described by the documents. A document can describe a person, an idea, a place. And in the same way as people are connected to each other, as ideas are connected to people and people to places, documents can be used to describe these connections by the means of hyperlinks or more advanced technologies like RDF.

    To refrain this thought - the graph is not about the documents and their connections, but about the things described in the documents and their relations, about the document's contents. The graph is about content and content relations.

    If you are a user of content management system or a content repository, if you are developing applications that deal with content, if you are a vendor of a content repository or content management systems there are some relevant implications for you:
    Your content repository should be about content, not about data or documents. It should allow you to deal with content in all representations, from highly structured to unstructured. It should allow you to unify access over all content stores. It should allow you to expose your content to the outside, allowing you to build a stronger graph.

    If you are looking for this kind of content repository, you should have a look at CRX and its open source companion Apache Jackrabbit.