SLING-461 Move Sling Console to Apache Felix/FELIX-562 Move OSGi Console to Apache Felix
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@657024 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/webconsole/src/main/resources/OSGI-INF/metatype/metatype.properties b/webconsole/src/main/resources/OSGI-INF/metatype/metatype.properties
new file mode 100644
index 0000000..be38663
--- /dev/null
+++ b/webconsole/src/main/resources/OSGI-INF/metatype/metatype.properties
@@ -0,0 +1,44 @@
+#
+# 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.
+#
+
+#
+# This file contains localization strings for configuration labels and
+# descriptions as used in the metatype.xml descriptor generated by the
+# the Sling SCR plugin
+
+manager.name = Sling Management Console
+manager.description = Configuration of the Sling Management Console.
+
+manager.root.name = Root URI
+manager.root.description = The root path to the Sling Management Console.
+
+realm.name = Realm
+realm.description = The name of the HTTP Authentication Realm.
+
+username.name = User Name
+username.description = The name of the user allowed to access the Sling \
+ Management Console. To disable authentication clear this value.
+
+password.name = Password
+password.description = The password for the user allowed to access the Sling \
+ Management Console.
+
+default.render.name = Default Page
+default.render.name.description = The name of the default configuration page \
+ when invoking the Sling Management console.
\ No newline at end of file
diff --git a/webconsole/src/main/resources/res/imgs/Sling.png b/webconsole/src/main/resources/res/imgs/Sling.png
new file mode 100644
index 0000000..e29d72b
--- /dev/null
+++ b/webconsole/src/main/resources/res/imgs/Sling.png
Binary files differ
diff --git a/webconsole/src/main/resources/res/imgs/element_add.png b/webconsole/src/main/resources/res/imgs/element_add.png
new file mode 100644
index 0000000..badd904
--- /dev/null
+++ b/webconsole/src/main/resources/res/imgs/element_add.png
Binary files differ
diff --git a/webconsole/src/main/resources/res/imgs/element_delete.png b/webconsole/src/main/resources/res/imgs/element_delete.png
new file mode 100644
index 0000000..2e41916
--- /dev/null
+++ b/webconsole/src/main/resources/res/imgs/element_delete.png
Binary files differ
diff --git a/webconsole/src/main/resources/res/imgs/element_run.png b/webconsole/src/main/resources/res/imgs/element_run.png
new file mode 100644
index 0000000..6dcd23b
--- /dev/null
+++ b/webconsole/src/main/resources/res/imgs/element_run.png
Binary files differ
diff --git a/webconsole/src/main/resources/res/imgs/element_stop.png b/webconsole/src/main/resources/res/imgs/element_stop.png
new file mode 100644
index 0000000..a89013d
--- /dev/null
+++ b/webconsole/src/main/resources/res/imgs/element_stop.png
Binary files differ
diff --git a/webconsole/src/main/resources/res/imgs/favicon.ico b/webconsole/src/main/resources/res/imgs/favicon.ico
new file mode 100644
index 0000000..a36e242
--- /dev/null
+++ b/webconsole/src/main/resources/res/imgs/favicon.ico
Binary files differ
diff --git a/webconsole/src/main/resources/res/ui/admin.css b/webconsole/src/main/resources/res/ui/admin.css
new file mode 100644
index 0000000..984d9a0
--- /dev/null
+++ b/webconsole/src/main/resources/res/ui/admin.css
@@ -0,0 +1,546 @@
+/*
+ * 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.
+ */ /* CSS Document */
+#main {
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-size: 10px;
+ color: black;
+ background-color: white;
+ border-collapse: collapse;
+ padding: 0px;
+ margin: 30px 0 30px 30px;
+ width: 957px;
+ position: absolute;
+ text-align: left;
+ border-color: black;
+}
+
+#lead {
+ color: #00678C;
+ /* color: #ffffff; */
+ margin: 0px 0px 26px 0px;
+ padding: 0px;
+ width: 957px;
+ height: 100px;
+}
+
+#lead h1 { /*
+ background-image: url(../imgs/banner_left.jpg);
+ background-repeat: no-repeat;
+ */
+ margin: 0px;
+ padding: 5px 0 0 8px;
+ font-size: 400%;
+ font-weight: bold;
+ line-height: 120%;
+ height: 95px;
+ /* account for 5px top marging to get a total of 100px */
+ float: left;
+}
+
+#lead br {
+ line-height: 20px;
+}
+
+#lead p { /*
+ background-image: url(../imgs/banner_right.jpg);
+ background-repeat: no-repeat;
+ border-left: 1px solid;
+ */
+ margin: 0px;
+ padding: 0px;
+ height: 100px;
+ float: right;
+}
+
+#technav {
+ border-bottom: 1px solid #6181A9;
+ border-top: 1px solid #6181A9;
+ color: black;
+ font-size: 10px;
+ font-weight: bold;
+ /*
+ border-top: 1px solid black;
+ */
+ height: 21px;
+ padding: 0;
+ margin: 0;
+}
+
+#technav a {
+ display: block;
+ float: left;
+ text-decoration: none;
+ padding: 3px 10px 3px 10px;
+ color: #6181A9;
+ text-decoration: none;
+}
+
+#technav a:hover {
+ background-color: black;
+}
+
+#technav .technavat {
+ display: block;
+ float: left;
+ text-decoration: none;
+ padding: 3px 10px 3px 10px;
+ background-color: #B6CAE4;
+ color: black;
+}
+
+#claim {
+ color: white;
+ background-color: black;
+ padding: 2px 10px 2px 10px;
+}
+
+#claim p {
+ margin: 0;
+ padding: 0;
+}
+
+#claim a {
+ color: #C5E2EE;
+ text-decoration: none;
+}
+
+/*
+.claimcell A:link {
+ color: #C5E2EE;
+ text-decoration: none;
+}
+
+.claimcell A:visited {
+ color: #C5E2EE;
+ text-decoration: none;
+}
+*/
+#claim a:hover {
+ color: #99FF33;
+ border-bottom: 1px solid;
+}
+
+#claim a:active {
+ color: #FFFFFF;
+}
+
+/* old styles */
+table {
+ text-align: left;
+}
+
+table.content {
+ clear: both;
+ font-size: 10px;
+ line-height: 13px;
+ border: 0px solid #66dd44;
+ border-top: 1px solid #cccccc;
+ padding: 0px;
+ margin: 0px;
+ margin-top: 26px;
+ margin-bottom: 26px;
+ /* width: 718px; */
+ text-align: left;
+}
+
+tr {
+ border-left: 1px solid #cccccc;
+ border-right: 1px solid #cccccc;
+}
+
+td.content {
+ color: #333333;
+ border: 0px solid #66dd44;
+ border-bottom: 1px solid #cccccc;
+ vertical-align: middle;
+ padding: 5px;
+}
+
+td.disabled {
+ color: #999999;
+}
+
+th.content {
+ color: #333333;
+ border: 0px solid #66dd44;
+ border-bottom: 1px solid #cccccc;
+ text-align: left;
+ padding: 5px;
+ padding-left: 10px;
+}
+
+.right {
+ text-align: right;
+}
+.center {
+ text-align: center;
+}
+
+th.container {
+ color: #6181A9;
+ background-color: #f0f0f0;
+}
+
+th.important {
+ color: #B81833;
+}
+
+.important {
+ color: #B81833;
+}
+
+#maintable { /* postion: absolute; */
+ font-size: 10px;
+ line-height: 13px;
+ border: 1px solid #000000;
+ padding: 0px;
+ margin: 0px;
+ width: 960px;
+}
+
+.toolcell {
+ font-size: 10px;
+ color: #999999;
+ line-height: 10px;
+ background-color: #000000;
+ height: 18px;
+ /* width: 960px; */
+ padding: 0px;
+ padding-bottom: 1px;
+ text-align: left;
+}
+
+.toolcell A:link {
+ color: #C5E2EE;
+ text-decoration: none;
+}
+
+.toolcell A:visited {
+ color: #C5E2EE;
+ text-decoration: none;
+}
+
+.toolcell A:hover {
+ color: #99FF33;
+ text-decoration: none;
+ border-bottom: 1px solid;
+}
+
+.toolcell A:active {
+ color: #FFFFFF;
+ text-decoration: none;
+}
+
+.leadcell {
+ margin: 0px;
+ padding: 0px;
+ border: 0px solid #000000;
+ width: 718px;
+ height: 100px;
+ background-image: url(../imgs/banner_left.jpg);
+ vertical-align: top;
+}
+
+.leadcelltext {
+ position: absolute;
+ border: 0px solid #000000;
+ font-size: 26px;
+ line-height: 32px;
+ margin-top: 5px;
+ margin-left: 8px;
+ color: #ffffff;
+ vertical-align: top;
+}
+
+.logocell {
+ border-left: 1px solid #000000;
+ width: 239px;
+ background-image: url(../imgs/banner_right.jpg);
+}
+
+#technavcell {
+ font-size: 10px;
+ font-weight: bold;
+ border: 0px solid #000000;
+ border-top: 1px solid #000000;
+ height: 21px;
+ background-color: #6181A9;
+}
+
+/*
+#technav A:link {
+ float: left;
+ display: block;
+ color: #ffffff;
+ border: 0px solid #000000;
+ border-right: 1px solid #000000;
+ height: 21px;
+ text-decoration: none;
+ padding: 0px 10px 0px 10px;
+ background-color: #6181A9;
+}
+
+#technav A:visited {
+ float: left;
+ display: block;
+ color: #ffffff;
+ border-right: 1px solid #000000;
+ height: 21px;
+ text-decoration: none;
+ padding: 0px 10px 0px 10px;
+ background-color: #6181A9;
+}
+
+#technav A:hover {
+ float: left;
+ display: block;
+ color: #ffffff;
+ border-right: 1px solid #000000;
+ height: 21px;
+ text-decoration: none;
+ padding: 0px 10px 0px 10px;
+ background-color: #000000;
+}
+
+#technav A:active {
+ float: left;
+ display: block;
+ color: #ffffff;
+ border-right: 1px solid #000000;
+ height: 21px;
+ text-decoration: none;
+ padding: 0px 10px 0px 10px;
+ background-color: #6181A9;
+}
+*/
+.techcontentcell { /* width: 718px; */
+ border: 0px solid #000000;
+ border-top: 1px solid #000000;
+}
+
+.relatedcell {
+ border-left: 1px solid #000000;
+ border-top: 1px solid #000000;
+ width: 239px;
+ background-color: #EBF0F6;
+}
+
+/*
+.claimcell {
+ width: 715px;
+ font-size: 10px;
+ color: #ffffff;
+ line-height: 10px;
+ background-color: #000000;
+ height: 18px;
+ padding: 0px;
+ padding-bottom: 1px;
+}
+
+.claimcell A:link {
+ color: #C5E2EE;
+ text-decoration: none;
+}
+
+.claimcell A:visited {
+ color: #C5E2EE;
+ text-decoration: none;
+}
+
+.claimcell A:hover {
+ color: #99FF33;
+ text-decoration: none;
+ border-bottom: 1px solid;
+}
+
+.claimcell A:active {
+ color: #FFFFFF;
+ text-decoration: none;
+}
+*/ /* CENTRAL CONTENT AREA STYLING */
+.content {
+ position: relative;
+ margin: 25px;
+ font-size: 11px;
+ line-height: 16px;
+ color: #000000;
+}
+
+.content A:link {
+ color: #336600;
+ text-decoration: underline;
+}
+
+.content A:visited {
+ color: #666666;
+ text-decoration: underline;
+}
+
+.content A:hover {
+ color: #ffffff;
+ background-color: #336600;
+ text-decoration: none;
+}
+
+.content A:active {
+ color: #ffffff;
+ background-color: #000000;
+ text-decoration: none;
+}
+
+body {
+ background-color: white;
+}
+
+/* TEXT STYLING */ /*
+h1, h2, h3, h4, h5, h6, p
+
+ {
+ margin: 0px;
+ margin-bottom: 8px;
+ font-size: 11px;
+ line-height: 16px;
+ font-weight:bold;
+ }
+
+*/ /*
+h1
+ {
+ color: #000000;
+ margin-top: 32px;
+ clear: left;
+ }
+
+
+h2
+ {
+ color: #336699;
+ }
+
+
+h3
+ {
+ color: #336699;
+ }
+*/ /*
+p
+ {
+ font-size: 11px;
+ line-height: 16px;
+ font-weight: normal;
+ color: #000000;
+ }
+*/ /* FORMS */
+form {
+ font-size: 9px;
+ border-top: 0px solid #000000;
+ border-bottom: 0px solid #000000;
+ border-left: 0px solid #000000;
+ border-right: 0px solid #000000;
+ margin: 0;
+ padding: 0;
+ clear: left;
+}
+
+select,textarea {
+ font-family: Verdana, Arial, Helvetica, san-serif;
+ font-size: 9px;
+ font-weight: normal;
+ display: block;
+ float: left;
+ padding-top: 3px;
+ margin-bottom: 10px;
+}
+
+.input {
+ font-family: Verdana, Arial, Helvetica, san-serif;
+ font-size: 9px;
+ font-weight: normal;
+ color: #184054;
+ background-color: #f0f0f0;
+ border: 1px solid #999999;
+ border-bottom: 1px solid #cccccc;
+ border-right: 1px solid #cccccc;
+}
+
+.submit {
+ cursor: default;
+ width: 60px;
+ font-family: Verdana, Arial, Helvetica, san-serif;
+ font-size: 10px;
+ font-weight: bold;
+ background-color: #f0f0f0;
+ height: 20px;
+ padding: 0px;
+ padding-bottom: 1px;
+ margin: 0px;
+ border: 1px solid #cccccc;
+ border-bottom: 1px solid #666666;
+ border-right: 1px solid #666666;
+}
+
+input.important {
+ background-color: #B81833;
+ color: #ffffff;
+}
+
+select {
+ color: #184054;
+ background-color: #f0f0f0;
+ border: 0px solid #999999;
+}
+
+textarea {
+ color: #184054;
+ background-color: #f0f0f0;
+ width: 234px;
+ height: 100px;
+ border: 1px solid #999999;
+ border-bottom: 1px solid #cccccc;
+ border-right: 1px solid #cccccc;
+}
+
+.clearleft {
+ clear: left;
+}
+
+.clearboth {
+ clear: both;
+}
+
+.checkradio {
+ background-color: #ffffff;
+ width: 20px;
+ padding: 0px;
+ padding-bottom: 10px;
+ margin: 0px;
+ margin-top: 2px;
+ border: 0px solid #999999;
+}
+
+.checkradiotext {
+ font-size: 9px;
+ font-weight: normal;
+ line-height: 11px;
+ width: 100px;
+ color: #000000;
+ padding: 0px;
+ padding-bottom: 10px;
+ margin: 0px;
+ margin-top: 4px;
+ border: 0px solid #999999;
+}
\ No newline at end of file
diff --git a/webconsole/src/main/resources/res/ui/admin.js b/webconsole/src/main/resources/res/ui/admin.js
new file mode 100644
index 0000000..3fe3697
--- /dev/null
+++ b/webconsole/src/main/resources/res/ui/admin.js
@@ -0,0 +1,152 @@
+/*
+ * 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.
+ */
+
+
+/* shuts down server after [num] seconds */
+function shutdown(num, formname, elemid) {
+ var elem;
+ var canCount = document.getElementById;
+ if (canCount) {
+ elem = document.getElementById(elemid);
+ canCount = (typeof(elem) != "undefined" && typeof(elem.innerHTML) != "undefined");
+ }
+ var secs=" second";
+ var ellipsis="...";
+ if (num > 0) {
+ if (num != 1) {
+ secs+="s";
+ }
+ if (canCount) {
+ elem.innerHTML=num+secs+ellipsis;
+ }
+ setTimeout('shutdown('+(--num)+', "'+formname+'", "'+elemid+'")',1000);
+ } else {
+ document[formname].submit();
+ }
+}
+
+/* aborts server shutdown and redirects to [target] */
+function abort(target) {
+ top.location.href=target;
+}
+
+/* checks if values of [pass1] and [pass2] match */
+function checkPasswd(form, pass0, pass1, pass2) {
+ var check = false;
+ check = (form[pass0].value != form[pass1].value);
+ if (!check) {
+ alert("Old and new password must be different.");
+ form[pass1].value="";
+ form[pass2].value="";
+ form[pass1].focus();
+ }
+ check = (form[pass1].value == form[pass2].value);
+ if (!check) {
+ alert("Passwords did not match. Please type again.");
+ form[pass1].value="";
+ form[pass2].value="";
+ form[pass1].focus();
+ }
+ return check;
+}
+
+/* displays a date in the user's local timezone */
+function localDate(time) {
+ var date = time ? new Date(time) : new Date();
+ document.write(date.toLocaleString());
+}
+
+/* shows the about screen */
+function showAbout() {
+// Temporarily disabled, as thee is no about.html page (fmeschbe, 20070330)
+// var arguments = ABOUT_VERSION+";"+ABOUT_JVERSION+";"+ABOUT_MEM+";"+ABOUT_USED+";"+ABOUT_FREE;
+// if (window.showModalDialog) {
+// window.showModalDialog("about.html", arguments, "help: no; status: no; resizable: no; center: yes; scroll: no");
+// } else {
+// aboutWin = window.open("about.html?a="+arguments, "about", "width=500,height=420,modal,status=no,toolbar=no,menubar=no,personalbar=no");
+// }
+}
+
+//-----------------------------------------------------------------------------
+// Ajax Support
+
+// request object, do not access directly, use getXmlHttp instead
+var xmlhttp = null;
+function getXmlHttp() {
+ if (xmlhttp) {
+ return xmlhttp;
+ }
+
+ if (window.XMLHttpRequest) {
+ xmlhttp = new XMLHttpRequest();
+ } else if (window.ActiveXObject) {
+ try {
+ xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
+ } catch (ex) {
+ try {
+ xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
+ } catch (ex) {
+ }
+ }
+ }
+
+ return xmlhttp;
+}
+
+function sendRequest(/* String */ method, /* url */ url, /* function */ callback) {
+ var xmlhttp = getXmlHttp();
+ if (!xmlhttp) {
+ return;
+ }
+
+ if (xmlhttp.readyState < 4) {
+ xmlhttp.abort();
+ }
+
+ if (!method) {
+ method = 'GET';
+ }
+
+ if (!url) {
+ url = document.location;
+ } else if (url.charAt(0) == '?') {
+ url = document.location + url;
+ }
+
+ xmlhttp.open(method, url);
+ xmlhttp.onreadystatechange = handleResult;
+ xmlhttp.priv_callback = callback;
+ xmlhttp.send(null);
+
+}
+
+function handleResult() {
+ var xmlhttp = getXmlHttp();
+ if (!xmlhttp || xmlhttp.readyState != 4) {
+ return;
+ }
+
+ var result = xmlhttp.responseText;
+ if (!result) {
+ return;
+ }
+
+ if (xmlhttp.priv_callback) {
+ var obj = eval('(' + result + ')');
+ xmlhttp.priv_callback(obj);
+ }
+}
diff --git a/webconsole/src/main/resources/res/ui/configmanager.js b/webconsole/src/main/resources/res/ui/configmanager.js
new file mode 100644
index 0000000..d15aa17
--- /dev/null
+++ b/webconsole/src/main/resources/res/ui/configmanager.js
@@ -0,0 +1,229 @@
+/*
+ * 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 configure() {
+ var span = document.getElementById('configField');
+ if (!span) {
+ return;
+ }
+ var select = document.configSelection.pid;
+ var pid = select.options[select.selectedIndex].value;
+ var parm = '?action=ajaxConfigManager&' + pid;
+ sendRequest('GET', parm, displayConfigForm);
+}
+
+function displayConfigForm(obj) {
+ var span = document.getElementById('configField');
+ if (!span) {
+ return;
+ }
+ var innerHtml = '<tr class="content" id="configField">' + span.innerHTML + '</tr>';
+ innerHtml += '<tr class="content">';
+ innerHtml += '<th colspan="2" class="content" >' + obj.title + '</th></tr>';
+ innerHtml += '<tr class="content">';
+ innerHtml += '<td class="content"> </td>';
+ innerHtml += '<td class="content">';
+ innerHtml += '<form method="post">';
+ innerHtml += '<input type="hidden" name="apply" value="true" />';
+ innerHtml += '<input type="hidden" name="pid" value="' + obj.pid + '" />';
+ innerHtml += '<input type="hidden" name="action" value="ajaxConfigManager" />';
+ innerHtml += '<table border="0" width="100%">';
+ if (obj.description) {
+ innerHtml += '<tr class="content">';
+ innerHtml += '<td class="content" colspan="2">' + obj.description + '</td></tr>';
+ }
+ if (obj.propertylist == 'properties') {
+ innerHtml += printTextArea(obj.properties);
+ } else {
+ innerHtml += printForm(obj);
+ }
+ innerHtml += '<tr class="content">';
+ innerHtml += '<td class="content"> </td>';
+ innerHtml += '<td class="content">';
+ innerHtml += '<input type="submit" class="submit" name="submit" value="Save" />';
+ innerHtml += ' ';
+ innerHtml += '<input type="reset" class="submit" name="reset" value="Reset" />';
+ innerHtml += ' ';
+ innerHtml += '<input type="submit" class="submit" name="delete" value="Delete" onClick="return confirmDelete();"/>';
+ if (obj.isFactory) {
+ innerHtml += ' ';
+ innerHtml += '<input type="submit" class="submit" name="create" value="Create Configuration" onClick="return promptContext(this);" />';
+ innerHtml += '<input type="hidden" name="sling.context" value="" />';
+ }
+ innerHtml += '</td></tr>';
+ innerHtml += '</table>';
+ innerHtml += '</form>';
+ innerHtml += '</td></tr>';
+ innerHtml += printConfigurationInfo(obj);
+ span.parentNode.innerHTML = innerHtml;
+}
+
+function printTextArea(props) {
+ var innerHtml = '<tr class="content">';
+ innerHtml += '<td class="content" style="vertical-align: top">Properties</td>';
+ innerHtml += '<td class="content" style="width: 99%">';
+ innerHtml += '<textarea name="properties" style="height: 50%; width: 99%">';
+ for (var key in props) {
+ innerHtml += key + ' = ' + props[key] + '\r\n';
+ }
+ innerHtml += '</textarea>';
+ innerHtml += 'Enter Name-Value pairs of configuration properties.</td>';
+ return innerHtml;
+}
+
+function printForm(obj) {
+ var innerHtml = '';
+ var propList;
+ for (var idx in obj.propertylist) {
+ var prop = obj.propertylist[idx];
+ var attr = obj[prop];
+ innerHtml += '<tr class="content">';
+ innerHtml += '<td class="content" style="vertical-align: top">' + attr.name + '</td>';
+ innerHtml += '<td class="content" style="width: 99%">';
+ if (attr.value != undefined) { // check is required to also handle empty strings, 0 and false
+ innerHtml += createInput(prop, attr.value, attr.type, '99%');
+ innerHtml += '<br />';
+ } else if (typeof(attr.type) == 'object') {
+ // assume attr.values and multiselect
+ innerHtml += createMultiSelect(prop, attr.values, attr.type, '99%');
+ innerHtml += '<br />';
+ } else {
+ for (var vidx in attr.values) {
+ var spanElement = createSpan(prop, attr.values[vidx], attr.type);
+ innerHtml += '<span id="' + spanElement.id + '">';
+ innerHtml += spanElement.innerHTML;
+ innerHtml += '</span>';
+ }
+ }
+ if (attr.description) {
+ innerHtml += attr.description;
+ }
+ innerHtml += '</td>';
+ if (propList) {
+ propList += ',' + prop;
+ } else {
+ propList = prop;
+ }
+ }
+ innerHtml += '<input type="hidden" name="propertylist" value="' + propList + '"/>';
+ return innerHtml;
+}
+
+function printConfigurationInfo(obj) {
+ var innerHtml = '<tr class="content">';
+ innerHtml += '<th colspan="2" class="content" >Configuration Information</th></tr>';
+ innerHtml += '<tr class="content">';
+ innerHtml += '<td class="content">Persistent Identity (PID)</td>';
+ innerHtml += '<td class="content">' + obj.pid + '</td></tr>';
+ if (obj.factoryPID) {
+ innerHtml += '<tr class="content">';
+ innerHtml += '<td class="content">Factory Peristent Identifier (Factory PID)</td>';
+ innerHtml += '<td class="content">' + obj.factoryPID + '</td></tr>';
+ }
+ innerHtml += '<tr class="content">';
+ innerHtml += '<td class="content">Configuration Binding</td>';
+ innerHtml += '<td class="content">' + obj.bundleLocation + '</td></tr>';
+ return innerHtml;
+}
+
+function addValue(prop, vidx) {
+ var span = document.getElementById(vidx);
+ if (!span) {
+ return;
+ }
+ var newSpan = createSpan(prop, '');
+ span.parentNode.insertBefore(newSpan, span.nextSibling);
+}
+
+var spanCounter = 0;
+function createSpan(prop, value, type) {
+ spanCounter++;
+ var newId = prop + spanCounter;
+ var innerHtml = createInput(prop, value, type, '89%');
+ innerHtml += '<input class="input" type="button" value="+" onClick="addValue(\'' + prop + '\',\'' + newId + '\');" style="width: 5%" />';
+ innerHtml += '<input class="input" type="button" value="-" onClick="removeValue(\'' + newId + '\');" style="width: 5%" />';
+ innerHtml += '<br />';
+ var newSpan = document.createElement('span');
+ newSpan.id = newId;
+ newSpan.innerHTML = innerHtml;
+ return newSpan;
+}
+
+function createInput(prop, value, type, width) {
+ if (type == 11) { // AttributeDefinition.BOOLEAN
+ if (value && typeof(value) != "boolean") {
+ value = value.toString().toLowerCase() == "true";
+ }
+ var checked = value ? 'checked' : '';
+ return '<input class="input" type="checkbox" name="' + prop + '" value="true" ' + checked + '/>';
+ } else if (typeof(type) == "object") { // predefined values
+ var labels = type.labels;
+ var values = type.values;
+ var innerHtml = '<select class="select" name="' + prop + '" style="width: ' + width + '">';
+ for (var idx in labels) {
+ var selected = (value == values[idx]) ? ' selected' : '';
+ innerHtml += '<option value="' + values[idx] + '"' + selected + '>' + labels[idx] + '</option>';
+ }
+ innerHtml += '</select>';
+ return innerHtml;
+ } else { // Simple
+ return '<input class="input" type="text" name="' + prop + '" value="' + value + '" style="width: ' + width + '"/>';
+ }
+}
+
+function createMultiSelect(prop, values, options, width) {
+ // convert value list into 'set'
+ var valueSet = new Object();
+ for (var idx in values) {
+ valueSet[ values[idx] ] = true;
+ }
+
+ var labels = options.labels;
+ var values = options.values;
+ var innerHtml = '';
+ for (var idx in labels) {
+ var checked = valueSet[ values[idx] ] ? ' checked' : '';
+ innerHtml += '<label><input type="checkbox" name="' + prop + '" value="' + values[idx] + '"' + checked + '>' + labels[idx] + '</label>';
+ }
+ return innerHtml;
+}
+
+function removeValue(vidx) {
+ var span = document.getElementById(vidx);
+ if (!span) {
+ return;
+ }
+ span.parentNode.removeChild(span);
+}
+
+function confirmDelete() {
+ return confirm("Are you sure to delete this configuration ?");
+}
+
+function promptContext(form) {
+ var result = prompt("Please give a Sling Context for the new configuration");
+ // alert("You entered: [" + result + "] for form [" + form + "/" + form.form + "]");
+
+ // set the hidden sling.context input field with the value
+ if (result != null) {
+ form.form["sling.context"].value = result;
+ return true;
+ }
+
+ return false;
+}
\ No newline at end of file