blob: 3b2c9fc40f849ce3fbfeb03a28f7b01d1e9d7048 [file] [log] [blame]
/*
* 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.
*/
var repoTable = false;
var repoTableTemplate = false;
var addRepoUri = false;
var resTable = false;
var searchField = false;
var ifStatusOK = false;
//This prototype is provided by the Mozilla foundation and
//is distributed under the MIT license.
//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license
if (!Array.prototype.map)
{
Array.prototype.map = function(fun /*, thisp*/)
{
var len = this.length;
if (typeof fun != "function")
throw new TypeError();
var res = new Array(len);
var thisp = arguments[1];
for (var i = 0; i < len; i++)
{
if (i in this)
res[i] = fun.call(thisp, this[i], i, this);
}
return res;
};
}
/* displays a date in the user's local timezone */
function localTm(time) {
return (time ? new Date(time) : new Date()).toLocaleString();
}
function doRepoAction(action, url) {
if ( !url ) {
Xalert('Invalid URI: ' + url, 'Error');
} else {
$.post(pluginRoot, {
'action' : action,
'url' : url
}, renderData, 'json');
}
}
function showDetails( symbolicname, version ) {
window.location.href = window.location.pathname + '?details&symbolicname=' + symbolicname + '&version=' + version;
}
function showVersions( symbolicname ) {
var _id = symbolicname.replace(/\./g, '_');
$("#block" + _id).append("<div id='pluginInlineVersions" + _id + "' style='margin-left: 4em'><ul/></div>");
$("#img" + _id).each(function() {
$(this).
removeClass('ui-icon-triangle-1-e').//right
addClass('ui-icon-triangle-1-s');//down
});
$("#entry" + _id).each(function() {
$(this).
unbind('click').
click(function() {hideVersions(symbolicname)}).
attr("title", "Hide Versions");
});
var versions = [];
for (var i in obrData.resources ) {
if (obrData.resources[i].symbolicname == symbolicname) {
versions.push(obrData.resources[i].version);
}
}
versions.sort();
for (var i in versions) {
var txt = "<li><a href='javascript: showDetails(\"" + symbolicname + "\",\"" + versions[i] + "\")'>" + versions[i] + "</a></li>";
$("#pluginInlineVersions" + _id + " > ul").append(txt);
}
}
function hideVersions( symbolicname ) {
var _id = symbolicname.replace(/\./g, '_');
$("#img" + _id).each(function() {
$(this).
removeClass('ui-icon-triangle-1-s').//down
addClass('ui-icon-triangle-1-e');//right
});
$("#pluginInlineVersions" + _id).each(function() {
$(this).
remove();
});
$("#entry" + _id).each(function() {
$(this).
unbind('click').
click(function() {showVersions(symbolicname)}).
attr("title", "Show Versions");
});
}
function renderResource(res) {
// proceed with resource
var _id = res.symbolicname.replace(/\./g, '_');
var _tr = resTable.find('#row' + _id);
if (_tr.length == 0) { // not created yet, create it
var blockElement = createElement('span', '', {
id: 'block' + _id
});
var titleElement = createElement('span', '', {
id: 'entry' + _id,
title: "Show Versions"
});
var inputElement = createElement('span', 'ui-icon ui-icon-triangle-1-e', {
id: 'img' + _id,
style: {display: "inline-block"}
});
blockElement.appendChild(titleElement);
titleElement.appendChild(inputElement);
titleElement.appendChild(text(" "));
titleElement.appendChild(text(res.presentationname ? res.presentationname : res.symbolicname));
$(titleElement).click(function() {showVersions(res.symbolicname)});
_tr = tr( null, { 'id' : 'row' + _id } , [
td( null, null, [ blockElement ] ),
td( null, null, [ text(res.installed ? res.version : '') ] )
]);
resTable.append( _tr );
}
}
function getCapabilitiesByName(res, name) {
var caps = [];
for (var v in res.capabilities) {
if (res.capabilities[v].name == name) {
caps.push(res.capabilities[v]);
}
}
return caps;
}
function getRequirementsByName(res, name) {
var caps = [];
for (var v in res.requirements) {
if (res.requirements[v].name == name) {
caps.push(res.requirements[v]);
}
}
return caps;
}
function createDetailedTable(enclosing, name, headers, rows, callback) {
if (rows && rows.length > 0) {
var uuid = jQuery.uuid();
var title = createElement('span', null, null, [
createElement('span', 'ui-icon ui-icon-triangle-1-e', { id: "img"+uuid, style: {display: "inline-block"} }),
text(" "),
text(name)
]);
enclosing.append(tr(null, null, [
td(null, null, [ title ]),
td(null, null, [ createElement('table', 'nicetable ui-widget ui-helper-hidden', { id: "alt1"+uuid }, [
createElement('thead', null, null, [
tr(null, null, headers.map(function(x) {
return th('ui-widget-header', null, [text(x)]);
}))
]),
createElement('tbody', null, null,
rows.map(function(x) {
var values = callback(x);
var tds = values.map(function(x) {
return td(null, null, [x]);
});
return tr(null, null, tds);
})
)
]),
createElement('span', null, { id: "alt2"+uuid }, [
text(rows.length)
])
])
]));
$(title).
unbind('click').
click(function(event) {
event.preventDefault();
$("#img"+uuid).toggleClass('ui-icon-triangle-1-s').//down
toggleClass('ui-icon-triangle-1-e');//right
$("#alt1"+uuid).toggle();
$("#alt2"+uuid).toggle();
});
}
}
function trim(stringToTrim) {
return stringToTrim.replace(/^\s+|\s+$/g,"");
}
function parseSimpleFilter(filter) {
filter = filter.substring(1, filter.length-1);
var start = 0;
var pos = 0;
var c = filter.charAt(pos);
while (c != '~' && c != '<' && c != '>' && c != '=' && c != '(' && c != ')') {
if (c == '<' && filterChars[pos+1] == '*') {
break;
}
if (c == '*' && filterChars[pos+1] == '>') {
break;
}
pos++;
c = filter.charAt(pos);
}
if (pos == start) {
throw ("Missing attr: " + filter.substring(pos));
}
var attr = trim(filter.substring(start, pos));
var oper = filter.substring(pos, pos+2);
var value;
if (oper == '*>' || oper == '~=' || oper == '>=' || oper == '<=' || oper == '<*') {
value = trim(filter.substring(pos+2));
if (value == '') {
throw ("Missing value: " + filter.substring(pos));
}
return { operator: oper, operands: [ attr, value ]};
} else {
if (c != '=') {
throw ("Invalid operator: " + filter.substring(pos));
}
oper = '=';
value = filter.substring(pos+1);
if (value == '*' ) {
return { operator: '=*', operands: [ attr ]};
}
return { operator: '=', operands: [ attr, value ]};
}
}
function parseFilter(filter) {
if (filter.charAt(0) != "(" || filter.charAt(filter.length-1) != ")") {
throw "Wrong parenthesis: " + filter;
}
if (filter.charAt(1) == "!") {
return { operator: filter.charAt(1), operands: [ parseFilter(filter.substring(2, filter.length-1)) ] };
}
if (filter.charAt(1) == "|" || filter.charAt(1) == "&") {
var inner = filter.substring(2, filter.length-1);
var flts = inner.match(/\([^\(\)]*(\([^\(\)]*(\([^\(\)]*(\([^\(\)]*\))*[^\(\)]*\))*[^\(\)]*\))*[^\(\)]*\)/g);
return { operator: filter.charAt(1), operands: flts.map(function(x) { return parseFilter(x); }) };
}
return parseSimpleFilter(filter);
}
function simplify(filter) {
if (filter.operator == '&' || filter.operator == '|') {
filter.operands = filter.operands.map(function(x) { return simplify(x); });
} else if (filter.operator == '!') {
if (filter.operands[0].operator == '<=') {
filter.operator = '>';
filter.operands = filter.operands[0].operands;
} else if (filter.operands[0].operator == '>=') {
filter.operator = '<';
filter.operands = filter.operands[0].operands;
}
}
return filter;
}
function addRow(tbody, key, value) {
if (value) {
tbody.append( tr(null, null, [
td(null, null, [ text(key) ]),
td(null, null, [ text(value) ])
]));
}
}
function renderDetailedResource(res) {
var tbody = $('#detailsTableBody');
tbody.append( tr(null, null, [
th('ui-widget-header', null, [
text("Resource")
]),
th('ui-widget-header', null, [
createElement('form', 'button-group', { method: "post"}, [
createElement('input', null, { type: "hidden", name: "bundle", value: res.id}),
createElement('input', 'ui-state-default ui-corner-all', { type: "submit", name: "deploy", value: "Deploy" }, [ text("dummy")]),
createElement('input', 'ui-state-default ui-corner-all', { type: "submit", name: "deploystart", value: "Start" }, [ text("dummy")]),
text(" "),
createElement('input', 'ui-state-default ui-corner-all', { id: "optional", type: "checkbox", name: "optional" }),
text(" "),
createElement('label', 'ui-widget', { 'for': "optional" }, [ text("optional") ])
])
])
]));
addRow(tbody, "Name", res.presentationname);
addRow(tbody, "Description", res.description);
addRow(tbody, "Symbolic name", res.symbolicname);
addRow(tbody, "Version", res.version);
addRow(tbody, "URI", res.uri);
addRow(tbody, "Documentation", res.documentation);
addRow(tbody, "Javadoc", res.javadoc);
addRow(tbody, "Source", res.source);
addRow(tbody, "License", res.license);
addRow(tbody, "Copyright", res.copyright);
addRow(tbody, "Size", res.size);
// Exported packages
createDetailedTable(tbody, "Exported packages", ["Package", "Version"],
getCapabilitiesByName(res, "package").sort(function(a,b) {
var pa = a.properties['package'], pb = b.properties['package']; return pa == pb ? 0 : pa < pb ? -1 : +1;
}),
function(p) {
return [ text(p.properties['package']), text(p.properties['version']) ];
});
// Exported services
createDetailedTable(tbody, "Exported services", ["Service"], getCapabilitiesByName(res, "service"), function(p) {
return [ text(p.properties['service']) ];
});
// Imported packages
createDetailedTable(tbody, "Imported packages", ["Package", "Version", "Optional"], getRequirementsByName(res, "package"), function(p) {
var f = parseFilter(p.filter);
simplify(f);
var n, vmin = "[0.0.0", vmax = "infinity)";
if (f.operator == '&') {
for (var i in f.operands) {
var fi = f.operands[i];
if (fi.operands[0] == 'package' && fi.operator == '=') {
n = fi.operands[1];
}
if (fi.operands[0] == 'version') {
if (fi.operator == '>=') {
vmin = '[' + fi.operands[1];
}
if (fi.operator == '>') {
vmin = '(' + fi.operands[1];
}
if (fi.operator == '<=') {
vmax = fi.operands[1] + "]";
}
if (fi.operator == '<') {
vmax = fi.operands[1] + ")";
}
}
}
}
return [ text(n ? n : p.filter), text(vmin + ", " + vmax), text(p.optional) ];
});
// Imported bundles
createDetailedTable(tbody, "Imported bundles", ["Bundle", "Version", "Optional"], getRequirementsByName(res, "bundle"), function(p) {
return [ text(p.filter), text(""), text(p.optional) ];
});
// Imported services
createDetailedTable(tbody, "Imported bundles", ["Service", "Optional"], getRequirementsByName(res, "service"), function(p) {
return [ text(p.filter), text(p.optional) ];
});
// Required dependencies
createDetailedTable(tbody, "Dependencies", ["Name", "Version"], res.required, function(p) {
var a = createElement('a', null, { href: (window.location.pathname + '?details&symbolicname=' + p.symbolicname + '&version=' + p.version) });
a.appendChild(text(p.presentationname ? p.presentationname : p.symbolicname));
return [ a, text(p.version) ];
});
// Optional dependencies
createDetailedTable(tbody, "Optional Dependencies", ["Name", "Version"], res.optional, function(p) {
var a = createElement('a', null, { href: (window.location.pathname + '?details&symbolicname=' + p.symbolicname + '&version=' + p.version) });
a.appendChild(text(p.presentationname ? p.presentationname : p.symbolicname));
return [ a, text(p.version) ];
});
// Unsatisfied requirements
createDetailedTable(tbody, "Unsatisfied Requirements", ["Requirement", "Optional"], res.unsatisfied, function(p) {
return [ text(p.filter), text(p.optional) ];
});
// $('#detailsTableBody').append( tr(null, null, [ th('ui-widget-header', { colspan: 2 }, [ text("Resource") ]) ]) );
// $('#detailsTableBody').append( tbody );
}
function renderRepository(repo) {
var _tr = repoTableTemplate.clone();
_tr.find('td:eq(0)').text( repo.name );
_tr.find('td:eq(1)').text( repo.url );
_tr.find('td:eq(2)').text( localTm(repo.lastModified) );
_tr.find('li:eq(0)').click(function() {
doRepoAction('refresh', repo.url);
});
_tr.find('li:eq(1)').click(function() {
doRepoAction('delete', repo.url);
});
repoTable.append(_tr);
}
function renderData() {
repoTable.empty();
resTable.empty();
if ( obrData.status ) {
$('.statline').html(i18n.status_ok);
ifStatusOK.removeClass('ui-helper-hidden');
for (var i in obrData.repositories ) {
renderRepository( obrData.repositories[i] );
}
if ($.getUrlVar('details')) {
$('#resTable').addClass('ui-helper-hidden');
$('#detailsTable').removeClass('ui-helper-hidden');
for (var i in obrData.resources ) {
renderDetailedResource( obrData.resources[i] );
}
} else {
for (var i in obrData.resources ) {
renderResource( obrData.resources[i] );
}
}
} else {
$('.statline').html(i18n.status_no);
ifStatusOK.addClass('ui-helper-hidden');
}
}
$.extend({
getUrlVars: function(){
var vars = [], hash;
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
for(var i = 0; i < hashes.length; i++)
{
var j = hashes[i].indexOf('=');
if (j > 0) {
var k = hashes[i].slice(0, j);
var v = hashes[i].slice(j + 1);
vars.push(k);
vars[k] = v;
} else {
vars.push(hashes[i]);
vars[hashes[i]] = true;
}
}
return vars;
},
getUrlVar: function(name){
return $.getUrlVars()[name];
}
});
$(document).ready( function() {
repoTable = $('#repoTable tbody');
repoTableTemplate = repoTable.find('tr').clone();
addRepoUri = $('#addRepoUri');
resTable = $('#resTable tbody').empty();
searchField = $('#searchField');
ifStatusOK = $('#ifStatusOK');
searchField.val($.getUrlVar('query'));
$('#addRepoBtn').click(function(event) {
event.preventDefault();
doRepoAction('add', addRepoUri.val());
});
$('#searchBtn').click(function(event) {
event.preventDefault();
window.location.href = window.location.pathname + '?query=' + searchField.val();
});
searchField.keypress(function(event) {
if (event.keyCode == 13) {
event.preventDefault();
$('#searchBtn').click();
}
});
renderData();
initStaticWidgets();
});