You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@marmotta.apache.org by wi...@apache.org on 2013/02/19 13:52:02 UTC

[2/52] [partial] code contribution, initial import of relevant modules of LMF-3.0.0-SNAPSHOT based on revision 4bf944319368 of the default branch at https://code.google.com/p/lmf/

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c32963d5/lmf-core/src/main/resources/web/admin/js/lib/sgvizler.pack.js
----------------------------------------------------------------------
diff --git a/lmf-core/src/main/resources/web/admin/js/lib/sgvizler.pack.js b/lmf-core/src/main/resources/web/admin/js/lib/sgvizler.pack.js
new file mode 100644
index 0000000..00706a7
--- /dev/null
+++ b/lmf-core/src/main/resources/web/admin/js/lib/sgvizler.pack.js
@@ -0,0 +1,1292 @@
+/*  Sgvizler JavaScript SPARQL result set visualizer, version 0.5.1
+ *  (c) 2011--2012 Martin G. Skjæveland
+ *
+ *  Sgvizler is freely distributable under the terms of an MIT-style license.
+ *  Sgvizler web site: https://code.google.com/p/sgvizler/
+ *--------------------------------------------------------------------------*/
+(function (global) {
+    "use strict";
+
+    /*global google, $, jQuery */
+    /*jslint browser: true */
+
+    var sgvizler = {
+
+        go: function (callback) {
+            this.loadLibs();
+
+            google.load('visualization',
+                        '1.0',
+                        {'packages':
+                         ['annotatedtimeline',
+                          'corechart',
+                          'gauge',
+                          'geomap',
+                          'geochart',
+                          'imagesparkline',
+                          'map',
+                          'orgchart',
+                          'table',
+                          'motionchart',
+                          'treemap'
+                         ]
+                        }
+                       );
+
+            google.setOnLoadCallback(function () {
+                sgvizler.charts.loadCharts();
+                sgvizler.drawFormQuery();
+                sgvizler.drawContainerQueries();
+                callback();
+            });
+        },
+
+        loadLibs: function () {
+            var i, libs = ['d3.v2.min.js', 'raphael-dracula.pack.min.js'];
+            if (sgvizler.ui.isElement(sgvizler.ui.id.script)) {
+                this.option.homefolder = $('#' + sgvizler.ui.id.script).attr('src').replace(/sgvizler\.pack\.js$/, "");
+                this.option.libfolder = this.option.homefolder + "/js/lib/";
+            }
+            // load "child" scripts
+            for (i = 0; i < libs.length; i += 1) {
+                $.ajax(this.option.libfolder + libs[i], { dataType: "script", async: false });
+            }
+
+            // load stylesheet
+            $('head').append('<link rel="stylesheet" href="' + this.option.homefolder + 'sgvizler.chart.css" type="text/css" />');
+        },
+
+        drawFormQuery: function () {
+            var query = new sgvizler.query(sgvizler.ui.id.chartCon),
+                params = sgvizler.ui.getUrlParams();
+            $.extend(query,
+                     sgvizler.option.query,
+                     { query: params.query, chart: params.chart });
+
+            if (sgvizler.ui.isElement(query.container) && query.query) {
+                $.extend(query.chartOptions,
+                         { width: params.width, height: params.height });
+                query.draw();
+            }
+            sgvizler.ui.displayUI(query);
+        },
+
+        drawContainerQueries: function () {
+            $('[' + this.ui.attr.prefix + 'query]').each(function () {
+                var query = new sgvizler.query();
+                $.extend(query,
+                         sgvizler.option.query,
+                         sgvizler.ui.getQueryOptionAttr(this));
+                $.extend(query.chartOptions,
+                         sgvizler.ui.getChartOptionAttr(this));
+                query.draw();
+            });
+        },
+
+        // kept in separate files:
+        option: {},   // settings, global variables.
+        chart: {},    // the set of user-defined rendering functions.
+        charts: {},   // functions for handling rendering functions.
+        parser: {},   // SPARQL results XML/JSON parser.
+        ui: {}       // html get/set functions.
+    };
+
+    jQuery.ajaxSetup({
+        accepts: {
+            xml:  "application/sparql-results+xml",
+            json: "application/sparql-results+json"
+        }
+    });
+    sgvizler.option = {
+
+        home: (window.location.href).replace(window.location.search, ""),
+        homefolder: "",
+        libfolder: "/lib/",
+
+        //// Prefixes included in queries:
+        namespace: {
+            '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#"
+        },
+
+        query: {}, // holds options set by user in html file.
+        chart: {}  // ditto.
+    };
+    sgvizler.ui = {
+
+        //// #id's to html elements:
+        id: {
+            script:       'sgvzlr_script',    // #id to the script tag for this file
+            chartCon:     'sgvzlr_gchart',    // #id to the container to hold the chart
+            queryForm:    'sgvzlr_formQuery', //
+            queryTxt:     'sgvzlr_cQuery',    // query text area.
+            formQuery:    'sgvzlr_strQuery',  // hidden query string. "trick" taken from snorql.
+            formWidth:    'sgvzlr_strWidth',  //
+            formHeight:   'sgvzlr_strHeight', //
+            formChart:    'sgvzlr_optChart',  //
+            prefixCon:    'sgvzlr_cPrefix',   // print prefixes
+            messageCon:   'sgvzlr_cMessage'  // print messages
+        },
+
+        attr: {
+            prefix:      'data-sgvizler-',
+            prefixChart: 'data-sgvizler-chart-options',
+
+            valueAssign: '=',
+            valueSplit:  '|'
+        },
+
+        params: [ 'query', 'chart', 'width', 'height' ], // permissible URL parameters.
+
+        displayUI: function (queryOpt) {
+            this.displayPrefixes();
+            this.displayChartTypesMenu();
+            this.displayUserInput(queryOpt);
+        },
+        displayPrefixes: function () {
+            this.setElementText(this.id.prefixCon, sgvizler.query.prototype.getPrefixes());
+        },
+        displayUserInput: function (queryOpt) {
+            this.setElementValue(this.id.queryTxt, queryOpt.query);
+            this.setElementValue(this.id.formChart, queryOpt.chart);
+            this.setElementValue(this.id.formWidth, queryOpt.chartOptions.width);
+            this.setElementValue(this.id.formHeight, queryOpt.chartOptions.height);
+        },
+        displayChartTypesMenu: function () {
+            var chart,
+                i;
+            if (this.isElement(this.id.formChart)) {
+                chart = sgvizler.charts.all;
+                for (i = 0; i < chart.length; i += 1) {
+                    $('#' + this.id.formChart)
+                        .append($('<option/>')
+                                .val(chart[i].id)
+                                .html(chart[i].id));
+                }
+            }
+        },
+
+        displayFeedback: function (queryOpt, messageName) {
+            var message,
+                container = queryOpt.container;
+            if (queryOpt.container === this.id.chartCon && this.isElement(this.id.messageCon)) {
+                container = this.id.messageCon;
+            }
+
+            if (queryOpt.loglevel === 0) {
+                message = "";
+            } else if (queryOpt.loglevel === 1) {
+                if (messageName === "LOADING") {
+                    message = "Loading...";
+                } else if (messageName === "ERROR_ENDPOINT" || messageName === "ERROR_UNKNOWN") {
+                    message = "Error.";
+                }
+            } else {
+                if (messageName === "LOADING") {
+                    message = "Sending query...";
+                } else if (messageName === "ERROR_ENDPOINT") {
+                    message = "Error querying endpoint. Possible errors:" +
+                        this.html.ul(
+                            this.html.a(queryOpt.endpoint, "SPARQL endpoint") + " down? " +
+                                this.html.a(queryOpt.endpoint + queryOpt.endpoint_query_url + queryOpt.encodedQuery,
+                                            "Check if query runs at the endpoint") + ".",
+                            "Malformed SPARQL query? " +
+                                this.html.a(queryOpt.validator_query_url + queryOpt.encodedQuery, "Check if it validates") + ".",
+                            "CORS supported and enabled? Read more about " +
+                                this.html.a("http://code.google.com/p/sgvizler/wiki/Compatibility", "CORS and compatibility") + ".",
+                            "Is your " + this.html.a("http://code.google.com/p/sgvizler/wiki/Compatibility", "browser support") + "ed?",
+                            "Hmm.. it might be a bug! Please file a report to " +
+                                this.html.a("http://code.google.com/p/sgvizler/issues/", "the issues") + "."
+                        );
+                } else if (messageName === "ERROR_UNKNOWN") {
+                    message = "Unknown error.";
+                } else if (messageName === "NO_RESULTS") {
+                    message = "Query returned no results.";
+                } else if (messageName === "DRAWING") {
+                    message = "Received " + queryOpt.noRows + " rows. Drawing chart...<br/>" +
+                        this.html.a(queryOpt.endpoint + queryOpt.endpoint_query_url + queryOpt.encodedQuery,
+                                    "View query results", "target='_blank'") + " (in new window).";
+                }
+            }
+            this.setElementHTML(container, this.html.tag("p", message));
+        },
+
+        setElementValue: function (elementID, value) {
+            if (this.isElement(elementID)) {
+                $('#' + elementID).val(value);
+            }
+        },
+        setElementText: function (elementID, value) {
+            if (this.isElement(elementID)) {
+                $('#' + elementID).text(value);
+            }
+        },
+        setElementHTML: function (elementID, value) {
+            if (this.isElement(elementID)) {
+                $('#' + elementID).html(value);
+            }
+        },
+        isElement: function (elementID) {
+            return $('#' + elementID).length > 0;
+        },
+
+        getQueryOptionAttr: function (element) {
+            var i,
+                queryOpt = {container: $(element).attr('id')},
+                attr = element.attributes;
+            for (i = 0; i < attr.length; i += 1) {
+                if (attr[i].name.lastIndexOf(this.attr.prefix, 0) === 0) { // starts-with attr.prefix.
+                    queryOpt[attr[i].name.substring(this.attr.prefix.length)] = attr[i].value;
+                }
+            }
+            return queryOpt;
+        },
+        getChartOptionAttr: function (element) {
+            var i,
+                options,
+                assignment,
+                path,
+                o,
+                j,
+                chartOpt = {},
+                attrValue = $(element).attr(sgvizler.ui.attr.prefixChart);
+            if (typeof attrValue !== 'undefined') {
+                options = attrValue.split(this.attr.valueSplit);
+                for (i = 0; i < options.length; i += 1) {
+                    assignment = options[i].split(this.attr.valueAssign);
+                    path = assignment[0].split(".");
+                    o = chartOpt;
+                    for (j = 0; j < path.length - 1; j += 1) {
+                        if (typeof o[path[j]] === 'undefined') {
+                            o[path[j]] = {};
+                        }
+                        o = o[path[j]];
+                    }
+                    o[path[j]] = assignment[1];
+                }
+            }
+            // get width and heigth from css. take only numbers.
+            chartOpt.width = /(\d+)/.exec($(element).css('width'))[1];
+            chartOpt.height = /(\d+)/.exec($(element).css('height'))[1];
+            return chartOpt;
+        },
+
+        getUrlParams: function () {
+            /*jslint regexp: true */
+            var urlParams = {},
+                e,
+                r = /([^&=]+)=?([^&]*)/g, // parameter, value pairs.
+                d = function (s) { return decodeURIComponent(s.replace(/\+/g, " ")); }, // replace '+' with space.
+                q = window.location.search.substring(1); // URL query string part.
+
+            while ((e = r.exec(q))) {
+                if (e[2].length > 0 && this.params.indexOf(e[1]) !== -1) {
+                    urlParams[d(e[1])] = d(e[2]);
+                }
+            }
+            return urlParams;
+        },
+
+        resetPage: function () {
+            document.location = sgvizler.home;
+        },
+        submitQuery: function () {
+            $('#' + this.id.formQuery).val($('#' + this.id.queryTxt).val());
+            $('#' + this.id.queryForm).submit();
+        },
+
+        html: {
+            a: function (href, link, attr) {
+                if (typeof attr === 'undefined') { attr = ""; }
+                if (typeof href !== 'undefined' && typeof link !== 'undefined') {
+                    return "<a " + attr + " href='" + href + "'>" + link + "</a>";
+                }
+            },
+            ul: function () {
+                var i,
+                    txt;
+                if (arguments.length) {
+                    txt = "<ul>";
+                    for (i = 0; i < arguments.length; i += 1) {
+                        txt += "<li>" + arguments[i] + "</li>";
+                    }
+                    return txt + "</ul>";
+                }
+            },
+            tag: function (tag, content) {
+                return "<" + tag + ">" + content + "</" + tag + ">";
+            }
+        }
+    };
+
+    sgvizler.parser = {
+
+        // variable notation: xtable, xcol(s), xrow(s) -- x is 's'(parql) or 'g'(oogle).
+
+        defaultGDatatype: 'string',
+
+        countRowsSparqlXML: function (sxml) {
+            return $(sxml).find('sparql').find('results').find('result').length;
+        },
+
+        countRowsSparqlJSON: function (stable) {
+            if (typeof stable.results.bindings !== 'undefined') {
+                return stable.results.bindings.length;
+            }
+        },
+
+        SparqlXML2GoogleJSON: function (sxml) {
+            var c,
+                r,
+                gcols = [],
+                grows = [],
+                gdatatype = [], // for easy reference of datatypes
+                sresults = $(sxml).find('sparql').find('results').find('result');
+
+            // gcols
+            c = 0;
+            $(sxml).find('sparql').find('head').find('variable').each(function () {
+                var stype = null,
+                    sdatatype = null,
+                    name = $(this).attr('name'),
+                    scell = null,
+                    scells = $(sresults).find('binding[name="' + name + '"]');
+                if (scells.length) {
+                    scell = $(scells).first().children().first()[0]; // uri, literal element
+                    stype = scell.nodeName;
+                    sdatatype = $(scell).attr('datatype');
+                }
+                gdatatype[c] = sgvizler.parser.getGoogleJsonDatatype(stype, sdatatype);
+                gcols[c] = {'id': name, 'label': name, 'type': gdatatype[c]};
+                c += 1;
+            });
+
+            // grows
+            r = 0;
+            $(sresults).each(function () {
+                var gvalue,
+                    scells,
+                    scell,
+                    stype,
+                    svalue,
+                    grow = [];
+                for (c = 0; c < gcols.length; c += 1) {
+                    gvalue = null;
+                    scells = $(this).find('binding[name="' + gcols[c].id + '"]');
+                    if (scells.length &&
+                            typeof $(scells).first().children().first() !== 'undefined' &&
+                            $(scells).first().children().first().firstChild !== null) {
+                        scell = $(scells).first().children().first()[0]; // uri, literal element
+                        stype = scell.nodeName;
+                        svalue = $(scell).first().text();
+                        gvalue = sgvizler.parser.getGoogleJsonValue(svalue, gdatatype[c], stype);
+                    }
+                    grow[c] = {'v': gvalue};
+                }
+                grows[r] = {'c': grow};
+                r += 1;
+            });
+            return {'cols': gcols, 'rows': grows};
+        },
+
+        SparqlJSON2GoogleJSON: function (stable) {
+            var c,
+                r,
+                srow,
+                grow,
+                gvalue,
+                stype,
+                sdatatype,
+                gcols = [],
+                grows = [],
+                gdatatype = [], // for easy reference of datatypes
+                scols = stable.head.vars,
+                srows = stable.results.bindings;
+
+            for (c = 0; c < scols.length; c += 1) {
+                r = 0;
+                stype = null;
+                sdatatype = null;
+                // find a row where there is a value for this column
+                while (typeof srows[r][scols[c]] === 'undefined' && r + 1 < srows.length) { r += 1; }
+                if (typeof srows[r][scols[c]] !== 'undefined') {
+                    stype = srows[r][scols[c]].type;
+                    sdatatype = srows[r][scols[c]].datatype;
+                }
+                gdatatype[c] = this.getGoogleJsonDatatype(stype, sdatatype);
+                gcols[c] = {'id': scols[c], 'label': scols[c], 'type': gdatatype[c]};
+            }
+
+            // loop rows
+            for (r = 0; r < srows.length; r += 1) {
+                srow = srows[r];
+                grow = [];
+                // loop cells
+                for (c = 0; c < scols.length; c += 1) {
+                    gvalue = null;
+                    if (typeof srow[scols[c]] !== 'undefined' &&
+                            typeof srow[scols[c]].value !== 'undefined') {
+                        gvalue = this.getGoogleJsonValue(srow[scols[c]].value, gdatatype[c], srow[scols[c]].type);
+                    }
+                    grow[c] = { 'v': gvalue };
+                }
+                grows[r] = {'c': grow};
+            }
+            return {'cols': gcols, 'rows': grows};
+        },
+
+        getGoogleJsonValue: function (value, gdatatype, stype) {
+            var newvalue;
+            if (gdatatype === 'number') {
+                newvalue = Number(value);
+            } else if (gdatatype === 'date') {
+                //assume format yyyy-MM-dd
+                newvalue = new Date(value.substr(0, 4),
+                                value.substr(5, 2),
+                                value.substr(8, 2));
+            } else if (gdatatype === 'datetime') {
+                //assume format yyyy-MM-ddZHH:mm:ss
+                newvalue = new Date(value.substr(0, 4),
+                                value.substr(5, 2),
+                                value.substr(8, 2),
+                                value.substr(11, 2),
+                                value.substr(14, 2),
+                                value.substr(17, 2));
+            } else if (gdatatype === 'timeofday') {
+                //assume format HH:mm:ss
+                newvalue = [value.substr(0, 2),
+                        value.substr(3, 2),
+                        value.substr(6, 2)];
+            } else { // datatype === 'string' || datatype === 'boolean'
+                if (stype === 'uri') { // replace namespace with prefix
+                    newvalue = this.prefixify(value);
+                }
+                newvalue = value;
+            }
+            return newvalue;
+        },
+
+        getGoogleJsonDatatype: function (stype, sdatatype) {
+            var gdatatype = this.defaultGDatatype,
+                xsdns = sgvizler.option.namespace.xsd;
+            if (typeof stype !== 'undefined' && (stype === 'typed-literal' || stype === 'literal')) {
+                if (sdatatype === xsdns + "float"   ||
+                        sdatatype === xsdns + "double"  ||
+                        sdatatype === xsdns + "decimal" ||
+                        sdatatype === xsdns + "int"     ||
+                        sdatatype === xsdns + "long"    ||
+                        sdatatype === xsdns + "integer") {
+                    gdatatype =  'number';
+                } else if (sdatatype === xsdns + "boolean") {
+                    gdatatype =  'boolean';
+                } else if (sdatatype === xsdns + "date") {
+                    gdatatype =  'date';
+                } else if (sdatatype === xsdns + "dateTime") {
+                    gdatatype =  'datetime';
+                } else if (sdatatype === xsdns + "time") {
+                    gdatatype =  'timeofday';
+                }
+            }
+            return gdatatype;
+        },
+
+        prefixify: function (url) {
+            var ns;
+            for (ns in sgvizler.option.namespace) {
+                if (sgvizler.option.namespace.hasOwnProperty(ns) &&
+                        url.lastIndexOf(sgvizler.option.namespace[ns], 0) === 0) {
+                    return url.replace(sgvizler.option.namespace[ns], ns + ":");
+                }
+            }
+            return url;
+        },
+        unprefixify: function (qname) {
+            var ns;
+            for (ns in sgvizler.option.namespace) {
+                if (sgvizler.option.namespace.hasOwnProperty(ns) &&
+                        qname.lastIndexOf(ns + ":", 0) === 0) {
+                    return qname.replace(ns + ":", sgvizler.option.namespace[ns]);
+                }
+            }
+            return qname;
+        }
+    };
+
+
+    /*global XDomainRequest */
+
+    sgvizler.query = function (container) {
+        this.container = container;
+
+        //defaults
+        this.query = "SELECT ?class (count(?instance) AS ?noOfInstances)\nWHERE{ ?instance a ?class }\nGROUP BY ?class\nORDER BY ?class";
+        this.endpoint = "http://sws.ifi.uio.no/sparql/world";
+        this.endpoint_output = 'json';  // xml, json, jsonp
+        this.endpoint_query_url = "?output=text&amp;query=";
+        this.validator_query_url = "http://www.sparql.org/query-validator?languageSyntax=SPARQL&amp;outputFormat=sparql&amp;linenumbers=true&amp;query=";
+        this.chart = 'gLineChart';
+        this.loglevel = 2;
+
+        this.chartOptions = {
+            'width':           '800',
+            'height':          '400',
+            'chartArea':       { left: '5%', top: '5%', width: '75%', height: '80%' },
+            'gGeoMap': {
+                'dataMode':           'markers'
+            },
+            'gMap': {
+                'dataMode':           'markers'
+            },
+            'sMap': {
+                'dataMode':           'markers',
+                'showTip':            true,
+                'useMapTypeControl':  true
+            },
+            'gSparkline': {
+                'showAxisLines':      false
+            }
+        };
+    };
+
+    sgvizler.query.prototype.draw = function (listeners,options,callback) {
+        var that = this,
+            chartFunc = sgvizler.charts.getChart(this.container, this.chart);
+        this.setChartSpecificOptions();
+        this.insertFrom();
+        $.extend(this.chartOptions,options);
+        this.runQuery(function (data) {
+            var dataTable = new google.visualization.DataTable(that.processQueryResults(data));
+            for(var listener in listeners) {
+                google.visualization.events.addListener(chartFunc, listener, function(){
+                    listeners[listener](chartFunc,dataTable);
+                });
+            }
+            chartFunc.draw(dataTable,that.chartOptions);
+            if(callback)callback(dataTable);
+        });
+    };
+
+    sgvizler.query.prototype.runQuery = function (callback) {
+        var xdr,
+            url,
+            endpoint_output = this.endpoint_output;
+        sgvizler.ui.displayFeedback(this, "LOADING");
+        this.encodedQuery = encodeURIComponent(this.getPrefixes() + this.query);
+        if (this.endpoint_output !== 'jsonp' && $.browser.msie && window.XDomainRequest) {
+            xdr = new XDomainRequest();
+            url = this.endpoint +
+                "?query=" + this.encodedQuery +
+                "&output=" + this.endpoint_output;
+            xdr.open("GET", url);
+            xdr.onload = function () {
+                var data;
+                if (endpoint_output === "xml") {
+                    data = $.parseXML(xdr.responseText);
+                } else {
+                    data = $.parseJSON(xdr.responseText);
+                }
+                callback(data);
+            };
+            xdr.send();
+        } else {
+            $.get(this.endpoint,
+                  { query: this.getPrefixes() + this.query,
+                    output: (this.endpoint_output === 'jsonp') ? 'json' : this.endpoint_output },
+                  function (data) { callback(data); },
+                  this.endpoint_output)
+                .error(function () {
+                    sgvizler.ui.displayFeedback(this, "ERROR_ENDPOINT");
+                });
+        }
+    };
+
+    sgvizler.query.prototype.processQueryResults = function (data) {
+        this.setResultRowCount(data);
+        if (this.noRows === null) {
+            sgvizler.ui.displayFeedback(this, "ERROR_UNKNOWN");
+        } else if (this.noRows === 0) {
+            sgvizler.ui.displayFeedback(this, "NO_RESULTS");
+        } else {
+            sgvizler.ui.displayFeedback(this, "DRAWING");
+            return this.getGoogleJSON(data);
+        }
+    };
+
+    sgvizler.query.prototype.setResultRowCount = function (data) {
+        if (this.endpoint_output === 'xml') {
+            this.noRows = sgvizler.parser.countRowsSparqlXML(data);
+        } else {
+            this.noRows = sgvizler.parser.countRowsSparqlJSON(data);
+        }
+    };
+
+    sgvizler.query.prototype.getGoogleJSON = function (data) {
+        if (this.endpoint_output === 'xml') {
+            data = sgvizler.parser.SparqlXML2GoogleJSON(data);
+        } else {
+            data = sgvizler.parser.SparqlJSON2GoogleJSON(data);
+        }
+        return data;
+    };
+
+    sgvizler.query.prototype.insertFrom = function () {
+        if (typeof this.rdf !== 'undefined') {
+            var i,
+                froms = this.rdf.split(sgvizler.ui.attr.valueSplit),
+                from = "";
+            for (i = 0; i < froms.length; i += 1) {
+                from += 'FROM <' + froms[i] + '>\n';
+            }
+            this.query = this.query.replace(/(WHERE)?(\s)*\{/, '\n' + from + 'WHERE {');
+        }
+    };
+
+    sgvizler.query.prototype.getPrefixes = function () {
+        var prefix,
+            prefixes = "";
+        for (prefix in sgvizler.option.namespace) {
+            if (sgvizler.option.namespace.hasOwnProperty(prefix)) {
+                prefixes += "PREFIX " + prefix + ": <" + sgvizler.option.namespace[prefix] + ">\n";
+            }
+        }
+        return prefixes;
+    };
+
+    sgvizler.query.prototype.setChartSpecificOptions = function () {
+        var level1,
+            level2;
+        for (level1 in this.chartOptions) {
+            if (this.chartOptions.hasOwnProperty(level1) &&
+                    level1 === this.chart) {
+                for (level2 in this.chartOptions[level1]) {
+                    if (this.chartOptions[level1].hasOwnProperty(level2)) {
+                        this.chartOptions[level2] = this.chartOptions[level1][level2];
+                    }
+                }
+            }
+        }
+    };
+
+    sgvizler.charts = {
+        // Package for handling rendering functions. The rendering
+        // functions themselves are kept in sgvizler.chart.*
+
+        all: [],
+
+        loadCharts: function () {
+            var googlecharts = [
+                { 'id': "gLineChart",        'func': google.visualization.LineChart },
+                { 'id': "gAreaChart",        'func': google.visualization.AreaChart },
+                { 'id': "gSteppedAreaChart", 'func': google.visualization.SteppedAreaChart },
+                { 'id': "gPieChart",         'func': google.visualization.PieChart },
+                { 'id': "gBubbleChart",      'func': google.visualization.BubbleChart },
+                { 'id': "gColumnChart",      'func': google.visualization.ColumnChart },
+                { 'id': "gBarChart",         'func': google.visualization.BarChart },
+                { 'id': "gSparkline",        'func': google.visualization.ImageSparkLine },
+                { 'id': "gScatterChart",     'func': google.visualization.ScatterChart },
+                { 'id': "gCandlestickChart", 'func': google.visualization.CandlestickChart },
+                { 'id': "gGauge",            'func': google.visualization.Gauge },
+                { 'id': "gOrgChart",         'func': google.visualization.OrgChart },
+                { 'id': "gTreeMap",          'func': google.visualization.TreeMap },
+                { 'id': "gTimeline",         'func': google.visualization.AnnotatedTimeLine },
+                { 'id': "gMotionChart",      'func': google.visualization.MotionChart },
+                { 'id': "gGeoChart",         'func': google.visualization.GeoChart },
+                { 'id': "gGeoMap",           'func': google.visualization.GeoMap },
+                { 'id': "gMap",              'func': google.visualization.Map },
+                { 'id': "gTable",            'func': google.visualization.Table }
+            ],
+                chart;
+
+            $.merge(this.all, googlecharts);
+            for (chart in sgvizler.chart) {
+                if (sgvizler.chart.hasOwnProperty(chart)) {
+                    this.register(
+                        sgvizler.chart[chart].prototype.id,
+                        sgvizler.chart[chart]
+                    );
+                }
+            }
+        },
+
+        register: function (id, func) {
+            this.all.push({'id': id, 'func': func});
+        },
+
+        getChart: function (containerId, chartId) {
+            var i,
+                container = document.getElementById(containerId);
+            for (i = 0; i < this.all.length; i += 1) {
+                if (chartId === this.all[i].id) {
+                    return new this.all[i].func(container);
+                }
+            }
+        }
+    };
+
+
+    /*global d3 */
+    /** dForceGraph **
+
+
+        D3 force directed graph. Under development.
+    */
+    sgvizler.chart.dForceGraph = function (container) { this.container = container; };
+    sgvizler.chart.dForceGraph.prototype = {
+        id:   "dForceGraph",
+        draw: function (data, chartOpt) {
+            var noColumns = data.getNumberOfColumns(),
+                noRows = data.getNumberOfRows(),
+                opt = $.extend({'maxnodesize': 15, 'minnodesize': 2 }, chartOpt), // set defaults
+                colors = d3.scale.category20(),
+                w = chartOpt.width,
+                h = chartOpt.height,
+                isNumber = function (n) {  return !isNaN(parseFloat(n)) && isFinite(n); },
+
+                // build arrays of nodes and links.
+                nodes = [],
+                edges = [],
+                t_color = {},
+                t_size = {},
+                t_maxnodesize = 0,
+
+                r,
+                source,
+                target,
+
+                nodesizeratio,
+                i,
+                color,
+                size,
+
+                vis,
+                force,
+                link,
+                node,
+                ticks;
+
+            for (r = 0; r < noRows; r += 1) {
+                source = data.getValue(r, 0);
+                target = data.getValue(r, 1);
+                // nodes
+                if (source !== null && $.inArray(source, nodes) === -1) {
+                    nodes.push(source);
+                    t_size[source] = (noColumns > 2) ? Math.sqrt(data.getValue(r, 2)) : 0;
+                    t_color[source] = (noColumns > 3) ? data.getValue(r, 3) : 0;
+                    if (t_size[source] > t_maxnodesize) {
+                        t_maxnodesize = t_size[source];
+                    }
+                }
+                if (target !== null && $.inArray(target, nodes) === -1) {
+                    nodes.push(target);
+                }
+                // edges
+                if (source !== null && target !== null) {
+                    edges.push({'source': $.inArray(source, nodes),
+                                'target': $.inArray(target, nodes)
+                            }
+                        );
+                }
+            }
+            if (t_maxnodesize === 0) {
+                t_maxnodesize = 1;
+            }
+            nodesizeratio = opt.maxnodesize / t_maxnodesize;
+            for (i = 0; i < nodes.length; i += 1) {
+                color = typeof t_color[nodes[i]] !== 'undefined' ?
+                        t_color[nodes[i]] :
+                        1;
+                size = isNumber(t_size[nodes[i]]) ?
+                        opt.minnodesize + t_size[nodes[i]] * nodesizeratio :
+                        opt.minnodesize;
+
+                nodes[i] = {'name': nodes[i], 'color': color, 'size': size };
+            }
+
+            $(this.container).empty();
+
+            vis = d3.select(this.container)
+                .append("svg:svg")
+                .attr("width", w)
+                .attr("height", h)
+                .attr("pointer-events", "all")
+                .append('svg:g')
+                .call(d3.behavior.zoom().on("zoom", function () {
+                    vis.attr("transform", "translate(" + d3.event.translate + ")" +
+                         " scale(" + d3.event.scale + ")");
+                }))
+                .append('svg:g');
+
+            vis.append('svg:rect')
+                .attr('width', w)
+                .attr('height', h)
+                .attr('fill', 'white');
+
+            force = d3.layout.force()
+                .gravity(0.05)
+                .distance(100)
+                .charge(-100)
+                .nodes(nodes)
+                .links(edges)
+                .size([w, h])
+                .start();
+
+            link = vis.selectAll("line.link")
+                .data(edges)
+                .enter().append("svg:line")
+                .attr("class", "link")
+                //.style("stroke-width", function (d) { return Math.sqrt(d.value); })
+                .attr("x1", function (d) { return d.source.x; })
+                .attr("y1", function (d) { return d.source.y; })
+                .attr("x2", function (d) { return d.target.x; })
+                .attr("y2", function (d) { return d.target.y; });
+
+            node = vis.selectAll("g.node")
+                .data(nodes)
+                .enter().append("svg:g")
+                .attr("class", "node")
+                .call(force.drag);
+
+            node.append("svg:circle")
+                .style("fill", function (d) { return colors(d.color); })
+                .attr("class", "node")
+                .attr("r", function (d) { return d.size; });
+
+            node.append("svg:title")
+                .text(function (d) { return d.name; });
+
+            node.append("svg:text")
+                .attr("class", "nodetext")
+                .attr("dx", 12)
+                .attr("dy", ".35em")
+                .text(function (d) { return d.name; });
+
+            ticks = 0;
+            force.on("tick", function () {
+                ticks += 1;
+                if (ticks > 250) {
+                    force.stop();
+                    force.charge(0)
+                        .linkStrength(0)
+                        .linkDistance(0)
+                        .gravity(0)
+                        .start();
+                }
+
+                link.attr("x1", function (d) { return d.source.x; })
+                    .attr("y1", function (d) { return d.source.y; })
+                    .attr("x2", function (d) { return d.target.x; })
+                    .attr("y2", function (d) { return d.target.y; });
+
+                node.attr("transform", function (d) {
+                    return "translate(" + d.x + "," + d.y + ")";
+                });
+            });
+        }
+    };
+
+
+    /*global Graph */
+    /** rdGraph **
+
+      Original version written by Magnus Stuhr.
+
+      Draws a graph with clickable and movable nodes. 
+
+      Input format:
+      - 7 columns, last three are optional.
+      - each row represents a source node, a target node and an edge from source to target.
+      - the URIs are the id's for the nodes, and make the nodes clickable.
+      
+      1             2         3         4             5           6             7
+      sourceURI sourceLabel   targetURI targetLabel   edgeLabel   sourceColor   targetColor
+
+    */
+    sgvizler.chart.rdGraph = function (container) { this.container = container; };
+    sgvizler.chart.rdGraph.prototype = {
+        id: "rdGraph",
+        draw: function (data, chartOpt) {
+
+            var numberOfColumns = data.getNumberOfColumns(),
+                numberOfRows = data.getNumberOfRows(),
+
+                // set defaults.
+                opt = $.extend({
+                    noderadius: 0.5,
+                    nodefontsize: "10px",
+                    nodeheight: 20,
+                    nodestrokewidth: "1px",
+                    nodecornerradius: "1px",
+                    nodepadding: 7,
+                    nodecolor: "green",
+                    edgestroke: "blue",
+                    edgefill: "blue",
+                    edgestrokewidth: 1,
+                    edgefontsize: "10px",
+                    edgeseparator: ", "
+                }, chartOpt),
+
+                graph = new Graph(),
+                layouter,
+                renderer,
+                row,
+                i,
+                edge,
+                source,
+                target,
+                label,
+
+                // custom node rendering using Raphael.
+                nodeRenderer = function (color, URL) {
+                    return function (r, n) {
+                        return r.set()
+                            // rectangle
+                            .push(r.rect(n.point[0],
+                                        n.point[1],
+                                        n.label.length * opt.nodepadding,
+                                        opt.nodeheight)
+                                 .attr({"fill": color,
+                                        "stroke-width": opt.nodestrokewidth,
+                                        "r" : opt.nodecornerradius}))
+                           // label inside rectangle
+                            .push(r.text(n.point[0] + n.label.length * opt.nodepadding / 2,
+                                        n.point[1] + opt.nodeheight / 2,
+                                        n.label)
+                                 .attr({"font-size": opt.nodefontsize})
+                                 .click(function () { if (URL) { window.open(sgvizler.parser.unprefixify(URL)); } })
+                                );
+                    };
+                },
+
+                // helper function.
+                addNode = function (URL, name, color) {
+                    graph.addNode(URL, {label: name, render: nodeRenderer(color, URL)});
+                    //console.log("add node - name: " + name + ", URL: " + URL);
+                },
+                edges = {},
+                keys_edges = [];
+
+            for (row = 0; row < numberOfRows; row += 1) {
+                source = data.getValue(row, 0);
+                target = data.getValue(row, 2);
+
+                // add source node
+                // Note: dracula library takes care of duplicates?
+                if (source) {
+                    addNode(source,
+                            data.getValue(row, 1) || source,
+                            numberOfColumns > 5 ? data.getValue(row, 5) : opt.nodecolor);
+                }
+                // add target node
+                if (target) {
+                    addNode(target,
+                            data.getValue(row, 3) || target,
+                            numberOfColumns > 6 ? data.getValue(row, 6) : opt.nodecolor);
+                }
+
+                // collect edge labels. Only one edge per pair of nodes,
+                // so we concatinate labels of multiple edges into one.
+                if (source && target) {
+                    label = "";
+                    // test if source--target pair is seen before:
+                    if (typeof edges[source + target] !== 'undefined') {
+                        label = edges[source + target].label; // retrieve accumulated label.
+                    } else {
+                        keys_edges.push(source + target);
+                    }
+
+                    if (numberOfColumns > 4 && data.getValue(row, 4).length > 0) {
+                        if (label.length > 0) {
+                            label += opt.edgeseparator;
+                        }
+                        label += data.getValue(row, 4);
+                    }
+
+                    edges[source + target] = {
+                        'source': source,
+                        'target': target,
+                        'label': label
+                    };
+                }
+            }
+
+            // add edges
+            for (i = 0; i < keys_edges.length; i += 1) {
+                edge = edges[keys_edges[i]];
+                //console.log("add edge - source: " + edge.source + ", target " + edge.target);
+                graph.addEdge(edge.source, edge.target,
+                              { "stroke": opt.edgestroke,
+                                "fill": opt.edgefill,
+                                "label": edge.label,
+                                "width": opt.edgestrokewidth,
+                                "fontsize": opt.edgefontsize
+                              });
+            }
+
+            layouter = new Graph.Layout.Spring(graph);
+            layouter.layout();
+
+            $(this.container).empty();
+            renderer = new Graph.Renderer.Raphael(this.container, graph, opt.width, opt.height, {"noderadius": opt.nodeheight * opt.noderadius});
+            renderer.draw();
+        }
+    };    /** sDefList **
+
+
+     Make a html dt list.
+
+
+     Format, 2--N columns:
+     1. Term
+     2--N. Definition
+
+
+     Available options:
+     'cellSep'   :  string (can be html) to separate cells in definition columns. (default: ' ')
+     'termPrefix  :  string (can be html) to prefix each term with. (default: '')
+     'termPostfix :  string (can be html) to postfix each term with. (default: ':')
+     'definitionPrefix  :  string (can be html) to prefix each definition with. (default: '')
+     'definitionPostfix :  string (can be html) to postfix each definition with. (default: '')
+    */
+    sgvizler.chart.DefList = function (container) { this.container = container; };
+    sgvizler.chart.DefList.prototype = {
+        id:   "sDefList",
+        draw: function (data, chartOpt) {
+            var r,
+                c,
+                term,
+                definition,
+                noColumns = data.getNumberOfColumns(),
+                noRows = data.getNumberOfRows(),
+                opt = $.extend({ cellSep: ' ', termPrefix: '', termPostfix: ':', definitionPrefix: '', definitionPostfix: '' }, chartOpt),
+                list = $(document.createElement('dl'));
+
+
+            for (r = 0; r < noRows; r += 1) {
+                term = opt.termPrefix + data.getValue(r, 0) + opt.termPostfix;
+                list.append($(document.createElement('dt')).html(term));
+                definition = opt.definitionPrefix;
+                for (c = 1; c < noColumns; c += 1) {
+                    definition += data.getValue(r, c);
+                    if (c + 1 !== noColumns) {
+                        definition += opt.cellSep;
+                    }
+                }
+                definition += opt.definitionPostfix;
+                list.append($(document.createElement('dd')).html(definition));
+            }
+            $(this.container).empty();
+            $(this.container).append(list);
+        }
+    };
+    /** sList **
+
+
+     Make a html list, either numbered (ol) or bullets (ul). Each row
+     becomes a list item.
+
+
+     Any number of columns in any format. Everything is displayed as text.
+
+
+     Available options:
+     'list'      :  "ol" / "ul"  (default: "ul")
+     'cellSep'   :  string (can be html) to separate cells in row. (default: ', ')
+     'rowPrefix  :  string (can be html) to prefix each row with. (default: '')
+     'rowPostfix :  string (can be html) to postfix each row with. (default: '')
+    */
+    sgvizler.chart.List = function (container) { this.container = container; };
+    sgvizler.chart.List.prototype = {
+        id:   "sList",
+        draw: function (data, chartOpt) {
+            var noColumns = data.getNumberOfColumns(),
+                noRows = data.getNumberOfRows(),
+                opt = $.extend({ list: 'ul', cellSep: ', ', rowPrefix: '', rowPostfix: '' }, chartOpt),
+                list = $(document.createElement(opt.list)),
+                r,
+                c,
+                rowtext;
+
+
+            for (r = 0; r < noRows; r += 1) {
+                rowtext = opt.rowPrefix;
+                for (c = 0; c < noColumns; c += 1) {
+                    rowtext += data.getValue(r, c);
+                    if (c + 1 !== noColumns) {
+                        rowtext += opt.cellSep;
+                    }
+                }
+                rowtext += opt.rowPostfix;
+                list.append($(document.createElement('li')).html(rowtext));
+            }
+            $(this.container).empty();
+            $(this.container).append(list);
+        }
+    };
+
+
+    /** sMap **
+
+
+     Extends gMap in markers dataMode. Draws textboxes with heading,
+     paragraph, link and image. The idea is to put all columns > 2 into
+     the 3. column with html formatting.
+
+
+     - Data Format 2--6 columns:
+       1. lat
+       2. long
+       3. name  (optional)
+       4. text  (optional)
+       5. link  (optional)
+       6. image (optional)
+
+
+     - If < 4 columns, then behaves just as gMap
+     - Only 6 columns will be read, columns > 6 are ignored.
+    */
+    sgvizler.chart.sMap = function (container) { this.container = container; };
+    sgvizler.chart.sMap.prototype = {
+        id:   "sMap",
+        draw: function (data, chartOpt) {
+            var chart,
+                newData,
+                newValue,
+                noColumns = data.getNumberOfColumns(),
+                r,
+                c;
+
+
+            if (noColumns > 3) {
+                newData = data.clone();
+                // drop columns > 3 from new
+                for (c = noColumns - 1; c > 2; c -= 1) {
+                    newData.removeColumn(c);
+                }
+
+
+                // build new 3. column
+                for (r = 0; r < data.getNumberOfRows(); r += 1) {
+                    newValue = "<div class='sgvizler sgvizler-sMap'>";
+                    newValue += "<h1>" + data.getValue(r, 2) + "</h1>";
+                    if (5 < noColumns && data.getValue(r, 5) !== null) {
+                        newValue += "<div class='img'><img src='" + data.getValue(r, 5) + "'/></div>";
+                    }
+                    if (3 < noColumns && data.getValue(r, 3) !== null) {
+                        newValue += "<p class='text'>" + data.getValue(r, 3) + "</p>";
+                    }
+                    if (4 < noColumns && data.getValue(r, 4) !== null) {
+                        newValue += "<p class='link'><a href='" + sgvizler.parser.unprefixify(data.getValue(r, 4)) + "'>" + data.getValue(r, 4) + "</a></p>";
+                    }
+                    newValue += "</div>";
+                    newData.setCell(r, 2, newValue);
+                }
+            } else { // do nothing.
+                newData = data;
+            }
+
+
+            chart = new google.visualization.Map(this.container);
+            chart.draw(newData, chartOpt);
+        }
+    };
+
+
+    /** sTable **
+
+
+     Make a html table.
+
+
+     Available options:
+     'headings'   :  "true" / "false"  (default: "true")
+    */
+    sgvizler.chart.Table = function (container) { this.container = container; };
+    sgvizler.chart.Table.prototype = {
+        id:   "sTable",
+        draw: function (data, chartOpt) {
+            var noColumns = data.getNumberOfColumns(),
+                noRows = data.getNumberOfRows(),
+                opt = $.extend({'headings': true }, chartOpt),
+                table = $(document.createElement('table')),
+                c,
+                r,
+                row;
+
+
+            if (opt.headings) {
+                row = $(document.createElement('tr'));
+                for (c = 0; c < noColumns; c += 1) {
+                    row.append($(document.createElement('th')).html(data.getColumnLabel(c)));
+                }
+                table.append(row);
+            }
+
+
+            for (r = 0; r < noRows; r += 1) {
+                row = $(document.createElement('tr'));
+                for (c = 0; c < noColumns; c += 1) {
+                    row.append($(document.createElement('td')).html(data.getValue(r, c)));
+                }
+                table.append(row);
+            }
+            $(this.container).empty();
+            $(this.container).append(table);
+        }
+    };
+
+    /** sText **
+
+
+     Write text.
+
+
+     Any number of columns. Everything is displayed as text.
+
+
+     Available options:
+     'cellSep'       :  string (can be html) to separate cells in each column. (default: ', ')
+     'cellPrefix     :  string (can be html) to prefix each cell with. (default: '')
+     'cellPostfix    :  string (can be html) to postfix each cell  with. (default: '')
+     'rowPrefix      :  string (can be html) to prefix each row with. (default: '<p>')
+     'rowPostfix     :  string (can be html) to postfix each row with. (default: '</p>')
+     'resultsPrefix  :  string (can be html) to prefix the results with. (default: '<div>')
+     'resultsPostfix :  string (can be html) to postfix the results with. (default: '</div>')
+    */
+    sgvizler.chart.Text = function (container) { this.container = container; };
+    sgvizler.chart.Text.prototype = {
+        id:   "sText",
+        draw: function (data, chartOpt) {
+            var noColumns = data.getNumberOfColumns(),
+                noRows = data.getNumberOfRows(),
+                opt = $.extend({ cellSep: ', ',
+                                 cellPrefix: '', cellPostfix: '',
+                                 rowPrefix: '<p>', rowPostfix: '</p>',
+                                 resultsPrefix: '<div>', resultsPostfix: '</div>' },
+                               chartOpt),
+                text = opt.resultsPrefix,
+                r,
+                c,
+                row;
+
+
+            for (r = 0; r < noRows; r += 1) {
+                row = opt.rowPrefix;
+                for (c = 0; c < noColumns; c += 1) {
+                    row += opt.cellPrefix + data.getValue(r, c) + opt.cellPostfix;
+                    if (c + 1 !== noColumns) {
+                        row += opt.cellSep;
+                    }
+                }
+                text += row + opt.rowPostfix;
+            }
+            text += opt.resultsPostfix;
+
+
+            $(this.container).empty();
+            $(this.container).html(text);
+        }
+    };
+    global.sgvizler = sgvizler;
+}(window));

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c32963d5/lmf-core/src/main/resources/web/admin/js/widgets/database.js
----------------------------------------------------------------------
diff --git a/lmf-core/src/main/resources/web/admin/js/widgets/database.js b/lmf-core/src/main/resources/web/admin/js/widgets/database.js
new file mode 100644
index 0000000..a0f5bd7
--- /dev/null
+++ b/lmf-core/src/main/resources/web/admin/js/widgets/database.js
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2013 Salzburg Research.
+ *
+ * Licensed 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.
+ */
+(function( $ ){
+    $.fn.lmf_database = function(options) {
+        var settings = {
+	        host: 'http://localhost:8080/LMF/',
+            anker_name: 'database',
+            title: 'Database Configuration',
+            loading_img: '../public/img/loader/ajax-loader_small.gif',
+            toplink:true
+        }
+
+        //jquery elements
+        var table;
+
+        //basically there are 2 functions
+        //1. getValues from server and write it to inputFields
+        //2. storeValues after testing Configuration
+        var functions = {
+            input_fields:undefined,
+            getValues : function(callback) {
+
+                var writeValues = function(databases, values) {
+                    table.html("");
+                    this.input_fields={};
+                    //DBMode
+                    var tr0 = $("<tr/>");
+                    var td01 = $("<td/>").css({"font-weight":"bold"}).text("Mode: ");
+                    var td02 = $("<td/>");
+                    this.input_fields.mode_select = $("<select/>").css({'width':'200px'}).html("<option>create</option><option>validate</option>");
+                    td02.append(this.input_fields.mode_select);
+                    td01.appendTo(tr0);
+                    td02.appendTo(tr0);
+                    tr0.appendTo(table);
+
+                    //DB Type
+                    var tr1 = $("<tr/>");
+                    var td11 = $("<td/>").css({"font-weight":"bold"}).text("Database: ");
+                    var td12 = $("<td/>");
+                    this.input_fields.db_select = $("<select/>").css({'width':'200px'});
+                    for (value in databases) {
+                        this.input_fields.db_select.append("<option>" + databases[value] + "</option>");
+                    }
+                    this.input_fields.db_select.val(values["database.type"]);
+                    td12.append(this.input_fields.db_select);
+                    this.input_fields.l_div = $("<div style='float:right;margin-top: -55px;'></div>");
+                    table.parent().append(this.input_fields.l_div);
+                    td11.appendTo(tr1);
+                    td12.appendTo(tr1);
+                    tr1.appendTo(table);
+
+                    //DBHost
+                    var tr2 = $("<tr/>");
+                    var td21 = $("<td/>").css({"font-weight":"bold"}).text("Host: ");
+                    var td22 = $("<td/>");
+                    this.input_fields.db_host = $("<input type='text' style='width:100%'/>");
+                    this.input_fields.db_host.val(values["database.url"]);
+                    td22.append(this.input_fields.db_host);
+                    td21.appendTo(tr2);
+                    td22.appendTo(tr2);
+                    tr2.appendTo(table);
+
+                    //DBUser
+                    var tr3 = $("<tr/>");
+                    var td31 = $("<td/>").css({"font-weight":"bold"}).text("User: ");
+                    var td32 = $("<td/>");
+                    this.input_fields.db_user = $("<input type='text' style='width:100%'/>");
+                    this.input_fields.db_user.val(values["database.user"]);
+                    td32.append(this.input_fields.db_user);
+                    td31.appendTo(tr3);
+                    td32.appendTo(tr3);
+                    tr3.appendTo(table);
+
+                    //DB password
+                    var tr4 = $("<tr/>");
+                    var td41 = $("<td/>").css({"font-weight":"bold"}).text("Password: ");
+                    var td42 = $("<td/>");
+                    this.input_fields.db_pass = $("<input type='password' style='width:100%'/>");
+                    this.input_fields.db_pass.val(values["database.password"]);
+                    td42.append(this.input_fields.db_pass);
+                    td41.appendTo(tr4);
+                    td42.appendTo(tr4);
+                    tr4.appendTo(table);
+
+                    this.input_fields.db_select.change(function() {
+                        getUrlValue();
+                    });
+
+                    if (callback) callback();
+                };
+
+                var getDatabases = function() {
+                    //get prefixes
+                    var url = settings.host+"config/list?prefix=database";
+                    var that = this;
+                    $.getJSON(url,function(data) {
+                        var values = [];
+                         var databases = new Array();
+                         for(var property in data) {
+                            property = property.substring(property.indexOf('.')+1);
+                            property = property.substring(0,property.indexOf('.'));
+                            if(property!="") {
+                                if($.inArray(property,databases)==-1) {
+                                    databases.push(property);
+                                }
+                            }
+                        }
+                        getDBType(databases,new Array());
+                    });
+                };
+
+                var getDBType = function(databases,values) {
+                    var cid = "database.type";
+                    var url = settings.host+"config/data/"+cid;
+                    $.getJSON(url,function(data) {
+                        values[cid] = data[cid];
+                        getDBHost(databases,values);
+                    });
+                };
+
+                var getDBHost = function(databases,values) {
+                    var cid = "database.url";
+                    var url = settings.host+"config/data/"+cid;
+                    $.getJSON(url,function(data) {
+                        values[cid] = data[cid];
+                        getDBUser(databases,values);
+                    });
+                };
+
+                var getDBUser = function(databases,values) {
+                    var cid = "database.user";
+                    var url = settings.host+"config/data/"+cid;
+                    $.getJSON(url,function(data) {
+                        values[cid] = data[cid];
+                        getDBPass(databases,values);
+                    });
+                };
+
+                var getDBPass = function(databases,values) {
+                    var cid = "database.password";
+                    var url = settings.host+"config/data/"+cid;
+                    $.getJSON(url,function(data) {
+                        values[cid] = data[cid];
+                        writeValues(databases,values);
+                    });
+
+                };
+                getDatabases();
+
+                //helper
+                function getUrlValue() {
+                    var that = this;
+                    $.getJSON(settings.host+"config/data/"+"database."+this.input_fields.db_select.val()+".url",function(data){
+                        that.input_fields.db_host.val(data["database."+that.input_fields.db_select.val()+".url"]);
+                    })
+                }
+            },
+
+            ping:function() {
+                var that = this;
+                var dburl = input_fields.db_host.val();
+                if (input_fields.db_host.val().indexOf(";") > 0) {
+                    dburl = input_fields.db_host.val().substring(0, input_fields.db_host.val().indexOf(";"));
+                }
+                var url = settings.host + "system/database/ping?type=" + input_fields.db_select.val() + "&url=" + dburl + "&user=" + input_fields.db_user.val() + "&pwd=" + input_fields.db_pass.val();
+                $.ajax({
+                    type:"POST",
+                    url: url,
+                    success: function() {
+                        if(confirm("Configuration Test successfully! Save values?")){
+                           that.saveValues();
+                        }
+                    },
+                    error: function(jqXHR, statusText, errorThrown) {
+                        alert(errorThrown + "(" + jqXHR.status + "):\n"+jqXHR.responseText)
+                    }
+                });
+            },
+
+            saveValues: function(callback) {
+                var saveMode= function() {
+                    input_fields.l_div.html("<span>Save Values </span><img src='" + settings.loading_img+ "'/>");
+                    $.ajax({
+                        type:"POST",
+                        contentType: "application/json",
+                        url: settings.host + "config/data/database.mode",
+                        data: '["' + input_fields.mode_select.val() + '"]',
+                        success: function() {
+                            saveDatabase();
+                        },
+                        error: function(jqXHR, statusText, errorThrown) {
+                            that.input_fields.l_div.html("");
+                            alert("Error: " + errorThrown + "(" + jqXHR.status + ")" + jqXHR.responseText);
+                        }
+                    });
+                }
+
+                function saveDatabase() {
+                    $.ajax({
+                        type:"POST",
+                        contentType: "application/json",
+                        url: settings.host + "config/data/database.type",
+                        data: '["' + input_fields.db_select.val() + '"]',
+                        success: function() {
+                            saveUrl();
+                        },
+                        error: function(jqXHR, statusText, errorThrown) {
+                            that.input_fields.l_div.html("");
+                            alert("Error: " + errorThrown + "(" + jqXHR.status + ")" + jqXHR.responseText);
+                        }
+                    });
+                }
+
+                function saveUrl() {
+                    $.ajax({
+                        type:"POST",
+                        contentType: "application/json",
+                        url: settings.host + "config/data/database.url",
+                        data: '["' + input_fields.db_host.val() + '"]',
+                        success: function() {
+                            saveUser();
+                        },
+                        error: function(jqXHR, statusText, errorThrown) {
+                            that.input_fields.l_div.html("");
+                            alert("Error: " + errorThrown + "(" + jqXHR.status + ")" + jqXHR.responseText);
+                        }
+                    });
+                }
+
+                function saveUser() {
+                    $.ajax({
+                        type:"POST",
+                        contentType: "application/json",
+                        url: settings.host + "config/data/database.user",
+                        data: '["' + input_fields.db_user.val() + '"]',
+                        success: function() {
+                            savePwd();
+                        },
+                        error: function(jqXHR, statusText, errorThrown) {
+                            that.input_fields.l_div.html("");
+                            alert("Error: " + errorThrown + "(" + jqXHR.status + ")" + jqXHR.responseText);
+                        }
+                    });
+                }
+
+                function savePwd() {
+                    $.ajax({
+                        type:"POST",
+                        contentType: "application/json",
+                        url: settings.host + "config/data/database.password",
+                        data: '["' + input_fields.db_pass.val() + '"]',
+                        success: function() {
+                            reinit();
+                        },
+                        error: function(jqXHR, statusText, errorThrown) {
+                            that.input_fields.l_div.html("");
+                            alert("Error: " + errorThrown + "(" + jqXHR.status + ")" + jqXHR.responseText);
+                        }
+                    });
+                }
+
+                function reinit() {
+                    var that = this;
+                    input_fields.l_div.html("<span>Reinitialize Database </span><img src='" + settings.loading_img + "'/>");
+                    $.ajax({
+                        type:"POST",
+                        url: settings.host + "system/database/reinit",
+                        success: function() {
+                            that.input_fields.l_div.html("");
+                            alert("Successfully reloaded!")
+                        },
+                        error: function(jqXHR, statusText, errorThrown) {
+                            that.input_fields.l_div.html("");
+                            alert("Error: " + errorThrown + "(" + jqXHR.status + ")" + jqXHR.responseText);
+                        }
+                    });
+                }
+                saveMode();
+            }
+        }
+
+        /**
+         * main method
+         */
+        return this.each(function() {
+            // merge options
+            if ( options ) {
+                $.extend( settings, options );
+            }
+            //build skeleton
+
+            //get Values
+            functions.getValues();
+            var top="";
+            if(settings.toplink)top='<a href="#" target="_top" style="position:absolute;right:5px;font-size:12px;top:7px;text-decoration:none;">top</a>';
+            //build basic view elements
+            var title = $("<h2 style='position:relative;margin-bottom:10px'><a style='text-decoration:none' name='"+settings.anker_name+"'>"+settings.title+"</a><span style='margin-left:10px;display:none;' class='tiny_text,lmf_configurator_loader'><img src='"+settings.loading_img+"' alt='loading...'></span>"+top+"</h2>");
+            table = $("<table style='margin:0px auto;background-color:#eeeeee;padding:20px;border:1px solid gray;-webkit-border-radius: 3px;border-radius: 3px;'></table>");
+            var buttons = $("<div style='width:100%;text-align:center;padding-top:10px;margin-bottom:30px;'></div>");
+            var b1 = $("<button>Reload</button>").click(function(){if(confirm("Discard all changes?"))functions.getValues()});
+            var b3 = $("<button style='margin-left:10px;'>Test Configuration</button>").click(function(){functions.ping()});
+            buttons.append(b1);
+            buttons.append(b3);
+
+            //append elements
+            $(this).html("");
+            $(this).append(title);
+            $(this).append(table);
+            $(this).append(buttons);
+        });
+    };
+})( jQuery );
+

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c32963d5/lmf-core/src/main/resources/web/admin/js/widgets/import.js
----------------------------------------------------------------------
diff --git a/lmf-core/src/main/resources/web/admin/js/widgets/import.js b/lmf-core/src/main/resources/web/admin/js/widgets/import.js
new file mode 100644
index 0000000..7cef191
--- /dev/null
+++ b/lmf-core/src/main/resources/web/admin/js/widgets/import.js
@@ -0,0 +1,292 @@
+/*
+ * Copyright (C) 2013 Salzburg Research.
+ *
+ * Licensed 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.
+ */
+function Importer(id,host) {
+
+    var LMF = new LMFClient(host);
+    //TODO
+    var loader =$("<img style='position: relative;top: 4px;margin-left: 10px;' src='../public/img/loader/ajax-loader_small.gif'>");
+
+    var container = $("#"+id);
+
+    var style = $("<style type='text/css'>.td_title{font-weight:bold;width:100px}</style>")
+
+    var step1 = $("<div></div>");
+    var step2 = $("<div></div>");
+    var step3 = $("<div></div>");
+    var step4 = $("<div></div>");
+    var button = $("<div style='margin-top:20px'></div>");
+
+    var metadata_types;
+    var contexts;
+    var example_context;
+
+    function init() {
+
+        $.getJSON("../../import/types",function(data) {
+            metadata_types = data;
+        });
+
+        $.getJSON("../../context/list",function(data) {
+            loader.hide();
+            contexts = data;
+        });
+        
+        $.getJSON("../../config/data/kiwi.host",function(data) {
+            example_context = data["kiwi.host"] + "context/name";
+        });        
+        
+        container.empty();
+        container.append(style);
+        container.append($("<h1></h1>").append("<span>Import</span>").append(loader));
+        container.append(step1);
+        container.append(step2);
+        container.append(step3);
+        container.append(step4);
+        container.append(button);
+
+        step1.append("<h2>1. Select input source-type:</h2>");
+        step1.append($("<a class='import_type'></a>").text("File").click(function(){
+          button.empty();
+          step4.empty();
+          step3.empty();
+          step2.empty();
+          step2.append("<h2>2. Select file:</h2>");
+          var input = $("<input type='file'>");
+          step2.append(input);
+          input.change(function(){
+              step3.empty();
+              if(input.val()==undefined || input.val()=="") alert("Select a file first!");
+              else predefine(input,"file");
+          });
+       }));
+       step1.append("<span>|</span>");
+       step1.append($("<a class='import_type' ></a>").text("URL").click(function(){
+          button.empty();
+          step4.empty()
+          step3.empty();
+          step2.empty();
+          step2.append("<h2>2. Define url:</h2>");
+          var input = $("<input type='text' style='width: 300px'>");
+          step2.append(input);
+          step2.append($("<button></button>").text("ok").click(function(){
+              step3.empty();
+              if(input.val()==undefined || input.val()=="") alert("Define an URL first!");
+              else if(!isUrl(input.val())) alert("URL is not valid!")
+              else predefine(input,"url");
+          }));
+       }));
+    }
+
+    function predefine(input_field,source_type) {
+        var source_relation;
+        var source_filetype;
+        var source_filetype_input;
+        var context;
+        var context_input;
+        var context_type="default";
+
+        var url = $("<input type='text' style='width: 300px'>");
+
+        function waitForMetadataTypes() {
+            step3.append("<h2>3. Import (..loading)</h2>");
+            if(metadata_types==undefined) setTimeout(waitForMetadataTypes,1000);
+            else writeTable()
+        }
+        waitForMetadataTypes();
+
+        function writeTable() {
+            step4.empty();
+            button.empty();
+            step3.empty().append("<h2>3. Import</h2>");
+            checkFileType();
+            var table = $("<table></table>").addClass("importer_table");
+
+            var td_mime = $("<td></td>");
+
+            var st = source_relation!="content" ? "style='display:none;'" :  "style='display:inline;'";
+            var url_div = $("<div "+st+"></div>").append("<span> url:</span>").append(url);
+
+            table.append($("<tr></tr>").append("<td class='td_title'>Source</td>").append("<td>"+source_type+"</td>"));
+            table.append($("<tr></tr>").append("<td class='td_title'>Relation</td>").append($("<td></td>").append(
+                $("<select></select>").append("<option>content</option><option>meta</option>").val(source_relation).change(function(){
+                    source_relation = $(this).val();
+                    createMimeTD(td_mime);
+                    if(source_relation=="content") url_div.css("display","inline");
+                    else url_div.css("display","none");
+                })
+            ).append(url_div)));
+            createMimeTD(td_mime);
+            table.append($("<tr></tr>").append("<td class='td_title'>Mime</td>").append(td_mime));
+
+            step3.append(table);
+
+            table.append($("<tr></tr>").append("<td class='td_title'>Context</td>").append($("<td></td>").append(
+                $("<select></select>").append("<option>default</option><option>use existing</option><option>define new</option>").change(function(){
+                    context_type = $(this).val();
+                    createContexts();
+                })
+            )));
+
+            var b= $("<button  style='font-weight:bold'></button>").text("Import!").click(function(){
+                context = context_type=="default"?undefined:context_input.val();
+                context = context==null?context=null:context;
+                var _url=undefined;
+                if(context!=null && !isUrl(context)) {
+                    alert("context must be an url!"); return;
+                }
+                if(source_relation=="content") {
+                    if(url.val() != "" && !isUrl(url.val())) alert("content url must be empty or valid!");
+                    else if(url.val()!="") _url=url.val();
+                }
+                if(source_relation=="content") {
+                    resource(source_type,input_field,source_relation,source_filetype_input.val(),context,_url);
+                } else {
+                    if(source_type=="file") {
+                        upload(input_field,source_filetype_input.val(),context);
+                    } else {
+                        external(input_field,source_filetype_input.val(),context);
+                    }
+                }
+            });
+            button.append(b);
+
+        }
+
+        function createMimeTD(td) {
+            if(source_relation=="meta") {
+                source_filetype_input = $("<select></select>");
+                for(var i in metadata_types) {
+                    source_filetype_input.append("<option>"+metadata_types[i]+"</option>");
+                }
+            } else {
+                source_filetype_input = $("<input type='text' style='width:300px'>");
+            }
+            td.empty().append(source_filetype_input);
+            if(source_filetype)source_filetype_input.val(source_filetype);
+        }
+
+        function createContexts() {
+            step4.empty();
+            context=undefined;
+            if(context_type=="use existing") {
+                context_input = $("<select></select>");
+                if(contexts.length==0) {
+                    step4.append("<h2>4. Select context uri:</h2>").append("no existing context, default is used.");
+                }  else {
+                    for(var i in contexts) {
+                        context_input.append("<option>"+contexts[i]+"</option>")
+                    }
+                    step4.append("<h2>4. Select context url:</h2>").append(context_input);
+                }
+            } else if(context_type=="define new"){
+                context_input = $("<input size='60' value='" + example_context + "' />");
+                step4.append("<h2>4. Defined context url:</h2>").append(context_input);
+            }
+        }
+
+        function checkFileType() {
+            function checkRDF() {
+                var inp = input_field.val();
+                var mimeType = null;
+                $.ajax({
+                    url:   "../../import/types",
+                    data:  { 'filename': inp },
+                    async: false,
+                    dataType: 'json',
+                    success: function(data) {
+                        if(data.length > 0) {
+                            mimeType = data[0];
+                        }
+                    }
+                });
+                return mimeType;
+            }
+            function checkFile() {
+                var inp = input_field.val();
+                if(/.gif$/.test(inp)) return "image/gif";
+                if(/.jpg$/.test(inp)) return "image/jpg";
+                if(/.png$/.test(inp)) return "image/png";
+                if(/.ogv$/.test(inp)) return "video/ogg";
+                if(/.mp4$/.test(inp)) return "video/mp4";
+                if(/.html$/.test(inp)) return "text/html";
+                if(/.txt$/.test(inp)) return "text/plain";
+                if(/.pdf$/.test(inp)) return "application/x-pdf";
+                else return null;
+            }
+            var x = checkRDF();
+            if(x) {
+                source_relation="meta";
+                source_filetype=x;
+            } else {
+                x = checkFile();
+                source_relation="content";
+                source_filetype=x;
+            }
+        }
+    }
+
+    function isUrl(s) {
+	    var regexp = /(file|ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/
+	    return regexp.test(s);
+    }
+
+
+    function upload(source_filetype_input,source_filetype,context) {
+       loader.show();
+       LMF.importClient.upload(source_filetype_input.get(0).files[0],source_filetype,context,function(){
+          alert("import was successful");
+           loader.hide();
+       },function(error){
+          alert(error.name+": "+error.message);
+           loader.hide();
+      });
+    }
+
+    function external(source_filetype_input,source_filetype,context) {
+      loader.show();
+      LMF.importClient.uploadFromUrl(source_filetype_input.val(),source_filetype,context,function(){
+          alert("upload is running; you can control the running import tasks on $LMF/core/admin/tasks.html");
+           loader.hide();
+      },function(error){
+          alert(error.name+": "+error.message);
+          loader.hide();
+      })
+    }
+
+    function resource(source_type,source_filetype_input,source_relation,source_filetype,context,content)  {
+        if(source_type!="file") {
+            alert("import content from url is not implemented yet");return;
+        }
+            if(!source_filetype) {
+                alert("mimetype must be defined");return;
+            }
+            loader.show();
+            LMF.resourceClient.createResource(content,function(data){
+                LMF.resourceClient.updateResourceContent(data,source_filetype_input.get(0).files[0],source_filetype,function(){
+                    alert("set content of "+data);
+                    loader.hide();
+                },function(error){
+                    loader.hide();
+                    alert(error.name+": "+error.message);
+                })
+            },function(error){
+                alert(error.name+": "+error.message);
+                loader.hide();
+            });
+    }
+
+    init();
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/c32963d5/lmf-core/src/main/resources/web/admin/js/widgets/system.js
----------------------------------------------------------------------
diff --git a/lmf-core/src/main/resources/web/admin/js/widgets/system.js b/lmf-core/src/main/resources/web/admin/js/widgets/system.js
new file mode 100644
index 0000000..861f354
--- /dev/null
+++ b/lmf-core/src/main/resources/web/admin/js/widgets/system.js
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2013 Salzburg Research.
+ *
+ * Licensed 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.
+ */
+/* QUARTZ CONFIGURATION */
+$(function() {
+    var root = _SERVER_URL;
+    var service = "statistics/";
+    var vcs = "http://code.google.com/p/lmf/" 
+
+    var auto_refresh_interval = ($("input#refresh_interval").val() || 5) * 1000;
+    
+    var pollerU;
+    var refresh = function() {
+        clearTimeout(pollerU);
+        $("#refresh_box").css({"marginTop":"4px"}).addClass("updating");
+
+        var tBody = $("tbody", document.getElementById("stats"));
+        var jl = $(document.getElementById("system_stats_jump"));
+        $.getJSON(root + service + "list", function(data, status, xhr) {
+            $("tr", tBody).addClass("toRemove");
+            $("a", jl).addClass("toRemove");
+            $.each(data, function(module, stats) {
+                var modKey = "mod_" + module.replace(/ /g, "_");
+                var mRow = $(document.getElementById(modKey));
+                if (mRow.size() == 0) {
+                    mRow = $("<tr>", {"id": modKey, 'class': 'subheading'});
+                    mRow.append($("<th>", {colspan:4, 'class': 'module'}).text(module));
+                    mRow.append($("<th>").append($("<a>",{ 'class': 'stat_status', click: function() {
+                        var status = $(this).hasClass("on");
+                        $.ajax(root + service + encodeURI(module) + "/enabled?value=" + (!status), {
+                            type: 'PUT'
+                        }).complete(refresh);
+                    }})));
+                    
+                    mRow.appendTo(tBody);
+                    jl.append($("<a>", {href: '#'+modKey, text: "[" + module + "]"}));
+                }
+                mRow.removeClass("toRemove");
+                $('a[href="#' + modKey + '"]', jl).removeClass("toRemove");
+                
+                $("a.stat_status", mRow).removeClass("on").attr('title', "Activate Statistics Module");
+                var pointer = mRow;
+                for(var key in stats) {
+                    var val = stats[key];
+                    var statKey = modKey + "." + key.replace(/ /g, "_");
+                    
+                    var row = $(document.getElementById(statKey));
+                    if (row.size() == 0) {
+                        row = $("<tr>", {"id" : statKey});
+                        row.append($("<td/>"));
+                        row.append($("<td>", { 'class': 'key', colspan: 2}).text(key));
+                        row.append($("<td>", { 'class': 'val' }).text(val || ""));
+                        row.append($("<td class='action' />"));
+                        
+                        row.insertAfter(pointer);
+                    } else {
+                        $("td.key", row).text(key);
+                        $("td.val", row).text(val || "");
+                    }
+                    
+                    row.removeClass("toRemove");
+                    $("a.stat_status", mRow).addClass("on").attr('title', "Dectivate Statistics Module");
+                    pointer = row;
+                }
+            });
+            
+            $("tr.toRemove", tBody).slideUp("slow", function() { $(this).remove(); });
+            $("a.toRemove", jl).hide("slow", function() { $(this).remove(); });
+            $('#messages div.error').slideUp('slow', function() { $(this).remove(); });
+        }).error(function() {
+            var t = $('#messages div.error'); 
+            if (t.size() == 0) {
+                $('#messages').append($("<div>", {'class':'error'}).text("Statistic update failed!"));
+            } else {
+                t.slideDown();
+            }
+        }).complete(function() {
+            $("#refresh_box").removeClass("updating");
+            if ($("input#refresh_auto").prop('checked')) {
+                pollerU = setTimeout(refresh, auto_refresh_interval);
+            }
+        });
+        
+    };
+    var fetchBuildInfo = function() {
+        $.getJSON(root + "modules/buildinfo",function(data, status, xhr) {
+            function createRow(col1, col2) {
+                var row = $("<tr>");
+                if (typeof col1 == 'string')
+                    row.append($("<td>", {}).text(col1));
+                else
+                    row.append($("<td>", {}).append(col1));
+                if (typeof col2 == 'string')
+                    row.append($("<td>", {}).text(col2));
+                else
+                    row.append($("<td>", {}).append(col2));
+
+                return row;
+            }
+            var tab = $("<table style='margin-top:10px;margin-bottom:20px' class='simple_table'>").hide();
+            var sl = $(document.getElementById("system_mod_jump"));
+            $.each(data, function(modTitle, info) {
+                var mod_id;
+                if (info !== null) mod_id = "mod_" + info.id;
+                else mod_id = modTitle.toLowerCase().replace(/[.#\s]/, "_");
+                
+                $("<tr>", {id: mod_id ,'class': 'subheading'}).append($("<th>", {colspan: 2}).text(modTitle)).appendTo(tab);
+                sl.append($("<a>", { href: "#"+mod_id, text: "[" + modTitle + "]"})).append(" ");
+                
+                if (!info) {
+                    // No build-info for this module
+                    $("<tr>").append($("<td>", { colspan: 2}).html("<i>No build-data available...</i>")).appendTo(tab);
+                    return true;
+                }
+                if (info.admin)
+                    createRow("Module ID", $("<a>", {href: root.replace(/\/$/, "") + info.admin}).text(info.id)).appendTo(tab);
+                else
+                    createRow("Module ID", info.id).appendTo(tab);
+                createRow("Version", info.version).appendTo(tab);
+                createRow("Build Date", info.timestamp).appendTo(tab);
+                createRow("Build Revision", info.revNumber).appendTo(tab);
+                if (info.id.search(/^lmf-/) == 0)
+                    createRow("Revision ID", $("<a>", {href: vcs + "source/browse/?r=" + info.revHash + "#hg/" + info.id, target: '_blank'}).text(info.revHash)).appendTo(tab);
+                else
+                    createRow("Revision ID", info.revHash).appendTo(tab);
+                createRow("Build User", info.user).appendTo(tab);
+                createRow("Build Host", info.host).appendTo(tab);
+                createRow("Build OS", info.os).appendTo(tab);
+            });
+            $(document.getElementById("build_info")).empty().append(tab);
+            tab.slideDown("slow");
+        });
+    };
+    
+    
+    
+    $("button#refresh_now").click(refresh);
+    $("input#refresh_interval").change(function(event) {
+        if ($(this).val() * 1000 > 0) {
+            var oVal = auto_refresh_interval;
+            auto_refresh_interval = $(this).val() * 1000;
+            if (oVal > auto_refresh_interval && $("input#refresh_auto").prop('checked')) {
+                refresh();          
+            }   
+        } else {
+            $(this).val(auto_refresh_interval / 1000);
+        }
+    });
+    $("input#refresh_auto").change(function(event) {
+        if (this.checked) {
+            $("button#refresh_now").attr('disabled','disabled')
+            pollerU = setTimeout(refresh, auto_refresh_interval);
+        } else {
+            $("button#refresh_now").removeAttr('disabled');
+            clearTimeout(pollerU);
+        }
+    });
+    fetchBuildInfo();
+    refresh();
+
+});