blob: 6eeeb2b78a20ef3fb2c67ec861e184179b6140db [file] [log] [blame]
Felix Meschberger62e1a4f2010-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 Ziegeler4e070fe2010-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 Ziegeler4e070fe2010-03-10 16:41:53 +000026var factoryBody = false;
27var factoryRow = false;
Felix Meschberger62e1a4f2010-02-18 15:36:53 +000028
29
Carsten Ziegeler4e070fe2010-03-10 16:41:53 +000030// editor dialog
31var editor = false;
Felix Meschberger62e1a4f2010-02-18 15:36:53 +000032
Carsten Ziegeler4e070fe2010-03-10 16:41:53 +000033function configure(pid, create) {
34 var uri = pluginRoot + '/' + pid;
35 $.post(create ? uri + '?create=1' : uri, null, displayConfigForm, 'json');
Felix Meschberger62e1a4f2010-02-18 15:36:53 +000036}
37
38function displayConfigForm(obj) {
Carsten Ziegeler4e070fe2010-03-10 16:41:53 +000039 var parent = document.getElementById('editorTable');
40 clearChildren( parent )
Felix Meschberger62e1a4f2010-02-18 15:36:53 +000041
Carsten Ziegeler4e070fe2010-03-10 16:41:53 +000042 var trEl = tr( );
Felix Meschberger62e1a4f2010-02-18 15:36:53 +000043 parent.appendChild( trEl );
44
Carsten Ziegeler4e070fe2010-03-10 16:41:53 +000045 var tdEl = td( null, { colSpan: "2" } );
Felix Meschberger62e1a4f2010-02-18 15:36:53 +000046 trEl.appendChild( tdEl );
47
48 var formEl = createElement( "form", null, {
Carsten Ziegeler4e070fe2010-03-10 16:41:53 +000049 id : "editorForm",
Felix Meschberger62e1a4f2010-02-18 15:36:53 +000050 method: "POST",
51 action: pluginRoot + "/" + obj.pid
52 });
53 tdEl.appendChild( formEl );
54
55 var inputEl = createElement( "input", null, {
56 type: "hidden",
57 name: "apply",
58 value: "true"
59 });
60 formEl.appendChild( inputEl );
61
62 // add the factory PID as a hidden form field if present
63 if (obj.factoryPid)
64 {
65 inputEl = createElement( "input", null, {
66 type: "hidden",
67 name: "factoryPid",
68 value: obj.factoryPid
69 });
70 formEl.appendChild( inputEl );
71 }
72
73 // add the PID filter as a hidden form field if present
74 if (obj.pidFilter)
75 {
76 inputEl = createElement( "input", null, {
77 type: "hidden",
78 name: "pidFilter",
79 value: obj.pidFilter
80 });
81 formEl.appendChild( inputEl );
82 }
83
84 inputEl = createElement( "input", null, {
85 type: "hidden",
86 name: "action",
87 value: "ajaxConfigManager"
88 });
89 formEl.appendChild( inputEl );
90
91 var tableEl = createElement( "table", null, {
92 border: 0,
93 width: "100%"
94 });
95 formEl.appendChild( tableEl );
96
97 var bodyEl = createElement( "tbody" );
98 tableEl.appendChild( bodyEl );
99
100 if (obj.description)
101 {
102 trEl = tr( );
103 tdEl = td( null, { colSpan: "2" } );
104 addText( tdEl, obj.description );
105 trEl.appendChild( tdEl );
106 bodyEl.appendChild( trEl );
107 }
108
109 if (obj.propertylist == 'properties')
110 {
111 printTextArea(bodyEl, obj.properties);
112 }
113 else
114 {
115 printForm(bodyEl, obj);
116 }
Felix Meschberger62e1a4f2010-02-18 15:36:53 +0000117
118 printConfigurationInfo(parent, obj);
Carsten Ziegeler4e070fe2010-03-10 16:41:53 +0000119 initStaticWidgets(editor.attr('__pid', obj.pid).dialog('option', 'title', obj.title).dialog('open'));
Felix Meschberger62e1a4f2010-02-18 15:36:53 +0000120}
121
122function printTextArea(/* Element */ parent, props )
123{
124
125 var propsValue = "";
126 for (var key in props)
127 {
128 propsValue += key + ' = ' + props[key] + '\r\n';
129 }
130
131 parent.appendChild(
132 tr( null, null, [
133 td( null, null, [
134 text( i18n.props_title )
135 ]),
136 td( null, { style: { width: "99%" } }, [
137 createElement( "textarea", null, {
138 name: "properties",
Guillaume Nodetb47d6602010-03-04 20:54:39 +0000139 style: { height: "20em", width: "99%" }
Felix Meschberger62e1a4f2010-02-18 15:36:53 +0000140 }, [ text( propsValue ) ] ),
Guillaume Nodetb47d6602010-03-04 20:54:39 +0000141 createElement( "br" ),
Felix Meschberger62e1a4f2010-02-18 15:36:53 +0000142 text( i18n.props_enter )
143 ])
144 ])
145 );
146}
147
148function printForm( /* Element */ parent, obj ) {
149 var propList;
150 for (var idx in obj.propertylist)
151 {
152 var prop = obj.propertylist[idx];
153 var attr = obj[prop];
154
155 var trEl = tr( null, null, [
156 td( null, null, [ text( attr.name ) ] )
157 ]);
158 parent.appendChild( trEl );
159
160 var tdEl = td( null, { style: { width: "99%" } } );
161 trEl.appendChild( tdEl );
162
163 if (attr.value != undefined)
164 {
165 // check is required to also handle empty strings, 0 and false
166 tdEl.appendChild( createInput( prop, attr.value, attr.type, '99%' ) );
167 tdEl.appendChild( createElement( "br" ) );
168 }
169 else if (typeof(attr.type) == 'object')
170 {
171 // assume attr.values and multiselect
172 createMultiSelect( tdEl, prop, attr.values, attr.type, '99%' );
173 tdEl.appendChild( createElement( "br" ) );
174 }
175 else if (attr.values.length == 0)
176 {
177 tdEl.appendChild( createSpan( prop, "", attr.type ) );
178 }
179 else
180 {
181 for (var i=0;i<attr.values.length;i++)
182 {
183 tdEl.appendChild( createSpan( prop, attr.values[i], attr.type ) );
184 }
185 }
186
187 if (attr.description)
188 {
189 addText( tdEl, attr.description );
190 }
191
192 if (propList) {
193 propList += ',' + prop;
194 } else {
195 propList = prop;
196 }
197 }
198
199 parent.appendChild( createElement( "input", null, {
200 type: "hidden",
201 name: "propertylist",
202 value: propList
203 })
204 );
205 // FIX for IE6 and above: checkbox can only be checked after it is in the DOM
206 $(".checked_box").attr("checked", true).removeClass("checked_box");
207}
208
209function printConfigurationInfo( /* Element */ parent, obj )
210{
211 parent.appendChild( tr( null, null, [
212 createElement( "th", null, { colSpan: "2" }, [
213 text( i18n.cfg_title )
214 ])
215 ])
216 );
217
218 parent.appendChild( tr( null, null, [
219 td( null, null, [
220 text( i18n.pid )
221 ]),
222 td( null, null, [
223 text( obj.pid )
224 ])
225 ])
226 );
227
228 if (obj.factoryPid)
229 {
230 parent.appendChild( tr( null, null, [
231 td( null, null, [
232 text( i18n.fpid )
233 ]),
234 td( null, null, [
235 text( obj.factoryPid )
236 ])
237 ])
238 );
239 }
240
241 var binding = obj.bundleLocation;
242 if (!binding)
243 {
244 binding = i18n.unbound;
245 }
246
247 parent.appendChild( tr( null, null, [
248 td( null, null, [
249 text( i18n.binding )
250 ]),
251 td( null, null, [
252 text( binding )
253 ])
254 ])
255 );
Felix Meschberger62e1a4f2010-02-18 15:36:53 +0000256
Felix Meschberger62e1a4f2010-02-18 15:36:53 +0000257}
258
259
260var spanCounter = 0;
261/* Element */ function createSpan(prop, value, type) {
262 spanCounter++;
263 var newId = prop + spanCounter;
264
265 var addButton = createElement("input", null,
266 { type: "button",
267 style: {width : "5%"},
268 value: "+"
269 }
270 );
271 $(addButton).click(function() {addValue(prop, newId)});
272 var remButton = createElement("input", null,
273 { type: "button",
274 style: {width : "5%"},
275 value: "-"
276 }
277 );
278 $(remButton).click(function() {removeValue(newId)});
279 var spanEl = createElement( "span", null, { id: newId }, [
280 createInput( prop, value, type, '89%' ), addButton, remButton,
281 createElement("br")
282 ]);
283
284 return spanEl;
285}
286
287/* Element */ function createInput(prop, value, type, width) {
288 if (type == 11) { // AttributeDefinition.BOOLEAN
289
290 var inputEl = createElement( "input", null, {
291 type: "checkbox",
292 name: prop,
293 value: "true"
294 });
295
296 if (value && typeof(value) != "boolean")
297 {
298 value = value.toString().toLowerCase() == "true";
299 }
300 if (value)
301 {
302 $(inputEl).addClass("checked_box");
303 }
304 var hiddenEl = createElement( "input", null, {
305 type: "hidden",
306 name: prop,
307 value: "false"
308 });
309 var divEl = createElement("div");
310 divEl.appendChild(inputEl);
311 divEl.appendChild(hiddenEl);
312 return divEl;
313
314 } else if (typeof(type) == "object") { // predefined values
315
316 var selectEl = createElement( "select", null, {
317 name: prop,
318 style: { width: width }
319 });
320
321 var labels = type.labels;
322 var values = type.values;
323 for (var idx in labels) {
324 var optionEl = createElement( "option", null, {
325 value: values[idx]
326 }, [ text( labels[idx] ) ]);
327
328 if (value == values[idx])
329 {
330 optionEl.setAttribute( "selected", true );
331 }
332 selectEl.appendChild( optionEl );
333 }
334
335 return selectEl;
336
337 } else { // Simple
338 return createElement( "input", null, {
339 type: "text",
340 name: prop,
341 value: value,
342 style: { width: width }
343 });
344 }
345}
346
347function createMultiSelect(/* Element */ parent, prop, values, options, width) {
348 // convert value list into 'set'
349 var valueSet = new Object();
350 for (var idx in values) {
351 valueSet[ values[idx] ] = true;
352 }
353
354 var labels = options.labels;
355 var values = options.values;
356 for (var idx in labels) {
357
358 var inputEl = createElement( "input", null, {
359 type: "checkbox",
360 name: prop,
361 value: values[idx]
362 });
363
364 if (valueSet[ values[idx] ])
365 {
366 inputEl.setAttribute( "checked", true );
367 }
368
369 var labelEl = createElement( "label", "multiselect" );
370 labelEl.appendChild( inputEl );
371 addText( labelEl, labels[idx] );
372
373 parent.appendChild( labelEl );
374 }
375}
376
377
378function addValue(prop, vidx)
379{
380 var span = document.getElementById(vidx);
381 if (!span)
382 {
383 return;
384 }
385 var newSpan = createSpan(prop, '');
386 span.parentNode.insertBefore(newSpan, span.nextSibling);
387 // FIX for IE6 and above: checkbox can only be checked after it is in the DOM
388 $(".checked_box").attr("checked", true).removeClass("checked_box");
389 //$(span).ready(initStaticWidgets);
390}
391
392function removeValue(vidx)
393{
394 var span = document.getElementById(vidx);
395 if (!span)
396 {
397 return;
398 }
399 span.parentNode.removeChild(span);
400}
401
402function configConfirm(/* String */ message, /* String */ title, /* String */ location)
403{
404 var message = i18n.del_ask;
405
406 if (title) {
407 message += "\r\n" + i18n.del_config + title;
408 }
409 if (location) {
410 message += "\r\n" + i18n.del_bundle + location;
411 }
412
413 return confirm(message);
414}
415
416function confirmDelete(/* String */ title, /* String */ location)
417{
Carsten Ziegeler4e070fe2010-03-10 16:41:53 +0000418 return configConfirm(i18n.del_ask, title, location);
Felix Meschberger62e1a4f2010-02-18 15:36:53 +0000419}
420
421function confirmUnbind(/* String */ title, /* String */ location)
422{
423 return configConfirm(i18n.unbind_ask, title, location);
424}
425
Carsten Ziegeler4e070fe2010-03-10 16:41:53 +0000426function addConfig(conf) {
427 var tr = configRow.clone().appendTo(configBody);
Felix Meschbergerfdfbd602010-03-17 06:55:00 +0000428
429 // rendering name - indented if factory pid is set
430 var nms = tr.find('td:eq(0) span')
431 if (conf.fpid) {
432 nms.after(conf.id);
433 tr.attr('fpid', conf.name);
434 } else {
435 nms.addClass('ui-helper-hidden').parent().text(conf.name);
436 }
437
438 tr.find('td:eq(0)').click(function() { // name & edit
Carsten Ziegeler4e070fe2010-03-10 16:41:53 +0000439 configure(conf.id);
440 });
Felix Meschbergerfdfbd602010-03-17 06:55:00 +0000441 tr.find('td:eq(1)').html(conf.bundle ? '<a href="' + pluginRoot + '/../bundles/' + conf.bundle + '">' + conf.bundle_name + '</a>' : '-'); // binding
Carsten Ziegeler4e070fe2010-03-10 16:41:53 +0000442
443 // buttons
444 tr.find('li:eq(0)').click(function() { // edit
445 configure(conf.id);
446 });
447 tr.find('li:eq(2)').click(function() { // delete
448 if ( confirmDelete(conf.id, conf.bundle_name) ) {
449 $.post(pluginRoot + '/' + conf.id + '?apply=1&delete=1', null, function() {
450 document.location.href = pluginRoot;
451 }, 'json');
452 }
453 });
454 if (conf.bundle) tr.find('li:eq(1)').click(function() { // unbind
455 if ( confirmUnbind(conf.id, conf.bundle_name) ) {
456 $.post(pluginRoot + '/' + conf.id + '?apply=1&delete=1', null, function() {
457 document.location.href = pluginRoot + '/' + conf.id;
458 }, 'json');
459 }
460 }).removeClass('ui-state-disabled');
Felix Meschberger62e1a4f2010-02-18 15:36:53 +0000461}
462
Carsten Ziegeler4e070fe2010-03-10 16:41:53 +0000463function addFactoryConfig(conf) {
Felix Meschbergerfdfbd602010-03-17 06:55:00 +0000464 var tr = factoryRow.clone().appendTo(configTable).attr('fpid', conf.name);
465 //tr.find('td:eq(1)').text(conf.id); // fpid
Felix Meschberger1206e2c2010-03-13 15:09:51 +0000466 tr.find('td:eq(0)').text(conf.name).click(function() { // name & edit
Carsten Ziegeler4e070fe2010-03-10 16:41:53 +0000467 configure(conf.id, true);
468 });
469 // buttons
470 tr.find('li:eq(0)').click(function() { // edit
471 configure(conf.id, true);
472 });
473}
474
Felix Meschbergerfdfbd602010-03-17 06:55:00 +0000475function treetableExtraction(node) {
476 var td = $(node);
477 var text = td.text();
478 if (!text) return text;
479
480 // current sort order
481 var desc = $(this)[0].sortList[0][1];
482
483 var row = td.parent();
484 var fpid = row.attr('fpid');
485
486 // factory row
487 if ( row.hasClass('fpid') && fpid) return fpid + (desc==0?1:0) + text;
488
489 // bundle or name row
490 if ( fpid ) return fpid + desc + text;
491
492 return mixedLinksExtraction(node);
493};
494
Felix Meschberger62e1a4f2010-02-18 15:36:53 +0000495$(document).ready(function() {
Carsten Ziegeler4e070fe2010-03-10 16:41:53 +0000496 configContent = $('#configContent');
497 // config table list
Felix Meschbergerfdfbd602010-03-17 06:55:00 +0000498 configTable = $('#configTable');
Carsten Ziegeler4e070fe2010-03-10 16:41:53 +0000499 configBody = configTable.find('tbody');
Felix Meschbergerfdfbd602010-03-17 06:55:00 +0000500 configRow = configBody.find('tr:eq(0)').clone();
501 factoryRow = configBody.find('tr:eq(1)').clone();
Felix Meschberger1206e2c2010-03-13 15:09:51 +0000502
Carsten Ziegeler4e070fe2010-03-10 16:41:53 +0000503 // setup button - cannot inline in dialog option because of i18n
504 var _buttons = {};
505 _buttons[i18n.abort] = function() {
506 $(this).dialog('close');
Felix Meschberger62e1a4f2010-02-18 15:36:53 +0000507 }
Carsten Ziegeler4e070fe2010-03-10 16:41:53 +0000508 _buttons[i18n.reset] = function() {
509 var form = document.getElementById('editorForm');
510 if (form) form.reset();
511 }
512 _buttons[i18n.save] = function() {
513 $.post(pluginRoot + '/' + $(this).attr('__pid') + '?' + $(this).find('form').serialize());
514 $(this).dialog('close');
515 }
516 // prepare editor, but don't open yet!
517 editor = $('#editor').dialog({
518 autoOpen : false,
519 modal : true,
520 width : '90%',
521 closeText: i18n.abort,
522 buttons : _buttons
523 });
524
525 // display the configuration data
526 $(".statline").html(configData.status ? i18n.stat_ok : i18n.stat_missing);
527 if (configData.status) {
Felix Meschbergerfdfbd602010-03-17 06:55:00 +0000528 configBody.empty();
529 var factories = {};
Carsten Ziegeler4e070fe2010-03-10 16:41:53 +0000530
Felix Meschbergerfdfbd602010-03-17 06:55:00 +0000531 for(var i in configData.pids) {
532 var c = configData.pids[i];
533 if (c.fpid) {
534 if (!factories[c.fpid]) factories[c.fpid] = new Array();
535 factories[c.fpid].push(c);
536 } else {
537 addConfig(c);
538 }
539 }
540 for(var i in configData.fpids) {
541 addFactoryConfig(configData.fpids[i]);
Felix Meschberger1206e2c2010-03-13 15:09:51 +0000542
Felix Meschbergerfdfbd602010-03-17 06:55:00 +0000543 var confs = factories[ configData.fpids[i].id ];
544 if (confs) for (var j in confs) {
545 addConfig(confs[j]);
546 }
547 }
548 initStaticWidgets(configTable);
549
550 // init tablesorte
551 configTable.tablesorter({
552 headers: { 2: { sorter: false } },
553 sortList: [[0,1]],
554 textExtraction: treetableExtraction
555 }).bind('sortStart', function() { // clear cache, otherwse extraction will not work
556 var table = $(this).trigger('update');
557 }).find('th:eq(0)').click();
Carsten Ziegeler4e070fe2010-03-10 16:41:53 +0000558 } else {
559 configContent.addClass('ui-helper-hidden');
560 }
561 if (selectedPid) configure(selectedPid);
Felix Meschberger62e1a4f2010-02-18 15:36:53 +0000562});