felix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Felix > RFC 147 Overview
Date Tue, 22 Dec 2009 22:57:00 GMT
<html>
<head>
    <base href="http://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/1519/1/1/_/styles/combined.css?spaceKey=FELIX&amp;forWysiwyg=true"
type="text/css">
    </head>
<body style="background-color: white" bgcolor="white">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
     <h2><a href="http://cwiki.apache.org/confluence/display/FELIX/RFC+147+Overview">RFC
147 Overview</a></h2>
     <h4>Page <b>edited</b> by             <a href="http://cwiki.apache.org/confluence/display/~dbaum">Derek
Baum</a>
    </h4>
     
          <br/>
     <div class="notificationGreySide">
         <h1><a name="RFC147Overview-RFC147Overview"></a>RFC-147 Overview</h1>

<p>The RFC-147 draft is not yet publicly available. It used to be called RFC-132, which
can be found about 40% into
<a href="http://www.osgi.org/download/osgi-4.2-early-draft.pdf" rel="nofollow">http://www.osgi.org/download/osgi-4.2-early-draft.pdf</a></p>

<p>This is an overview of its main features:</p>

<style type='text/css'>/*<![CDATA[*/
div.rbtoc1261522614847 {margin-left: 1.5em;padding: 0px;}
div.rbtoc1261522614847 ul {margin-left: 0px;padding-left: 10px;}
div.rbtoc1261522614847 li {margin-left: 0px;padding-left: 0px;}

/*]]>*/</style><div class='rbtoc1261522614847'>
<ul>
    <li><a href='#RFC147Overview-StandardwaytoimplementandruncommandsforanyOSGi4.2framework'>Standard
way to implement and run commands for any OSGi 4.2 framework</a></li>
    <li><a href='#RFC147Overview-Easytouseinteractivelynounnecessarysyntax.'>Easy
to use interactively - no unnecessary syntax.</a></li>
    <li><a href='#RFC147Overview-Provideslists%2Cpipesandclosures.'>Provides lists,
pipes and closures.</a></li>
    <li><a href='#RFC147Overview-LeveragesexistingJavacapabilities%2Cviareflection.'>Leverages
existing Java capabilities, via reflection.</a></li>
    <li><a href='#RFC147Overview-EasytoimplementandtestcommandswithoutneedingOSGi.'>Easy
to implement and test commands without needing OSGi.</a></li>
    <li><a href='#RFC147Overview-Normalcommandscanprovidecontrolprimitives.'>Normal
commands can provide control primitives.</a></li>
</ul></div>

<h2><a name="RFC147Overview-StandardwaytoimplementandruncommandsforanyOSGi4.2framework"></a>Standard
way to implement and run commands for any OSGi 4.2 framework</h2>

<p>Commands are registered via service attributes, you don't have to register a specific
service. This allows commands to be registered by existing services, just by adding the new
attributes:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
Dictionary&lt;<span class="code-object">String</span>, <span class="code-object">Object</span>&gt;
dict = <span class="code-keyword">new</span> Hashtable&lt;<span class="code-object">String</span>,
<span class="code-object">Object</span>&gt;();
dict.put(CommandProcessor.COMMAND_SCOPE, <span class="code-quote">"shell"</span>);
dict.put(CommandProcessor.COMMAND_FUNCTION, <span class="code-keyword">new</span>
<span class="code-object">String</span>[] {<span class="code-quote">"sleep"</span>,
<span class="code-quote">"grep"</span>});
context.registerService(name, service, dict);
</pre>
</div></div>

<p>Scope is used to provide a namespace for commands. The commands above can be invoked
as "shell:sleep" and "shell:grep". If the scope is omitted (e.g. "sleep" and "grep") then
the first matching command is invoked.</p>

<p>Commands can have any signature - arguments are coerced to call the best matching
method using reflection. A CommandSession argument is inserted if required:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> void sleep(<span class="code-object">long</span>
millis) <span class="code-keyword">throws</span> InterruptedException{
        <span class="code-object">Thread</span>.sleep(millis);
}

<span class="code-keyword">public</span> void sleep(<span class="code-object">String</span>[]
args) <span class="code-keyword">throws</span> Exception;

<span class="code-keyword">public</span> <span class="code-object">boolean</span>
grep(CommandSession session, <span class="code-object">String</span>[] args) <span
class="code-keyword">throws</span> Exception;
</pre>
</div></div>

<p>The CommandSession interface provides methods for executing commands and getting
and setting session variables:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> <span class="code-keyword">interface</span>
org.osgi.service.command.CommandSession {
        <span class="code-object">Object</span> execute(CharSequence commandline)
<span class="code-keyword">throws</span> Exception;
        <span class="code-object">Object</span> get(<span class="code-object">String</span>
name);
        
void put(<span class="code-object">String</span> name, <span class="code-object">Object</span>
value);
        ...
}
</pre>
</div></div>

