Add framework distribution.

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@910114 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/main.distribution/doc/apache-felix-shell-service.html b/main.distribution/doc/apache-felix-shell-service.html
new file mode 100644
index 0000000..f2198d8
--- /dev/null
+++ b/main.distribution/doc/apache-felix-shell-service.html
@@ -0,0 +1,439 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html><head>
+
+
+  
+    <title>Apache Felix - Apache Felix Shell Service</title>
+    <link rel="stylesheet" href="apache-felix-shell-service_files/site.css" type="text/css" media="all">
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+  </head><body>
+    <div class="title"><div class="logo"><a href="http://felix.apache.org/site/index.html"><img alt="Apache Felix" src="apache-felix-shell-service_files/logo.png" border="0"></a></div><div class="header"><a href="http://www.apache.org/"><img alt="Apache" src="apache-felix-shell-service-Dateien/apache.png" border="0"></a></div></div>
+    <div class="menu">
+<ul>
+	<li><a href="http://felix.apache.org/site/news.html" title="news">news</a></li>
+	<li><a href="http://felix.apache.org/site/license.html" title="license">license</a></li>
+	<li><a href="http://felix.apache.org/site/downloads.cgi" rel="nofollow">downloads</a></li>
+	<li><a href="http://felix.apache.org/site/documentation.html" title="documentation">documentation</a></li>
+	<li><a href="http://felix.apache.org/site/mailinglists.html" title="mailinglists">mailing lists</a></li>
+	<li><a href="http://felix.apache.org/site/contributing.html" title="Contributing">contributing</a></li>
+	<li><a href="http://www.apache.org/" rel="nofollow">asf</a></li>
+	<li><a href="http://www.apache.org/foundation/sponsorship.html" rel="nofollow">sponsorship</a></li>
+	<li><a href="http://www.apache.org/foundation/thanks.html" rel="nofollow">sponsors</a>
+<!-- ApacheCon Ad -->
+<iframe src="apache-felix-shell-service_files/button.html" style="border-width: 0pt; float: left;" frameborder="0" height="135" scrolling="no" width="135"></iframe>
+<p style="height: 100px;">
+<!-- ApacheCon Ad -->
+</p></li></ul> </div>
+    <div class="main">
+<h1><a name="ApacheFelixShellService-ApacheFelixShellService"></a>Apache Felix Shell Service</h1>
+
+<ul>
+	<li><a href="#ApacheFelixShellService-overview">Overview</a></li>
+	<li><a href="#ApacheFelixShellService-service">How the Shell Service Works</a></li>
+	<li><a href="#ApacheFelixShellService-commands">How Commands Work</a></li>
+	<li><a href="#ApacheFelixShellService-creating">Creating a Command</a></li>
+	<li><a href="#ApacheFelixShellService-security">Security and the Shell Service</a></li>
+	<li><a href="#ApacheFelixShellService-feedback">Feedback</a></li>
+</ul>
+
+
+<p><a name="ApacheFelixShellService-overview"></a></p>
+
+<h2><a name="ApacheFelixShellService-Overview"></a>Overview</h2>
+
+<p>In order to interact with Felix it is necessary to have some sort of
+interactive shell that allows you to issue commands to the framework
+and to obtain information from it. The OSGi specification does not
+define how an OSGi framework should provide this interactivity. Felix
+defines a shell service for creating and executing arbitrary commands.
+The shell service does not define a user interface, only a service API.</p>
+
+<p>The benefit of the Felix shell service approach is that it is possible to:</p>
+
+<ul>
+	<li>have multiple shell user interfaces (e.g., textual and graphical),</li>
+	<li>add custom commands to the shell (i.e., bundles can make commands available via the shell service), and</li>
+	<li>use the shell service from other bundles/services.</li>
+</ul>
+
+
+<p>The remainder of this document describes how the shell service works
+and how to create custom commands for it. This document does not
+describe how to use the command shell, nor does it describe the
+text-based or GUI-based user interfaces that are available for the
+shell.</p>
+
+<p><a name="ApacheFelixShellService-service"></a></p>
+
+<h2><a name="ApacheFelixShellService-HowtheShellServiceWorks"></a>How the Shell Service Works</h2>
+
+<p>The Felix shell service is intended to be a simple, but extensible
+shell service that can have multiple user interface implementations,
+all of which are independent from the Felix framework. The shell
+service is currently not intended to be sophisticated, rather it is
+just a mechanism to execute commands. The shell service maintains a
+list of command services, each of which have a unique command name. The
+shell service is defined by the following service interface:</p>
+
+<style type="text/css">
+@import url(/confluence/download/resources/confluence.ext.code:code/shStyles.css);
+</style>
+<!--[if IE]>
+<style type="text/css">
+    .code textarea, .code input { padding: 0 !important; }
+</style>
+<![endif]-->
+<script class="javascript" src="apache-felix-shell-service_files/shCore.js"></script>
+<script class="javascript" src="apache-felix-shell-service_files/shBrushCSharp.js"></script>
+<script class="javascript" src="apache-felix-shell-service_files/shBrushPhp.js"></script>
+<script class="javascript" src="apache-felix-shell-service_files/shBrushJScript.js"></script>
+<script class="javascript" src="apache-felix-shell-service_files/shBrushVb.js"></script>
+<script class="javascript" src="apache-felix-shell-service_files/shBrushSql.js"></script>
+<script class="javascript" src="apache-felix-shell-service_files/shBrushXml.js"></script>
+<script class="javascript" src="apache-felix-shell-service_files/shBrushShell.html"></script>
+<script class="javascript" src="apache-felix-shell-service_files/shBrushDelphi.js"></script>
+<script class="javascript" src="apache-felix-shell-service_files/shBrushPython.js"></script>
+<script class="javascript" src="apache-felix-shell-service_files/shBrushJava.js"></script>
+<div class="code">
+<textarea name="newcodemacro" class="java:nocontrols:nogutter" rows="10" readonly="readonly">package org.apache.felix.shell;
+
+public interface ShellService
+{
+    public String[] getCommands();
+    public String getCommandUsage(String name);
+    public String getCommandDescription(String name);
+    public ServiceReference getCommandReference(String name);
+    public void executeCommand(
+        String commandLine, PrintStream out, PrintStream err)
+        throws Exception;
+}</textarea>
+<script class="javascript">
+    if(!window.newcodemacro_initialised)
+    {
+        window.newcodemacro_initialised = true;
+        window.oldonloadmethod = window.onload;
+        window.onload = function(){
+            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
+            if(window.oldonloadmethod)
+            {
+                window.oldonloadmethod();
+            }
+        }
+    }
+
+</script>
+</div>
+
+
+<p>Using the shell service interface, it is possible to access and
+execute available commands. The shell service methods perform the
+following functions:</p>
+
+<ul>
+	<li><tt>getCommands()</tt> - returns an array of strings that correspond to the names of the installed shell commands.</li>
+	<li><tt>getCommandUsage()</tt> - returns the command usage string for a particular command name</li>
+	<li><tt>getCommandDescription()</tt> - returns a short description for a particular command name.</li>
+	<li><tt>getCommandReference()</tt> - returns the service reference for a particular command name.</li>
+	<li><tt>executeCommand()</tt> - executes a particular command using the specified command line and print streams.</li>
+</ul>
+
+
+<p>Most of the shell service methods require no explanation except for
+the executeCommand() method. Even though this method is the most
+complex, it is still fairly simplistic. The assumption of the shell
+service is that a command line will be typed by the user (or perhaps
+constructed by a GUI) and passed into it for execution. The shell
+service interprets the command line in a very simplistic fashion; it
+takes the leading string of characters terminated by a space character
+(not including it) and assumes that this leading token is the command
+name. Consider the following command line:</p>
+
+<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
+<pre>update 3 http://www.foo.com/bar.jar
+</pre>
+</div></div>
+
+<p>The shell service interprets this as an <tt>update</tt> command and
+will search for a command service with the same name. If a
+corresponding command service is not found, then it will print an error
+message to the error print stream. If a corresponding command service
+is found, then it will pass the entire command line string and the
+print streams into the <tt>executeCommand()</tt> method of the command service (for a more detailed description of command services, see the next section).</p>
+
+<p>Notice that there is no method to add commands to the shell service
+interface. This is because commands are implemented as OSGi services
+and the shell service listens for service events and when a command
+service registers/unregisters it automatically updates its list of
+commands accordingly.</p>
+
+<p><a name="ApacheFelixShellService-commands"></a></p>
+
+<h2><a name="ApacheFelixShellService-HowCommandsWork"></a>How Commands Work</h2>
+
+<p>All commands available in the shell service are implemented as OSGi
+services. The advantage of this approach is two-fold: the shell service
+can leverage OSGi service events to maintain its list of available
+commands and the set available commands is dynamically extendable by
+installed bundles. The command service interface is defined as follows:</p>
+
+<div class="code">
+<textarea name="newcodemacro" class="java:nocontrols:nogutter" rows="10" readonly="readonly">package org.apache.felix.shell;
+
+public interface Command
+{
+    public String getName();
+    public String getUsage();
+    public String getShortDescription();
+    public void execute(String line, PrintStream out, PrintStream err);
+}</textarea>
+<script class="javascript">
+    if(!window.newcodemacro_initialised)
+    {
+        window.newcodemacro_initialised = true;
+        window.oldonloadmethod = window.onload;
+        window.onload = function(){
+            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
+            if(window.oldonloadmethod)
+            {
+                window.oldonloadmethod();
+            }
+        }
+    }
+
+</script>
+</div>
+
+
+<p>The semantics of the command service methods are:</p>
+
+<ul>
+	<li><tt>getName()</tt> - returns the name of the command; this must not contain whitespace and must be unique.</li>
+	<li><tt>getUsage()</tt>
+- returns the usage string of the command; this should be one line and
+as short as possible (this is used for generating the help command
+output).</li>
+	<li><tt>getShortDescription()</tt> - returns a short
+description of the command; this should be one line and as short as
+possible (this is used for generating the help command output).</li>
+	<li><tt>execute()</tt> - executes the command's functionality using supplied command line and print streams.</li>
+</ul>
+
+
+<p><a name="ApacheFelixShellService-creating"></a></p>
+
+<h2><a name="ApacheFelixShellService-CreatingaCommand"></a>Creating a Command</h2>
+
+<p>The following example creates a simple version of the <tt>start</tt> command.</p>
+
+<div class="code">
+<textarea name="newcodemacro" class="java:nocontrols:nogutter" rows="10" readonly="readonly">package test;
+
+import java.io.PrintStream;
+import java.net.URL;
+import java.net.MalformedURLException;
+import java.util.StringTokenizer;
+
+import org.osgi.framework.*;
+import org.apache.felix.shell.ShellService;
+import org.apache.felix.shell.Command;
+
+public class MyStartCommandImpl implements Command
+{
+    private BundleContext m_context = null;
+
+    public MyStartCommandImpl(BundleContext context)
+    {
+        m_context = context;
+    }
+
+    public String getName()
+    {
+        return "mystart";
+    }
+
+    public String getUsage()
+    {
+        return "mystart &lt;id&gt; [&lt;id&gt; ...]";
+    }
+
+    public String getShortDescription()
+    {
+        return "start bundle(s).";
+    }
+
+    public void execute(String s, PrintStream out, PrintStream err)
+    {
+        StringTokenizer st = new StringTokenizer(s, " ");
+
+        // Ignore the command name.
+        st.nextToken();
+
+        // There should be at least one bundle id.
+        if (st.countTokens() &gt;= 1)
+        {
+            while (st.hasMoreTokens())
+            {
+                String id = st.nextToken().trim();
+
+                try {
+                    long l = Long.valueOf(id).longValue();
+                    Bundle bundle = m_context.getBundle(l);
+                    if (bundle != null)
+                    {
+                        bundle.start();
+                    }
+                    else
+                    {
+                        err.println("Bundle ID " + id + " is invalid.");
+                    }
+                } catch (NumberFormatException ex) {
+                    err.println("Unable to parse id '" + id + "'.");
+                } catch (BundleException ex) {
+                    if (ex.getNestedException() != null)
+                        err.println(ex.getNestedException().toString());
+                    else
+                        err.println(ex.toString());
+                } catch (Exception ex) {
+                    err.println(ex.toString());
+                }
+            }
+        }
+        else
+        {
+            err.println("Incorrect number of arguments");
+        }
+    }
+}</textarea>
+<script class="javascript">
+    if(!window.newcodemacro_initialised)
+    {
+        window.newcodemacro_initialised = true;
+        window.oldonloadmethod = window.onload;
+        window.onload = function(){
+            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
+            if(window.oldonloadmethod)
+            {
+                window.oldonloadmethod();
+            }
+        }
+    }
+
+</script>
+</div>
+
+
+<p>A bundle activator class is needed for packaging the command servce; the bundle activator registers the command service in its <tt>start()</tt> method. Note: You do not need one activator per command, a single activator can register any number of commands.</p>
+
+<div class="code">
+<textarea name="newcodemacro" class="java:nocontrols:nogutter" rows="10" readonly="readonly">package test;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+public class MyStartActivator implements BundleActivator
+{
+    private transient BundleContext m_context = null;
+
+    public void start(BundleContext context)
+    {
+        m_context = context;
+
+        // Register the command service.
+        context.registerService(
+            org.apache.felix.shell.Command.class.getName(),
+            new MyStartCommandImpl(m_context), null);
+    }
+
+    public void stop(BundleContext context)
+    {
+        // Services are automatically unregistered so
+        // we don't have to unregister the factory here.
+    }
+}</textarea>
+<script class="javascript">
+    if(!window.newcodemacro_initialised)
+    {
+        window.newcodemacro_initialised = true;
+        window.oldonloadmethod = window.onload;
+        window.onload = function(){
+            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
+            if(window.oldonloadmethod)
+            {
+                window.oldonloadmethod();
+            }
+        }
+    }
+
+</script>
+</div>
+
+
+<p>To compile these classes you will need to have the <tt>framework.jar</tt> file on your class path. Compile all of the source files using a command like:</p>
+
+<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
+<pre>java -d c:\classes *.java
+</pre>
+</div></div>
+
+<p>This command compiles all of the source files and outputs the generated class files into a subdirectory of the <tt>c:\classes</tt> directory, called test, named after the package of the source files; for the above command to work, the <tt>c:\classes</tt>
+directory must exist. Once you have compiled all of the above classes,
+you need to create a bundle JAR file of the generated package
+directory. The bundle JAR file needs a manifest, so create a file
+called <tt>manifest.mf</tt> with the following contents:</p>
+
+<div class="code">
+<textarea name="newcodemacro" class="java:nocontrols:nogutter" rows="10" readonly="readonly">Bundle-Name: My Start Command
+Bundle-Description: A 'start' command for the shell service.
+Bundle-Activator: test.MyStartActivator
+Bundle-ClassPath: .
+Import-Package: org.apache.felix.shell</textarea>
+<script class="javascript">
+    if(!window.newcodemacro_initialised)
+    {
+        window.newcodemacro_initialised = true;
+        window.oldonloadmethod = window.onload;
+        window.onload = function(){
+            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
+            if(window.oldonloadmethod)
+            {
+                window.oldonloadmethod();
+            }
+        }
+    }
+
+</script>
+</div>
+
+
+<p>To create the bundle JAR file, issue the command:</p>
+
+<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
+<pre>jar cfm mystart.jar manifest.mf -C c:\classes test
+</pre>
+</div></div>
+
+<p>This command creates a JAR file using the manifest you created and
+includes all of the classes in the test directory inside of the <tt>c:\classes</tt>
+directory. Once the bundle JAR file is created, you are ready to add
+the command service to the shell service; simply start Felix and
+install and start the bundle created by the above command. By doing so,
+the new <tt>mystart</tt> command is made available via the shell service.</p>
+
+<p><a name="ApacheFelixShellService-security"></a></p>
+
+<h2><a name="ApacheFelixShellService-SecurityandtheShellService"></a>Security and the Shell Service</h2>
+
+<p>The shell service security handling is quite simple, all security is
+handled by the standard OSGi framework mechanisms. For example, if a
+bundle should not be able to register a shell service, then it should
+not be given the corresponding service permission. Security handling
+may change in future release after some experience is gained through
+usage.</p>
+
+<p><a name="ApacheFelixShellService-feedback"></a></p>
+
+<h2><a name="ApacheFelixShellService-Feedback"></a>Feedback</h2>
+
+<p>Subscribe to the Felix users mailing list by sending a message to <a href="mailto:users-subscribe@felix.apache.org" rel="nofollow">users-subscribe@felix.apache.org</a>; after subscribing, email questions or feedback to <a href="mailto:users@felix.apache.org" rel="nofollow">users@felix.apache.org</a>.</p>
+    </div>
+  </body></html>