blob: 8ef06bd15e4367c97f5d3755341178109e3837c7 [file] [log] [blame]
Felix Meschbergerb812b2e2010-02-18 15:36:53 +00001/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
Carsten Ziegeler149faaa2010-03-10 16:41:53 +000017// tables container - will get hidden, when no config service available
18var configContent = false;
19
20// config table list
21var configTable = false;
22var configBody = false;
23var configRow = false;
24
25// factories table list
Carsten Ziegeler149faaa2010-03-10 16:41:53 +000026var factoryBody = false;
27var factoryRow = false;
Felix Meschbergerb812b2e2010-02-18 15:36:53 +000028
29
Carsten Ziegeler149faaa2010-03-10 16:41:53 +000030// editor dialog
31var editor = false;
Valentin Valchevde160882010-03-22 09:30:38 +000032var editorMessage = false;
Felix Meschbergerb812b2e2010-02-18 15:36:53 +000033
Carsten Ziegeler149faaa2010-03-10 16:41:53 +000034function configure(pid, create) {
35 var uri = pluginRoot + '/' + pid;
36 $.post(create ? uri + '?create=1' : uri, null, displayConfigForm, 'json');
Felix Meschbergerb812b2e2010-02-18 15:36:53 +000037}
38
39function displayConfigForm(obj) {
Carsten Ziegeler149faaa2010-03-10 16:41:53 +000040 var parent = document.getElementById('editorTable');
41 clearChildren( parent )
Felix Meschbergerb812b2e2010-02-18 15:36:53 +000042
Carsten Ziegeler149faaa2010-03-10 16:41:53 +000043 var trEl = tr( );
Felix Meschbergerb812b2e2010-02-18 15:36:53 +000044 parent.appendChild( trEl );
45
Carsten Ziegeler149faaa2010-03-10 16:41:53 +000046 var tdEl = td( null, { colSpan: "2" } );
Felix Meschbergerb812b2e2010-02-18 15:36:53 +000047 trEl.appendChild( tdEl );
48
49 var formEl = createElement( "form", null, {
Carsten Ziegeler149faaa2010-03-10 16:41:53 +000050 id : "editorForm",
Felix Meschbergerb812b2e2010-02-18 15:36:53 +000051 method: "POST",
52 action: pluginRoot + "/" + obj.pid
53 });
54 tdEl.appendChild( formEl );
55
56 var inputEl = createElement( "input", null, {
57 type: "hidden",
58 name: "apply",
59 value: "true"
60 });
61 formEl.appendChild( inputEl );
62
63 // add the factory PID as a hidden form field if present
64 if (obj.factoryPid)
65 {
66 inputEl = createElement( "input", null, {
67 type: "hidden",
68 name: "factoryPid",
69 value: obj.factoryPid
70 });
71 formEl.appendChild( inputEl );
72 }
73
74 // add the PID filter as a hidden form field if present
75 if (obj.pidFilter)
76 {
77 inputEl = createElement( "input", null, {
78 type: "hidden",
79 name: "pidFilter",
80 value: obj.pidFilter
81 });
82 formEl.appendChild( inputEl );
83 }
84
85 inputEl = createElement( "input", null, {
86 type: "hidden",
87 name: "action",
88 value: "ajaxConfigManager"
89 });
90 formEl.appendChild( inputEl );
91
92 var tableEl = createElement( "table", null, {
93 border: 0,
94 width: "100%"
95 });
96 formEl.appendChild( tableEl );
97
98 var bodyEl = createElement( "tbody" );
99 tableEl.appendChild( bodyEl );
100
101 if (obj.description)
102 {
103 trEl = tr( );
104 tdEl = td( null, { colSpan: "2" } );
105 addText( tdEl, obj.description );
106 trEl.appendChild( tdEl );
107 bodyEl.appendChild( trEl );
108 }
109
110 if (obj.propertylist == 'properties')
111 {
112 printTextArea(bodyEl, obj.properties);
113 }
114 else
115 {
116 printForm(bodyEl, obj);
117 }
Felix Meschbergerb812b2e2010-02-18 15:36:53 +0000118
119 printConfigurationInfo(parent, obj);
Valentin Valchevde160882010-03-22 09:30:38 +0000120 if ( obj.service_location && obj.bundle_location && obj.service_location != obj.bundle_location) {
121 editorMessage.removeClass('ui-helper-hidden').text(i18n.err_bind.msgFormat(obj.pid, obj.bundle_location, obj.service_location));
122 } else editorMessage.addClass('ui-helper-hidden');
Valentin Valchev0fc8b7b2010-04-15 12:33:58 +0000123
124 // ugly workaround for IE6 and IE7 - these browsers don't show correctly the dialog
125 var ua = navigator.userAgent;
126 if (ua.indexOf('MSIE 6') != -1 || ua.indexOf('MSIE 7') != -1) $(parent).html(parent.innerHTML);
127
Carsten Ziegeler149faaa2010-03-10 16:41:53 +0000128 initStaticWidgets(editor.attr('__pid', obj.pid).dialog('option', 'title', obj.title).dialog('open'));
Felix Meschbergerb812b2e2010-02-18 15:36:53 +0000129}
130
131function printTextArea(/* Element */ parent, props )
132{
133
134 var propsValue = "";
135 for (var key in props)
136 {
137 propsValue += key + ' = ' + props[key] + '\r\n';
138 }
139
140 parent.appendChild(
141 tr( null, null, [
142 td( null, null, [
143 text( i18n.props_title )
144 ]),
145 td( null, { style: { width: "99%" } }, [
146 createElement( "textarea", null, {
147 name: "properties",
Guillaume Nodet283faa32010-03-04 20:54:39 +0000148 style: { height: "20em", width: "99%" }
Felix Meschbergerb812b2e2010-02-18 15:36:53 +0000149 }, [ text( propsValue ) ] ),
Guillaume Nodet283faa32010-03-04 20:54:39 +0000150 createElement( "br" ),
Felix Meschbergerb812b2e2010-02-18 15:36:53 +0000151 text( i18n.props_enter )
152 ])
153 ])
154 );
155}
156
157function printForm( /* Element */ parent, obj ) {
158 var propList;
159 for (var idx in obj.propertylist)
160 {
161 var prop = obj.propertylist[idx];
162 var attr = obj[prop];
163
164 var trEl = tr( null, null, [
165 td( null, null, [ text( attr.name ) ] )
166 ]);
167 parent.appendChild( trEl );
168
169 var tdEl = td( null, { style: { width: "99%" } } );
170 trEl.appendChild( tdEl );
171
172 if (attr.value != undefined)
173 {
174 // check is required to also handle empty strings, 0 and false
175 tdEl.appendChild( createInput( prop, attr.value, attr.type, '99%' ) );
176 tdEl.appendChild( createElement( "br" ) );
177 }
178 else if (typeof(attr.type) == 'object')
179 {
180 // assume attr.values and multiselect
181 createMultiSelect( tdEl, prop, attr.values, attr.type, '99%' );
182 tdEl.appendChild( createElement( "br" ) );
183 }
184 else if (attr.values.length == 0)
185 {
186 tdEl.appendChild( createSpan( prop, "", attr.type ) );
187 }
188 else
189 {
190 for (var i=0;i<attr.values.length;i++)
191 {
192 tdEl.appendChild( createSpan( prop, attr.values[i], attr.type ) );
193 }
194 }
195
196 if (attr.description)
197 {
198 addText( tdEl, attr.description );
199 }
200
201 if (propList) {
202 propList += ',' + prop;
203 } else {
204 propList = prop;
205 }
206 }
207
208 parent.appendChild( createElement( "input", null, {
209 type: "hidden",
210 name: "propertylist",
211 value: propList
212 })
213 );
214 // FIX for IE6 and above: checkbox can only be checked after it is in the DOM
215 $(".checked_box").attr("checked", true).removeClass("checked_box");
216}
217
218function printConfigurationInfo( /* Element */ parent, obj )
219{
220 parent.appendChild( tr( null, null, [
221 createElement( "th", null, { colSpan: "2" }, [
222 text( i18n.cfg_title )
223 ])
224 ])
225 );
226
227 parent.appendChild( tr( null, null, [
228 td( null, null, [
229 text( i18n.pid )
230 ]),
231 td( null, null, [
232 text( obj.pid )
233 ])
234 ])
235 );
236
237 if (obj.factoryPid)
238 {
239 parent.appendChild( tr( null, null, [
240 td( null, null, [
241 text( i18n.fpid )
242 ]),
243 td( null, null, [
244 text( obj.factoryPid )
245 ])
246 ])
247 );
248 }
249
250 var binding = obj.bundleLocation;
251 if (!binding)
252 {
253 binding = i18n.unbound;
254 }
255
256 parent.appendChild( tr( null, null, [
257 td( null, null, [
258 text( i18n.binding )
259 ]),
260 td( null, null, [
261 text( binding )
262 ])
263 ])
264 );
Felix Meschbergerb812b2e2010-02-18 15:36:53 +0000265
Felix Meschbergerb812b2e2010-02-18 15:36:53 +0000266}
267
268
269var spanCounter = 0;
270/* Element */ function createSpan(prop, value, type) {
271 spanCounter++;
272 var newId = prop + spanCounter;
273
274 var addButton = createElement("input", null,
275 { type: "button",
276 style: {width : "5%"},
277 value: "+"
278 }
279 );
280 $(addButton).click(function() {addValue(prop, newId)});
281 var remButton = createElement("input", null,
282 { type: "button",
283 style: {width : "5%"},
284 value: "-"
285 }
286 );
287 $(remButton).click(function() {removeValue(newId)});
288 var spanEl = createElement( "span", null, { id: newId }, [
289 createInput( prop, value, type, '89%' ), addButton, remButton,
290 createElement("br")
291 ]);
292
293 return spanEl;
294}
295
296/* Element */ function createInput(prop, value, type, width) {
297 if (type == 11) { // AttributeDefinition.BOOLEAN
298
299 var inputEl = createElement( "input", null, {
300 type: "checkbox",
301 name: prop,
302 value: "true"
303 });
304
305 if (value && typeof(value) != "boolean")
306 {
307 value = value.toString().toLowerCase() == "true";
308 }
309 if (value)
310 {
311 $(inputEl).addClass("checked_box");
312 }
313 var hiddenEl = createElement( "input", null, {
314 type: "hidden",
315 name: prop,
316 value: "false"
317 });
318 var divEl = createElement("div");
319 divEl.appendChild(inputEl);
320 divEl.appendChild(hiddenEl);
321 return divEl;
322
323 } else if (typeof(type) == "object") { // predefined values
324
325 var selectEl = createElement( "select", null, {
326 name: prop,
327 style: { width: width }
328 });
329
330 var labels = type.labels;
331 var values = type.values;
332 for (var idx in labels) {
333 var optionEl = createElement( "option", null, {
334 value: values[idx]
335 }, [ text( labels[idx] ) ]);
336
337 if (value == values[idx])
338 {
339 optionEl.setAttribute( "selected", true );
340 }
341 selectEl.appendChild( optionEl );
342 }
343
344 return selectEl;
345
346 } else { // Simple
347 return createElement( "input", null, {
348 type: "text",
349 name: prop,
350 value: value,
351 style: { width: width }
352 });
353 }
354}
355
356function createMultiSelect(/* Element */ parent, prop, values, options, width) {
357 // convert value list into 'set'
358 var valueSet = new Object();
359 for (var idx in values) {
360 valueSet[ values[idx] ] = true;
361 }
362
363 var labels = options.labels;
364 var values = options.values;
365 for (var idx in labels) {
366
367 var inputEl = createElement( "input", null, {
368 type: "checkbox",
369 name: prop,
370 value: values[idx]
371 });
372
373 if (valueSet[ values[idx] ])
374 {
375 inputEl.setAttribute( "checked", true );
376 }
377
378 var labelEl = createElement( "label", "multiselect" );
379 labelEl.appendChild( inputEl );
380 addText( labelEl, labels[idx] );
381
382 parent.appendChild( labelEl );
383 }
384}
385
386
387function addValue(prop, vidx)
388{
389 var span = document.getElementById(vidx);
390 if (!span)
391 {
392 return;
393 }
394 var newSpan = createSpan(prop, '');
395 span.parentNode.insertBefore(newSpan, span.nextSibling);
396 // FIX for IE6 and above: checkbox can only be checked after it is in the DOM
397 $(".checked_box").attr("checked", true).removeClass("checked_box");
398 //$(span).ready(initStaticWidgets);
399}
400
401function removeValue(vidx)
402{
403 var span = document.getElementById(vidx);
404 if (!span)
405 {
406 return;
407 }
408 span.parentNode.removeChild(span);
409}
410
411function configConfirm(/* String */ message, /* String */ title, /* String */ location)
412{
413 var message = i18n.del_ask;
414
415 if (title) {
416 message += "\r\n" + i18n.del_config + title;
417 }
418 if (location) {
419 message += "\r\n" + i18n.del_bundle + location;
420 }
421
422 return confirm(message);
423}
424
425function confirmDelete(/* String */ title, /* String */ location)
426{
Carsten Ziegeler149faaa2010-03-10 16:41:53 +0000427 return configConfirm(i18n.del_ask, title, location);
Felix Meschbergerb812b2e2010-02-18 15:36:53 +0000428}
429
430function confirmUnbind(/* String */ title, /* String */ location)
431{
432 return configConfirm(i18n.unbind_ask, title, location);
433}
434
Carsten Ziegeler149faaa2010-03-10 16:41:53 +0000435function addConfig(conf) {
436 var tr = configRow.clone().appendTo(configBody);
Felix Meschberger67726fe2010-03-17 06:55:00 +0000437
438 // rendering name - indented if factory pid is set
Valentin Valchev0fc8b7b2010-04-15 12:33:58 +0000439 var nms = tr.find('td:eq(0) div');
Felix Meschberger67726fe2010-03-17 06:55:00 +0000440 if (conf.fpid) {
441 nms.after(conf.id);
442 tr.attr('fpid', conf.name);
443 } else {
444 nms.addClass('ui-helper-hidden').parent().text(conf.name);
445 }
446
447 tr.find('td:eq(0)').click(function() { // name & edit
Carsten Ziegeler149faaa2010-03-10 16:41:53 +0000448 configure(conf.id);
449 });
Felix Meschberger67726fe2010-03-17 06:55:00 +0000450 tr.find('td:eq(1)').html(conf.bundle ? '<a href="' + pluginRoot + '/../bundles/' + conf.bundle + '">' + conf.bundle_name + '</a>' : '-'); // binding
Carsten Ziegeler149faaa2010-03-10 16:41:53 +0000451
452 // buttons
453 tr.find('li:eq(0)').click(function() { // edit
454 configure(conf.id);
455 });
456 tr.find('li:eq(2)').click(function() { // delete
457 if ( confirmDelete(conf.id, conf.bundle_name) ) {
458 $.post(pluginRoot + '/' + conf.id + '?apply=1&delete=1', null, function() {
459 document.location.href = pluginRoot;
460 }, 'json');
461 }
462 });
463 if (conf.bundle) tr.find('li:eq(1)').click(function() { // unbind
464 if ( confirmUnbind(conf.id, conf.bundle_name) ) {
465 $.post(pluginRoot + '/' + conf.id + '?apply=1&delete=1', null, function() {
466 document.location.href = pluginRoot + '/' + conf.id;
467 }, 'json');
468 }
469 }).removeClass('ui-state-disabled');
Felix Meschbergerb812b2e2010-02-18 15:36:53 +0000470}
471
Carsten Ziegeler149faaa2010-03-10 16:41:53 +0000472function addFactoryConfig(conf) {
Felix Meschberger67726fe2010-03-17 06:55:00 +0000473 var tr = factoryRow.clone().appendTo(configTable).attr('fpid', conf.name);
474 //tr.find('td:eq(1)').text(conf.id); // fpid
Felix Meschberger1e671e12010-03-13 15:09:51 +0000475 tr.find('td:eq(0)').text(conf.name).click(function() { // name & edit
Carsten Ziegeler149faaa2010-03-10 16:41:53 +0000476 configure(conf.id, true);
477 });
478 // buttons
479 tr.find('li:eq(0)').click(function() { // edit
480 configure(conf.id, true);
481 });
482}
483
Felix Meschberger67726fe2010-03-17 06:55:00 +0000484function treetableExtraction(node) {
485 var td = $(node);
486 var text = td.text();
487 if (!text) return text;
488
489 // current sort order
490 var desc = $(this)[0].sortList[0][1];
491
492 var row = td.parent();
493 var fpid = row.attr('fpid');
494
495 // factory row
496 if ( row.hasClass('fpid') && fpid) return fpid + (desc==0?1:0) + text;
497
498 // bundle or name row
499 if ( fpid ) return fpid + desc + text;
500
501 return mixedLinksExtraction(node);
502};
503
Felix Meschbergerb812b2e2010-02-18 15:36:53 +0000504$(document).ready(function() {
Carsten Ziegeler149faaa2010-03-10 16:41:53 +0000505 configContent = $('#configContent');
506 // config table list
Felix Meschberger67726fe2010-03-17 06:55:00 +0000507 configTable = $('#configTable');
Carsten Ziegeler149faaa2010-03-10 16:41:53 +0000508 configBody = configTable.find('tbody');
Felix Meschberger67726fe2010-03-17 06:55:00 +0000509 configRow = configBody.find('tr:eq(0)').clone();
510 factoryRow = configBody.find('tr:eq(1)').clone();
Felix Meschberger1e671e12010-03-13 15:09:51 +0000511
Carsten Ziegeler149faaa2010-03-10 16:41:53 +0000512 // setup button - cannot inline in dialog option because of i18n
513 var _buttons = {};
514 _buttons[i18n.abort] = function() {
515 $(this).dialog('close');
Felix Meschbergerb812b2e2010-02-18 15:36:53 +0000516 }
Carsten Ziegeler149faaa2010-03-10 16:41:53 +0000517 _buttons[i18n.reset] = function() {
518 var form = document.getElementById('editorForm');
519 if (form) form.reset();
520 }
521 _buttons[i18n.save] = function() {
522 $.post(pluginRoot + '/' + $(this).attr('__pid') + '?' + $(this).find('form').serialize());
523 $(this).dialog('close');
524 }
525 // prepare editor, but don't open yet!
526 editor = $('#editor').dialog({
527 autoOpen : false,
528 modal : true,
529 width : '90%',
530 closeText: i18n.abort,
531 buttons : _buttons
532 });
Valentin Valchevde160882010-03-22 09:30:38 +0000533 editorMessage = editor.find('p');
Carsten Ziegeler149faaa2010-03-10 16:41:53 +0000534
535 // display the configuration data
536 $(".statline").html(configData.status ? i18n.stat_ok : i18n.stat_missing);
537 if (configData.status) {
Felix Meschberger67726fe2010-03-17 06:55:00 +0000538 configBody.empty();
539 var factories = {};
Carsten Ziegeler149faaa2010-03-10 16:41:53 +0000540
Felix Meschberger67726fe2010-03-17 06:55:00 +0000541 for(var i in configData.pids) {
542 var c = configData.pids[i];
543 if (c.fpid) {
544 if (!factories[c.fpid]) factories[c.fpid] = new Array();
545 factories[c.fpid].push(c);
546 } else {
547 addConfig(c);
548 }
549 }
550 for(var i in configData.fpids) {
551 addFactoryConfig(configData.fpids[i]);
Felix Meschberger1e671e12010-03-13 15:09:51 +0000552
Felix Meschberger67726fe2010-03-17 06:55:00 +0000553 var confs = factories[ configData.fpids[i].id ];
554 if (confs) for (var j in confs) {
555 addConfig(confs[j]);
556 }
557 }
558 initStaticWidgets(configTable);
559
560 // init tablesorte
561 configTable.tablesorter({
562 headers: { 2: { sorter: false } },
563 sortList: [[0,1]],
564 textExtraction: treetableExtraction
565 }).bind('sortStart', function() { // clear cache, otherwse extraction will not work
566 var table = $(this).trigger('update');
567 }).find('th:eq(0)').click();
Carsten Ziegeler149faaa2010-03-10 16:41:53 +0000568 } else {
569 configContent.addClass('ui-helper-hidden');
570 }
571 if (selectedPid) configure(selectedPid);
Felix Meschbergerb812b2e2010-02-18 15:36:53 +0000572});