<h2><a name="RFC147Overview-Easytouseinteractivelynounnecessarysyntax."></a>Easy
to use interactively - no unnecessary syntax.</h2>

<p>// simple command</p>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent
panelContent">
<pre>$ echo hello world
hello world
</pre>
</div></div>

<p>// session variables</p>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent
panelContent">
<pre>$ msg = "hello world"
$ echo $msg
hello world
</pre>
</div></div>

<p>// execution quotes () - similar to bash backquotes</p>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent
panelContent">
<pre>$ (bundle 1) location
file:/Users/derek/Downloads/felix-framework-2.0.1/bundle/org.apache.felix.bundlerepository-1.4.2.jar
</pre>
</div></div>

<h2><a name="RFC147Overview-Provideslists%2Cpipesandclosures."></a>Provides
lists, pipes and closures.</h2>

<p>// lists - []</p>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent
panelContent">
<pre>$ list = [1 2 a b]
1
2
a
b

$ map = [Jan=1 Feb=2 Mar=3]
Jan                 1
Feb                 2
Mar                 3
</pre>
</div></div>

<p>// pipes</p>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent
panelContent">
<pre>$ bundles | grep gogo
000002 ACT org.apache.felix.gogo.console-0.2.2
000003 ACT org.apache.felix.gogo.runtime-0.2.2
</pre>
</div></div>

<p>// closures - {}</p>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent
panelContent">
<pre>$ echo2 = { echo xxx $args yyy }
$ echo2 hello world
xxx hello world yyy
</pre>
</div></div>

<h2><a name="RFC147Overview-LeveragesexistingJavacapabilities%2Cviareflection."></a>Leverages
existing Java capabilities, via reflection.</h2>

<p>// exception handling - console shows summary, but full context available</p>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent
panelContent">
<pre>$ start xxx
E: Cannot coerce start[xxx] to any of [(Bundle)]
$ $exception printstacktrace
java.lang.IllegalArgumentException: Cannot coerce start[xxx] to any of [(Bundle)]
        at org.apache.felix.gogo.runtime.shell.Reflective.method(Reflective.java:162)
        at org.apache.felix.gogo.runtime.shell.Command.execute(Command.java:40)
        at org.apache.felix.gogo.runtime.shell.Closure.execute(Closure.java:211)
        at org.apache.felix.gogo.runtime.shell.Closure.executeStatement(Closure.java:146)
        at org.apache.felix.gogo.runtime.shell.Pipe.run(Pipe.java:91)
...
</pre>
</div></div>

<p>// add all public methods on java.lang.System as commands:</p>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent
panelContent">
<pre>$ addcommand system (loadClass java.lang.System)
$ system:getproperties
sun.io.unicode.encodingUnicodeLittle
java.version        1.5.0_19
java.class.path     bin/felix.jar
java.awt.graphicsenvapple.awt.CGraphicsEnvironment
user.language       en
sun.os.patch.level  unknown
os.version          10.6.2
[snip]
</pre>
</div></div>

<h2><a name="RFC147Overview-EasytoimplementandtestcommandswithoutneedingOSGi."></a>Easy
to implement and test commands without needing OSGi.</h2>

<p>Command implementations don't need to reference any OSGi interfaces. They can use
System.in, System.out and System.err, just as you would in a trivial Java application. The
ThreadIO service transparently manages the singleton System.out etc, so that each thread sees
the appropriate stream:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">    
<span class="code-keyword">public</span> void cat(<span class="code-object">String</span>[]
args) <span class="code-keyword">throws</span> Exception {
    <span class="code-keyword">for</span> (<span class="code-object">String</span>
arg : args)
        IOUtil.copy(arg, <span class="code-object">System</span>.out);
    }
</pre>
</div></div>

<h2><a name="RFC147Overview-Normalcommandscanprovidecontrolprimitives."></a>Normal
commands can provide control primitives.</h2>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">    
<span class="code-keyword">public</span> void each(CommandSession session, Collection&lt;<span
class="code-object">Object</span>&gt; list, Function, closure) <span class="code-keyword">throws</span>
Exception {   
    <span class="code-keyword">for</span> (<span class="code-object">Object</span>
x : list) {
        closure.execute(session, <span class="code-keyword">null</span>);
    }
}
</pre>
</div></div>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent
panelContent">
<pre>$ each [Jan Feb Mar] { echo $it | grep . }
Jan
Feb
Mar
</pre>
</div></div>

     </div>
     <div id="commentsSection" class="wiki-content pageSection">
       <div style="float: right;">
            <a href="http://cwiki.apache.org/confluence/users/viewnotifications.action"
class="grey">Change Notification Preferences</a>
       </div>

       <a href="http://cwiki.apache.org/confluence/display/FELIX/RFC+147+Overview">View
Online</a>
       |
       <a href="http://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=9797723&revisedVersion=2&originalVersion=1">View
Change</a>
              |
       <a href="http://cwiki.apache.org/confluence/display/FELIX/RFC+147+Overview?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message