FELIX-1988 Apply 10.deployment_plugin.patch by Valentin Valchev (thanks)

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@911379 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/webconsole/src/main/resources/res/ui/deployment.css b/webconsole/src/main/resources/res/ui/deployment.css
new file mode 100644
index 0000000..5c569c7
--- /dev/null
+++ b/webconsole/src/main/resources/res/ui/deployment.css
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+
+.pkgname { cursor:pointer }
+.pkgname span { float:left }
diff --git a/webconsole/src/main/resources/res/ui/deployment.js b/webconsole/src/main/resources/res/ui/deployment.js
new file mode 100644
index 0000000..7dbe6ec
--- /dev/null
+++ b/webconsole/src/main/resources/res/ui/deployment.js
@@ -0,0 +1,171 @@
+/*
+ * 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.
+ */
+
+function fixId(id) { return id.replace('.', '_'); }
+
+function data( /* Array of Object */ dataArray ) { // render components
+	if (dataArray.length == 1) {
+		entry( dataArray[0], true );
+	} else {
+		for ( var idx in dataArray ) {
+			entry( dataArray[idx] );
+		}
+	}
+}
+
+function entry( /* Object */ dataEntry, /* boolean */ singleEntry ) {
+	var id = fixId(dataEntry.id);
+	var trElement = tr( 'ui-state-active', { 'id': 'entry' + id });
+
+	// entry brief
+	entryInternal( trElement,  dataEntry, singleEntry );
+	plugin_table.append(trElement);
+
+	// dataEntry detailed properties
+	trElement = tr( 'ui-helper-hidden', { 
+		'id'   : 'entry' + id + '_details'
+	});
+	if (dataEntry.props) {
+		getDataEntryDetails( trElement, dataEntry.props );
+	}
+	plugin_table.append(trElement);
+}
+
+function entryInternal( /* Element */ parent, /* Object */ dataEntry, /* boolean */ singleEntry ) {
+	var id = dataEntry.id;
+	var _id = fixId(id);
+
+	parent.appendChild( td( null, null, [ text( id ) ] ) );
+	parent.appendChild( td( null, 
+			{
+				'onclick': 'toggleDetails("#entry' + _id + '")',
+				'class': 'pkgname'
+			}, 
+			[
+				createElement( 'span', 'ui-icon ui-icon-triangle-1-e', { id: 'entry' + _id + '_icon'} ),
+				text(dataEntry.name)
+			]
+		)
+	);
+	parent.appendChild( td( null, null, [ text( dataEntry.state ) ] ) );
+
+	for ( var aidx in dataEntry.actions ) {
+		var action = dataEntry.actions[aidx];
+		parent.appendChild( actionButton( action.enabled, id, action.link, action.name ) );
+	}
+}
+
+
+/* Element */ function actionButton( /* boolean */ enabled, /* long */ id, /* String */ op, /* String */ opLabel ) {
+	var buttonTd = td( "content", { align: "right" } );
+	if ( op ) {
+		switch (opLabel) {
+			case "Uninstall" : opLabel = i18n.uninstall; break;
+		}
+		var input = createElement( "input", null, {
+				type: 'button',
+				value: opLabel,
+				onclick: 'changeDataEntryState("' + id + '", "' + op + '");'
+			});
+		if (!enabled) {
+			input.setAttribute( "disabled", true );
+			$(input).addClass('ui-state-disabled');
+		}
+		buttonTd.appendChild( input );
+	} else {
+		addText( buttonTd, "\u00a0" );
+	}
+	return buttonTd;
+}
+
+
+function getDataEntryDetails( /* Element */ parent, /* Array of Object */ details )
+{
+	parent.appendChild( addText( td( "content"), "\u00a0" ) );
+	
+	var tdEl = td( null, { colspan: 4 } );
+	parent.appendChild( tdEl );
+	
+	var tableEl = createElement( "table", null, { border: 0 } );
+	tdEl.appendChild( tableEl );
+	
+	var tbody = createElement( "tbody" );
+	tableEl.appendChild( tbody );
+	for (var idx in details) {
+		var prop = details[idx];
+		var trEl = tr();
+		var key = prop.key;
+		switch (key) {
+			case 'Package Name': key = i18n.package_name; break;
+			case 'Version'     : key = i18n.version; break;
+			case 'Bundles'     : key = i18n.bundles; break;
+		}
+		trEl.appendChild( addText( td( null, { noWrap: true } ), key ) );
+
+		var proptd = td();
+		trEl.appendChild( proptd );
+		$(proptd).html( prop.value ? prop.value : "\u00a0");
+
+		tbody.appendChild( trEl );
+	}
+ }
+
+
+function changeDataEntryState(/* long */ id, /* String */ action) {
+	var parm = pluginRoot + "/" + id + "?action=" + action;
+	$.post(parm, null, function() { // always reload
+		document.location.reload();
+	}, "text");
+}
+
+
+function toggleDetails(name) {
+	var icon = $(name + '_icon');
+	var details = $(name + '_details');
+	var show = icon.attr('show');
+	if (typeof show == 'undefined') show = '';
+	icon.attr('show', show ? '' : 'true');
+
+	if (show == 'true') {
+		icon.removeClass('ui-icon-triangle-1-s').addClass('ui-icon-triangle-1-e');
+		details.addClass('ui-helper-hidden');
+	} else {
+		icon.removeClass('ui-icon-triangle-1-e').addClass('ui-icon-triangle-1-s');
+		details.removeClass('ui-helper-hidden');
+	}
+}
+
+var plugin_table = false;
+$(document).ready(function() {
+	plugin_table = $('#plugin_table');
+	var /* Array of Data Objects */ bundleData = packageListData;
+	if (bundleData.error) {
+		$('.statline').text(i18n.status_no_serv);
+		$('#dps1').addClass('ui-helper-hidden');
+	} else if (!bundleData.data || bundleData.data.length == 0) {
+		$('.statline').text(i18n.status_no_data);
+		$('#dps1').removeClass('ui-helper-hidden');
+		$('#dps2').addClass('ui-helper-hidden');
+	} else {
+		data( bundleData.data );
+		$('.statline').text(i18n.status_ok);
+		$('#dps1').removeClass('ui-helper-hidden');
+		$('#dps2').removeClass('ui-helper-hidden');
+		initStaticWidgets(plugin_table);
+	}
+});
+
diff --git a/webconsole/src/main/resources/templates/deployment.html b/webconsole/src/main/resources/templates/deployment.html
new file mode 100644
index 0000000..525738d
--- /dev/null
+++ b/webconsole/src/main/resources/templates/deployment.html
@@ -0,0 +1,52 @@
+<script type="text/javascript" src="res/ui/deployment.js"></script>
+<script type="text/javascript">
+// <![CDATA[
+var i18n = {
+	status_no_data : "${deployment.status.no_data}",
+	status_no_serv : "${deployment.status.no_service}",
+	status_ok      : "${deployment.status.ok}",
+	package_name   : "${deployment.package.name}",
+	version        : "${version}",
+	bundles        : "${deployment.bundles}",
+	uninstall      : "${deployment.uninstall}"
+}
+var packageListData = ${__data__};
+// ]]>
+</script>
+
+<p class="statline">&nbsp;</p>
+
+<div id="dps1"> <!-- will be hidden if no DP service available -->
+<!-- top header -->
+<form method="post" enctype="multipart/form-data" >
+	<div class="ui-widget-header ui-corner-top buttonGroup" style="text-align: right">
+		<input name="action"  type="hidden" value="deploydp" />
+		<input name="pckfile" type="file" size="50" />
+		<input type="submit" value="${deployment.install_update}" />
+	</div>
+</form>
+
+<div id="dps2"> <!-- will be hidden if no data available -->
+	<table id="plugin_table" class="nicetable">
+	<thead>
+		<tr>
+			<th>${id}</th>
+			<th width="100%">${deployment.details}</th>
+			<th>${version}</th>
+			<th colspan="1">${deployment.actions}</th>
+		</tr>
+	</thead>
+	<tbody>
+	</tbody>
+	</table>
+
+	<!-- bottom header -->
+	<form method="post" enctype="multipart/form-data" >
+		<div class="ui-widget-header ui-corner-bottom buttonGroup" style="text-align: right">
+			<input name="action"  type="hidden" value="deploydp" />
+			<input name="pckfile" type="file" size="50" />
+			<input type="submit" value="${deployment.install_update}" />
+		</div>
+	</form>
+</div><!--dps2-->
+</div><!--dps1-->