FELIX-3111 : Separate OBR Plugin
FELIX-3107 : Separate Shell Plugin
FELIX-3099 : Separate Deployment Admin plugin
FELIX-3100 : Separate SCR plugin

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1169777 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/webconsole-plugins/shell/src/main/java/org/apache/felix/webconsole/plugins/shell/internal/Activator.java b/webconsole-plugins/shell/src/main/java/org/apache/felix/webconsole/plugins/shell/internal/Activator.java
new file mode 100644
index 0000000..c26abac
--- /dev/null
+++ b/webconsole-plugins/shell/src/main/java/org/apache/felix/webconsole/plugins/shell/internal/Activator.java
@@ -0,0 +1,98 @@
+/*

+ * 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.

+ */

+package org.apache.felix.webconsole.plugins.shell.internal;

+

+import org.apache.felix.shell.ShellService;

+import org.apache.felix.webconsole.SimpleWebConsolePlugin;

+import org.osgi.framework.BundleActivator;

+import org.osgi.framework.BundleContext;

+import org.osgi.framework.ServiceReference;

+import org.osgi.util.tracker.ServiceTracker;

+import org.osgi.util.tracker.ServiceTrackerCustomizer;

+

+/**

+ * Activator is the main starting class.

+ */

+public class Activator implements BundleActivator, ServiceTrackerCustomizer

+{

+

+    private ServiceTracker tracker;

+    private BundleContext context;

+

+    private SimpleWebConsolePlugin plugin;

+

+    /**

+     * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)

+     */

+    public final void start(BundleContext context) throws Exception

+    {

+        this.context = context;

+        this.tracker = new ServiceTracker(context, ShellService.class.getName(), this);

+        this.tracker.open();

+    }

+

+    /**

+     * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)

+     */

+    public final void stop(BundleContext context) throws Exception

+    {

+        if (tracker != null)

+        {

+            tracker.close();

+            tracker = null;

+        }

+    }

+

+    // - begin tracker

+    /**

+     * @see org.osgi.util.tracker.ServiceTrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference,

+     *      java.lang.Object)

+     */

+    public final void modifiedService(ServiceReference reference, Object service)

+    {/* unused */

+    }

+

+    /**

+     * @see org.osgi.util.tracker.ServiceTrackerCustomizer#addingService(org.osgi.framework.ServiceReference)

+     */

+    public final Object addingService(ServiceReference reference)

+    {

+        SimpleWebConsolePlugin plugin = this.plugin;

+        if (plugin == null)

+        {

+            this.plugin = plugin = new WebConsolePlugin(tracker).register(context);

+        }

+

+        return context.getService(reference);

+    }

+

+    /**

+     * @see org.osgi.util.tracker.ServiceTrackerCustomizer#removedService(org.osgi.framework.ServiceReference,

+     *      java.lang.Object)

+     */

+    public final void removedService(ServiceReference reference, Object service)

+    {

+        SimpleWebConsolePlugin plugin = this.plugin;

+

+        if (tracker.getTrackingCount() == 0 && plugin != null)

+        {

+            plugin.unregister();

+            this.plugin = null;

+        }

+

+    }

+}

