You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@clerezza.apache.org by re...@apache.org on 2014/06/04 23:54:25 UTC

[1/7] git commit: CLEREZZA-829: added platform.editor to reaactor

Repository: clerezza
Updated Branches:
  refs/heads/master 485189151 -> 0531034bf


CLEREZZA-829: added platform.editor to reaactor


Project: http://git-wip-us.apache.org/repos/asf/clerezza/repo
Commit: http://git-wip-us.apache.org/repos/asf/clerezza/commit/61e303ea
Tree: http://git-wip-us.apache.org/repos/asf/clerezza/tree/61e303ea
Diff: http://git-wip-us.apache.org/repos/asf/clerezza/diff/61e303ea

Branch: refs/heads/master
Commit: 61e303eac7df0b8a663187bed285908df8ca7e94
Parents: fc22bc1
Author: Reto Bachmann-Gmür <re...@apache.org>
Authored: Mon Jun 2 16:46:15 2014 +0200
Committer: Reto Bachmann-Gmür <re...@apache.org>
Committed: Mon Jun 2 16:46:15 2014 +0200

----------------------------------------------------------------------
 pom.xml | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/clerezza/blob/61e303ea/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index d232c2c..ceb0433 100644
--- a/pom.xml
+++ b/pom.xml
@@ -87,6 +87,7 @@
                 <module>platform.documentation</module>
                 <module>platform.documentation.viewer</module>
                 <module>platform.enrichment</module>
+                <module>platform.editor</module>
                 <module>platform.globalmenu.api</module>
                 <module>platform.graphnodeprovider</module>
                 <module>platform.graphprovider.content</module>


[5/7] git commit: CLEREZZA-815: added platform.tools

Posted by re...@apache.org.
CLEREZZA-815: added platform.tools


Project: http://git-wip-us.apache.org/repos/asf/clerezza/repo
Commit: http://git-wip-us.apache.org/repos/asf/clerezza/commit/61328c27
Tree: http://git-wip-us.apache.org/repos/asf/clerezza/tree/61328c27
Diff: http://git-wip-us.apache.org/repos/asf/clerezza/diff/61328c27

Branch: refs/heads/master
Commit: 61328c27f445b9fcb4d6f77a84e37e7fbd858b36
Parents: 8d34e62
Author: Reto Bachmann-Gmür <re...@apache.org>
Authored: Wed Jun 4 23:53:26 2014 +0200
Committer: Reto Bachmann-Gmür <re...@apache.org>
Committed: Wed Jun 4 23:53:26 2014 +0200

----------------------------------------------------------------------
 provisioning/platform.tools/pom.xml             | 85 ++++++++++++++++++++
 .../platform.tools/src/main/feature/feature.xml | 26 ++++++
 2 files changed, 111 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/clerezza/blob/61328c27/provisioning/platform.tools/pom.xml
----------------------------------------------------------------------
diff --git a/provisioning/platform.tools/pom.xml b/provisioning/platform.tools/pom.xml
new file mode 100644
index 0000000..d6ce139
--- /dev/null
+++ b/provisioning/platform.tools/pom.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" 
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <artifactId>clerezza</artifactId>
+        <groupId>org.apache.clerezza</groupId>
+        <version>0.5-SNAPSHOT</version>
+        <relativePath>../../parent</relativePath>
+    </parent>
+    
+    <groupId>org.apache.clerezza.provisioning</groupId>
+    <artifactId>platform.content</artifactId>
+    <version>0.1-SNAPSHOT</version>
+    <packaging>feature</packaging>
+
+    <name>Clerezza - Provisioning - Platform Content</name>
+    <description>A Karaf feature and partialbundlelist with the bundles providing 
+        the clerezza content functionality.
+    
+        This feature depends on java and OSGi platform libraries (javax.xml,
+        org.osgi.service.cm and others), slf4j logging
+        - rdf
+        - rdf.web
+        - platform.graphnodprovider
+        - typerendering
+        - typehandlerspace   
+    </description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.clerezza</groupId>
+            <artifactId>platform.content</artifactId>
+            <version>0.14-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.clerezza</groupId>
+            <artifactId>platform.content.default404</artifactId>
+            <version>0.2-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.clerezza</groupId>
+            <artifactId>platform.content.fsadaptor</artifactId>
+            <version>0.2-SNAPSHOT</version>
+        </dependency>
+        <!-- this doesn't strictly belongs to here -->
+        <dependency>
+            <groupId>org.apache.stanbol</groupId>
+            <artifactId>org.apache.stanbol.commons.web.resources</artifactId>
+            <version>0.12.0</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.wymiwyg.karaf.tooling</groupId>
+                <artifactId>karaf-sling-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+    
+</project>

http://git-wip-us.apache.org/repos/asf/clerezza/blob/61328c27/provisioning/platform.tools/src/main/feature/feature.xml
----------------------------------------------------------------------
diff --git a/provisioning/platform.tools/src/main/feature/feature.xml b/provisioning/platform.tools/src/main/feature/feature.xml
new file mode 100644
index 0000000..9b0f399
--- /dev/null
+++ b/provisioning/platform.tools/src/main/feature/feature.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<features name="${project.artifactId}-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.0.0">
+
+    <feature name='${project.artifactId}' description='${project.name}' version='${project.version}'>
+        <details>${project.description}</details>
+        <!-- <config>foo=bar</config> -->
+    </feature>
+
+</features>
\ No newline at end of file


[2/7] CLEREZZA-829: USing rdfstore-js to store the parsed RDFa data, working around changes in literal roundtripping using the content property (even though according to the spec this is ignored for XMLLiterals)

