blob: 8b93e7ed74fa4934fac2c286a2ac68f0d7f9a707 [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
Felix Meschberger07741202011-07-07 11:55:53 +0000128 initStaticWidgets(editor
129 .attr('__pid', obj.pid)
130 .attr('__location', obj.bundleLocation?obj.bundleLocation:'')
131 .dialog('option', 'title', obj.title)
132 .dialog('open'));
Felix Meschbergerb812b2e2010-02-18 15:36:53 +0000133}
134
135function printTextArea(/* Element */ parent, props )
136{
137
138 var propsValue = "";
139 for (var key in props)
140 {
141 propsValue += key + ' = ' + props[key] + '\r\n';
142 }
143
144 parent.appendChild(
145 tr( null, null, [
146 td( null, null, [
147 text( i18n.props_title )
148 ]),
149 td( null, { style: { width: "99%" } }, [
150 createElement( "textarea", null, {
151 name: "properties",
Guillaume Nodet283faa32010-03-04 20:54:39 +0000152 style: { height: "20em", width: "99%" }
Felix Meschbergerb812b2e2010-02-18 15:36:53 +0000153 }, [ text( propsValue ) ] ),
Guillaume Nodet283faa32010-03-04 20:54:39 +0000154 createElement( "br" ),
Felix Meschbergerb812b2e2010-02-18 15:36:53 +0000155 text( i18n.props_enter )
156 ])
157 ])
158 );
159}
160
161function printForm( /* Element */ parent, obj ) {
162 var propList;
163 for (var idx in obj.propertylist)
164 {
165 var prop = obj.propertylist[idx];
166 var attr = obj[prop];
167
168 var trEl = tr( null, null, [
169 td( null, null, [ text( attr.name ) ] )
170 ]);
171 parent.appendChild( trEl );
172
173 var tdEl = td( null, { style: { width: "99%" } } );
174 trEl.appendChild( tdEl );
175
176 if (attr.value != undefined)
177 {
178 // check is required to also handle empty strings, 0 and false
179 tdEl.appendChild( createInput( prop, attr.value, attr.type, '99%' ) );
180 tdEl.appendChild( createElement( "br" ) );
181 }
182 else if (typeof(attr.type) == 'object')
183 {
184 // assume attr.values and multiselect
185 createMultiSelect( tdEl, prop, attr.values, attr.type, '99%' );
186 tdEl.appendChild( createElement( "br" ) );
187 }
188 else if (attr.values.length == 0)
189 {
190 tdEl.appendChild( createSpan( prop, "", attr.type ) );
191 }
192 else
193 {
194 for (var i=0;i<attr.values.length;i++)
195 {
196 tdEl.appendChild( createSpan( prop, attr.values[i], attr.type ) );
197 }
198 }
199
200 if (attr.description)
201 {
202 addText( tdEl, attr.description );
203 }
204
205 if (propList) {
206 propList += ',' + prop;
207 } else {
208 propList = prop;
209 }
210 }
211
212 parent.appendChild( createElement( "input", null, {
213 type: "hidden",
214 name: "propertylist",
215 value: propList
216 })
217 );
218 // FIX for IE6 and above: checkbox can only be checked after it is in the DOM
219 $(".checked_box").attr("checked", true).removeClass("checked_box");
220}
221
222function printConfigurationInfo( /* Element */ parent, obj )
223{
224 parent.appendChild( tr( null, null, [
225 createElement( "th", null, { colSpan: "2" }, [
226 text( i18n.cfg_title )
227 ])
228 ])
229 );
230
231 parent.appendChild( tr( null, null, [
232 td( null, null, [
233 text( i18n.pid )
234 ]),
235 td( null, null, [
236 text( obj.pid )
237 ])
238 ])
239 );
240
241 if (obj.factoryPid)
242 {
243 parent.appendChild( tr( null, null, [
244 td( null, null, [
245 text( i18n.fpid )
246 ]),
247 td( null, null, [
248 text( obj.factoryPid )
249 ])
250 ])
251 );
252 }
253
254 var binding = obj.bundleLocation;
255 if (!binding)
256 {
257 binding = i18n.unbound;
258 }
259
260 parent.appendChild( tr( null, null, [
261 td( null, null, [
262 text( i18n.binding )
263 ]),
264 td( null, null, [
265 text( binding )
266 ])
267 ])
268 );
Felix Meschbergerb812b2e2010-02-18 15:36:53 +0000269
Felix Meschbergerb812b2e2010-02-18 15:36:53 +0000270}
271
272
273var spanCounter = 0;
274/* Element */ function createSpan(prop, value, type) {
275 spanCounter++;
276 var newId = prop + spanCounter;
277
278 var addButton = createElement("input", null,
279 { type: "button",
280 style: {width : "5%"},
281 value: "+"
282 }
283 );
284 $(addButton).click(function() {addValue(prop, newId)});
285 var remButton = createElement("input", null,
286 { type: "button",
287 style: {width : "5%"},
288 value: "-"
289 }
290 );
291 $(remButton).click(function() {removeValue(newId)});
292 var spanEl = createElement( "span", null, { id: newId }, [
293 createInput( prop, value, type, '89%' ), addButton, remButton,
294 createElement("br")
295 ]);
296
297 return spanEl;
298}
299
300/* Element */ function createInput(prop, value, type, width) {
301 if (type == 11) { // AttributeDefinition.BOOLEAN
302
303 var inputEl = createElement( "input", null, {
304 type: "checkbox",
305 name: prop,
306 value: "true"
307 });
308
309 if (value && typeof(value) != "boolean")
310 {
311 value = value.toString().toLowerCase() == "true";
312 }
313 if (value)
314 {
315 $(inputEl).addClass("checked_box");
316 }
317 var hiddenEl = createElement( "input", null, {
318 type: "hidden",
319 name: prop,
320 value: "false"
321 });
322 var divEl = createElement("div");
323 divEl.appendChild(inputEl);
324 divEl.appendChild(hiddenEl);
325 return divEl;
326
327 } else if (typeof(type) == "object") { // predefined values
328
329 var selectEl = createElement( "select", null, {
330 name: prop,
331 style: { width: width }
332 });
333
334 var labels = type.labels;
335 var values = type.values;
336 for (var idx in labels) {
337 var optionEl = createElement( "option", null, {
338 value: values[idx]
339 }, [ text( labels[idx] ) ]);
340
341 if (value == values[idx])
342 {
343 optionEl.setAttribute( "selected", true );
344 }
345 selectEl.appendChild( optionEl );
346 }
347
348 return selectEl;
349
350 } else { // Simple
351 return createElement( "input", null, {
352 type: "text",
353 name: prop,
354 value: value,
355 style: { width: width }
356 });
357 }
358}
359
360function createMultiSelect(/* Element */ parent, prop, values, options, width) {
361 // convert value list into 'set'
362 var valueSet = new Object();
363 for (var idx in values) {
364 valueSet[ values[idx] ] = true;
365 }
366
367 var labels = options.labels;
368 var values = options.values;
369 for (var idx in labels) {
370
371 var inputEl = createElement( "input", null, {
372 type: "checkbox",
373 name: prop,
374 value: values[idx]
375 });
376
377 if (valueSet[ values[idx] ])
378 {
379 inputEl.setAttribute( "checked", true );
380 }
381
382 var labelEl = createElement( "label", "multiselect" );
383 labelEl.appendChild( inputEl );
384 addText( labelEl, labels[idx] );
385
386 parent.appendChild( labelEl );
387 }
388}
389
390
391function addValue(prop, vidx)
392{
393 var span = document.getElementById(vidx);
394 if (!span)
395 {
396 return;
397 }
398 var newSpan = createSpan(prop, '');
399 span.parentNode.insertBefore(newSpan, span.nextSibling);
400 // FIX for IE6 and above: checkbox can only be checked after it is in the DOM
401 $(".checked_box").attr("checked", true).removeClass("checked_box");
402 //$(span).ready(initStaticWidgets);
403}
404
405function removeValue(vidx)
406{
407 var span = document.getElementById(vidx);
408 if (!span)
409 {
410 return;
411 }
412 span.parentNode.removeChild(span);
413}
414
415function configConfirm(/* String */ message, /* String */ title, /* String */ location)
416{
Felix Meschbergerb812b2e2010-02-18 15:36:53 +0000417 if (title) {
418 message += "\r\n" + i18n.del_config + title;
419 }
420 if (location) {
421 message += "\r\n" + i18n.del_bundle + location;
422 }
423
424 return confirm(message);
425}
426
Felix Meschberger07741202011-07-07 11:55:53 +0000427function deleteConfig(/* String */ configId, /* String */ bundleLocation)
Felix Meschbergerb812b2e2010-02-18 15:36:53 +0000428{
Felix Meschberger07741202011-07-07 11:55:53 +0000429 if ( configConfirm(i18n.del_ask, configId, bundleLocation) ) {
430 $.post(pluginRoot + '/' + configId + '?apply=1&delete=1', null, function() {
431 document.location.href = pluginRoot;
432 }, 'json');
433 return true;
434 }
435 return false;
Felix Meschbergerb812b2e2010-02-18 15:36:53 +0000436}
437
Felix Meschberger07741202011-07-07 11:55:53 +0000438function unbindConfig(/* String */ configId, /* String */ bundleLocation)
Felix Meschbergerb812b2e2010-02-18 15:36:53 +0000439{
Felix Meschberger07741202011-07-07 11:55:53 +0000440 if ( configConfirm(i18n.unbind_ask, configId, bundleLocation) ) {
441 $.post(pluginRoot + '/' + configId + '?unbind=1', null, function() {
442 document.location.href = pluginRoot + '/' + configId;
443 }, 'json');
444 return true;
445 }
446 return false;
Felix Meschbergerb812b2e2010-02-18 15:36:53 +0000447}
448
Carsten Ziegeler149faaa2010-03-10 16:41:53 +0000449function addConfig(conf) {
450 var tr = configRow.clone().appendTo(configBody);
Felix Meschberger67726fe2010-03-17 06:55:00 +0000451
452 // rendering name - indented if factory pid is set
Valentin Valchev0fc8b7b2010-04-15 12:33:58 +0000453 var nms = tr.find('td:eq(0) div');
Felix Meschberger67726fe2010-03-17 06:55:00 +0000454 if (conf.fpid) {
455 nms.after(conf.id);
456 tr.attr('fpid', conf.name);
457 } else {
458 nms.addClass('ui-helper-hidden').parent().text(conf.name);
459 }
460
461 tr.find('td:eq(0)').click(function() { // name & edit
Carsten Ziegeler149faaa2010-03-10 16:41:53 +0000462 configure(conf.id);
463 });
Felix Meschberger67726fe2010-03-17 06:55:00 +0000464 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 +0000465
466 // buttons
467 tr.find('li:eq(0)').click(function() { // edit
468 configure(conf.id);
469 });
470 tr.find('li:eq(2)').click(function() { // delete
Felix Meschberger07741202011-07-07 11:55:53 +0000471 deleteConfig(conf.id, conf.bundle_name);
Carsten Ziegeler149faaa2010-03-10 16:41:53 +0000472 });
Felix Meschberger07741202011-07-07 11:55:53 +0000473 if (conf.bundle) {
474 tr.find('li:eq(1)').click(function() { // unbind
475 unbindConfig(conf.id, conf.bundle_name);
476 }).removeClass('ui-state-disabled');
477 }
Felix Meschbergerb812b2e2010-02-18 15:36:53 +0000478}
479
Carsten Ziegeler149faaa2010-03-10 16:41:53 +0000480function addFactoryConfig(conf) {
Felix Meschberger67726fe2010-03-17 06:55:00 +0000481 var tr = factoryRow.clone().appendTo(configTable).attr('fpid', conf.name);
482 //tr.find('td:eq(1)').text(conf.id); // fpid
Felix Meschberger1e671e12010-03-13 15:09:51 +0000483 tr.find('td:eq(0)').text(conf.name).click(function() { // name & edit
Carsten Ziegeler149faaa2010-03-10 16:41:53 +0000484 configure(conf.id, true);
485 });
486 // buttons
487 tr.find('li:eq(0)').click(function() { // edit
488 configure(conf.id, true);
489 });
490}
491
Felix Meschberger67726fe2010-03-17 06:55:00 +0000492function treetableExtraction(node) {
493 var td = $(node);
494 var text = td.text();
495 if (!text) return text;
496
497 // current sort order
498 var desc = $(this)[0].sortList[0][1];
499
500 var row = td.parent();
501 var fpid = row.attr('fpid');
502
503 // factory row
504 if ( row.hasClass('fpid') && fpid) return fpid + (desc==0?1:0) + text;
505
506 // bundle or name row
507 if ( fpid ) return fpid + desc + text;
508
509 return mixedLinksExtraction(node);
510};
511
Felix Meschbergerb812b2e2010-02-18 15:36:53 +0000512$(document).ready(function() {
Carsten Ziegeler149faaa2010-03-10 16:41:53 +0000513 configContent = $('#configContent');
514 // config table list
Felix Meschberger67726fe2010-03-17 06:55:00 +0000515 configTable = $('#configTable');
Carsten Ziegeler149faaa2010-03-10 16:41:53 +0000516 configBody = configTable.find('tbody');
Felix Meschberger67726fe2010-03-17 06:55:00 +0000517 configRow = configBody.find('tr:eq(0)').clone();
518 factoryRow = configBody.find('tr:eq(1)').clone();
Felix Meschberger1e671e12010-03-13 15:09:51 +0000519
Carsten Ziegeler149faaa2010-03-10 16:41:53 +0000520 // setup button - cannot inline in dialog option because of i18n
521 var _buttons = {};
522 _buttons[i18n.abort] = function() {
523 $(this).dialog('close');
Felix Meschbergerb812b2e2010-02-18 15:36:53 +0000524 }
Carsten Ziegeler149faaa2010-03-10 16:41:53 +0000525 _buttons[i18n.reset] = function() {
526 var form = document.getElementById('editorForm');
527 if (form) form.reset();
528 }
Felix Meschberger07741202011-07-07 11:55:53 +0000529 _buttons[i18n.del] = function() {
530 if (deleteConfig($(this).attr('__pid'), $(this).attr('__location'))) {
531 $(this).dialog('close');
532 }
533 }
534 _buttons[i18n.unbind_btn] = function() {
535 unbindConfig($(this).attr('__pid'), $(this).attr('__location'));
536 }
Carsten Ziegeler149faaa2010-03-10 16:41:53 +0000537 _buttons[i18n.save] = function() {
Valentin Valchev4b25d4f2011-09-15 07:06:36 +0000538 $.post(pluginRoot + '/' + $(this).attr('__pid') + '?' + $(this).find('form').serialize(), function() {
539 // reload on success - prevents AJAX errors - see FELIX-3116
540 document.location.href = pluginRoot;
541 });
Carsten Ziegeler149faaa2010-03-10 16:41:53 +0000542 $(this).dialog('close');
543 }
544 // prepare editor, but don't open yet!
545 editor = $('#editor').dialog({
546 autoOpen : false,
547 modal : true,
548 width : '90%',
549 closeText: i18n.abort,
550 buttons : _buttons
551 });
Valentin Valchevde160882010-03-22 09:30:38 +0000552 editorMessage = editor.find('p');
Carsten Ziegeler149faaa2010-03-10 16:41:53 +0000553
554 // display the configuration data
555 $(".statline").html(configData.status ? i18n.stat_ok : i18n.stat_missing);
556 if (configData.status) {
Felix Meschberger67726fe2010-03-17 06:55:00 +0000557 configBody.empty();
558 var factories = {};
Carsten Ziegeler149faaa2010-03-10 16:41:53 +0000559
Felix Meschberger67726fe2010-03-17 06:55:00 +0000560 for(var i in configData.pids) {
561 var c = configData.pids[i];
562 if (c.fpid) {
563 if (!factories[c.fpid]) factories[c.fpid] = new Array();
564 factories[c.fpid].push(c);
565 } else {
566 addConfig(c);
567 }
568 }
569 for(var i in configData.fpids) {
570 addFactoryConfig(configData.fpids[i]);
Felix Meschberger1e671e12010-03-13 15:09:51 +0000571
Felix Meschberger67726fe2010-03-17 06:55:00 +0000572 var confs = factories[ configData.fpids[i].id ];
573 if (confs) for (var j in confs) {
574 addConfig(confs[j]);
575 }
576 }
577 initStaticWidgets(configTable);
578
579 // init tablesorte
580 configTable.tablesorter({
581 headers: { 2: { sorter: false } },
582 sortList: [[0,1]],
583 textExtraction: treetableExtraction
584 }).bind('sortStart', function() { // clear cache, otherwse extraction will not work
585 var table = $(this).trigger('update');
586 }).find('th:eq(0)').click();
Carsten Ziegeler149faaa2010-03-10 16:41:53 +0000587 } else {
588 configContent.addClass('ui-helper-hidden');
589 }
590 if (selectedPid) configure(selectedPid);
Felix Meschbergerb812b2e2010-02-18 15:36:53 +0000591});