diff --git a/webconsole-plugins/shell/src/main/java/org/apache/felix/webconsole/plugins/shell/internal/WebConsolePlugin.java b/webconsole-plugins/shell/src/main/java/org/apache/felix/webconsole/plugins/shell/internal/WebConsolePlugin.java
new file mode 100644
index 0000000..9508ebc
--- /dev/null
+++ b/webconsole-plugins/shell/src/main/java/org/apache/felix/webconsole/plugins/shell/internal/WebConsolePlugin.java
@@ -0,0 +1,150 @@
+/*
+ * 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.
+ */
+package org.apache.felix.webconsole.plugins.shell.internal;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.felix.shell.ShellService;
+import org.apache.felix.webconsole.DefaultVariableResolver;
+import org.apache.felix.webconsole.SimpleWebConsolePlugin;
+import org.apache.felix.webconsole.WebConsoleUtil;
+import org.osgi.util.tracker.ServiceTracker;
+
+/**
+ * ShellServlet provides a Web bases interface to the Apache shell service, allowing
+ * the user to execute shell commands from the browser.
+ */
+class WebConsolePlugin extends SimpleWebConsolePlugin
+{
+
+    private static final String LABEL = "shell"; //$NON-NLS-1$
+    private static final String TITLE = "%shell.pluginTitle"; //$NON-NLS-1$
+    private static final String CSS[] = { "/" + LABEL + "/res/plugin.css" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+    private final ServiceTracker tracker;
+
+    // templates
+    private final String TEMPLATE;
+
+    WebConsolePlugin(ServiceTracker tracker)
+    {
+        super(LABEL, TITLE, CSS);
+
+        // load templates
+        TEMPLATE = readTemplateFile("/res/plugin.html"); //$NON-NLS-1$
+        this.tracker = tracker;
+    }
+
+    /**
+     * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+     */
+    protected void doPost(HttpServletRequest request, HttpServletResponse response)
+        throws ServletException, IOException
+    {
+        response.setCharacterEncoding("utf-8"); //$NON-NLS-1$
+        response.setContentType("text/html"); //$NON-NLS-1$
+
+        PrintWriter pw = response.getWriter();
+
+        try
+        {
+            String command = request.getParameter("command"); //$NON-NLS-1$
+            if (command != null)
+            {
+                command = WebConsoleUtil.urlDecode(command);
+            }
+
+            pw.print("<span class=\"consolecommand\">-&gt; "); //$NON-NLS-1$
+            pw.print(command == null ? "" : WebConsoleUtil.escapeHtml(command)); //$NON-NLS-1$
+            pw.println("</span><br />"); //$NON-NLS-1$
+
+            if (command != null && command.length() > 0)
+            {
+                ShellService shellService = getShellService();
+                if (shellService != null)
+                {
+                    ByteArrayOutputStream baosOut = new ByteArrayOutputStream();
+                    ByteArrayOutputStream baosErr = new ByteArrayOutputStream();
+
+                    shellService.executeCommand(command, new PrintStream(baosOut, true),
+                        new PrintStream(baosErr, true));
+                    if (baosOut.size() > 0)
+                    {
+                        pw.print(WebConsoleUtil.escapeHtml(new String(
+                            baosOut.toByteArray())));
+                    }
+                    if (baosErr.size() > 0)
+                    {
+                        pw.print("<span class=\"error\">"); //$NON-NLS-1$
+                        pw.print(WebConsoleUtil.escapeHtml(new String(
+                            baosErr.toByteArray())));
+                        pw.println("</span>"); //$NON-NLS-1$
+                    }
+                }
+                else
+                {
+                    pw.print("<span class=\"error\">"); //$NON-NLS-1$
+                    pw.print("Error: No shell service available<br />");
+                    pw.println("</span>"); //$NON-NLS-1$
+                }
+            }
+        }
+        catch (Throwable t)
+        {
+            pw.print("<span class=\"error\">"); //$NON-NLS-1$
+            StringWriter out = new StringWriter();
+            t.printStackTrace(new PrintWriter(out, true));
+            pw.print(WebConsoleUtil.escapeHtml(out.toString()));
+            pw.println("</span>"); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * @see org.apache.felix.webconsole.AbstractWebConsolePlugin#renderContent(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+     */
+    protected void renderContent(HttpServletRequest request, HttpServletResponse response)
+        throws IOException
+    {
+        DefaultVariableResolver vr = (DefaultVariableResolver) WebConsoleUtil.getVariableResolver(request);
+        if (getShellService() == null)
+        {
+            vr.put("shell.status", "Shell Service not available"); //$NON-NLS-1$
+            vr.put("shell.disabled", "true"); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        else
+        {
+            vr.put("shell.disabled", "false"); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        response.getWriter().print(TEMPLATE);
+    }
+
+    private final ShellService getShellService()
+    {
+        return (ShellService) tracker.getService();
+    }
+
+}
diff --git a/webconsole-plugins/shell/src/main/native2ascii/OSGI-INF/l10n/bundle_bg.properties b/webconsole-plugins/shell/src/main/native2ascii/OSGI-INF/l10n/bundle_bg.properties
new file mode 100644
index 0000000..b2c2e0f
--- /dev/null
+++ b/webconsole-plugins/shell/src/main/native2ascii/OSGI-INF/l10n/bundle_bg.properties
@@ -0,0 +1,33 @@
+#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.

+

+#

+# Web Console strings for reference all strings here are commented.

+# This file may be used to produce a translation of the strings

+#

+# Note that properties files are ISO-8859-1 encoded. To provide translations

+# for languages requiring different character encodings, you may use the

+# native2ascii Maven Plugin from http://mojo.codehaus.org/native2ascii-maven-plugin/

+# to translate the natively encoded files to ISO-8859-1 during bundle build

+#

+# Translations requiring non-ISO-8859-1 encoding are placed in the

+# src/main/native2ascii/OSGI-INF/l10n folder and are converted using said

+# plugin while building the bundle

+# native2ascii -encoding utf-8 bundle_bg.raw_properties bundle_bg.properties

+

+# Shell plugin

+shell.pluginTitle=Конзола

+shell.clear=Изчистване

+shell.status=Използвайте командният ред за изпълнение на команди.

diff --git a/webconsole-plugins/shell/src/main/native2ascii/OSGI-INF/l10n/bundle_de.properties b/webconsole-plugins/shell/src/main/native2ascii/OSGI-INF/l10n/bundle_de.properties
new file mode 100644
index 0000000..265adcc
--- /dev/null
+++ b/webconsole-plugins/shell/src/main/native2ascii/OSGI-INF/l10n/bundle_de.properties
@@ -0,0 +1,33 @@
+#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.

+

+#

+# Web Console strings for reference all strings here are commented.

+# This file may be used to produce a translation of the strings

+#

+# Note that properties files are ISO-8859-1 encoded. To provide translations

+# for languages requiring different character encodings, you may use the

+# native2ascii Maven Plugin from http://mojo.codehaus.org/native2ascii-maven-plugin/

+# to translate the natively encoded files to ISO-8859-1 during bundle build

+#

+# Translations requiring non-ISO-8859-1 encoding are placed in the

+# src/main/native2ascii/OSGI-INF/l10n folder and are converted using said

+# plugin while building the bundle

+#

+

+# Shell plugin

+shell.pluginTitle=Shell

+shell.clear=Löschen

+shell.status=Nutzen Sie das Eingabefeld um Shell Kommandos auszuführen.

diff --git a/webconsole-plugins/shell/src/main/native2ascii/OSGI-INF/l10n/bundle_ru.properties b/webconsole-plugins/shell/src/main/native2ascii/OSGI-INF/l10n/bundle_ru.properties
new file mode 100644
index 0000000..88b47dc
--- /dev/null
+++ b/webconsole-plugins/shell/src/main/native2ascii/OSGI-INF/l10n/bundle_ru.properties
@@ -0,0 +1,33 @@
+#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.
+
+#
+# Web Console strings for reference all strings here are commented.
+# This file may be used to produce a translation of the strings
+#
+# Note that properties files are ISO-8859-1 encoded. To provide translations
+# for languages requiring different character encodings, you may use the
+# native2ascii Maven Plugin from http://mojo.codehaus.org/native2ascii-maven-plugin/
+# to translate the natively encoded files to ISO-8859-1 during bundle build
+#
+# Translations requiring non-ISO-8859-1 encoding are placed in the
+# src/main/native2ascii/OSGI-INF/l10n folder and are converted using said
+# plugin while building the bundle
+#
+
+# Shell plugin
+shell.pluginTitle=Консоль
+shell.clear=Очистить
+shell.status=Используйте строку ввода для выполнения команд в консоли.
diff --git a/webconsole-plugins/shell/src/main/resources/OSGI-INF/l10n/bundle.properties b/webconsole-plugins/shell/src/main/resources/OSGI-INF/l10n/bundle.properties
new file mode 100644
index 0000000..bf0b203
--- /dev/null
+++ b/webconsole-plugins/shell/src/main/resources/OSGI-INF/l10n/bundle.properties
@@ -0,0 +1,33 @@
+#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.

+

+#

+# Web Console strings for reference all strings here are commented.

+# This file may be used to produce a translation of the strings

+#

+# Note that properties files are ISO-8859-1 encoded. To provide translations

+# for languages requiring different character encodings, you may use the

+# native2ascii Maven Plugin from http://mojo.codehaus.org/native2ascii-maven-plugin/

+# to translate the natively encoded files to ISO-8859-1 during bundle build

+#

+# Translations requiring non-ISO-8859-1 encoding are placed in the

+# src/main/native2ascii/OSGI-INF/l10n folder and are converted using said

+# plugin while building the bundle

+#

+

+# Shell plugin

+shell.pluginTitle=Shell

+shell.clear=Clear

+shell.status=Use the command prompt to execute shell commands.

diff --git a/webconsole-plugins/shell/src/main/resources/res/plugin.css b/webconsole-plugins/shell/src/main/resources/res/plugin.css
new file mode 100644
index 0000000..e164930
--- /dev/null
+++ b/webconsole-plugins/shell/src/main/resources/res/plugin.css
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+#consoleframe {
+    font-family: monospace;
+    background-color: #f0f0f0;
+    height: 500px;
+    overflow: auto;
+}
+
+span.consolecommand {
+    white-space: pre;
+	font-weight: bold;
+}
+
+span.error {
+    color: #ff0000;
+}
+
+input.command {
+    font-family: monospace;
+    width: 80%;
+}
diff --git a/webconsole-plugins/shell/src/main/resources/res/plugin.html b/webconsole-plugins/shell/src/main/resources/res/plugin.html
new file mode 100644
index 0000000..c2b9b9b
--- /dev/null
+++ b/webconsole-plugins/shell/src/main/resources/res/plugin.html
@@ -0,0 +1,27 @@
+<script type="text/javascript" src="${pluginRoot}/res/plugin.js"></script>

+<script type="text/javascript">

+// <![CDATA[

+var shellDisabled = ${shell.disabled};

+// ]]>

+</script>

+<p class="statline">${shell.status}</p>

+

+<form id="shell_form" method="post" action="${pluginRoot}">

+	<!-- top header -->

+	<div class="ui-widget-header ui-corner-top buttonGroup">

+		<input id="help" value="${help}" type="button" />

+		<input id="clear" value="${shell.clear}" type="button" />

+	</div>

+

+	<!-- the console window -->

+	<div id="consoleframe">

+		<div id="console">

+			<!-- HERE COMES CONSOLE CONTENTS -->

+		</div><!-- console -->

+	</div><!-- consoleframe -->

+

+	<!-- bottom header -->

+	<div class="ui-widget-header ui-corner-bottom buttonGroup" style="text-align: left">

+		&nbsp;-&gt; <input id="command" name="command" class="command" autocomplete="off" type="text" />

+	</div>

+</form>

diff --git a/webconsole-plugins/shell/src/main/resources/res/plugin.js b/webconsole-plugins/shell/src/main/resources/res/plugin.js
new file mode 100644
index 0000000..7d34014
--- /dev/null
+++ b/webconsole-plugins/shell/src/main/resources/res/plugin.js
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+
+// elements cache
+var consoleframe = false;
+var konsole = false;
+var command = false;
+
+function executeCommand(cmd) {
+	$.post(document.location.href, { 'command' : encodeURIComponent(cmd) },
+		function(result) {
+			konsole.removeClass('ui-helper-hidden').append(result);
+			consoleframe.attr('scrollTop', konsole.attr('scrollHeight'));
+			command.val('');
+			shellCommandFocus();
+		}, 'html');
+}
+
+function shellCommandFocus() { command.focus() }
+
+// automatically executed on load
+$(document).ready(function(){
+    
+    // disable the shell form if the shell service is not available
+    if (shellDisabled) {
+    
+        $('#shell_form').hide();
+    
+    } else {
+    
+    	// init cache
+    	consoleframe = $('#consoleframe').click(shellCommandFocus);
+    	konsole      = $('#console');
+    	command      = $('#command').focus();
+    
+    	// attach action handlers
+    	$('#clear').click(function() {
+    		konsole.addClass('ui-helper-hidden').html('');
+    		consoleframe.attr('scrollTop', 0);
+    		shellCommandFocus();
+    	});
+    	$('#help').click(function() {
+    		executeCommand('help');
+    	});
+    	$('form').submit(function() {
+    		executeCommand(command.val());
+    		return false;
+    	});
+    	
+	}
+});