blob: 11061ce3604f2e4254d3b2e33fff1783373a4f6e [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');
Carsten Ziegeler149faaa2010-03-10 16:41:53 +0000123 initStaticWidgets(editor.attr('__pid', obj.pid).dialog('option', 'title', obj.title).dialog('open'));
Felix Meschbergerb812b2e2010-02-18 15:36:53 +0000124}
125
126function printTextArea(/* Element */ parent, props )
127{
128
129 var propsValue = "";
130 for (var key in props)
131 {
132 propsValue += key + ' = ' + props[key] + '\r\n';
133 }
134
135 parent.appendChild(
136 tr( null, null, [
137 td( null, null, [
138 text( i18n.props_title )
139 ]),
140 td( null, { style: { width: "99%" } }, [
141 createElement( "textarea", null, {
142 name: "properties",
Guillaume Nodet283faa32010-03-04 20:54:39 +0000143 style: { height: "20em", width: "99%" }
Felix Meschbergerb812b2e2010-02-18 15:36:53 +0000144 }, [ text( propsValue ) ] ),
Guillaume Nodet283faa32010-03-04 20:54:39 +0000145 createElement( "br" ),
Felix Meschbergerb812b2e2010-02-18 15:36:53 +0000146 text( i18n.props_enter )
147 ])
148 ])
149 );
150}
151
152function printForm( /* Element */ parent, obj ) {
153 var propList;
154 for (var idx in obj.propertylist)
155 {
156 var prop = obj.propertylist[idx];
157 var attr = obj[prop];
158
159 var trEl = tr( null, null, [
160 td( null, null, [ text( attr.name ) ] )
161 ]);
162 parent.appendChild( trEl );
163
164 var tdEl = td( null, { style: { width: "99%" } } );
165 trEl.appendChild( tdEl );
166
167 if (attr.value != undefined)
168 {
169 // check is required to also handle empty strings, 0 and false
170 tdEl.appendChild( createInput( prop, attr.value, attr.type, '99%' ) );
171 tdEl.appendChild( createElement( "br" ) );
172 }
173 else if (typeof(attr.type) == 'object')
174 {
175 // assume attr.values and multiselect
176 createMultiSelect( tdEl, prop, attr.values, attr.type, '99%' );
177 tdEl.appendChild( createElement( "br" ) );
178 }
179 else if (attr.values.length == 0)
180 {
181 tdEl.appendChild( createSpan( prop, "", attr.type ) );
182 }
183 else
184 {
185 for (var i=0;i<attr.values.length;i++)
186 {
187 tdEl.appendChild( createSpan( prop, attr.values[i], attr.type ) );
188 }
189 }
190
191 if (attr.description)
192 {
193 addText( tdEl, attr.description );
194 }
195
196 if (propList) {
197 propList += ',' + prop;
198 } else {
199 propList = prop;
200 }
201 }
202
203 parent.appendChild( createElement( "input", null, {
204 type: "hidden",
205 name: "propertylist",
206 value: propList
207 })
208 );
209 // FIX for IE6 and above: checkbox can only be checked after it is in the DOM
210 $(".checked_box").attr("checked", true).removeClass("checked_box");
211}
212
213function printConfigurationInfo( /* Element */ parent, obj )
214{
215 parent.appendChild( tr( null, null, [
216 createElement( "th", null, { colSpan: "2" }, [
217 text( i18n.cfg_title )
218 ])
219 ])
220 );
221
222 parent.appendChild( tr( null, null, [
223 td( null, null, [
224 text( i18n.pid )
225 ]),
226 td( null, null, [
227 text( obj.pid )
228 ])
229 ])
230 );
231
232 if (obj.factoryPid)
233 {
234 parent.appendChild( tr( null, null, [
235 td( null, null, [
236 text( i18n.fpid )
237 ]),
238 td( null, null, [
239 text( obj.factoryPid )
240 ])
241 ])
242 );
243 }
244
245 var binding = obj.bundleLocation;
246 if (!binding)
247 {
248 binding = i18n.unbound;
249 }
250
251 parent.appendChild( tr( null, null, [
252 td( null, null, [
253 text( i18n.binding )
254 ]),
255 td( null, null, [
256 text( binding )
257 ])
258 ])
259 );
Felix Meschbergerb812b2e2010-02-18 15:36:53 +0000260
Felix Meschbergerb812b2e2010-02-18 15:36:53 +0000261}
262
263
264var spanCounter = 0;
265/* Element */ function createSpan(prop, value, type) {
266 spanCounter++;
267 var newId = prop + spanCounter;
268
269 var addButton = createElement("input", null,
270 { type: "button",
271 style: {width : "5%"},
272 value: "+"
273 }
274 );
275 $(addButton).click(function() {addValue(prop, newId)});
276 var remButton = createElement("input", null,
277 { type: "button",
278 style: {width : "5%"},
279 value: "-"
280 }
281 );
282 $(remButton).click(function() {removeValue(newId)});
283 var spanEl = createElement( "span", null, { id: newId }, [
284 createInput( prop, value, type, '89%' ), addButton, remButton,
285 createElement("br")
286 ]);
287
288 return spanEl;
289}
290
291/* Element */ function createInput(prop, value, type, width) {
292 if (type == 11) { // AttributeDefinition.BOOLEAN
293
294 var inputEl = createElement( "input", null, {
295 type: "checkbox",
296 name: prop,
297 value: "true"
298 });
299
300 if (value && typeof(value) != "boolean")
301 {
302 value = value.toString().toLowerCase() == "true";
303 }
304 if (value)
305 {
306 $(inputEl).addClass("checked_box");
307 }
308 var hiddenEl = createElement( "input", null, {
309 type: "hidden",
310 name: prop,
311 value: "false"
312 });
313 var divEl = createElement("div");
314 divEl.appendChild(inputEl);
315 divEl.appendChild(hiddenEl);
316 return divEl;
317
318 } else if (typeof(type) == "object") { // predefined values
319
320 var selectEl = createElement( "select", null, {
321 name: prop,
322 style: { width: width }
323 });
324
325 var labels = type.labels;
326 var values = type.values;
327 for (var idx in labels) {
328 var optionEl = createElement( "option", null, {
329 value: values[idx]
330 }, [ text( labels[idx] ) ]);
331
332 if (value == values[idx])
333 {
334 optionEl.setAttribute( "selected", true );
335 }
336 selectEl.appendChild( optionEl );
337 }
338
339 return selectEl;
340
341 } else { // Simple
342 return createElement( "input", null, {
343 type: "text",
344 name: prop,
345 value: value,
346 style: { width: width }
347 });
348 }
349}
350
351function createMultiSelect(/* Element */ parent, prop, values, options, width) {
352 // convert value list into 'set'
353 var valueSet = new Object();
354 for (var idx in values) {
355 valueSet[ values[idx] ] = true;
356 }
357
358 var labels = options.labels;
359 var values = options.values;
360 for (var idx in labels) {
361
362 var inputEl = createElement( "input", null, {
363 type: "checkbox",
364 name: prop,
365 value: values[idx]
366 });
367
368 if (valueSet[ values[idx] ])
369 {
370 inputEl.setAttribute( "checked", true );
371 }
372
373 var labelEl = createElement( "label", "multiselect" );
374 labelEl.appendChild( inputEl );
375 addText( labelEl, labels[idx] );
376
377 parent.appendChild( labelEl );
378 }
379}
380
381
382function addValue(prop, vidx)
383{
384 var span = document.getElementById(vidx);
385 if (!span)
386 {
387 return;
388 }
389 var newSpan = createSpan(prop, '');
390 span.parentNode.insertBefore(newSpan, span.nextSibling);
391 // FIX for IE6 and above: checkbox can only be checked after it is in the DOM
392 $(".checked_box").attr("checked", true).removeClass("checked_box");
393 //$(span).ready(initStaticWidgets);
394}
395
396function removeValue(vidx)
397{
398 var span = document.getElementById(vidx);
399 if (!span)
400 {
401 return;
402 }
403 span.parentNode.removeChild(span);
404}
405
406function configConfirm(/* String */ message, /* String */ title, /* String */ location)
407{
408 var message = i18n.del_ask;
409
410 if (title) {
411 message += "\r\n" + i18n.del_config + title;
412 }
413 if (location) {
414 message += "\r\n" + i18n.del_bundle + location;
415 }
416
417 return confirm(message);
418}
419
420function confirmDelete(/* String */ title, /* String */ location)
421{
Carsten Ziegeler149faaa2010-03-10 16:41:53 +0000422 return configConfirm(i18n.del_ask, title, location);
Felix Meschbergerb812b2e2010-02-18 15:36:53 +0000423}
424
425function confirmUnbind(/* String */ title, /* String */ location)
426{
427 return configConfirm(i18n.unbind_ask, title, location);
428}
429
Carsten Ziegeler149faaa2010-03-10 16:41:53 +0000430function addConfig(conf) {
431 var tr = configRow.clone().appendTo(configBody);
Felix Meschberger67726fe2010-03-17 06:55:00 +0000432
433 // rendering name - indented if factory pid is set
434 var nms = tr.find('td:eq(0) span')
435 if (conf.fpid) {
436 nms.after(conf.id);
437 tr.attr('fpid', conf.name);
438 } else {
439 nms.addClass('ui-helper-hidden').parent().text(conf.name);
440 }
441
442 tr.find('td:eq(0)').click(function() { // name & edit
Carsten Ziegeler149faaa2010-03-10 16:41:53 +0000443 configure(conf.id);
444 });
Felix Meschberger67726fe2010-03-17 06:55:00 +0000445 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 +0000446
447 // buttons
448 tr.find('li:eq(0)').click(function() { // edit
449 configure(conf.id);
450 });
451 tr.find('li:eq(2)').click(function() { // delete
452 if ( confirmDelete(conf.id, conf.bundle_name) ) {
453 $.post(pluginRoot + '/' + conf.id + '?apply=1&delete=1', null, function() {
454 document.location.href = pluginRoot;
455 }, 'json');
456 }
457 });
458 if (conf.bundle) tr.find('li:eq(1)').click(function() { // unbind
459 if ( confirmUnbind(conf.id, conf.bundle_name) ) {
460 $.post(pluginRoot + '/' + conf.id + '?apply=1&delete=1', null, function() {
461 document.location.href = pluginRoot + '/' + conf.id;
462 }, 'json');
463 }
464 }).removeClass('ui-state-disabled');
Felix Meschbergerb812b2e2010-02-18 15:36:53 +0000465}
466
Carsten Ziegeler149faaa2010-03-10 16:41:53 +0000467function addFactoryConfig(conf) {
Felix Meschberger67726fe2010-03-17 06:55:00 +0000468 var tr = factoryRow.clone().appendTo(configTable).attr('fpid', conf.name);
469 //tr.find('td:eq(1)').text(conf.id); // fpid
Felix Meschberger1e671e12010-03-13 15:09:51 +0000470 tr.find('td:eq(0)').text(conf.name).click(function() { // name & edit
Carsten Ziegeler149faaa2010-03-10 16:41:53 +0000471 configure(conf.id, true);
472 });
473 // buttons
474 tr.find('li:eq(0)').click(function() { // edit
475 configure(conf.id, true);
476 });
477}
478
Felix Meschberger67726fe2010-03-17 06:55:00 +0000479function treetableExtraction(node) {
480 var td = $(node);
481 var text = td.text();
482 if (!text) return text;
483
484 // current sort order
485 var desc = $(this)[0].sortList[0][1];
486
487 var row = td.parent();
488 var fpid = row.attr('fpid');
489
490 // factory row
491 if ( row.hasClass('fpid') && fpid) return fpid + (desc==0?1:0) + text;
492
493 // bundle or name row
494 if ( fpid ) return fpid + desc + text;
495
496 return mixedLinksExtraction(node);
497};
498
Felix Meschbergerb812b2e2010-02-18 15:36:53 +0000499$(document).ready(function() {
Carsten Ziegeler149faaa2010-03-10 16:41:53 +0000500 configContent = $('#configContent');
501 // config table list
Felix Meschberger67726fe2010-03-17 06:55:00 +0000502 configTable = $('#configTable');
Carsten Ziegeler149faaa2010-03-10 16:41:53 +0000503 configBody = configTable.find('tbody');
Felix Meschberger67726fe2010-03-17 06:55:00 +0000504 configRow = configBody.find('tr:eq(0)').clone();
505 factoryRow = configBody.find('tr:eq(1)').clone();
Felix Meschberger1e671e12010-03-13 15:09:51 +0000506
Carsten Ziegeler149faaa2010-03-10 16:41:53 +0000507 // setup button - cannot inline in dialog option because of i18n
508 var _buttons = {};
509 _buttons[i18n.abort] = function() {
510 $(this).dialog('close');
Felix Meschbergerb812b2e2010-02-18 15:36:53 +0000511 }
Carsten Ziegeler149faaa2010-03-10 16:41:53 +0000512 _buttons[i18n.reset] = function() {
513 var form = document.getElementById('editorForm');
514 if (form) form.reset();
515 }
516 _buttons[i18n.save] = function() {
517 $.post(pluginRoot + '/' + $(this).attr('__pid') + '?' + $(this).find('form').serialize());
518 $(this).dialog('close');
519 }
520 // prepare editor, but don't open yet!
521 editor = $('#editor').dialog({
522 autoOpen : false,
523 modal : true,
524 width : '90%',
525 closeText: i18n.abort,
526 buttons : _buttons
527 });
Valentin Valchevde160882010-03-22 09:30:38 +0000528 editorMessage = editor.find('p');
Carsten Ziegeler149faaa2010-03-10 16:41:53 +0000529
530 // display the configuration data
531 $(".statline").html(configData.status ? i18n.stat_ok : i18n.stat_missing);
532 if (configData.status) {
Felix Meschberger67726fe2010-03-17 06:55:00 +0000533 configBody.empty();
534 var factories = {};
Carsten Ziegeler149faaa2010-03-10 16:41:53 +0000535
Felix Meschberger67726fe2010-03-17 06:55:00 +0000536 for(var i in configData.pids) {
537 var c = configData.pids[i];
538 if (c.fpid) {
539 if (!factories[c.fpid]) factories[c.fpid] = new Array();
540 factories[c.fpid].push(c);
541 } else {
542 addConfig(c);
543 }
544 }
545 for(var i in configData.fpids) {
546 addFactoryConfig(configData.fpids[i]);
Felix Meschberger1e671e12010-03-13 15:09:51 +0000547
Felix Meschberger67726fe2010-03-17 06:55:00 +0000548 var confs = factories[ configData.fpids[i].id ];
549 if (confs) for (var j in confs) {
550 addConfig(confs[j]);
551 }
552 }
553 initStaticWidgets(configTable);
554
555 // init tablesorte
556 configTable.tablesorter({
557 headers: { 2: { sorter: false } },
558 sortList: [[0,1]],
559 textExtraction: treetableExtraction
560 }).bind('sortStart', function() { // clear cache, otherwse extraction will not work
561 var table = $(this).trigger('update');
562 }).find('th:eq(0)').click();
Carsten Ziegeler149faaa2010-03-10 16:41:53 +0000563 } else {
564 configContent.addClass('ui-helper-hidden');
565 }
566 if (selectedPid) configure(selectedPid);
Felix Meschbergerb812b2e2010-02-18 15:36:53 +0000567});