Posted by re...@apache.org.
http://git-wip-us.apache.org/repos/asf/clerezza/blob/8d34e62b/platform.editor/src/main/scala/org/apache/clerezza/platform/editor/renderlets/DiscobitsContentEtch.scala
----------------------------------------------------------------------
diff --git a/platform.editor/src/main/scala/org/apache/clerezza/platform/editor/renderlets/DiscobitsContentEtch.scala b/platform.editor/src/main/scala/org/apache/clerezza/platform/editor/renderlets/DiscobitsContentEtch.scala
index 302834d..36c5d15 100644
--- a/platform.editor/src/main/scala/org/apache/clerezza/platform/editor/renderlets/DiscobitsContentEtch.scala
+++ b/platform.editor/src/main/scala/org/apache/clerezza/platform/editor/renderlets/DiscobitsContentEtch.scala
@@ -23,103 +23,139 @@ abstract class DiscobitsContentEtch extends SRenderlet {
     new XmlResult(arguments) {
       override def content = {
         val initScript = """
-                       var discoBitsCollection = new Backbone.Collection();
+            var discoBitsCollection = new Backbone.Collection();
             $(function() {
-              
-                var gp = new GraphRDFaProcessor();
-                gp.target.graph = new RDFaGraph();
-                gp.process(document);
-                var origTurtle = gp.target.graph.toString();
-                //alert(origTurtle);
-                function saveAllModified() {
-                    /*var modifiedModels = discoBitsCollection.filter(function(model) {return model.hasChanged()})
-                    var modified = new Backbone.Collection(modifiedModels);
-                    alert("could save: " +modifiedModels+" models "+ JSON.stringify(modified.toJSON()))
-                    var gp = new GraphRDFaProcessor();*/
-                    gp.target.graph = new RDFaGraph();
-                    gp.process(document);
-                    var newTurtle = gp.target.graph.toString()
-                    $.post( "/tools/editor/post", { assert: newTurtle, revoke: origTurtle, rdfFormat: 'text/turtle' }, function( data ) {
-                      alert("saved");
-                      origTurtle = newTurtle;
-                    }) .fail(function( data) {
-                      errdata = data
-                      alert( "error: " + data.statusText);
-                    });
-                }
                 
-                var InfoBit = Backbone.Model.extend({
-                    defaults: {
-                        "@type": 'disco:XHTMLInfoDiscoBit',
-                        "disco:infoBit": 'Some content'
-                    },
-                    initialize: function() {
-                        console.log('This model has been initialized.');
-                        var m = this;
-                        this.on('change', function(msg) {
-                            console.log('A value for this model has changed: ');
-                            console.log(m.changed);
-                            console.log(m.get("@id"));
-                            console.log('A value for this model has changed: '+m.hasChanged(null));
-                            m.foo = "bar"
+                GreenRdfStore.getGraph(document, function(origGraph) {
+                    //now that we have the orig graph we no longer need the content atr
+                    $("span[property='disco:infoBit']").removeAttr("content");
+                    var InfoBit = Backbone.Model.extend({
+                        defaults: {
+                            "@type": 'disco:XHTMLInfoDiscoBit',
+                            "disco:infoBit": 'Some content'
+                        },
+                        initialize: function() {
+                            console.log('This model has been initialized.');
+                            var m = this;
+                            this.on('change', function(msg) {
+                                console.log('A value for this model has changed: ');
+                                console.log(m.changed);
+                                console.log(m.get("@id"));
+                                console.log('A value for this model has changed: '+m.hasChanged(null));
+                                m.foo = "bar"
+                            });
+                        }
+                    });
+                    function saveAllModified() {
+                        GreenRdfStore.getGraph(document, function(newGraph) {
+                            //alert("orig: "+origGraph.toNT());
+                            //alert("new: "+ newGraph.toNT());
+                            $.post( "/tools/editor/post", { assert: newGraph.toNT(), revoke: origGraph.toNT(), rdfFormat: 'text/turtle' }, function( data ) {
+                                alert("saved");
+                                origTurtle = newTurtle;
+                              }) .fail(function( data) {
+                                errdata = data
+                                alert( "error: " + data.statusText);
+                              });
                         });
-                    }
-                });
 
-                var InfoBitView = Backbone.View.extend({
-                    initialize: function() {
-                        _.bindAll(this, 'save')
-                        this.model.bind('save', this.save);
-                        var infoBit = $(this.el).find('[property="disco:infoBit"]').html()
-                        console.log(this.model.hasChanged(null))
-                        //this.model.set("disco:infoBit", infoBit)
-                        console.log(this.model.hasChanged(null))
-                        this.stickit();
-                    },
-                    events: {
-                        'mousedown .editable': 'editableClick'
-                    },
-                    bindings: {
-                        '[property="disco:infoBit"]': 'disco:infoBit'
-                    },
-                    editableClick: etch.editableInit,
-                    save: function() {
-
-                        // normally you would call model.save() here but this is a demo
-                        // $(this.el).find('.editable').effect('highlight', {color: 'yellow'});
-                        // $('.save-event').fadeIn('fast', function() {
-                        //     setTimeout($(this).fadeOut('slow'), 10000);
-                        // });
-                        console.log("this modified: ");
-                        console.log(this.model.get("@id"));
-                        console.log(this.model.changed);
-                        console.log("this is modified: "+this.model.hasChanged(null));
-                        saveAllModified();
                     }
+                    var InfoBitView = Backbone.View.extend({
+                        initialize: function() {
+                            _.bindAll(this, 'save')
+                            this.model.bind('save', this.save);
+                            var infoBit = $(this.el).find('[property="disco:infoBit"]').html()
+                            console.log(this.model.hasChanged(null))
+                            //this.model.set("disco:infoBit", infoBit)
+                            console.log(this.model.hasChanged(null))
+                            this.stickit();
+                        },
+                        events: {
+                            'mousedown .editable': 'editableClick'
+                        },
+                        bindings: {
+                            '[property="disco:infoBit"]': 'disco:infoBit'
+                        },
+                        editableClick: etch.editableInit,
+                        save: function() {
 
-                });
+                            // normally you would call model.save() here but this is a demo
+                            // $(this.el).find('.editable').effect('highlight', {color: 'yellow'});
+                            // $('.save-event').fadeIn('fast', function() {
+                            //     setTimeout($(this).fadeOut('slow'), 10000);
+                            // });
+                            console.log("this modified: ");
+                            console.log(this.model.get("@id"));
+                            console.log(this.model.changed);
+                            console.log("this is modified: "+this.model.hasChanged(null));
+                            saveAllModified();
+                        }
 
-                //$article = $('[property="disco:infoBit"]');
-                $('[property="disco:infoBit"]').addClass("editable")
-                $('[property="disco:infoBit"]').attr("data-button-class", "all")
-                //this ensure two way binding with stickit
-                $('[property="disco:infoBit"]').attr("contenteditable", "true")
-                $article = $('[typeof="disco:XHTMLInfoDiscoBit"]');
-                _.forEach($article, function(art) {
-                    console.log(art);
-                    var infoBit = $(art).find('[property="disco:infoBit"]').html()
-                    var about = $(art).attr('about')
-                    var model = new InfoBit({
-                        "@id": about,
-                        "disco:infoBit": infoBit
                     });
-                    new InfoBitView({model: model, el: art, tagName: art.tagName});
-                    discoBitsCollection.add(model)
+                    //$article = $('[property="disco:infoBit"]');
+                    $('[property="disco:infoBit"]').addClass("editable")
+                    $('[property="disco:infoBit"]').attr("data-button-class", "all")
+                    //this ensure two way binding with stickit
+                    $('[property="disco:infoBit"]').attr("contenteditable", "true")
+                    $article = $('[typeof="disco:XHTMLInfoDiscoBit"]');
+                    _.forEach($article, function(art) {
+                        console.log(art);
+                        var infoBit = $(art).find('[property="disco:infoBit"]').html()
+                        var about = $(art).attr('about')
+                        var model = new InfoBit({
+                            "@id": about,
+                            "disco:infoBit": infoBit
+                        });
+                        new InfoBitView({model: model, el: art, tagName: art.tagName});
+                        discoBitsCollection.add(model)
+                    });
+                    
+                    
+                    
                 });
+                /*var store = rdfstore.create();
+                
+                    CallbackProcessor.prototype = new RDFaProcessor();
+                    CallbackProcessor.prototype.constructor=RDFaProcessor;
+                    function CallbackProcessor() {
+                       RDFaProcessor.call(this);
+                    }
+
+                    CallbackProcessor.prototype.addTriple = function(origin,subject,predicate,object) {
+                       alert("New triple: "+subject+", predicate "+predicate+", object "+object.value+", "+object.language+", "+object.type);
+                       //RDFaProcessor.prototype.addTriple.call(this, origin, subject, predicate, object);
+                       //graph.add(env.createTriple())
+                    }*/
+                    //var gp = new GraphRDFaProcessor();
+                    /*function WrappedGraphProcessor() {
+                        GraphRDFaProcessor.call(this)
+                    }
+                    WrappedGraphProcessor.prototype = new GraphRDFaProcessor();
+                    WrappedGraphProcessor.prototype.addTriple= function(origin,subject,predicate,object) {
+                            alert("uff "+origin+","+subject+","+predicate+","+object);
+                            if (origin.getAttribute("content")) {
+                                object.value = origin.getAttribute("content");
+                            }
+                            GraphRDFaProcessor.prototype.addTriple.call(this, origin, subject, predicate, object);
+                        }
+                    var gp = new WrappedGraphProcessor();
+                    //var gp = new CallbackProcessor();
+                    gp.target.graph = new RDFaGraph();
+                    gp.process(document);
+                    var origTurtle = gp.target.graph.toString();
+                    alert(origTurtle);*/
+                    
+                            
+                //});
+                
+
+                
+
+                
                 //var view = new articleView({model: model, el: $article[0], tagName: $article[0].tagName});
 
             });
-
+        
             Backbone.on('all', function(s) {
                 console.log('Handling all: ' + s);
             });
@@ -161,7 +197,7 @@ abstract class DiscobitsContentEtch extends SRenderlet {
               false
             );*/
             """
-        val html = <html xmlns:disco="http://discobits.org/ontology#"> 
+        val html = <html xmlns:disco="http://discobits.org/ontology#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> 
           
             <head>
                 <link type="text/css" href="/style/style.css" rel="stylesheet" />
@@ -178,6 +214,8 @@ abstract class DiscobitsContentEtch extends SRenderlet {
             <script src="/tools/editor/scripts/backbone-min.js"></script>
             <script src="/tools/editor/scripts/etch.js"></script>
             <script src="/tools/editor/scripts/backbone.stickit.js"></script>
+            <script src="/tools/editor/scripts/rdfstore.js" type="text/javascript"></script>
+            <script src="/tools/editor/scripts/greenrdfstore.js"></script>
             <script>
               {Unparsed(initScript)}
             </script>

http://git-wip-us.apache.org/repos/asf/clerezza/blob/8d34e62b/platform.editor/src/main/scala/org/apache/clerezza/platform/editor/renderlets/HtmlInfoDicobitRDFaNaked.scala
----------------------------------------------------------------------
diff --git a/platform.editor/src/main/scala/org/apache/clerezza/platform/editor/renderlets/HtmlInfoDicobitRDFaNaked.scala b/platform.editor/src/main/scala/org/apache/clerezza/platform/editor/renderlets/HtmlInfoDicobitRDFaNaked.scala
index 8a297d8..5e64b41 100644
--- a/platform.editor/src/main/scala/org/apache/clerezza/platform/editor/renderlets/HtmlInfoDicobitRDFaNaked.scala
+++ b/platform.editor/src/main/scala/org/apache/clerezza/platform/editor/renderlets/HtmlInfoDicobitRDFaNaked.scala
@@ -25,7 +25,7 @@ class HtmlInfoDicobitRDFaNaked extends SRenderlet {
     new XmlResult(arguments) {
       override def content = {
               <div typeof="disco:XHTMLInfoDiscoBit" about={res*}>
-                <span property="disco:infoBit"  datatype="rdf:XMLLiteral">{Unparsed(res/DISCOBITS.infoBit*)}</span>
+                <span property="disco:infoBit" content={(res/DISCOBITS.infoBit*).replace("\n","\\n")} datatype="rdf:XMLLiteral">{Unparsed(res/DISCOBITS.infoBit*)}</span>
               </div>
       }
     }


[4/7] git commit: CLEREZZA-829: USing rdfstore-js to store the parsed RDFa data, working around changes in literal roundtripping using the content property (even though according to the spec this is ignored for XMLLiterals)

Posted by re...@apache.org.
CLEREZZA-829: USing rdfstore-js to store the parsed RDFa data, working around changes in literal roundtripping using the content property (even though according to the spec  this is ignored for XMLLiterals)

Project: http://git-wip-us.apache.org/repos/asf/clerezza/repo
Commit: http://git-wip-us.apache.org/repos/asf/clerezza/commit/8d34e62b
Tree: http://git-wip-us.apache.org/repos/asf/clerezza/tree/8d34e62b
Diff: http://git-wip-us.apache.org/repos/asf/clerezza/diff/8d34e62b

Branch: refs/heads/master
Commit: 8d34e62bd43ab2b3222a015dfce400bfcc8f7f85
Parents: 61e303e
Author: reto <re...@apache.org>
Authored: Wed Jun 4 23:50:40 2014 +0200
Committer: reto <re...@apache.org>
Committed: Wed Jun 4 23:50:40 2014 +0200

----------------------------------------------------------------------
 .../tools/editor/scripts/greenrdfstore.js       |    78 +
 .../resources/tools/editor/scripts/rdfstore.js  | 31836 +++++++++++++++++
 .../renderlets/DiscobitsContentEtch.scala       |   210 +-
 .../renderlets/HtmlInfoDicobitRDFaNaked.scala   |     2 +-
 4 files changed, 32039 insertions(+), 87 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/clerezza/blob/8d34e62b/platform.editor/src/main/resources/META-INF/resources/tools/editor/scripts/greenrdfstore.js
----------------------------------------------------------------------
diff --git a/platform.editor/src/main/resources/META-INF/resources/tools/editor/scripts/greenrdfstore.js b/platform.editor/src/main/resources/META-INF/resources/tools/editor/scripts/greenrdfstore.js
new file mode 100644
index 0000000..eef998f
--- /dev/null
+++ b/platform.editor/src/main/resources/META-INF/resources/tools/editor/scripts/greenrdfstore.js
@@ -0,0 +1,78 @@
+/*
+ * functions to read RDFa to an rdfstore-js graph
+ */
+
+function GreenRdfStore() {
+}
+
+GreenRdfStore.getGraph = function(element, callback) {
+    var store = rdfstore.create();
+    store.graph(function(success,graph) {
+        var env = store.rdf;
+        CallbackProcessor.prototype = new RDFaProcessor();
+        CallbackProcessor.prototype.constructor=RDFaProcessor;
+        function CallbackProcessor() {
+           RDFaProcessor.call(this);
+        }
+        var bNodeTable = {};
+        CallbackProcessor.prototype.addTriple = function(origin,subject,predicate,object) {
+            function convertNonLiteral(node) { 
+                if (node.startsWith("_:")) {
+                    if (!bNodeTable[node]) {
+                        bNodeTable[node] = env.createBlankNode(node);
+                    }
+                    return bNodeTable[node];
+                } else {
+                    return env.createNamedNode(node);s
+                }
+            }
+            function serializeNodeList(nodeList) {
+                //code taken from Greenturtle's GraphRDFaProcessor
+                var serializer = new XMLSerializer();
+                var value = "";
+                for (var x=0; x<nodeList.length; x++) {
+                   if (nodeList[x].nodeType==Node.ELEMENT_NODE) {
+                      var prefixMap = RDFaPredicate.getPrefixMap(nodeList[x]);
+                      var prefixes = [];
+                      for (var prefix in prefixMap) {
+                         prefixes.push(prefix);
+                      }
+                      prefixes.sort();
+                      var e = nodeList[x].cloneNode(true);
+                      for (var p=0; p<prefixes.length; p++) {
+                         e.setAttributeNS("http://www.w3.org/2000/xmlns/",prefixes[p].length==0 ? "xmlns" : "xmlns:"+prefixes[p],prefixMap[prefixes[p]]);
+                      }
+                      value += serializer.serializeToString(e);
+                   } else if (nodeList[x].nodeType==Node.TEXT_NODE) {
+                      value += nodeList[x].nodeValue;
+                   }
+                }
+                return value;
+            }
+            //alert("New triple: "+subject+", predicate "+predicate+", object "+object.value+", "+object.language+", "+object.type);
+            var subjectRS = convertNonLiteral(subject);
+            
+            var predicateRS = env.createNamedNode(predicate);
+            if (object.type === "http://www.w3.org/1999/02/22-rdf-syntax-ns#object") {
+                var objectRS = convertNonLiteral(object.value);
+            } else {
+                if (origin.getAttribute("content")) {
+                    //according to the spec this attribute should be ignored for xmlLiterals, we don't
+                    var value = origin.getAttribute("content");
+                } else {
+                    if (object.value.length) {
+                        var value = serializeNodeList(object.value);
+                    } else {
+                        var value = object.value;
+                    }
+                }
+                var objectRS = env.createLiteral(value.toString(), object.language, object.type);
+            }
+            graph.add(env.createTriple(subjectRS, predicateRS, objectRS));
+        };
+        var gp = new CallbackProcessor();
+                    //gp.target.graph = new RDFaGraph();
+        gp.process(element);
+        callback(graph)
+    });
+};
\ No newline at end of file


[3/7] CLEREZZA-829: USing rdfstore-js to store the parsed RDFa data, working around changes in literal roundtripping using the content property (even though according to the spec this is ignored for XMLLiterals)

Posted by re...@apache.org.
http://git-wip-us.apache.org/repos/asf/clerezza/blob/8d34e62b/platform.editor/src/main/resources/META-INF/resources/tools/editor/scripts/rdfstore.js
----------------------------------------------------------------------
diff --git a/platform.editor/src/main/resources/META-INF/resources/tools/editor/scripts/rdfstore.js b/platform.editor/src/main/resources/META-INF/resources/tools/editor/scripts/rdfstore.js
new file mode 100644
index 0000000..41ecf4d
--- /dev/null
+++ b/platform.editor/src/main/resources/META-INF/resources/tools/editor/scripts/rdfstore.js
@@ -0,0 +1,31836 @@
+(function() {
+
+
+  if(typeof(console)=='undefined') {
+     console = {};
+     console.log = function(e){};
+  }
+  
+  window.process = {};
+  process.nextTick = function(f) {
+    setTimeout(f,0);
+  };
+var Utils = {};
+
+
+
+Utils['extends'] = function(supertype, descendant) {
+    descendant.prototype = new supertype();
+};
+
+
+Utils.stackCounterLimit = 1000;
+Utils.stackCounter = 0;
+
+Utils.recur = function(c){
+    if(Utils.stackCounter === Utils.stackCounterLimit) {
+        Utils.stackCounter = 0;
+        setTimeout(c, 0);
+    } else {
+        Utils.stackCounter++;
+        c();
+    } 
+};
+
+Utils.clone = function(o) {
+    return JSON.parse(JSON.stringify(o));
+};
+
+Utils.shuffle = function(o){ //v1.0
+    for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x){};
+    return o;
+};
+
+Utils.include = function(a,v) {
+    var cmp = arguments[2];
+
+    for(var i=(a.length-1); i>=0; i--) {
+        var res = false;
+        if(cmp == null) {
+            res = (a[i] === v);
+        } else {
+            res = (cmp(a[i],v) === 0);
+        }
+
+        if(res === true) {
+            return true;
+        }
+    }
+
+    return false;
+};
+
+Utils.remove = function(a,v) {
+    var acum = [];
+    for(var i=0; i<a.length; i++) {
+        if(a[i] !== v) {
+            acum.push(a[i]);
+        }
+    }
+
+    return acum;
+};
+
+Utils.repeat = function(c,max,floop,fend,env) {
+    if(arguments.length===4) { env = {}; }
+    if(c<max) {
+        env._i = c;
+        floop(function(floop,env){
+            // avoid stack overflow
+            // deadly hack
+            Utils.recur(function(){ Utils.repeat(c+1, max, floop, fend, env); });
+        },env);
+    } else {
+        fend(env);
+    }
+};
+
+
+Utils.meanwhile = function(c,floop,fend,env) {
+    if(arguments.length===3) { env = {}; }
+
+    if(env['_stack_counter'] == null) {
+        env['_stack_counter'] = 0;
+    }
+
+    if(c===true) {
+        floop(function(c,floop,env){
+            if(env['_stack_counter'] % 40 == 39) {
+                env['_stack_counter'] = env['_stack_counter'] + 1;
+                setTimeout(function(){ Utils.neanwhile(c, floop, fend, env); }, 0);
+            } else {
+                env['_stack_counter'] = env['_stack_counter'] + 1;
+                Utils.meanwhile(c, floop, fend, env);
+            }
+        },env);
+    } else {
+        fend(env);
+    }
+};
+
+Utils.seq = function() {
+    var fs = arguments;
+    return function(callback) {
+        Utils.repeat(0, fs.length, function(k,env){
+            var floop = arguments.callee;
+            fs[env._i](function(){
+                k(floop, env);
+            });
+        }, function(){
+            callback();
+        });
+    };
+};
+
+
+Utils.partition = function(c, n) {
+    var rem = c.length % n;
+    var currentGroup = [];
+    for(var i=0; i<rem; i++) {
+        currentGroup.push(null);
+    }
+    
+    var groups = [];
+    for(var i=0; i<c.length; i++) {
+        currentGroup.push(c[i]);
+        if(currentGroup.length % n == 0) {
+            groups.push(currentGroup);
+            currentGroup = [];
+        }
+    }
+    return groups;
+};
+
+Utils.keys = function(obj) {
+    var variables = [];
+    for(var variable in obj) {
+        variables.push(variable);
+    }
+
+    return variables;
+};
+
+Utils.iso8601 = function(date) {
+    function pad(n){
+        return n<10 ? '0'+n : n;
+    }    
+    return date.getUTCFullYear()+'-'
+        + pad(date.getUTCMonth()+1)+'-'
+        + pad(date.getUTCDate())+'T'
+        + pad(date.getUTCHours())+':'
+        + pad(date.getUTCMinutes())+':'
+        + pad(date.getUTCSeconds())+'Z';
+};
+
+
+Utils.parseStrictISO8601 = function (str) {
+    var regexp = "([0-9]{4})(-([0-9]{2})(-([0-9]{2})" +
+        "(T([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?" +
+        "(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?";
+    var d = str.match(new RegExp(regexp));
+
+    var offset = 0;
+    var date = new Date(d[1], 0, 1);
+
+    if (d[3]) {
+        date.setMonth(d[3] - 1);
+    } else {
+        throw "missing ISO8061 component"
+    }
+    if (d[5]) {
+        date.setDate(d[5]);
+    } else {
+        throw "missing ISO8061 component"
+    }
+    if (d[7]) {
+        date.setHours(d[7]);
+    } else {
+        throw "missing ISO8061 component"
+    }
+    if (d[8]) {
+        date.setMinutes(d[8]);
+    } else {
+        throw "missing ISO8061 component"
+    }
+    if (d[10]) {
+        date.setSeconds(d[10]);
+    } else {
+        throw "missing ISO8061 component"
+    }
+    if (d[12]) {
+        date.setMilliseconds(Number("0." + d[12]) * 1000);
+    }
+    if (d[14]) {
+        offset = (Number(d[16]) * 60) + Number(d[17]);
+        offset *= ((d[15] == '-') ? 1 : -1);
+    }
+
+    offset -= date.getTimezoneOffset();
+    var time = (Number(date) + (offset * 60 * 1000));
+    var toReturn = new Date();
+    toReturn.setTime(Number(time));
+    return toReturn;
+};
+
+
+Utils.parseISO8601 = function (str) {
+    var regexp = "([0-9]{4})(-([0-9]{2})(-([0-9]{2})" +
+        "(T([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?" +
+        "(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?";
+    var d = str.match(new RegExp(regexp));
+
+    var offset = 0;
+    var date = new Date(d[1], 0, 1);
+
+    if (d[3]) { date.setMonth(d[3] - 1); }
+    if (d[5]) { date.setDate(d[5]);  }
+    if (d[7]) { date.setHours(d[7]);  }
+    if (d[8]) { date.setMinutes(d[8]);  }
+    if (d[10]) { date.setSeconds(d[10]);  }
+    if (d[12]) { date.setMilliseconds(Number("0." + d[12]) * 1000); }
+    if (d[14]) {
+        offset = (Number(d[16]) * 60) + Number(d[17]);
+        offset *= ((d[15] == '-') ? 1 : -1);
+    }
+
+    offset -= date.getTimezoneOffset();
+    var time = (Number(date) + (offset * 60 * 1000));
+    var toReturn = new Date();
+    toReturn.setTime(Number(time));
+    return toReturn;
+};
+
+Utils.parseISO8601Components = function (str) {
+    var regexp = "([0-9]{4})(-([0-9]{2}))(-([0-9]{2}))(T([0-9]{2}):([0-9]{2})(:([0-9]{2}))?(\.([0-9]+))?)?(Z|([-+])([0-9]{2})(:([0-9]{2}))?)?";
+    var d = str.match(new RegExp(regexp));
+    var year, month, date, hours, minutes, seconds, millisecs, timezone;
+    year = Number(d[1]);
+    month = d[3] - 1;
+    date  = Number(d[5]);
+    hours = Number(d[7]);
+    minutes = Number(d[8]);
+    seconds = Number(d[10]);
+
+    if(d[12]) { millisecs = Number("0." + d[12]) * 1000; }
+
+    if(d[13]==="Z") {
+        timezone = 0;
+    } else if (d[14]) {
+        timezone = 0;
+        if(d[17]) {
+            timezone = Number(d[17]);
+        }
+        timezone = timezone+(Number(d[15]) * 60);
+        timezone *= ((d[14] == '-') ? -1 : +1);
+    } else if(d[14]==null && d[11]) {
+        timezone = Number(d[12])*60;
+    }    
+
+    return {'year': isNaN(year) ? null : year,
+            'month': isNaN(month) ? null : month,
+            'date': isNaN(date) ? null : date,
+            'hours': isNaN(hours) ? null : hours,
+            'minutes': isNaN(minutes) ? null : minutes,
+            'seconds': isNaN(seconds) ? null : seconds,
+            'millisecs':isNaN(millisecs) ? null : millisecs,
+            'timezone': isNaN(timezone) ? null : timezone};
+};
+
+Utils.compareDateComponents = function(stra,strb) {
+    var a = Utils.parseISO8601Components(stra);
+    var b = Utils.parseISO8601Components(strb);
+
+    if((a.timezone == null && b.timezone == null) ||
+       (a.timezone != null && b.timezone != null)) {        
+        var da = Utils.parseISO8601(stra);
+        var db = Utils.parseISO8601(strb);
+        
+        if(da.getTime() == db.getTime()) {
+            return 0;
+        } else if(da.getTime() < db.getTime()){
+            return -1;
+        } else {
+            return 1;
+        }
+    } else if (a.timezone != null && b.timezone == null){
+        da = Utils.parseISO8601(stra);
+        db = Utils.parseISO8601(strb);
+        var ta = da.getTime();
+        var tb = db.getTime();
+
+        var offset = 14*60*60;
+
+        if(ta < tb && ta < (tb + offset)) {
+            return -1;
+        } else if(ta > tb && ta > (tb - offset)) {
+            return 1;
+        } else {
+        return null;
+        }
+    } else {
+        da = Utils.parseISO8601(stra);
+        db = Utils.parseISO8601(strb);
+        ta = da.getTime();
+        tb = db.getTime();
+
+        var offset = 14*60*60;
+        if(ta < tb && (ta + offset)  < tb) {
+            return -1;
+        } else if(ta > tb && (ta + offset) > tb) {
+            return 1;
+        } else {
+        return null;
+        }
+    }
+};
+
+// RDF utils
+Utils.lexicalFormLiteral = function(term, env) {
+    var value = term.value;
+    var lang = term.lang;
+    var type = term.type;
+
+    var indexedValue = null;
+    if(value != null && type != null && typeof(type) != 'string') {
+        var typeValue = type.value;
+
+        if(typeValue == null) {
+            var typePrefix = type.prefix;
+            var typeSuffix = type.suffix;
+
+            var resolvedPrefix = env.namespaces[typePrefix];
+            term.type = resolvedPrefix+typeSuffix;
+	    typeValue = resolvedPrefix+typeSuffix;
+        }
+	// normalization
+	if(typeValue.indexOf('hexBinary') != -1) {
+            indexedValue = '"' + term.value.toLowerCase() + '"^^<' + typeValue + '>';
+	} else {
+            indexedValue = '"' + term.value + '"^^<' + typeValue + '>';
+	}
+    } else {
+        if(lang == null && type == null) {
+            indexedValue = '"' + value + '"';
+        } else if(type == null) {
+            indexedValue = '"' + value + '"' + "@" + lang;        
+        } else {
+	    // normalization
+	    if(type.indexOf('hexBinary') != -1) {
+		indexedValue = '"' + term.value.toLowerCase() + '"^^<'+type+'>';
+	    } else {
+		indexedValue = '"' + term.value + '"^^<'+type+'>';
+	    }
+        }
+    }
+    return indexedValue;
+};
+
+Utils.lexicalFormBaseUri = function(term, env) {
+    var uri = null;
+    env = env || {};
+    //console.log("*** normalizing URI token:");
+    //console.log(term);
+    if(term.value == null) {
+        //console.log(" - URI has prefix and suffix");
+        //console.log(" - prefix:"+term.prefix);
+        //console.log(" - suffixx:"+term.suffix);
+        var prefix = term.prefix;
+        var suffix = term.suffix;
+        var resolvedPrefix = env.namespaces[prefix];
+        if(resolvedPrefix != null) {            
+            uri = resolvedPrefix+suffix;
+        } else {
+            uri = prefix+":"+suffix;
+        }
+    } else {
+        //console.log(" - URI is not prefixed");
+        uri = term.value;
+    }
+
+    if(uri===null) {
+        return null;
+    } else {
+        //console.log(" - resolved URI is "+uri);
+        if(uri.indexOf(":") == -1) {
+            //console.log(" - URI is partial");
+            uri = (env.base||"") + uri; // applyBaseUri
+        } else {
+            //console.log(" - URI is complete");
+        }
+        //console.log(" -> FINAL URI: "+uri);
+    }
+
+    return uri;
+};
+
+
+Utils.lexicalFormTerm = function(term, ns) {
+    if(term.token === 'uri') {
+        return {'uri': Utils.lexicalFormBaseUri(term, ns)};
+    } else if(term.token === 'literal') {
+        return {'literal': Utils.lexicalFormLiteral(term, ns)};
+    } else if(term.token === 'blank') {
+        var label = '_:'+term.value;
+        return {'blank': label};
+    } else {
+	throw "Error, cannot get lexical form of unknown token: "+term.token;
+    }
+};
+
+Utils.normalizeUnicodeLiterals = function (string) {
+    var escapedUnicode = string.match(/\\u[0-9abcdefABCDEF]{4,4}/g) || [];
+    var dups = {};
+    for (var i = 0; i < escapedUnicode.length; i++) {
+        if (dups[escapedUnicode[i]] == null) {
+            dups[escapedUnicode[i]] = true;
+            string = string.replace(new RegExp("\\" + escapedUnicode[i], "g"), eval("'" + escapedUnicode[i] + "'"));
+        }
+    }
+
+    return string;
+};
+
+Utils.hashTerm = function(term) {
+    try {
+      if(term == null) {
+          return "";
+      } if(term.token==='uri') {
+          return "u"+term.value;
+      } else if(term.token === 'blank') {
+          return "b"+term.value;
+      } else if(term.token === 'literal') {
+          var l = "l"+term.value;
+          l = l + (term.type || "");
+          l = l + (term.lang || "");        
+   
+          return l;
+      }
+    } catch(e) {
+        if(typeof(term) === 'object') {
+            var key = "";
+            for(p in term) {
+                key = key + p + term[p];
+            }
+
+            return key;
+        }
+        return term;
+    }
+};
+
+// end of ./src/js-trees/src/utils.js 
+// exports
+var InMemoryBTree = {};
+
+var left = -1;
+var right = 1;
+
+
+/**
+ * @doc
+ * Implementation based on <http://www.gossamer-threads.com/lists/linux/kernel/667935>
+ *
+ */
+
+/**
+ * Tree
+ *
+ * Implements the interface of BinarySearchTree.Tree
+ *
+ * An implementation of an in memory B-Tree.
+ */
+
+InMemoryBTree.Tree = function(order) {
+    if(arguments.length != 0) {
+        this.order = order;
+        this.root = this._allocateNode();
+        this.root.isLeaf = true;
+        this.root.level = 0;
+        this._diskWrite(this.root);
+        this._updateRootNode(this.root);
+
+        this.comparator = function(a,b) {
+            if(a < b) {
+                return -1;
+            } else if(a > b){
+                return 1;
+            } else {
+                return 0;
+            }
+        };
+        this.merger = null;
+    }
+};
+
+/**
+ * Creates the new node.
+ *
+ * This class can be overwritten by different versions of
+ * the tree t select the right kind of node to be used
+ *
+ * @returns the new alloacted node
+ */
+InMemoryBTree.Tree.prototype._allocateNode = function () {
+    return new InMemoryBTree.Node();
+};
+
+/**
+ * _diskWrite
+ *
+ * Persists the node to secondary memory.
+ */
+InMemoryBTree.Tree.prototype._diskWrite= function(node) {
+    // dummy implementation;
+    // no-op
+};
+
+
+/**
+ * _diskRead
+ *
+ * Retrieves a node from secondary memory using the provided
+ * pointer
+ */
+InMemoryBTree.Tree.prototype._diskRead = function(pointer) {
+    // dummy implementation;
+    // no-op
+    return pointer;
+};
+
+
+InMemoryBTree.Tree.prototype._diskDelete= function(node) {
+    // dummy implmentation
+    // no-op
+};
+
+/**
+ * _updateRootNode
+ *
+ * Updates the pointer to the root node stored in disk.
+ */
+InMemoryBTree.Tree.prototype._updateRootNode = function(node) {
+    // dummy implementation;
+    // no-op
+    return node;
+};
+
+InMemoryBTree.Tree.prototype.clear = function() {
+        this.root = this._allocateNode();
+        this.root.isLeaf = true;
+        this.root.level = 0;
+        this._updateRootNode(this.root);
+};
+
+/**
+ * search
+ *
+ * Retrieves the node matching the given value.
+ * If no node is found, null is returned.
+ */
+InMemoryBTree.Tree.prototype.search = function(key, checkExists) {
+    var searching = true;
+    var node = this.root;
+
+    while(searching) {
+        var idx = 0;
+        while(idx < node.numberActives && this.comparator(key, node.keys[idx].key) === 1) {
+            idx++;
+        }
+
+        if(idx < node.numberActives && this.comparator(node.keys[idx].key,key) === 0) {
+            if(checkExists != null && checkExists == true) {
+                return true;
+            } else {
+                return node.keys[idx].data;
+            }
+        } else {
+            if(node.isLeaf === true) {
+                searching = false;
+            } else {
+                node = this._diskRead(node.children[idx]);
+            }
+        }
+    }
+
+    return null;
+};
+
+
+/**
+ * walk
+ * Applies a function to all the nodes key and data in the the
+ * tree in key order.
+ */
+InMemoryBTree.Tree.prototype.walk = function(f) {
+    this._walk(f,this.root);
+};
+
+InMemoryBTree.Tree.prototype._walk = function(f,node) {
+    if(node.isLeaf) {
+        for(var i=0; i<node.numberActives; i++) {
+            f(node.keys[i]);
+        }
+    } else {
+        for(var i=0; i<node.numberActives; i++) {
+            this._walk(f,this._diskRead(node.children[i]));
+            f(node.keys[i]);
+        }
+        this._walk(f,this._diskRead(node.children[node.numberActives]));
+    }
+};
+
+/**
+ * walkNodes
+ * Applies a function to all the nodes in the the
+ * tree in key order.
+ */
+InMemoryBTree.Tree.prototype.walkNodes = function(f) {
+    this._walkNodes(f,this.root);
+};
+
+InMemoryBTree.Tree.prototype._walkNodes = function(f,node) {
+    if(node.isLeaf) {
+        f(node);
+    } else {
+        f(node);
+        for(var i=0; i<node.numberActives; i++) {
+            this._walkNodes(f,this._diskRead(node.children[i]));
+        }
+        this._walkNodes(f,this._diskRead(node.children[node.numberActives]));
+    }
+};
+
+/**
+ * _splitChild
+ *
+ * Split the child node and adjusts the parent.
+ */
+InMemoryBTree.Tree.prototype._splitChild = function(parent, index, child) {
+    var newChild = this._allocateNode();
+    newChild.isLeaf = child.isLeaf;
+    newChild.level = child.level;
+    newChild.numberActives = this.order - 1;
+
+    // Copy the higher order keys to the new child
+    var newParentChild = child.keys[this.order-1];
+    child.keys[this.order-1] = null;
+
+    for(var i=0; i< this.order-1; i++) {
+	newChild.keys[i]=child.keys[i+this.order];
+	child.keys[i+this.order] = null;
+	if(!child.isLeaf) {
+	    newChild.children[i] = child.children[i+this.order];
+            child.children[i+this.order] = null;
+	}
+    }
+
+    // Copy the last child pointer
+    if(!child.isLeaf) {
+	newChild.children[i] = child.children[i+this.order];
+        child.children[i+this.order] = null;
+    }
+
+    child.numberActives = this.order - 1;
+
+
+    for(i = parent.numberActives + 1; i>index+1; i--) {
+	parent.children[i] = parent.children[i-1];
+    }
+
+    parent.children[index+1] = newChild;
+
+    for(i = parent.numberActives; i>index; i--) {
+	parent.keys[i] = parent.keys[i-1];
+    }
+
+    parent.keys[index] = newParentChild;
+    parent.numberActives++;
+
+    this._diskWrite(newChild);
+    this._diskWrite(parent);
+    this._diskWrite(child);
+};
+
+/**
+ * insert
+ *
+ * Creates a new node with value key and data and inserts it
+ * into the tree.
+ */
+InMemoryBTree.Tree.prototype.insert = function(key,data) {
+    if(this.root.numberActives === (2 * this.order - 1)) {
+        var newRoot = this._allocateNode();
+        newRoot.isLeaf = false;
+        newRoot.level = this.root.level + 1;
+        newRoot.numberActives = 0;
+        newRoot.children[0] = this.root;
+
+        this._splitChild(newRoot, 0, this.root);
+        this.root = newRoot;
+        this._updateRootNode(this.root);
+        this._insertNonFull(newRoot, key, data);
+    } else {
+        this._insertNonFull(this.root, key, data);
+    }
+};
+
+/**
+ * _insertNonFull
+ *
+ * Recursive function that tries to insert the new key in
+ * in the prvided node, or splits it and go deeper
+ * in the BTree hierarchy.
+ */
+InMemoryBTree.Tree.prototype._insertNonFull = function(node,key,data) {
+    var idx = node.numberActives - 1;
+
+    while(!node.isLeaf) {
+        while(idx>=0 && this.comparator(key,node.keys[idx].key) === -1) {
+            idx--;
+        }
+        idx++;
+        var child = this._diskRead(node.children[idx]);
+
+        if(child.numberActives === 2*this.order -1) {
+            this._splitChild(node,idx,child);
+            if(this.comparator(key, node.keys[idx].key)===1) {
+                idx++;
+            }
+        }
+        node = this._diskRead(node.children[idx]);
+        idx = node.numberActives -1;
+    }
+
+    while(idx>=0 && this.comparator(key,node.keys[idx].key) === -1) {
+        node.keys[idx+1] = node.keys[idx];
+        idx--;
+    }
+
+    node.keys[idx + 1] = {key:key, data:data};
+    node.numberActives++;
+    this._diskWrite(node);
+};
+
+/**
+ * delete
+ *
+ * Deletes the key from the BTree.
+ * If the key is not found, an exception is thrown.
+ *
+ * @param key the key to be deleted
+ * @returns true if the key is deleted false otherwise
+ */
+InMemoryBTree.Tree.prototype['delete'] = function(key) {
+    var node = this.root;
+    var parent = null;
+    var searching = true;
+    var idx = null;
+    var lsibling = null;
+    var rsibling = null;
+    var shouldContinue = true;
+
+    while(shouldContinue === true) {
+        shouldContinue = false;
+
+        while(searching === true) {
+            i = 0;
+
+            if(node.numberActives === 0) {
+                return false;
+            }
+
+            while(i<node.numberActives && this.comparator(key, node.keys[i].key) === 1) {
+                i++;
+            }
+
+            idx = i;
+
+            if(i<node.numberActives && this.comparator(key, node.keys[i].key) === 0) {
+                searching = false;
+            }
+
+            if(searching === true) {
+
+                if(node.isLeaf === true) {
+                    return false;
+                }
+
+                parent = node;
+                node = this._diskRead(node.children[i]);
+
+                if(node===null) {
+                    return false;
+                }
+
+                if(idx === parent.numberActives) {
+                    lsibling = this._diskRead(parent.children[idx-1]);
+                    rsibling = null;
+                } else if(idx === 0) {
+                    lsibling = null;
+                    rsibling = this._diskRead(parent.children[1]);
+                } else {
+                    lsibling = this._diskRead(parent.children[idx-1]);
+                    rsibling = this._diskRead(parent.children[idx+1]);
+                }
+
+
+                if(node.numberActives === (this.order-1) && parent != null) {
+                    if(rsibling != null && rsibling.numberActives > (this.order-1)) {
+                        // The current node has (t - 1) keys but the right sibling has > (t - 1) keys
+                        this._moveKey(parent,i,left);
+                    } else if(lsibling != null && lsibling.numberActives > (this.order-1)) {
+                        // The current node has (t - 1) keys but the left sibling has > (t - 1) keys
+                        this._moveKey(parent,i,right);
+                    } else if(lsibling != null && lsibling.numberActives === (this.order-1)) {
+                        // The current node has (t - 1) keys but the left sibling has (t - 1) keys
+                        node = this._mergeSiblings(parent,i,left);
+                    } else if(rsibling != null && rsibling.numberActives === (this.order-1)){
+                        // The current node has (t - 1) keys but the left sibling has (t - 1) keys
+                        node = this._mergeSiblings(parent,i,right);
+                    }
+                }
+            }
+        }
+
+
+        //Case 1 : The node containing the key is found and is the leaf node.
+        //Also the leaf node has keys greater than the minimum required.
+        //Simply remove the key
+        if(node.isLeaf && (node.numberActives > (this.order-1))) {
+            this._deleteKeyFromNode(node,idx);
+            return true;
+        }
+
+
+        //If the leaf node is the root permit deletion even if the number of keys is
+        //less than (t - 1)
+        if(node.isLeaf && (node === this.root)) {
+            this._deleteKeyFromNode(node,idx);
+            return true;
+        }
+
+
+        //Case 2: The node containing the key is found and is an internal node
+        if(node.isLeaf === false) {
+            var tmpNode = null;
+            var tmpNode2 = null;
+            if((tmpNode=this._diskRead(node.children[idx])).numberActives > (this.order-1)) {
+                var subNodeIdx = this._getMaxKeyPos(tmpNode);
+                key = subNodeIdx.node.keys[subNodeIdx.index];
+
+                node.keys[idx] = key;
+
+                //this._delete(node.children[idx],key.key);
+                this._diskWrite(node);
+                node = tmpNode;
+                key = key.key;
+                shouldContinue = true;
+                searching = true;
+            } else if ((tmpNode = this._diskRead(node.children[idx+1])).numberActives >(this.order-1)) {
+                var subNodeIdx = this._getMinKeyPos(tmpNode);
+                key = subNodeIdx.node.keys[subNodeIdx.index];
+
+                node.keys[idx] = key;
+
+                //this._delete(node.children[idx+1],key.key);
+                this._diskWrite(node);
+                node = tmpNode;
+                key = key.key;
+                shouldContinue = true;
+                searching = true;
+            } else if((tmpNode = this._diskRead(node.children[idx])).numberActives === (this.order-1) &&
+                      (tmpNode2 = this._diskRead(node.children[idx+1])).numberActives === (this.order-1)) {
+
+                var combNode = this._mergeNodes(tmpNode, node.keys[idx], tmpNode2);
+                node.children[idx] = combNode;
+
+                idx++;
+                for(var i=idx; i<node.numberActives; i++) {
+          	    node.children[i] = node.children[i+1];
+          	    node.keys[i-1] = node.keys[i];
+                }
+                // freeing unused references
+                node.children[i] = null;
+                node.keys[i-1] = null;
+
+                node.numberActives--;
+                if (node.numberActives === 0 && this.root === node) {
+                    this.root = combNode;
+                }
+
+                this._diskWrite(node);
+
+                node = combNode;
+                shouldContinue = true;
+                searching = true;
+            }
+        }
+
+
+        // Case 3:
+	// In this case start from the top of the tree and continue
+	// moving to the leaf node making sure that each node that
+	// we encounter on the way has atleast 't' (order of the tree)
+	// keys
+	if(node.isLeaf && (node.numberActives > this.order - 1) && searching===false) {
+            this._deleteKeyFromNode(node,idx);
+	}
+
+        if(shouldContinue === false) {
+            return true;
+        }
+    }
+};
+
+/**
+ * _moveKey
+ *
+ * Move key situated at position i of the parent node
+ * to the left or right child at positions i-1 and i+1
+ * according to the provided position
+ *
+ * @param parent the node whose is going to be moved to a child
+ * @param i Index of the key in the parent
+ * @param position left, or right
+ */
+InMemoryBTree.Tree.prototype._moveKey = function (parent, i, position) {
+
+    if (position === right) {
+        i--;
+    }
+
+    //var lchild = parent.children[i-1];
+    var lchild = this._diskRead(parent.children[i]);
+    var rchild = this._diskRead(parent.children[i + 1]);
+
+
+    if (position == left) {
+        lchild.keys[lchild.numberActives] = parent.keys[i];
+        lchild.children[lchild.numberActives + 1] = rchild.children[0];
+        rchild.children[0] = null;
+        lchild.numberActives++;
+
+        parent.keys[i] = rchild.keys[0];
+
+        for (var _i = 1; _i < rchild.numberActives; _i++) {
+            rchild.keys[_i - 1] = rchild.keys[_i];
+            rchild.children[_i - 1] = rchild.children[_i];
+        }
+        rchild.children[rchild.numberActives - 1] = rchild.children[rchild.numberActives];
+        rchild.numberActives--;
+    } else {
+        rchild.children[rchild.numberActives + 1] = rchild.children[rchild.numberActives];
+        for (var _i = rchild.numberActives; _i > 0; _i--) {
+            rchild.children[_i] = rchild.children[_i - 1];
+            rchild.keys[_i] = rchild.keys[_i - 1];
+        }
+        rchild.keys[0] = null;
+        rchild.children[0] = null;
+
+        rchild.children[0] = lchild.children[lchild.numberActives];
+        rchild.keys[0] = parent.keys[i];
+        rchild.numberActives++;
+
+        lchild.children[lchild.numberActives] = null;
+        parent.keys[i] = lchild.keys[lchild.numberActives - 1];
+        lchild.keys[lchild.numberActives - 1] = null;
+        lchild.numberActives--;
+    }
+
+    this._diskWrite(lchild);
+    this._diskWrite(rchild);
+    this._diskWrite(parent);
+};
+
+/**
+ * _mergeSiblings
+ *
+ * Merges two nodes at the left and right of the provided
+ * index in the parent node.
+ *
+ * @param parent the node whose children will be merged
+ * @param i Index of the key in the parent pointing to the nodes to merge
+ */
+InMemoryBTree.Tree.prototype._mergeSiblings = function (parent, index, pos) {
+    var i, j;
+    var n1, n2;
+
+    if (index === (parent.numberActives)) {
+        index--;
+        n1 = this._diskRead(parent.children[parent.numberActives - 1]);
+        n2 = this._diskRead(parent.children[parent.numberActives]);
+    } else {
+        n1 = this._diskRead(parent.children[index]);
+        n2 = this._diskRead(parent.children[index + 1]);
+    }
+
+    //Merge the current node with the left node
+    var newNode = this._allocateNode();
+    newNode.isLeaf = n1.isLeaf;
+    newNode.level = n1.level;
+
+    for (j = 0; j < this.order - 1; j++) {
+        newNode.keys[j] = n1.keys[j];
+        newNode.children[j] = n1.children[j];
+    }
+
+    newNode.keys[this.order - 1] = parent.keys[index];
+    newNode.children[this.order - 1] = n1.children[this.order - 1];
+
+    for (j = 0; j < this.order - 1; j++) {
+        newNode.keys[j + this.order] = n2.keys[j];
+        newNode.children[j + this.order] = n2.children[j];
+    }
+    newNode.children[2 * this.order - 1] = n2.children[this.order - 1];
+
+    parent.children[index] = newNode;
+
+    for (j = index; j < parent.numberActives; j++) {
+        parent.keys[j] = parent.keys[j + 1];
+        parent.children[j + 1] = parent.children[j + 2];
+    }
+
+    newNode.numberActives = n1.numberActives + n2.numberActives + 1;
+    parent.numberActives--;
+
+    for (i = parent.numberActives; i < 2 * this.order - 1; i++) {
+        parent.keys[i] = null;
+    }
+
+    if (parent.numberActives === 0 && this.root === parent) {
+        this.root = newNode;
+        if (newNode.level) {
+            newNode.isLeaf = false;
+        } else {
+            newNode.isLeaf = true;
+        }
+    }
+
+    this._diskWrite(newNode);
+    if (this.root === newNode) {
+        this._updateRootNode(this.root);
+    }
+    this._diskWrite(parent);
+    this._diskDelete(n1);
+    this._diskDelete(n2);
+
+    return newNode;
+};
+
+/**
+ * _deleteKeyFromNode
+ *
+ * Deletes the key at position index from the provided node.
+ *
+ * @param node The node where the key will be deleted.
+ * @param index The index of the key that will be deletd.
+ * @return true if the key can be deleted, false otherwise
+ */
+InMemoryBTree.Tree.prototype._deleteKeyFromNode = function (node, index) {
+    var keysMax = (2 * this.order) - 1;
+    if (node.numberActives < keysMax) {
+        keysMax = node.numberActives;
+    }
+    ;
+
+    var i;
+
+    if (node.isLeaf === false) {
+        return false;
+    }
+
+    var key = node.keys[index];
+
+    for (i = index; i < keysMax - 1; i++) {
+        node.keys[i] = node.keys[i + 1];
+    }
+
+    // cleaning invalid reference
+    node.keys.pop();
+
+    node.numberActives--;
+
+    this._diskWrite(node);
+
+    return true;
+};
+
+InMemoryBTree.Tree.prototype._mergeNodes = function (n1, key, n2) {
+    var newNode;
+    var i;
+
+    newNode = this._allocateNode();
+    newNode.isLeaf = true;
+
+    for (i = 0; i < n1.numberActives; i++) {
+        newNode.keys[i] = n1.keys[i];
+        newNode.children[i] = n1.children[i];
+    }
+    newNode.children[n1.numberActives] = n1.children[n1.numberActives];
+    newNode.keys[n1.numberActives] = key;
+
+    for (i = 0; i < n2.numberActives; i++) {
+        newNode.keys[i + n1.numberActives + 1] = n2.keys[i];
+        newNode.children[i + n1.numberActives + 1] = n2.children[i];
+    }
+    newNode.children[(2 * this.order) - 1] = n2.children[n2.numberActives];
+
+    newNode.numberActives = n1.numberActives + n2.numberActives + 1;
+    newNode.isLeaf = n1.isLeaf;
+    newNode.level = n1.level;
+
+
+    this._diskWrite(newNode);
+    // @todo
+    // delte old nodes from disk
+    return newNode;
+};
+
+/**
+ * audit
+ *
+ * Checks that the tree data structure is
+ * valid.
+ */
+InMemoryBTree.Tree.prototype.audit = function (showOutput) {
+    var errors = [];
+    var alreadySeen = [];
+    var that = this;
+
+    var foundInArray = function (data) {
+        for (var i = 0; i < alreadySeen.length; i++) {
+            if (that.comparator(alreadySeen[i], data) === 0) {
+                var error = " !!! duplicated key " + data;
+                if (showOutput === true) {
+                    console.log(error);
+                }
+                errors.push(error);
+            }
+        }
+    };
+
+    var length = null;
+    var that = this;
+    this.walkNodes(function (n) {
+        if (showOutput === true) {
+            console.log("--- Node at " + n.level + " level");
+            console.log(" - leaf? " + n.isLeaf);
+            console.log(" - num actives? " + n.numberActives);
+            console.log(" - keys: ");
+        }
+        for (var i = n.numberActives; i < n.keys.length; i++) {
+            if (n.keys[i] != null) {
+                if (showOutput === true) {
+                    console.log(" * warning : redundant key data");
+                    errors.push(" * warning : redundant key data");
+                }
+            }
+        }
+
+        for (var i = n.numberActives + 1; i < n.children.length; i++) {
+            if (n.children[i] != null) {
+                if (showOutput === true) {
+                    console.log(" * warning : redundant children data");
+                    errors.push(" * warning : redundant key data");
+                }
+            }
+        }
+
+
+        if (n.isLeaf === false) {
+            for (var i = 0; i < n.numberActives; i++) {
+                var maxLeft = that._diskRead(n.children[i]).keys[that._diskRead(n.children[i]).numberActives - 1 ].key;
+                var minRight = that._diskRead(n.children[i + 1]).keys[0].key;
+                if (showOutput === true) {
+                    console.log("   " + n.keys[i].key + "(" + maxLeft + "," + minRight + ")");
+                }
+                if (that.comparator(n.keys[i].key, maxLeft) === -1) {
+                    var error = " !!! value max left " + maxLeft + " > key " + n.keys[i].key;
+                    if (showOutput === true) {
+                        console.log(error);
+                    }
+                    errors.push(error);
+                }
+                if (that.comparator(n.keys[i].key, minRight) === 1) {
+                    var error = " !!! value min right " + minRight + " < key " + n.keys[i].key;
+                    if (showOutput === true) {
+                        console.log(error);
+                    }
+                    errors.push(error);
+                }
+
+                foundInArray(n.keys[i].key);
+                alreadySeen.push(n.keys[i].key);
+            }
+        } else {
+            if (length === null) {
+                length = n.level;
+            } else {
+                if (length != n.level) {
+                    var error = " !!! Leaf node with wrong level value";
+                    if (showOutput === true) {
+                        console.log(error);
+                    }
+                    errors.push(error);
+                }
+            }
+            for (var i = 0; i < n.numberActives; i++) {
+                if (showOutput === true) {
+                    console.log(" " + n.keys[i].key);
+                }
+                foundInArray(n.keys[i].key);
+                alreadySeen.push(n.keys[i].key);
+
+            }
+        }
+
+        if (n != that.root) {
+            if (n.numberActives > ((2 * that.order) - 1)) {
+                if (showOutput === true) {
+                    var error = " !!!! MAX num keys restriction violated ";
+                }
+                console.log(error);
+                errors.push(error);
+            }
+            if (n.numberActives < (that.order - 1)) {
+                if (showOutput === true) {
+                    var error = " !!!! MIN num keys restriction violated ";
+                }
+                console.log(error);
+                errors.push(error);
+            }
+
+        }
+    });
+
+    return errors;
+};
+
+/**
+ *  _getMaxKeyPos
+ *
+ *  Used to get the position of the MAX key within the subtree
+ *  @return An object containing the key and position of the key
+ */
+InMemoryBTree.Tree.prototype._getMaxKeyPos = function (node) {
+    var node_pos = {};
+
+    while (true) {
+        if (node === null) {
+            break;
+        }
+
+        if (node.isLeaf === true) {
+            node_pos.node = node;
+            node_pos.index = node.numberActives - 1;
+            return node_pos;
+        } else {
+            node_pos.node = node;
+            node_pos.index = node.numberActives - 1;
+            node = this._diskRead(node.children[node.numberActives]);
+        }
+    }
+
+    return node_pos;
+};
+
+/**
+ *  _getMinKeyPos
+ *
+ *  Used to get the position of the MAX key within the subtree
+ *  @return An object containing the key and position of the key
+ */
+InMemoryBTree.Tree.prototype._getMinKeyPos = function (node) {
+    var node_pos = {};
+
+    while (true) {
+        if (node === null) {
+            break;
+        }
+
+        if (node.isLeaf === true) {
+            node_pos.node = node;
+            node_pos.index = 0;
+            return node_pos;
+        } else {
+            node_pos.node = node;
+            node_pos.index = 0;
+            node = this._diskRead(node.children[0]);
+        }
+    }
+
+    return node_pos;
+};
+
+
+/**
+ * Node
+ *
+ * Implements the interface of BinarySearchTree.Node
+ *
+ * A Tree node augmented with BTree
+ * node structures
+ */
+InMemoryBTree.Node = function() {
+    this.numberActives = 0;
+    this.isLeaf = null;
+    this.keys = [];
+    this.children = [];
+    this.level = 0;
+};
+
+// end of ./src/js-trees/src/in_memory_b_tree.js 
+// exports
+var QuadIndexCommon = {};
+
+/**
+ * NodeKey
+ *
+ * Implements the interface of BinarySearchTree.Node
+ *
+ * A Tree node augmented with BPlusTree
+ * node structures
+ */
+QuadIndexCommon.NodeKey = function(components, order) {
+    this.subject = components.subject;
+    this.predicate = components.predicate;
+    this.object = components.object;
+    this.graph = components.graph;
+    this.order = order;
+};
+
+QuadIndexCommon.NodeKey.prototype.comparator = function(keyPattern) {
+    for(var i=0; i<this.order.length; i++) {
+        var component = this.order[i];
+        if(keyPattern[component] == null) {
+            return 0;
+        } else {
+            if(this[component] < keyPattern[component] ) {
+                return -1
+            } else if(this[component] > keyPattern[component]) {
+                return 1
+            }
+        }
+    }
+
+    return 0;
+};
+
+/**
+ * Pattern
+ *
+ * A pattern with some variable components
+ */
+QuadIndexCommon.Pattern = function (components) {
+    this.subject = components.subject;
+    this.predicate = components.predicate;
+    this.object = components.object;
+    this.graph = components.graph;
+    this.indexKey = [];
+
+    this.keyComponents = {};
+
+    var order = [];
+    var indif = [];
+    var components = ['subject', 'predicate', 'object', 'graph'];
+
+    // components must have been already normalized and
+    // inserted in the lexicon.
+    // OIDs retrieved from the lexicon *are* numbers so
+    // they can be told apart from variables (strings)
+    for (var i = 0; i < components.length; i++) {
+        if (typeof(this[components[i]]) === 'string') {
+            indif.push(components[i]);
+            this.keyComponents[components[i]] = null;
+        } else {
+            order.push(components[i]);
+            this.keyComponents[components[i]] = this[components[i]];
+            this.indexKey.push(components[i]);
+        }
+    }
+
+    this.order = order.concat(indif);
+    this.key = new QuadIndexCommon.NodeKey(this.keyComponents, this.order);
+};
+
+// end of ./src/js-rdf-persistence/src/quad_index_common.js 
+// exports
+var QuadIndex = {};
+
+// imports
+var BaseTree = InMemoryBTree;
+
+QuadIndex.Tree = function(params,callback) {
+    if(arguments != 0) {
+        this.componentOrder = params.componentOrder;
+
+
+        // @todo change this if using the file backed implementation
+        BaseTree.Tree.call(this, params.order, params['name'], params['persistent'], params['cacheMaxSize']);
+
+        this.comparator = function (a, b) {
+            for (var i = 0; i < this.componentOrder.length; i++) {
+                var component = this.componentOrder[i];
+                var vala = a[component];
+                var valb = b[component];
+                if (vala < valb) {
+                    return -1;
+                } else if (vala > valb) {
+                    return 1;
+                }
+            }
+            return 0;
+        };
+
+        this.rangeComparator = function (a, b) {
+            for (var i = 0; i < this.componentOrder.length; i++) {
+                var component = this.componentOrder[i];
+                if (b[component] == null || a[component] == null) {
+                    return 0;
+                } else {
+                    if (a[component] < b[component]) {
+                        return -1
+                    } else if (a[component] > b[component]) {
+                        return 1
+                    }
+                }
+            }
+
+            return 0;
+        };
+
+        if(callback!=null) {
+            callback(this);
+        }
+    }
+};
+
+Utils['extends'](BaseTree.Tree, QuadIndex.Tree);
+
+QuadIndex.Tree.prototype.insert = function(quad, callback) {
+    BaseTree.Tree.prototype.insert.call(this, quad, null);
+    if(callback)
+        callback(true);
+
+    return true
+};
+
+QuadIndex.Tree.prototype.search = function(quad, callback) {
+    var result = BaseTree.Tree.prototype.search.call(this, quad, true); // true -> check exists : not present in all the b-tree implementations, check first.
+    if(callback)
+        callback(result);
+
+    return result;
+};
+
+QuadIndex.Tree.prototype.range = function (pattern, callback) {
+    var result = null;
+    if (typeof(this.root) === 'string') {
+        result = this._rangeTraverse(this, this._diskRead(this.root), pattern);
+    } else {
+        result = this._rangeTraverse(this, this.root, pattern);
+    }
+
+    if (callback)
+        callback(result);
+
+    return result;
+};
+
+QuadIndex.Tree.prototype._rangeTraverse = function(tree,node, pattern) {
+    var patternKey  = pattern.key;
+    var acum = [];
+    var pendingNodes = [node];
+    var node, idxMin, idxMax;
+    while(pendingNodes.length > 0) {
+        node = pendingNodes.shift();
+        idxMin = 0;
+
+        while(idxMin < node.numberActives && tree.rangeComparator(node.keys[idxMin].key,patternKey) === -1) {
+            idxMin++;
+        }
+        if(node.isLeaf === true) {
+            idxMax = idxMin;
+
+            while(idxMax < node.numberActives && tree.rangeComparator(node.keys[idxMax].key,patternKey) === 0) {
+                acum.push(node.keys[idxMax].key);
+                idxMax++;
+            }
+
+        } else {
+            var pointer = node.children[idxMin];
+            var childNode = tree._diskRead(pointer);
+            pendingNodes.push(childNode);
+
+            var idxMax = idxMin;
+            while(true) {
+                if(idxMax < node.numberActives && tree.rangeComparator(node.keys[idxMax].key,patternKey) === 0) {
+                    acum.push(node.keys[idxMax].key);
+                    idxMax++;
+                    childNode = tree._diskRead(node.children[idxMax]);
+                    pendingNodes.push(childNode);
+                } else {
+                    break;
+                }
+            }
+        }
+    }
+    return acum;
+};
+
+// end of ./src/js-rdf-persistence/src/quad_index.js 
+// exports
+var QuadBackend = {};
+
+
+// imports
+
+
+/*
+ * "perfect" indices for RDF indexing
+ *
+ * SPOG (?, ?, ?, ?), (s, ?, ?, ?), (s, p, ?, ?), (s, p, o, ?), (s, p, o, g)
+ * GP   (?, ?, ?, g), (?, p, ?, g)
+ * OGS  (?, ?, o, ?), (?, ?, o, g), (s, ?, o, g)
+ * POG  (?, p, ?, ?), (?, p, o, ?), (?, p, o, g)
+ * GSP  (s, ?, ?, g), (s, p, ?, g)
+ * OS   (s, ?, o, ?)
+ */
+QuadBackend.QuadBackend = function (configuration, callback) {
+    if (arguments != 0) {
+        this.indexMap = {};
+        this.treeOrder = configuration['treeOrder'];
+        this.indices = ['SPOG', 'GP', 'OGS', 'POG', 'GSP', 'OS'];
+        this.componentOrders = {
+            SPOG:['subject', 'predicate', 'object', 'graph'],
+            GP:['graph', 'predicate', 'subject', 'object'],
+            OGS:['object', 'graph', 'subject', 'predicate'],
+            POG:['predicate', 'object', 'graph', 'subject'],
+            GSP:['graph', 'subject', 'predicate', 'object'],
+            OS:['object', 'subject', 'predicate', 'graph']
+        };
+
+        for (var i = 0; i < this.indices.length; i++) {
+            var indexKey = this.indices[i];
+            this.indexMap[indexKey] = new QuadIndex.Tree({order:this.treeOrder,
+                componentOrder:this.componentOrders[indexKey],
+                persistent:configuration['persistent'],
+                name:(configuration['name'] || "") + indexKey,
+                cacheMaxSize:configuration['cacheMaxSize']});
+        }
+
+        if (callback)
+            callback(this);
+    }
+};
+
+QuadBackend.QuadBackend.prototype.clear = function() {
+        for(var i=0; i<this.indices.length; i++) {
+            var indexKey = this.indices[i];
+            this.indexMap[indexKey].clear();
+        }
+};
+
+QuadBackend.QuadBackend.prototype._indexForPattern = function (pattern) {
+    var indexKey = pattern.indexKey;
+    var matchingIndices = this.indices;
+
+    for (var i = 0; i < matchingIndices.length; i++) {
+        var index = matchingIndices[i];
+        var indexComponents = this.componentOrders[index];
+        for (var j = 0; j < indexComponents.length; j++) {
+            if (Utils.include(indexKey, indexComponents[j]) === false) {
+                break;
+            }
+            if (j == indexKey.length - 1) {
+                return index;
+            }
+        }
+    }
+
+    return 'SPOG'; // If no other match, we erturn the more generic index
+};
+
+
+QuadBackend.QuadBackend.prototype.index = function (quad, callback) {
+    for (var i = 0; i < this.indices.length; i++) {
+        var indexKey = this.indices[i];
+        var index = this.indexMap[indexKey];
+
+        index.insert(quad);
+    }
+
+    if (callback)
+        callback(true);
+
+    return true;
+};
+
+QuadBackend.QuadBackend.prototype.range = function (pattern, callback) {
+    var indexKey = this._indexForPattern(pattern);
+    var index = this.indexMap[indexKey];
+    var quads = index.range(pattern);
+    if (callback)
+        callback(quads);
+
+    return quads;
+};
+
+QuadBackend.QuadBackend.prototype.search = function (quad, callback) {
+    var indexKey = this.indices[0];
+    var index = this.indexMap[indexKey];
+    var result = index.search(quad);
+
+    if (callback)
+        callback(result != null);
+
+    return (result != null)
+};
+
+
+QuadBackend.QuadBackend.prototype['delete'] = function (quad, callback) {
+    var indexKey, index;
+    for (var i = 0; i < this.indices.length; i++) {
+        indexKey = this.indices[i];
+        index = this.indexMap[indexKey];
+
+        index['delete'](quad);
+    }
+
+    if (callback)
+        callback(true);
+
+    return true;
+};
+
+// end of ./src/js-rdf-persistence/src/quad_backend.js 
+// exports
+var Lexicon = {};
+
+// imports
+
+/**
+ * Temporal implementation of the lexicon
+ */
+
+
+Lexicon.Lexicon = function(callback){
+    this.uriToOID = {};
+    this.OIDToUri = {};
+
+    this.literalToOID = {};
+    this.OIDToLiteral = {};
+
+    this.blankToOID = {};
+    this.OIDToBlank = {};
+
+    this.defaultGraphOid = 0;
+
+    this.defaultGraphUri = "https://github.com/antoniogarrote/rdfstore-js#default_graph";
+    this.defaultGraphUriTerm = {"token": "uri", "prefix": null, "suffix": null, "value": this.defaultGraphUri, "oid": this.defaultGraphOid};
+    this.oidCounter = 1;
+
+    this.knownGraphs = {};
+    
+    if(callback != null) {
+        callback(this);
+    }
+};
+
+Lexicon.Lexicon.prototype.registerGraph = function(oid){
+    if(oid != this.defaultGraphOid) {
+        this.knownGraphs[oid] = true;
+    }
+    return true
+};
+
+Lexicon.Lexicon.prototype.registeredGraphs = function(shouldReturnUris) {
+    var acum = [];
+
+    for(var g in this.knownGraphs) {
+        if(shouldReturnUris === true) {
+            acum.push(this.OIDToUri['u'+g]);
+        } else {
+            acum.push(g);
+        }
+    }
+    return acum;
+};
+
+Lexicon.Lexicon.prototype.registerUri = function(uri) {
+    if(uri === this.defaultGraphUri) {
+        return(this.defaultGraphOid);
+    } else if(this.uriToOID[uri] == null){
+        var oid = this.oidCounter;
+        var oidStr = 'u'+oid;
+        this.oidCounter++;
+
+        this.uriToOID[uri] =[oid, 0];
+        this.OIDToUri[oidStr] = uri;
+
+        return(oid);
+    } else {
+        var oidCounter = this.uriToOID[uri];
+        var oid = oidCounter[0];
+        var counter = oidCounter[1] + 1;
+        this.uriToOID[uri] = [oid, counter];
+        return(oid);
+    }
+};
+
+Lexicon.Lexicon.prototype.resolveUri = function(uri) {
+    if(uri === this.defaultGraphUri) {
+        return(this.defaultGraphOid);
+    } else {
+        var oidCounter = this.uriToOID[uri];
+        if(oidCounter != null) {
+            return(oidCounter[0]);
+        } else {
+            return(-1);
+        }
+    }
+};
+
+Lexicon.Lexicon.prototype.resolveUriCost = function(uri) {
+    if(uri === this.defaultGraphUri) {
+        return(this.defaultGraphOid);
+    } else {
+        var oidCounter = this.uriToOID[uri];
+        if(oidCounter != null) {
+            return(oidCounter[1]);
+        } else {
+            return(-1);
+        }
+    }
+};
+
+Lexicon.Lexicon.prototype.registerBlank = function(label) {
+    var oid = this.oidCounter;
+    this.oidCounter++;
+    var oidStr = ""+oid;
+    this.OIDToBlank[oidStr] = true;
+    return(oidStr);
+};
+
+Lexicon.Lexicon.prototype.resolveBlank = function(label) {
+//    @todo
+//    this is failing with unicode tests... e.g. kanji2
+
+//    var id = label.split(":")[1];
+//    callback(id);
+
+    var oid = this.oidCounter;
+    this.oidCounter++;
+    return(""+oid);
+};
+
+Lexicon.Lexicon.prototype.resolveBlankCost = function(label) {
+    return 0;
+};
+
+Lexicon.Lexicon.prototype.registerLiteral = function(literal) {
+    if(this.literalToOID[literal] == null){
+        var oid = this.oidCounter;
+        var oidStr =  'l'+ oid;
+        this.oidCounter++;
+
+        this.literalToOID[literal] = [oid, 0];
+        this.OIDToLiteral[oidStr] = literal;
+
+        return(oid);
+    } else {
+        var oidCounter = this.literalToOID[literal];
+        var oid = oidCounter[0];
+        var counter = oidCounter[1] + 1;
+        this.literalToOID[literal] = [oid, counter];
+        return(oid);
+    }
+};
+
+Lexicon.Lexicon.prototype.resolveLiteral = function (literal) {
+    var oidCounter = this.literalToOID[literal];
+    if (oidCounter != null) {
+        return(oidCounter[0]);
+    } else {
+        return(-1);
+    }
+};
+
+Lexicon.Lexicon.prototype.resolveLiteralCost = function (literal) {
+    var oidCounter = this.literalToOID[literal];
+    if (oidCounter != null) {
+        return(oidCounter[1]);
+    } else {
+        return(0);
+    }
+};
+
+
+Lexicon.Lexicon.prototype.parseLiteral = function(literalString) {
+    var parts = literalString.lastIndexOf("@");
+    if(parts!=-1 && literalString[parts-1]==='"' && literalString.substring(parts, literalString.length).match(/^@[a-zA-Z\-]+$/g)!=null) {
+        var value = literalString.substring(1,parts-1);
+        var lang = literalString.substring(parts+1, literalString.length);
+        return {token: "literal", value:value, lang:lang};
+    }
+
+    var parts = literalString.lastIndexOf("^^");
+    if(parts!=-1 && literalString[parts-1]==='"' && literalString[parts+2] === '<' && literalString[literalString.length-1] === '>') {
+        var value = literalString.substring(1,parts-1);
+        var type = literalString.substring(parts+3, literalString.length-1);
+
+        return {token: "literal", value:value, type:type};
+    }
+
+    var value = literalString.substring(1,literalString.length-1);
+    return {token:"literal", value:value};
+};
+
+Lexicon.Lexicon.prototype.parseUri = function(uriString) {
+    return {token: "uri", value:uriString};
+};
+
+Lexicon.Lexicon.prototype.retrieve = function(oid) {
+    try {
+        if(oid === this.defaultGraphOid) {
+            return({ token: "uri", 
+                       value:this.defaultGraphUri,
+                       prefix: null,
+                       suffix: null,
+                       defaultGraph: true });
+        } else {
+          var maybeUri = this.OIDToUri['u'+oid];
+          if(maybeUri != null) {
+              return(this.parseUri(maybeUri));
+          } else {
+              var maybeLiteral = this.OIDToLiteral['l'+oid];
+              if(maybeLiteral != null) {
+                  return(this.parseLiteral(maybeLiteral));
+              } else {
+                  var maybeBlank = this.OIDToBlank[""+oid];
+                  if(maybeBlank != null) {
+                      return({token:"blank", value:"_:"+oid});
+                  } else {
+                      throw("Null value for OID");
+                  }
+              }
+          }
+        }
+    } catch(e) {
+        console.log("error in lexicon retrieving OID:");
+        console.log(oid);
+        if(e.message || e.stack) {
+            if(e.message) {
+                console.log(e.message); 
+            }
+            if(e.stack) {
+                console.log(e.stack);
+            }
+        } else {
+            console.log(e);
+        }
+        throw new Error("Unknown retrieving OID in lexicon:"+oid);
+
+    }
+};
+
+Lexicon.Lexicon.prototype.clear = function() {
+    this.uriToOID = {};
+    this.OIDToUri = {};
+
+    this.literalToOID = {};
+    this.OIDToLiteral = {};
+
+    this.blankToOID = {};
+    this.OIDToBlank = {};
+};
+
+Lexicon.Lexicon.prototype.unregister = function (quad, key) {
+    try {
+        this.unregisterTerm(quad.subject.token, key.subject);
+        this.unregisterTerm(quad.predicate.token, key.predicate);
+        this.unregisterTerm(quad.object.token, key.object);
+        if (quad.graph != null) {
+            this.unregisterTerm(quad.graph.token, key.graph);
+        }
+        return(true);
+    } catch (e) {
+        console.log("Error unregistering quad");
+        console.log(e.message);
+        return(false);
+    }
+};
+
+Lexicon.Lexicon.prototype.unregisterTerm = function (kind, oid) {
+    if (kind === 'uri') {
+        if (oid != this.defaultGraphOid) {
+            var oidStr = 'u' + oid;
+            var uri = this.OIDToUri[oidStr];     // = uri;
+            var oidCounter = this.uriToOID[uri]; // =[oid, 0];
+
+            var counter = oidCounter[1];
+            if ("" + oidCounter[0] === "" + oid) {
+                if (counter === 0) {
+                    delete this.OIDToUri[oidStr];
+                    delete this.uriToOID[uri];
+                    // delete the graph oid from known graphs
+                    // in case this URI is a graph identifier
+                    delete this.knownGraphs[oid];
+                } else {
+                    this.uriToOID[uri] = [oid, counter - 1];
+                }
+            } else {
+                throw("Not matching OID : " + oid + " vs " + oidCounter[0]);
+            }
+        }
+    } else if (kind === 'literal') {
+        this.oidCounter++;
+        var oidStr = 'l' + oid;
+        var literal = this.OIDToLiteral[oidStr];  // = literal;
+        var oidCounter = this.literalToOID[literal]; // = [oid, 0];
+
+        var counter = oidCounter[1];
+        if ("" + oidCounter[0] === "" + oid) {
+            if (counter === 0) {
+                delete this.OIDToLiteral[oidStr];
+                delete this.literalToOID[literal];
+            } else {
+                this.literalToOID[literal] = [oid, counter - 1];
+            }
+        } else {
+            throw("Not matching OID : " + oid + " vs " + oidCounter[0]);
+        }
+
+    } else if (kind === 'blank') {
+        delete this.OIDToBlank["" + oid];
+    }
+};
+
+// end of ./src/js-rdf-persistence/src/lexicon.js 
+// exports
+var NetworkTransport = {};
+
+NetworkTransport.load = function (uri, accept, callback, redirect) {
+    var transport = jQuery;
+
+    transport.ajax({
+        url:uri,
+        headers:{"Accept":accept},
+
+        success:function (data, status, xhr) {
+            if (("" + xhr.status)[0] == '2') {
+                var headers = xhr.getAllResponseHeaders().split("\n");
+                var acum = {};
+                for (var i = 0; i < headers.length; i++) {
+                    var header = headers[i].split(":");
+                    acum[header[0]] = header[1];
+                }
+
+                callback(true, {headers:acum,
+                                data:data});
+            }
+        },
+
+        error:function (xhr, textStatus, ex) {
+            if (("" + xhr.status)[0] == '3') {
+                if (redirection == 0) {
+                    callback(false, 500);
+                } else {
+                    var location = (xhr.getAllResponseHeaders()["Location"] || xhr.getAllResponseHeaders()["location"]);
+                    if (location != null) {
+                        NetworkTransport.load(location, accept, callback, (redirection - 1));
+                    } else {
+                        callback(false, 500);
+                    }
+                }
+            } else {
+                callback(false, xhr.statusCode());
+            }
+        }
+    });
+};
+
+// end of ./src/js-communication/src/ajax_transport.js 
+
+/**
+ * Javascript implementation of JSON-LD.
+ *
+ * @author Dave Longley
+ *
+ * Copyright (c) 2011 Digital Bazaar, Inc. All rights reserved.
+ */
+
+var jsonldParser = null;
+
+(function()
+{
+
+// used by Exception
+var _setMembers = function(self, obj)
+{
+   self.stack = '';
+   for(var key in obj)
+   {
+      self[key] = obj[key];
+   }
+};
+
+// define jsonld
+if(typeof(window) !== 'undefined')
+{
+   var jsonld = window.jsonld = window.jsonld || {};
+   Exception = function(obj)
+   {
+      _setMembers(this, obj);
+   };
+
+   // define js 1.8.5 Object.keys method unless present
+   if(!Object.keys)
+   {
+      Object.keys = function(o)
+      {  
+         if(o !== Object(o))
+         {
+            throw new TypeError('Object.keys called on non-object');
+         }
+         var rval = [];
+         for(var p in o)
+         {
+            if(Object.prototype.hasOwnProperty.call(o, p))
+            {
+               rval.push(p);
+            }
+         }
+         return rval;
+      };
+   }
+
+   if (!Array.prototype.filter)
+   {
+     Array.prototype.filter = function(fun /*, thisp */)
+     {
+       "use strict";
+    
+       if (this == null)
+         throw new TypeError();
+    
+       var t = Object(this);
+       var len = t.length >>> 0;
+       if (typeof fun != "function")
+         throw new TypeError();
+    
+       var res = [];
+       var thisp = arguments[1];
+       for (var i = 0; i < len; i++)
+       {
+         if (i in t)
+         {
+           var val = t[i]; // in case fun mutates this
+           if (fun.call(thisp, val, i, t))
+             res.push(val);
+         }
+       }
+    
+       return res;
+     };
+   }
+
+}
+// define node.js module
+else if(typeof(module) !== 'undefined' && module.exports)
+{
+   var jsonld = {};
+   //module.exports = jsonld;
+   Exception = function(obj)
+   {
+      _setMembers(this, obj);
+      this.stack = new Error().stack;
+   };
+}
+
+
+jsonldParser = jsonld;
+
+var defaultContext = { "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
+                       "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
+                       "owl": "http://www.w3.org/2002/07/owl#",
+                       "xsd": "http://www.w3.org/2001/XMLSchema#",
+                       "dcterms": "http://purl.org/dc/terms/",
+                       "foaf": "http://xmlns.com/foaf/0.1/",
+                       "cal": "http://www.w3.org/2002/12/cal/ical#",
+                       "vcard": "http://www.w3.org/2006/vcard/ns# ",
+                       "geo": "http://www.w3.org/2003/01/geo/wgs84_pos#",
+                       "cc": "http://creativecommons.org/ns#",
+                       "sioc": "http://rdfs.org/sioc/ns#",
+                       "doap": "http://usefulinc.com/ns/doap#",
+                       "com": "http://purl.org/commerce#",
+                       "ps": "http://purl.org/payswarm#",
+                       "gr": "http://purl.org/goodrelations/v1#",
+                       "sig": "http://purl.org/signature#",
+                       "ccard": "http://purl.org/commerce/creditcard#"
+                     };
+
+/*
+ * Globals and helper functions.
+ */
+var ns =
+{
+   xsd: 'http://www.w3.org/2001/XMLSchema#'
+};
+
+var xsd =
+{
+   'boolean': ns.xsd + 'boolean',
+   'double': ns.xsd + 'double',
+   'integer': ns.xsd + 'integer'
+};
+
+/**
+ * Sets a subject's property to the given object value. If a value already
+ * exists, it will be appended to an array.
+ *
+ * @param s the subject.
+ * @param p the property.
+ * @param o the object.
+ */
+var _setProperty = function(s, p, o)
+{
+   if(p in s)
+   {
+      if(s[p].constructor === Array)
+      {
+         s[p].push(o);
+      }
+      else
+      {
+         s[p] = [s[p], o];
+      }
+   }
+   else
+   {
+      s[p] = o;
+   }
+};
+
+/**
+ * Clones an object, array, or string/number. If cloning an object, the keys
+ * will be sorted.
+ * 
+ * @param value the value to clone.
+ * 
+ * @return the cloned value.
+ */
+var _clone = function(value)
+{
+   var rval;
+   
+   if(value.constructor === Object)
+   {
+      rval = {};
+      var keys = Object.keys(value).sort();
+      for(var i in keys)
+      {
+         var key = keys[i];
+         rval[key] = _clone(value[key]);
+      }
+   }
+   else if(value.constructor === Array)
+   {
+      rval = [];
+      for(var i in value)
+      {
+         rval[i] = _clone(value[i]);
+      }
+   }
+   else
+   {
+      rval = value;
+   }
+   
+   return rval;
+};
+
+/**
+ * Gets the keywords from a context.
+ * 
+ * @param ctx the context.
+ * 
+ * @return the keywords.
+ */
+var _getKeywords = function(ctx)
+{
+   // TODO: reduce calls to this function by caching keywords in processor
+   // state
+   
+   var rval =
+   {
+      '@id': '@id',
+      '@language': '@language',
+      '@literal': '@literal',
+      '@type': '@type'
+   };
+   
+   if(ctx)
+   {
+      // gather keyword aliases from context
+      var keywords = {};
+      for(var key in ctx)
+      {
+         if(ctx[key].constructor === String && ctx[key] in rval)
+         {
+            keywords[ctx[key]] = key;
+         }
+      }
+      
+      // overwrite keywords
+      for(var key in keywords)
+      {
+         rval[key] = keywords[key];
+      }
+   }
+   
+   return rval;
+};
+
+/**
+ * Gets the iri associated with a term.
+ * 
+ * @param ctx the context.
+ * @param term the term.
+ * 
+ * @return the iri or NULL.
+ */
+var _getTermIri = function(ctx, term)
+{
+   var rval = null;
+   if(term in ctx)
+   {
+      if(ctx[term].constructor === String)
+      {
+         rval = ctx[term];
+      }
+      else if(ctx[term].constructor === Object && '@id' in ctx[term])
+      {
+         rval = ctx[term]['@id'];
+      }
+   }
+   return rval;
+};
+
+/**
+ * Compacts an IRI into a term or prefix if it can be. IRIs will not be
+ * compacted to relative IRIs if they match the given context's default
+ * vocabulary.
+ *
+ * @param ctx the context to use.
+ * @param iri the IRI to compact.
+ * @param usedCtx a context to update if a value was used from "ctx".
+ *
+ * @return the compacted IRI as a term or prefix or the original IRI.
+ */
+var _compactIri = function(ctx, iri, usedCtx)
+{
+   var rval = null;
+   
+   // check the context for a term that could shorten the IRI
+   // (give preference to terms over prefixes)
+   for(var key in ctx)
+   {
+      // skip special context keys (start with '@')
+      if(key.length > 0 && key[0] !== '@')
+      {
+         // compact to a term
+         if(iri === _getTermIri(ctx, key))
+         {
+            rval = key;
+            if(usedCtx !== null)
+            {
+               usedCtx[key] = _clone(ctx[key]);
+            }
+            break;
+         }
+      }
+   }
+   
+   // term not found, if term is @type, use keyword
+   if(rval === null && iri === '@type')
+   {
+      rval = _getKeywords(ctx)['@type'];
+   }
+   
+   // term not found, check the context for a prefix
+   if(rval === null)
+   {
+      for(var key in ctx)
+      {
+         // skip special context keys (start with '@')
+         if(key.length > 0 && key[0] !== '@')
+         {
+            // see if IRI begins with the next IRI from the context
+            var ctxIri = _getTermIri(ctx, key);
+            if(ctxIri !== null)
+            {
+               var idx = iri.indexOf(ctxIri);
+               
+               // compact to a prefix
+               if(idx === 0 && iri.length > ctxIri.length)
+               {
+                  rval = key + ':' + iri.substr(ctxIri.length);
+                  if(usedCtx !== null)
+                  {
+                     usedCtx[key] = _clone(ctx[key]);
+                  }
+                  break;
+               }
+            }
+         }
+      }
+   }
+
+   // could not compact IRI
+   if(rval === null)
+   {
+      rval = iri;
+   }
+
+   return rval;
+};
+
+/**
+ * Expands a term into an absolute IRI. The term may be a regular term, a
+ * prefix, a relative IRI, or an absolute IRI. In any case, the associated
+ * absolute IRI will be returned.
+ *
+ * @param ctx the context to use.
+ * @param term the term to expand.
+ * @param usedCtx a context to update if a value was used from "ctx".
+ *
+ * @return the expanded term as an absolute IRI.
+ */
+var _expandTerm = function(ctx, term, usedCtx)
+{
+   var rval = term;
+   
+   // get JSON-LD keywords
+   var keywords = _getKeywords(ctx);
+   
+   // 1. If the property has a colon, it is a prefix or an absolute IRI:
+   var idx = term.indexOf(':');
+   if(idx !== -1)
+   {
+      // get the potential prefix
+      var prefix = term.substr(0, idx);
+
+      // expand term if prefix is in context, otherwise leave it be
+      if(prefix in ctx)
+      {
+         // prefix found, expand property to absolute IRI
+         var iri = _getTermIri(ctx, prefix);
+         rval = iri + term.substr(idx + 1);
+         if(usedCtx !== null)
+         {
+            usedCtx[prefix] = _clone(ctx[prefix]);
+         }
+      }
+   }
+   // 2. If the property is in the context, then it's a term.
+   else if(term in ctx)
+   {
+      rval = _getTermIri(ctx, term);
+      if(usedCtx !== null)
+      {
+         usedCtx[term] = _clone(ctx[term]);
+      }
+   }
+   // 3. The property is a keyword.
+   else
+   {
+      for(var key in keywords)
+      {
+         if(term === keywords[key])
+         {
+            rval = key;
+            break;
+         }
+      }
+   }
+   
+   return rval;
+};
+
+/**
+ * Sorts the keys in a context.
+ * 
+ * @param ctx the context to sort.
+ * 
+ * @return the sorted context.
+ */
+var _sortContextKeys = function(ctx)
+{
+   // sort keys
+   var rval = {};
+   var keys = Object.keys(ctx).sort();
+   for(var k in keys)
+   {
+      var key = keys[k];
+      rval[key] = ctx[key];
+   }
+   return rval;
+};
+
+/**
+ * Gets whether or not a value is a reference to a subject (or a subject with
+ * no properties).
+ * 
+ * @param value the value to check.
+ * 
+ * @return true if the value is a reference to a subject, false if not.
+ */
+var _isReference = function(value)
+{
+   // Note: A value is a reference to a subject if all of these hold true:
+   // 1. It is an Object.
+   // 2. It is has an @id key.
+   // 3. It has only 1 key.
+   return (value !== null &&
+      value.constructor === Object &&
+      '@id' in value &&
+      Object.keys(value).length === 1);
+};
+
+/**
+ * Gets whether or not a value is a subject with properties.
+ * 
+ * @param value the value to check.
+ * 
+ * @return true if the value is a subject with properties, false if not.
+ */
+var _isSubject = function(value)
+{
+   var rval = false;
+   
+   // Note: A value is a subject if all of these hold true:
+   // 1. It is an Object.
+   // 2. It is not a literal.
+   // 3. It has more than 1 key OR any existing key is not '@id'.
+   if(value !== null && value.constructor === Object && !('@literal' in value))
+   {
+      var keyCount = Object.keys(value).length;
+      rval = (keyCount > 1 || !('@id' in value));
+   }
+   
+   return rval;
+};
+
+/*
+ * JSON-LD API.
+ */
+
+/**
+ * Normalizes a JSON-LD object.
+ *
+ * @param input the JSON-LD object to normalize.
+ * 
+ * @return the normalized JSON-LD object.
+ */
+jsonld.normalize = function(input)
+{
+   return new Processor().normalize(input);
+};
+
+/**
+ * Removes the context from a JSON-LD object, expanding it to full-form.
+ *
+ * @param input the JSON-LD object to remove the context from.
+ * 
+ * @return the context-neutral JSON-LD object.
+ */
+jsonld.expand = function(input)
+{
+   return new Processor().expand({}, null, input);
+};
+
+/**
+ * Expands the given JSON-LD object and then compacts it using the
+ * given context.
+ *
+ * @param ctx the new context to use.
+ * @param input the input JSON-LD object.
+ * 
+ * @return the output JSON-LD object.
+ */
+jsonld.compact = function(ctx, input)
+{
+   var rval = null;
+   
+   // TODO: should context simplification be optional? (ie: remove context
+   // entries that are not used in the output)
+
+   if(input !== null)
+   {
+      // fully expand input
+      input = jsonld.expand(input);
+      
+      var tmp;
+      if(input.constructor === Array)
+      {
+         rval = [];
+         tmp = input;
+      }
+      else
+      {
+         tmp = [input];
+      }
+      
+      // merge context if it is an array
+      if(ctx.constructor === Array)
+      {
+         ctx = jsonld.mergeContexts({}, ctx);
+      }
+      
+      for(var i in tmp)
+      {
+         // setup output context
+         var ctxOut = {};
+         
+         // compact
+         var out = new Processor().compact(_clone(ctx), null, tmp[i], ctxOut);
+         
+         // add context if used
+         if(Object.keys(ctxOut).length > 0)
+         {
+            // sort context keys
+            ctxOut = _sortContextKeys(ctxOut);
+            
+            // sort keys
+            var keys = Object.keys(out);
+            keys.sort();
+            
+            // put @context first
+            keys.unshift('@context');
+            out['@context'] = ctxOut;
+            
+            // order keys in output
+            var ordered = {};
+            for(var k in keys)
+            {
+               var key = keys[k];
+               ordered[key] = out[key];
+            }
+            out = ordered;
+         }
+         
+         if(rval === null)
+         {
+            rval = out;
+         }
+         else
+         {
+            rval.push(out);
+         }
+      }
+   }
+
+   return rval;
+};
+
+/**
+ * Merges one context with another.
+ *
+ * @param ctx1 the context to overwrite/append to.
+ * @param ctx2 the new context to merge onto ctx1.
+ *
+ * @return the merged context.
+ */
+jsonld.mergeContexts = function(ctx1, ctx2)
+{
+   // merge first context if it is an array
+   if(ctx1.constructor === Array)
+   {
+      ctx1 = jsonld.mergeContexts({}, ctx1);
+   }
+   
+   // copy context to merged output
+   var merged = _clone(ctx1);
+   
+   if(ctx2.constructor === Array)
+   {
+      // merge array of contexts in order
+      for(var i in ctx2)
+      {
+         merged = jsonld.mergeContexts(merged, ctx2[i]);
+      }
+   }
+   else
+   {
+      // if the new context contains any IRIs that are in the merged context,
+      // remove them from the merged context, they will be overwritten
+      for(var key in ctx2)
+      {
+         // ignore special keys starting with '@'
+         if(key.indexOf('@') !== 0)
+         {
+            for(var mkey in merged)
+            {
+               if(merged[mkey] === ctx2[key])
+               {
+                  // FIXME: update related coerce rules
+                  delete merged[mkey];
+                  break;
+               }
+            }
+         }
+      }
+   
+      // merge contexts
+      for(var key in ctx2)
+      {
+         merged[key] = _clone(ctx2[key]);
+      }
+   }
+
+   return merged;
+};
+
+/**
+ * Expands a term into an absolute IRI. The term may be a regular term, a
+ * prefix, a relative IRI, or an absolute IRI. In any case, the associated
+ * absolute IRI will be returned.
+ *
+ * @param ctx the context to use.
+ * @param term the term to expand.
+ *
+ * @return the expanded term as an absolute IRI.
+ */
+jsonld.expandTerm = _expandTerm;
+
+/**
+ * Compacts an IRI into a term or prefix if it can be. IRIs will not be
+ * compacted to relative IRIs if they match the given context's default
+ * vocabulary.
+ *
+ * @param ctx the context to use.
+ * @param iri the IRI to compact.
+ *
+ * @return the compacted IRI as a term or prefix or the original IRI.
+ */
+jsonld.compactIri = function(ctx, iri)
+{
+   return _compactIri(ctx, iri, null);
+};
+
+/**
+ * Frames JSON-LD input.
+ * 
+ * @param input the JSON-LD input.
+ * @param frame the frame to use.
+ * @param options framing options to use.
+ * 
+ * @return the framed output.
+ */
+jsonld.frame = function(input, frame, options)
+{
+   return new Processor().frame(input, frame, options);
+};
+
+/**
+ * Generates triples given a JSON-LD input. Each triple that is generated
+ * results in a call to the given callback. The callback takes 3 parameters:
+ * subject, property, and object. If the callback returns false then this
+ * method will stop generating triples and return. If the callback is null,
+ * then an array with triple objects containing "s", "p", "o" properties will
+ * be returned.
+ * 
+ * The object or "o" property will be a JSON-LD formatted object.
+ * 
+ * @param input the JSON-LD input.
+ * @param callback the triple callback.
+ * 
+ * @return an array of triple objects if callback is null, null otherwise.
+ */
+jsonld.toTriples = function(input, graph, callback)
+{
+   var rval = null;
+   
+   // normalize input
+   var normalized = jsonld.normalize(input);
+   
+   // setup default callback
+   callback = callback || null;
+   if(callback === null)
+   {
+      rval = [];
+      callback = function(s, p, o)
+      {
+         rval.push({'subject': Utils.lexicalFormTerm(s), 
+                    'predicate': Utils.lexicalFormTerm(p), 
+                    'object': Utils.lexicalFormTerm(o), 
+                    'graph': graph});
+      };
+   }
+   
+   // generate triples
+   var quit = false;
+   for(var i1 in normalized)
+   {
+      var e = normalized[i1];
+      var s = e['@id'];
+       if(s[0] == "_") {
+           s = {'token':'blank', 'value':s.split(":")[1]};
+       } else {
+           s = {'token':'uri', 'value':s};
+       }
+
+      for(var p in e)
+      {
+         if(p !== '@id')
+         {
+	     var obj = e[p];
+             if(obj.constructor !== Array)
+             {
+		 obj = [obj];
+             }
+            for(var i2 in obj)
+            {
+                var obji2 = obj[i2];
+		if(p === '@type' || p === 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type') {
+		    p = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type';
+                    obji2 = {'token':'uri', 'value':obji2};		    
+                } else if(typeof(obji2) === 'string') {
+                    obji2 = {'token': 'literal', 'value':obji2};
+                } else if(obji2['@id'] != null) {
+                    if(obji2['@id'][0] == "_") {
+                        obji2 = {'token':'blank', 'value':obji2['@id'].split(":")[1]};
+                    } else {
+                        obji2 = {'token':'uri', 'value':obji2['@id']};
+                    }
+                } else if(obji2['@type'] != null) {
+                    obji2 = {'token':'literal', 'value':obji2['@literal'], 'type':obji2['@type']};
+                } else if(obji2['@language'] != null) {
+                    obji2 = {'token':'literal', 'value':obji2['@literal'], 'lang':obji2['@language']};
+                }
+
+		quit = (callback(s, {'token':'uri', 'value':p}, obji2) === false);
+		if(quit)
+		{
+                    break;
+		}
+            }
+            if(quit)
+            {
+               break;
+            }
+         }
+      }
+      if(quit)
+      {
+         break;
+      }
+   }
+   
+   return rval;
+};
+
+/**
+ * Resolves external @context URLs. Every @context URL in the given JSON-LD
+ * object is resolved using the given URL-resolver function. Once all of
+ * the @contexts have been resolved, the given result callback is invoked.
+ * 
+ * @param input the JSON-LD input object (or array).
+ * @param resolver the resolver method that takes a URL and a callback that
+ *           receives a JSON-LD serialized @context or null on error (with
+ *           optional an error object as the second parameter).
+ * @param callback the callback to be invoked with the fully-resolved
+ *           JSON-LD output (object or array) or null on error (with an
+ *           optional error array as the second parameter).
+ */
+jsonld.resolve = function(input, resolver, callback)
+{
+   // find all @context URLs
+   var urls = {};
+   var findUrls = function(input, replace)
+   {
+      if(input.constructor === Array)
+      {
+         for(var i in input)
+         {
+            findUrls(input[i]);
+         }
+      }
+      else if(input.constructor === Object)
+      {
+         for(var key in input)
+         {
+            if(key === '@context')
+            {
+               // @context is an array that might contain URLs
+               if(input[key].constructor === Array)
+               {
+                  var list = input[key];
+                  for(var i in list)
+                  {
+                     if(list[i].constructor === String)
+                     {
+                        // replace w/resolved @context if appropriate
+                        if(replace)
+                        {
+                           list[i] = urls[list[i]];
+                        }
+                        // unresolved @context found
+                        else
+                        {
+                           urls[list[i]] = {};
+                        }
+                     }
+                  }
+               }
+               else if(input[key].constructor === String)
+               {
+                  // replace w/resolved @context if appropriate
+                  if(replace)
+                  {
+                     input[key] = urls[input[key]];
+                  }
+                  // unresolved @context found
+                  else
+                  {
+                     urls[input[key]] = {};
+                  }
+               }
+            }
+         }
+      }
+   };
+   findUrls(input, false);
+   
+   // state for resolving URLs
+   var count = Object.keys(urls).length;
+   var errors = null;
+   
+   if(count === 0)
+   {
+      callback(input, errors);
+   }
+   else
+   {
+      // resolve all URLs
+      for(var url in urls)
+      {
+         resolver(url, function(result, error)
+         {
+            --count;
+            
+            if(result === null)
+            {
+               errors = errors || [];
+               errors.push({ url: url, error: error });
+            }
+            else
+            {
+               try
+               {
+                  if(result.constructor === String)
+                  {
+                     urls[url] = JSON.parse(result)['@context'];
+                  }
+                  else
+                  {
+                     urls[url] = result['@context'];
+                  }
+               }
+               catch(ex)
+               {
+                  errors = errors || [];
+                  errors.push({ url: url, error: ex });
+               }
+            }
+            
+            if(count === 0)
+            {
+               if(errors === null)
+               {
+                  findUrls(input, true);
+               }
+               callback(input, errors);
+            }
+         });
+      }
+   }
+};
+
+// TODO: organizational rewrite
+
+/**
+ * Constructs a new JSON-LD processor.
+ */
+var Processor = function()
+{
+};
+
+/**
+ * Recursively compacts a value. This method will compact IRIs to prefixes or
+ * terms and do reverse type coercion to compact a value.
+ *
+ * @param ctx the context to use.
+ * @param property the property that points to the value, NULL for none.
+ * @param value the value to compact.
+ * @param usedCtx a context to update if a value was used from "ctx".
+ *
+ * @return the compacted value.
+ */
+Processor.prototype.compact = function(ctx, property, value, usedCtx)
+{
+   var rval;
+   
+   // get JSON-LD keywords
+   var keywords = _getKeywords(ctx);
+   
+   if(value === null)
+   {
+      // return null, but check coerce type to add to usedCtx
+      rval = null;
+      this.getCoerceType(ctx, property, usedCtx);
+   }
+   else if(value.constructor === Array)
+   {
+      // recursively add compacted values to array
+      rval = [];
+      for(var i in value)
+      {
+         rval.push(this.compact(ctx, property, value[i], usedCtx));
+      }
+   }
+   // graph literal/disjoint graph
+   else if(
+      value.constructor === Object &&
+      '@id' in value && value['@id'].constructor === Array)
+   {
+      rval = {};
+      rval[keywords['@id']] = this.compact(
+         ctx, property, value['@id'], usedCtx);
+   }
+   // recurse if value is a subject
+   else if(_isSubject(value))
+   {
+      // recursively handle sub-properties that aren't a sub-context
+      rval = {};
+      for(var key in value)
+      {
+         if(value[key] !== '@context')
+         {
+            // set object to compacted property, only overwrite existing
+            // properties if the property actually compacted
+            var p = _compactIri(ctx, key, usedCtx);
+            if(p !== key || !(p in rval))
+            {
+               // FIXME: clean old values from the usedCtx here ... or just
+               // change usedCtx to be built at the end of processing?
+               rval[p] = this.compact(ctx, key, value[key], usedCtx);
+            }
+         }
+      }
+   }
+   else
+   {
+      // get coerce type
+      var coerce = this.getCoerceType(ctx, property, usedCtx);
+      
+      // get type from value, to ensure coercion is valid
+      var type = null;
+      if(value.constructor === Object)
+      {
+         // type coercion can only occur if language is not specified
+         if(!('@language' in value))
+         {
+            // type must match coerce type if specified
+            if('@type' in value)
+            {
+               type = value['@type'];
+            }
+            // type is ID (IRI)
+            else if('@id' in value)
+            {
+               type = '@id';
+            }
+            // can be coerced to any type
+            else
+            {
+               type = coerce;
+            }
+         }
+      }
+      // type can be coerced to anything
+      else if(value.constructor === String)
+      {
+         type = coerce;
+      }
+
+      // types that can be auto-coerced from a JSON-builtin
+      if(coerce === null &&
+         (type === xsd['boolean'] || type === xsd['integer'] ||
+         type === xsd['double']))
+      {
+         coerce = type;
+      }
+
+      // do reverse type-coercion
+      if(coerce !== null)
+      {
+         // type is only null if a language was specified, which is an error
+         // if type coercion is specified
+         if(type === null)
+         {
+            throw {
+               message: 'Cannot coerce type when a language is specified. ' +
+                  'The language information would be lost.'
+            };
+         }
+         // if the value type does not match the coerce type, it is an error
+         else if(type !== coerce)
+         {
+            throw new Exception({
+               message: 'Cannot coerce type because the type does ' +
+                  'not match.',
+               type: type,
+               expected: coerce
+            });
+         }
+         // do reverse type-coercion
+         else
+         {
+            if(value.constructor === Object)
+            {
+               if('@id' in value)
+               {
+                  rval = value['@id'];
+               }
+               else if('@literal' in value)
+               {
+                  rval = value['@literal'];
+               }
+            }
+            else
+            {
+               rval = value;
+            }
+
+            // do basic JSON types conversion
+            if(coerce === xsd['boolean'])
+            {
+               rval = (rval === 'true' || rval != 0);
+            }
+            else if(coerce === xsd['double'])
+            {
+               rval = parseFloat(rval);
+            }
+            else if(coerce === xsd['integer'])
+            {
+               rval = parseInt(rval);
+            }
+         }
+      }
+      // no type-coercion, just change keywords/copy value
+      else if(value.constructor === Object)
+      {
+         rval = {};
+         for(var key in value)
+         {
+            rval[keywords[key]] = value[key];
+         }
+      }
+      else
+      {
+         rval = _clone(value);
+      }
+
+      // compact IRI
+      if(type === '@id')
+      {
+         if(rval.constructor === Object)
+         {
+            rval[keywords['@id']] = _compactIri(
+               ctx, rval[keywords['@id']], usedCtx);
+         }
+         else
+         {
+            rval = _compactIri(ctx, rval, usedCtx);
+         }
+      }
+   }
+
+   return rval;
+};
+
+/**
+ * Recursively expands a value using the given context. Any context in
+ * the value will be removed.
+ *
+ * @param ctx the context.
+ * @param property the property that points to the value, NULL for none.
+ * @param value the value to expand.
+ *
+ * @return the expanded value.
+ */
+Processor.prototype.expand = function(ctx, property, value)
+{
+   var rval;
+   
+   // TODO: add data format error detection?
+   
+   // value is null, nothing to expand
+   if(value === null)
+   {
+      rval = null;
+   }
+   // if no property is specified and the value is a string (this means the
+   // value is a property itself), expand to an IRI
+   else if(property === null && value.constructor === String)
+   {
+      rval = _expandTerm(ctx, value, null);
+   }
+   else if(value.constructor === Array)
+   {
+      // recursively add expanded values to array
+      rval = [];
+      for(var i in value)
+      {
+         rval.push(this.expand(ctx, property, value[i]));
+      }
+   }
+   else if(value.constructor === Object)
+   {
+      // if value has a context, use it
+      if('@context' in value)
+      {
+         ctx = jsonld.mergeContexts(ctx, value['@context']);
+      }
+      
+      // recursively handle sub-properties that aren't a sub-context
+      rval = {};
+      for(var key in value)
+      {
+         // preserve frame keywords
+         if(key === '@embed' || key === '@explicit' ||
+            key === '@default' || key === '@omitDefault')
+         {
+            _setProperty(rval, key, _clone(value[key]));
+         }
+         else if(key !== '@context')
+         {
+

<TRUNCATED>

[7/7] git commit: Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/clerezza

Posted by re...@apache.org.
Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/clerezza


Project: http://git-wip-us.apache.org/repos/asf/clerezza/repo
Commit: http://git-wip-us.apache.org/repos/asf/clerezza/commit/0531034b
Tree: http://git-wip-us.apache.org/repos/asf/clerezza/tree/0531034b
Diff: http://git-wip-us.apache.org/repos/asf/clerezza/diff/0531034b

Branch: refs/heads/master
Commit: 0531034bfbf0b0391931f5ac79b7515a52da8748
Parents: be30bfb 4851891
Author: Reto Bachmann-Gmür <re...@apache.org>
Authored: Wed Jun 4 23:53:46 2014 +0200
Committer: Reto Bachmann-Gmür <re...@apache.org>
Committed: Wed Jun 4 23:53:46 2014 +0200

----------------------------------------------------------------------
 provisioning/launchers/full-launcher/pom.xml    |   7 +
 .../launchers/linked-data-launcher/pom.xml      |   8 +
 .../launchers/typerendering-launcher/pom.xml    |   7 +
 provisioning/pom.xml                            |   1 +
 provisioning/rdf.tdb/pom.xml                    | 207 +++++++++++++++++++
 provisioning/rdf/pom.xml                        |   8 +-
 6 files changed, 234 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/clerezza/blob/0531034b/provisioning/launchers/full-launcher/pom.xml
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/clerezza/blob/0531034b/provisioning/pom.xml
----------------------------------------------------------------------


[6/7] git commit: CLEREZZA-815: added platform.tools

Posted by re...@apache.org.
CLEREZZA-815: added platform.tools


Project: http://git-wip-us.apache.org/repos/asf/clerezza/repo
Commit: http://git-wip-us.apache.org/repos/asf/clerezza/commit/be30bfbd
Tree: http://git-wip-us.apache.org/repos/asf/clerezza/tree/be30bfbd
Diff: http://git-wip-us.apache.org/repos/asf/clerezza/diff/be30bfbd

Branch: refs/heads/master
Commit: be30bfbd0cd8268c3c2f6ebd6cf0665c24d53041
Parents: 61328c2
Author: Reto Bachmann-Gmür <re...@apache.org>
Authored: Wed Jun 4 23:53:42 2014 +0200
Committer: Reto Bachmann-Gmür <re...@apache.org>
Committed: Wed Jun 4 23:53:42 2014 +0200

----------------------------------------------------------------------
 provisioning/launchers/full-launcher/pom.xml |  6 +++++
 provisioning/platform.tools/pom.xml          | 30 ++++++++++-------------
 provisioning/pom.xml                         |  1 +
 provisioning/shell/pom.xml                   |  1 -
 4 files changed, 20 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/clerezza/blob/be30bfbd/provisioning/launchers/full-launcher/pom.xml
----------------------------------------------------------------------
diff --git a/provisioning/launchers/full-launcher/pom.xml b/provisioning/launchers/full-launcher/pom.xml
index 23a0f1d..debd1df 100644
--- a/provisioning/launchers/full-launcher/pom.xml
+++ b/provisioning/launchers/full-launcher/pom.xml
@@ -288,6 +288,12 @@
         </dependency>
         <dependency>
             <groupId>org.apache.clerezza.provisioning</groupId>
+            <artifactId>platform.tools</artifactId>
+            <version>0.1-SNAPSHOT</version>
+            <type>partialbundlelist</type>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.clerezza.provisioning</groupId>
             <artifactId>security</artifactId>
             <version>0.1-SNAPSHOT</version>
             <type>partialbundlelist</type>

http://git-wip-us.apache.org/repos/asf/clerezza/blob/be30bfbd/provisioning/platform.tools/pom.xml
----------------------------------------------------------------------
diff --git a/provisioning/platform.tools/pom.xml b/provisioning/platform.tools/pom.xml
index d6ce139..5db466d 100644
--- a/provisioning/platform.tools/pom.xml
+++ b/provisioning/platform.tools/pom.xml
@@ -32,13 +32,13 @@
     </parent>
     
     <groupId>org.apache.clerezza.provisioning</groupId>
-    <artifactId>platform.content</artifactId>
+    <artifactId>platform.tools</artifactId>
     <version>0.1-SNAPSHOT</version>
     <packaging>feature</packaging>
 
-    <name>Clerezza - Provisioning - Platform Content</name>
+    <name>Clerezza - Provisioning - Platform Tools</name>
     <description>A Karaf feature and partialbundlelist with the bundles providing 
-        the clerezza content functionality.
+        clerezza platfotm tools such as the editor.
     
         This feature depends on java and OSGi platform libraries (javax.xml,
         org.osgi.service.cm and others), slf4j logging
@@ -46,31 +46,27 @@
         - rdf.web
         - platform.graphnodprovider
         - typerendering
-        - typehandlerspace   
+        - typehandlerspace
+        - platform.content   
+        - shell
     </description>
 
     <dependencies>
         <dependency>
             <groupId>org.apache.clerezza</groupId>
-            <artifactId>platform.content</artifactId>
-            <version>0.14-SNAPSHOT</version>
-        </dependency>
+            <artifactId>platform.editor</artifactId>
+            <version>0.1-SNAPSHOT</version>
+        </dependency>   
         <dependency>
             <groupId>org.apache.clerezza</groupId>
-            <artifactId>platform.content.default404</artifactId>
+            <artifactId>platform.shellcustomizer</artifactId>
             <version>0.2-SNAPSHOT</version>
-        </dependency>
+        </dependency>        
         <dependency>
             <groupId>org.apache.clerezza</groupId>
-            <artifactId>platform.content.fsadaptor</artifactId>
+            <artifactId>bundledevtool</artifactId>
             <version>0.2-SNAPSHOT</version>
-        </dependency>
-        <!-- this doesn't strictly belongs to here -->
-        <dependency>
-            <groupId>org.apache.stanbol</groupId>
-            <artifactId>org.apache.stanbol.commons.web.resources</artifactId>
-            <version>0.12.0</version>
-        </dependency>
+        </dependency> 
     </dependencies>
 
     <build>

http://git-wip-us.apache.org/repos/asf/clerezza/blob/be30bfbd/provisioning/pom.xml
----------------------------------------------------------------------
diff --git a/provisioning/pom.xml b/provisioning/pom.xml
index 31587b2..c0f2f75 100644
--- a/provisioning/pom.xml
+++ b/provisioning/pom.xml
@@ -53,6 +53,7 @@
         <module>typerendering</module>
         <module>rdf.web</module>
         <module>platform.content</module>
+        <module>platform.tools</module>
         <module>shell</module>
         <module>security</module>
         <module>launchers</module>

http://git-wip-us.apache.org/repos/asf/clerezza/blob/be30bfbd/provisioning/shell/pom.xml
----------------------------------------------------------------------
diff --git a/provisioning/shell/pom.xml b/provisioning/shell/pom.xml
index 9f397c8..c795350 100644
--- a/provisioning/shell/pom.xml
+++ b/provisioning/shell/pom.xml
@@ -124,7 +124,6 @@
         <dependency>
             <groupId>org.apache.stanbol</groupId>
             <artifactId>org.apache.stanbol.commons.security.core</artifactId>
-            <version>0.11.0</version>
         </dependency>
         
         <dependency> <!-- this give the system graph required by org.apache.stanbol.commons.security.core-->